diff --git a/.gitignore b/.gitignore index 8a1fc47c9d..aa2528a7fe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ -#ignore misc BYOND files -*.log -*.int -*.rsc -*.dmb -*.lk -data/ +#ignore misc BYOND files +*.log +*.int +*.rsc +*.dmb +*.lk +*.backup +data/ diff --git a/baystation12.dme b/baystation12.dme index 4746152b2a..9d2be5ed2b 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -31,6 +31,7 @@ #include "code\__HELPERS\turfs.dm" #include "code\__HELPERS\type2type.dm" #include "code\__HELPERS\unsorted.dm" +#include "code\__HELPERS\vector.dm" #include "code\_onclick\adjacent.dm" #include "code\_onclick\ai.dm" #include "code\_onclick\click.dm" @@ -93,8 +94,35 @@ #include "code\controllers\lighting_controller.dm" #include "code\controllers\master_controller.dm" #include "code\controllers\shuttle_controller.dm" +#include "code\controllers\subsystems.dm" #include "code\controllers\verbs.dm" #include "code\controllers\voting.dm" +#include "code\controllers\Processes\air.dm" +#include "code\controllers\Processes\alarm.dm" +#include "code\controllers\Processes\disease.dm" +#include "code\controllers\Processes\emergencyShuttle.dm" +#include "code\controllers\Processes\event.dm" +#include "code\controllers\Processes\inactivity.dm" +#include "code\controllers\Processes\lighting.dm" +#include "code\controllers\Processes\machinery.dm" +#include "code\controllers\Processes\mob.dm" +#include "code\controllers\Processes\nanoui.dm" +#include "code\controllers\Processes\obj.dm" +#include "code\controllers\Processes\pipenet.dm" +#include "code\controllers\Processes\powernet.dm" +#include "code\controllers\Processes\Shuttle.dm" +#include "code\controllers\Processes\sun.dm" +#include "code\controllers\Processes\supply.dm" +#include "code\controllers\Processes\ticker.dm" +#include "code\controllers\Processes\vote.dm" +#include "code\controllers\ProcessScheduler\core\_define.dm" +#include "code\controllers\ProcessScheduler\core\_stubs.dm" +#include "code\controllers\ProcessScheduler\core\process.dm" +#include "code\controllers\ProcessScheduler\core\processScheduler.dm" +#include "code\controllers\ProcessScheduler\core\updateQueue.dm" +#include "code\controllers\ProcessScheduler\core\updateQueueWorker.dm" +#include "code\controllers\subsystem\alarms.dm" +#include "code\datums\ai_law_sets.dm" #include "code\datums\ai_laws.dm" #include "code\datums\browser.dm" #include "code\datums\computerfiles.dm" @@ -106,7 +134,6 @@ #include "code\datums\modules.dm" #include "code\datums\organs.dm" #include "code\datums\recipe.dm" -#include "code\datums\spell.dm" #include "code\datums\sun.dm" #include "code\datums\supplypacks.dm" #include "code\datums\diseases\appendicitis.dm" @@ -150,21 +177,6 @@ #include "code\datums\helper_datums\global_iterator.dm" #include "code\datums\helper_datums\teleport.dm" #include "code\datums\helper_datums\topic_input.dm" -#include "code\datums\spells\area_teleport.dm" -#include "code\datums\spells\conjure.dm" -#include "code\datums\spells\dumbfire.dm" -#include "code\datums\spells\emplosion.dm" -#include "code\datums\spells\ethereal_jaunt.dm" -#include "code\datums\spells\explosion.dm" -#include "code\datums\spells\genetic.dm" -#include "code\datums\spells\horsemask.dm" -#include "code\datums\spells\inflict_handler.dm" -#include "code\datums\spells\knock.dm" -#include "code\datums\spells\mind_transfer.dm" -#include "code\datums\spells\projectile.dm" -#include "code\datums\spells\trigger.dm" -#include "code\datums\spells\turf_teleport.dm" -#include "code\datums\spells\wizard.dm" #include "code\datums\wires\airlock.dm" #include "code\datums\wires\alarm.dm" #include "code\datums\wires\apc.dm" @@ -201,8 +213,31 @@ #include "code\game\smoothwall.dm" #include "code\game\sound.dm" #include "code\game\supplyshuttle.dm" +#include "code\game\antagonist\antagonist.dm" +#include "code\game\antagonist\antagonist_build.dm" +#include "code\game\antagonist\antagonist_globals.dm" +#include "code\game\antagonist\antagonist_helpers.dm" +#include "code\game\antagonist\antagonist_objectives.dm" +#include "code\game\antagonist\antagonist_spawn.dm" +#include "code\game\antagonist\alien\borer.dm" +#include "code\game\antagonist\alien\xenomorph.dm" +#include "code\game\antagonist\outsider\commando.dm" +#include "code\game\antagonist\outsider\deathsquad.dm" +#include "code\game\antagonist\outsider\ert.dm" +#include "code\game\antagonist\outsider\mercenary.dm" +#include "code\game\antagonist\outsider\ninja.dm" +#include "code\game\antagonist\outsider\raider.dm" +#include "code\game\antagonist\outsider\wizard.dm" +#include "code\game\antagonist\station\changeling.dm" +#include "code\game\antagonist\station\cultist.dm" +#include "code\game\antagonist\station\highlander.dm" +#include "code\game\antagonist\station\renegade.dm" +#include "code\game\antagonist\station\revolutionary.dm" +#include "code\game\antagonist\station\rogue_ai.dm" +#include "code\game\antagonist\station\traitor.dm" #include "code\game\area\ai_monitored.dm" #include "code\game\area\areas.dm" +#include "code\game\area\asteroid_areas.dm" #include "code\game\area\Space Station 13 areas.dm" #include "code\game\dna\dna2.dm" #include "code\game\dna\dna2_domutcheck.dm" @@ -210,16 +245,13 @@ #include "code\game\dna\dna_modifier.dm" #include "code\game\dna\genes\disabilities.dm" #include "code\game\dna\genes\gene.dm" -#include "code\game\dna\genes\monkey.dm" #include "code\game\dna\genes\powers.dm" #include "code\game\gamemodes\events.dm" -#include "code\game\gamemodes\factions.dm" #include "code\game\gamemodes\game_mode.dm" #include "code\game\gamemodes\gameticker.dm" #include "code\game\gamemodes\intercept_report.dm" #include "code\game\gamemodes\objective.dm" #include "code\game\gamemodes\setupgame.dm" -#include "code\game\gamemodes\autotraitor\autotraitor.dm" #include "code\game\gamemodes\blob\blob.dm" #include "code\game\gamemodes\blob\theblob.dm" #include "code\game\gamemodes\blob\blobs\core.dm" @@ -230,21 +262,17 @@ #include "code\game\gamemodes\changeling\changeling.dm" #include "code\game\gamemodes\changeling\changeling_powers.dm" #include "code\game\gamemodes\changeling\modularchangling.dm" -#include "code\game\gamemodes\changeling\traitor_chan.dm" #include "code\game\gamemodes\cult\cult.dm" #include "code\game\gamemodes\cult\cult_items.dm" #include "code\game\gamemodes\cult\cult_structures.dm" #include "code\game\gamemodes\cult\ritual.dm" #include "code\game\gamemodes\cult\runes.dm" #include "code\game\gamemodes\cult\talisman.dm" -#include "code\game\gamemodes\events\biomass.dm" #include "code\game\gamemodes\events\black_hole.dm" #include "code\game\gamemodes\events\clang.dm" #include "code\game\gamemodes\events\dust.dm" #include "code\game\gamemodes\events\miniblob.dm" #include "code\game\gamemodes\events\power_failure.dm" -#include "code\game\gamemodes\events\space_ninja.dm" -#include "code\game\gamemodes\events\spacevines.dm" #include "code\game\gamemodes\events\wormholes.dm" #include "code\game\gamemodes\events\holidays\Christmas.dm" #include "code\game\gamemodes\events\holidays\Holidays.dm" @@ -255,32 +283,11 @@ #include "code\game\gamemodes\malfunction\malfunction.dm" #include "code\game\gamemodes\meteor\meteor.dm" #include "code\game\gamemodes\meteor\meteors.dm" -#include "code\game\gamemodes\mutiny\auth_key.dm" -#include "code\game\gamemodes\mutiny\directive.dm" -#include "code\game\gamemodes\mutiny\emergency_authentication_device.dm" -#include "code\game\gamemodes\mutiny\key_pinpointer.dm" -#include "code\game\gamemodes\mutiny\mutiny.dm" -#include "code\game\gamemodes\mutiny\mutiny_admin.dm" -#include "code\game\gamemodes\mutiny\mutiny_fluff.dm" -#include "code\game\gamemodes\mutiny\mutiny_hooks.dm" -#include "code\game\gamemodes\mutiny\directives\alien_fraud_directive.dm" -#include "code\game\gamemodes\mutiny\directives\bluespace_contagion_directive.dm" -#include "code\game\gamemodes\mutiny\directives\financial_crisis_directive.dm" -#include "code\game\gamemodes\mutiny\directives\ipc_virus_directive.dm" -#include "code\game\gamemodes\mutiny\directives\research_to_ripleys_directive.dm" -#include "code\game\gamemodes\mutiny\directives\tau_ceti_needs_women_directive.dm" -#include "code\game\gamemodes\mutiny\directives\terminations_directive.dm" #include "code\game\gamemodes\ninja\ninja.dm" #include "code\game\gamemodes\nuclear\nuclear.dm" -#include "code\game\gamemodes\nuclear\nuclearbomb.dm" #include "code\game\gamemodes\nuclear\pinpointer.dm" #include "code\game\gamemodes\revolution\revolution.dm" -#include "code\game\gamemodes\revolution\rp_revolution.dm" #include "code\game\gamemodes\traitor\traitor.dm" -#include "code\game\gamemodes\wizard\artifact.dm" -#include "code\game\gamemodes\wizard\rightandwrong.dm" -#include "code\game\gamemodes\wizard\soulstone.dm" -#include "code\game\gamemodes\wizard\spellbook.dm" #include "code\game\gamemodes\wizard\wizard.dm" #include "code\game\jobs\access.dm" #include "code\game\jobs\job_controller.dm" @@ -304,8 +311,8 @@ #include "code\game\machinery\autolathe.dm" #include "code\game\machinery\autolathe_datums.dm" #include "code\game\machinery\Beacon.dm" -#include "code\game\machinery\bees_apiary.dm" #include "code\game\machinery\bees_items.dm" +#include "code\game\machinery\biogenerator.dm" #include "code\game\machinery\bioprinter.dm" #include "code\game\machinery\buttons.dm" #include "code\game\machinery\cell_charger.dm" @@ -329,6 +336,7 @@ #include "code\game\machinery\mass_driver.dm" #include "code\game\machinery\navbeacon.dm" #include "code\game\machinery\newscaster.dm" +#include "code\game\machinery\nuclear_bomb.dm" #include "code\game\machinery\OpTable.dm" #include "code\game\machinery\overview.dm" #include "code\game\machinery\portable_tag_turret.dm" @@ -382,8 +390,6 @@ #include "code\game\machinery\computer\computer.dm" #include "code\game\machinery\computer\crew.dm" #include "code\game\machinery\computer\guestpass.dm" -#include "code\game\machinery\computer\HolodeckControl.dm" -#include "code\game\machinery\computer\hologram.dm" #include "code\game\machinery\computer\law.dm" #include "code\game\machinery\computer\medical.dm" #include "code\game\machinery\computer\message.dm" @@ -453,9 +459,7 @@ #include "code\game\machinery\embedded_controller\embedded_program_base.dm" #include "code\game\machinery\embedded_controller\simple_docking_controller.dm" #include "code\game\machinery\kitchen\gibber.dm" -#include "code\game\machinery\kitchen\juicer.dm" #include "code\game\machinery\kitchen\microwave.dm" -#include "code\game\machinery\kitchen\processor.dm" #include "code\game\machinery\kitchen\smartfridge.dm" #include "code\game\machinery\pipe\construction.dm" #include "code\game\machinery\pipe\pipe_dispenser.dm" @@ -489,6 +493,7 @@ #include "code\game\mecha\working\hoverpod.dm" #include "code\game\mecha\working\ripley.dm" #include "code\game\mecha\working\working.dm" +#include "code\game\objects\buckling.dm" #include "code\game\objects\empulse.dm" #include "code\game\objects\explosion.dm" #include "code\game\objects\explosion_recursive.dm" @@ -552,6 +557,7 @@ #include "code\game\objects\items\devices\pipe_painter.dm" #include "code\game\objects\items\devices\powersink.dm" #include "code\game\objects\items\devices\scanners.dm" +#include "code\game\objects\items\devices\spy_bug.dm" #include "code\game\objects\items\devices\suit_cooling.dm" #include "code\game\objects\items\devices\taperecorder.dm" #include "code\game\objects\items\devices\traitordevices.dm" @@ -572,6 +578,7 @@ #include "code\game\objects\items\robot\robot_items.dm" #include "code\game\objects\items\robot\robot_parts.dm" #include "code\game\objects\items\robot\robot_upgrades.dm" +#include "code\game\objects\items\stacks\matter_synth.dm" #include "code\game\objects\items\stacks\medical.dm" #include "code\game\objects\items\stacks\nanopaste.dm" #include "code\game\objects\items\stacks\rods.dm" @@ -632,9 +639,12 @@ #include "code\game\objects\items\weapons\circuitboards\computer\research.dm" #include "code\game\objects\items\weapons\circuitboards\computer\supply.dm" #include "code\game\objects\items\weapons\circuitboards\computer\telecomms.dm" +#include "code\game\objects\items\weapons\circuitboards\machinery\biogenerator.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\cloning.dm" +#include "code\game\objects\items\weapons\circuitboards\machinery\mining_drill.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\pacman.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\power.dm" +#include "code\game\objects\items\weapons\circuitboards\machinery\recharge_station.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\research.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\shieldgen.dm" #include "code\game\objects\items\weapons\circuitboards\machinery\telecomms.dm" @@ -704,6 +714,7 @@ #include "code\game\objects\structures\tank_dispenser.dm" #include "code\game\objects\structures\target_stake.dm" #include "code\game\objects\structures\transit_tubes.dm" +#include "code\game\objects\structures\under_wardrobe.dm" #include "code\game\objects\structures\watercloset.dm" #include "code\game\objects\structures\windoor_assembly.dm" #include "code\game\objects\structures\window.dm" @@ -779,6 +790,7 @@ #include "code\modules\admin\verbs\adminjump.dm" #include "code\modules\admin\verbs\adminpm.dm" #include "code\modules\admin\verbs\adminsay.dm" +#include "code\modules\admin\verbs\antag-ooc.dm" #include "code\modules\admin\verbs\atmosdebug.dm" #include "code\modules\admin\verbs\BrokenInhands.dm" #include "code\modules\admin\verbs\buildmode.dm" @@ -789,11 +801,10 @@ #include "code\modules\admin\verbs\debug.dm" #include "code\modules\admin\verbs\diagnostics.dm" #include "code\modules\admin\verbs\getlogs.dm" +#include "code\modules\admin\verbs\icarus.dm" #include "code\modules\admin\verbs\mapping.dm" #include "code\modules\admin\verbs\massmodvar.dm" #include "code\modules\admin\verbs\modifyvariables.dm" -#include "code\modules\admin\verbs\one_click_antag.dm" -#include "code\modules\admin\verbs\onlyone.dm" #include "code\modules\admin\verbs\playsound.dm" #include "code\modules\admin\verbs\possess.dm" #include "code\modules\admin\verbs\pray.dm" @@ -802,10 +813,15 @@ #include "code\modules\admin\verbs\SDQL_2.dm" #include "code\modules\admin\verbs\SDQL_2_parser.dm" #include "code\modules\admin\verbs\striketeam.dm" -#include "code\modules\admin\verbs\striketeam_syndicate.dm" #include "code\modules\admin\verbs\ticklag.dm" #include "code\modules\admin\verbs\tripAI.dm" -#include "code\modules\admin\verbs\vox_raiders.dm" +#include "code\modules\alarm\alarm.dm" +#include "code\modules\alarm\alarm_handler.dm" +#include "code\modules\alarm\atmosphere_alarm.dm" +#include "code\modules\alarm\camera_alarm.dm" +#include "code\modules\alarm\fire_alarm.dm" +#include "code\modules\alarm\motion_alarm.dm" +#include "code\modules\alarm\power_alarm.dm" #include "code\modules\assembly\assembly.dm" #include "code\modules\assembly\bomb.dm" #include "code\modules\assembly\helpers.dm" @@ -871,7 +887,6 @@ #include "code\modules\clothing\spacesuits\rig\modules\computer.dm" #include "code\modules\clothing\spacesuits\rig\modules\modules.dm" #include "code\modules\clothing\spacesuits\rig\modules\ninja.dm" -#include "code\modules\clothing\spacesuits\rig\modules\rig_weapons.dm" #include "code\modules\clothing\spacesuits\rig\modules\utility.dm" #include "code\modules\clothing\spacesuits\rig\modules\vision.dm" #include "code\modules\clothing\spacesuits\rig\suits\alien.dm" @@ -898,14 +913,16 @@ #include "code\modules\clothing\under\miscellaneous.dm" #include "code\modules\clothing\under\shorts.dm" #include "code\modules\clothing\under\syndicate.dm" -#include "code\modules\clothing\under\ties.dm" +#include "code\modules\clothing\under\accessories\accessory.dm" +#include "code\modules\clothing\under\accessories\armband.dm" +#include "code\modules\clothing\under\accessories\holster.dm" +#include "code\modules\clothing\under\accessories\storage.dm" #include "code\modules\clothing\under\jobs\civilian.dm" #include "code\modules\clothing\under\jobs\engineering.dm" #include "code\modules\clothing\under\jobs\medsci.dm" #include "code\modules\clothing\under\jobs\security.dm" #include "code\modules\customitems\item_defines.dm" #include "code\modules\customitems\item_spawning.dm" -#include "code\modules\destilery\main.dm" #include "code\modules\detectivework\evidence.dm" #include "code\modules\detectivework\footprints_and_rag.dm" #include "code\modules\detectivework\forensics.dm" @@ -919,11 +936,8 @@ #include "code\modules\economy\EFTPOS.dm" #include "code\modules\economy\Events.dm" #include "code\modules\economy\Events_Mundane.dm" -#include "code\modules\economy\Job_Departments.dm" #include "code\modules\economy\TradeDestinations.dm" -#include "code\modules\events\alien_infestation.dm" #include "code\modules\events\blob.dm" -#include "code\modules\events\borers.dm" #include "code\modules\events\brand_intelligence.dm" #include "code\modules\events\carp_migration.dm" #include "code\modules\events\comms_blackout.dm" @@ -943,6 +957,7 @@ #include "code\modules\events\money_spam.dm" #include "code\modules\events\prison_break.dm" #include "code\modules\events\radiation_storm.dm" +#include "code\modules\events\random_antagonist.dm" #include "code\modules\events\rogue_drones.dm" #include "code\modules\events\space_ninja.dm" #include "code\modules\events\spacevine.dm" @@ -950,6 +965,15 @@ #include "code\modules\events\spontaneous_appendicitis.dm" #include "code\modules\events\viral_infection.dm" #include "code\modules\events\wallrot.dm" +#include "code\modules\examine\examine.dm" +#include "code\modules\examine\descriptions\atmospherics.dm" +#include "code\modules\examine\descriptions\engineering.dm" +#include "code\modules\examine\descriptions\medical.dm" +#include "code\modules\examine\descriptions\mobs.dm" +#include "code\modules\examine\descriptions\stacks.dm" +#include "code\modules\examine\descriptions\structures.dm" +#include "code\modules\examine\descriptions\turfs.dm" +#include "code\modules\examine\descriptions\weapons.dm" #include "code\modules\ext_scripts\irc.dm" #include "code\modules\ext_scripts\python.dm" #include "code\modules\flufftext\Dreaming.dm" @@ -958,15 +982,29 @@ #include "code\modules\food\recipes_microwave.dm" #include "code\modules\games\cards.dm" #include "code\modules\genetics\side_effects.dm" -#include "code\modules\hydroponics\biogenerator.dm" +#include "code\modules\holodeck\HolodeckControl.dm" +#include "code\modules\holodeck\HolodeckObjects.dm" +#include "code\modules\hydroponics\_hydro_setup.dm" +#include "code\modules\hydroponics\grown.dm" #include "code\modules\hydroponics\grown_inedible.dm" -#include "code\modules\hydroponics\hydro_tools.dm" -#include "code\modules\hydroponics\hydro_tray.dm" +#include "code\modules\hydroponics\grown_predefined.dm" +#include "code\modules\hydroponics\seed.dm" +#include "code\modules\hydroponics\seed_controller.dm" #include "code\modules\hydroponics\seed_datums.dm" #include "code\modules\hydroponics\seed_machines.dm" #include "code\modules\hydroponics\seed_mobs.dm" -#include "code\modules\hydroponics\seeds.dm" -#include "code\modules\hydroponics\vines.dm" +#include "code\modules\hydroponics\seed_packets.dm" +#include "code\modules\hydroponics\seed_storage.dm" +#include "code\modules\hydroponics\spreading\spreading.dm" +#include "code\modules\hydroponics\spreading\spreading_growth.dm" +#include "code\modules\hydroponics\spreading\spreading_response.dm" +#include "code\modules\hydroponics\trays\tray.dm" +#include "code\modules\hydroponics\trays\tray_apiary.dm" +#include "code\modules\hydroponics\trays\tray_process.dm" +#include "code\modules\hydroponics\trays\tray_reagents.dm" +#include "code\modules\hydroponics\trays\tray_soil.dm" +#include "code\modules\hydroponics\trays\tray_tools.dm" +#include "code\modules\hydroponics\trays\tray_update_icons.dm" #include "code\modules\library\lib_items.dm" #include "code\modules\library\lib_machines.dm" #include "code\modules\library\lib_readme.dm" @@ -982,7 +1020,6 @@ #include "code\modules\mining\machine_processing.dm" #include "code\modules\mining\machine_stacking.dm" #include "code\modules\mining\machine_unloading.dm" -#include "code\modules\mining\mine_areas.dm" #include "code\modules\mining\mine_items.dm" #include "code\modules\mining\mine_turfs.dm" #include "code\modules\mining\minerals.dm" @@ -991,7 +1028,6 @@ #include "code\modules\mining\ore.dm" #include "code\modules\mining\ore_datum.dm" #include "code\modules\mining\satchel_ore_boxdm.dm" -#include "code\modules\mining\drilling\distribution.dm" #include "code\modules\mining\drilling\drill.dm" #include "code\modules\mining\drilling\scanner.dm" #include "code\modules\mob\death.dm" @@ -999,7 +1035,6 @@ #include "code\modules\mob\hear_say.dm" #include "code\modules\mob\holder.dm" #include "code\modules\mob\inventory.dm" -#include "code\modules\mob\language.dm" #include "code\modules\mob\login.dm" #include "code\modules\mob\logout.dm" #include "code\modules\mob\mob.dm" @@ -1017,6 +1052,16 @@ #include "code\modules\mob\dead\observer\logout.dm" #include "code\modules\mob\dead\observer\observer.dm" #include "code\modules\mob\dead\observer\say.dm" +#include "code\modules\mob\freelook\chunk.dm" +#include "code\modules\mob\freelook\eye.dm" +#include "code\modules\mob\freelook\update_triggers.dm" +#include "code\modules\mob\freelook\visualnet.dm" +#include "code\modules\mob\language\generic.dm" +#include "code\modules\mob\language\language.dm" +#include "code\modules\mob\language\monkey.dm" +#include "code\modules\mob\language\outsider.dm" +#include "code\modules\mob\language\station.dm" +#include "code\modules\mob\language\synthetic.dm" #include "code\modules\mob\living\damage_procs.dm" #include "code\modules\mob\living\living.dm" #include "code\modules\mob\living\living_defense.dm" @@ -1026,11 +1071,13 @@ #include "code\modules\mob\living\logout.dm" #include "code\modules\mob\living\say.dm" #include "code\modules\mob\living\blob\blob.dm" +#include "code\modules\mob\living\carbon\breathe.dm" #include "code\modules\mob\living\carbon\carbon.dm" #include "code\modules\mob\living\carbon\carbon_defines.dm" #include "code\modules\mob\living\carbon\carbon_powers.dm" #include "code\modules\mob\living\carbon\give.dm" #include "code\modules\mob\living\carbon\shock.dm" +#include "code\modules\mob\living\carbon\viruses.dm" #include "code\modules\mob\living\carbon\alien\alien.dm" #include "code\modules\mob\living\carbon\alien\alien_attacks.dm" #include "code\modules\mob\living\carbon\alien\alien_damage.dm" @@ -1060,6 +1107,7 @@ #include "code\modules\mob\living\carbon\brain\posibrain.dm" #include "code\modules\mob\living\carbon\brain\robot.dm" #include "code\modules\mob\living\carbon\brain\say.dm" +#include "code\modules\mob\living\carbon\human\appearance.dm" #include "code\modules\mob\living\carbon\human\death.dm" #include "code\modules\mob\living\carbon\human\emote.dm" #include "code\modules\mob\living\carbon\human\examine.dm" @@ -1076,6 +1124,7 @@ #include "code\modules\mob\living\carbon\human\login.dm" #include "code\modules\mob\living\carbon\human\logout.dm" #include "code\modules\mob\living\carbon\human\MedicalSideEffects.dm" +#include "code\modules\mob\living\carbon\human\npcs.dm" #include "code\modules\mob\living\carbon\human\say.dm" #include "code\modules\mob\living\carbon\human\unarmed_attack.dm" #include "code\modules\mob\living\carbon\human\update_icons.dm" @@ -1086,6 +1135,7 @@ #include "code\modules\mob\living\carbon\human\species\outsider\shadow.dm" #include "code\modules\mob\living\carbon\human\species\outsider\vox.dm" #include "code\modules\mob\living\carbon\human\species\station\golem.dm" +#include "code\modules\mob\living\carbon\human\species\station\monkey.dm" #include "code\modules\mob\living\carbon\human\species\station\slime.dm" #include "code\modules\mob\living\carbon\human\species\station\station.dm" #include "code\modules\mob\living\carbon\human\species\xenomorphs\alien_embryo.dm" @@ -1097,6 +1147,7 @@ #include "code\modules\mob\living\carbon\metroid\emote.dm" #include "code\modules\mob\living\carbon\metroid\examine.dm" #include "code\modules\mob\living\carbon\metroid\hud.dm" +#include "code\modules\mob\living\carbon\metroid\items.dm" #include "code\modules\mob\living\carbon\metroid\life.dm" #include "code\modules\mob\living\carbon\metroid\login.dm" #include "code\modules\mob\living\carbon\metroid\metroid.dm" @@ -1104,28 +1155,22 @@ #include "code\modules\mob\living\carbon\metroid\say.dm" #include "code\modules\mob\living\carbon\metroid\subtypes.dm" #include "code\modules\mob\living\carbon\metroid\update_icons.dm" -#include "code\modules\mob\living\carbon\monkey\death.dm" -#include "code\modules\mob\living\carbon\monkey\emote.dm" -#include "code\modules\mob\living\carbon\monkey\examine.dm" -#include "code\modules\mob\living\carbon\monkey\inventory.dm" -#include "code\modules\mob\living\carbon\monkey\life.dm" -#include "code\modules\mob\living\carbon\monkey\login.dm" -#include "code\modules\mob\living\carbon\monkey\monkey.dm" -#include "code\modules\mob\living\carbon\monkey\update_icons.dm" -#include "code\modules\mob\living\silicon\alarm.dm" #include "code\modules\mob\living\silicon\death.dm" #include "code\modules\mob\living\silicon\laws.dm" #include "code\modules\mob\living\silicon\login.dm" #include "code\modules\mob\living\silicon\say.dm" #include "code\modules\mob\living\silicon\silicon.dm" +#include "code\modules\mob\living\silicon\subystems.dm" #include "code\modules\mob\living\silicon\ai\ai.dm" #include "code\modules\mob\living\silicon\ai\death.dm" #include "code\modules\mob\living\silicon\ai\examine.dm" +#include "code\modules\mob\living\silicon\ai\latejoin.dm" #include "code\modules\mob\living\silicon\ai\laws.dm" #include "code\modules\mob\living\silicon\ai\life.dm" #include "code\modules\mob\living\silicon\ai\login.dm" #include "code\modules\mob\living\silicon\ai\logout.dm" #include "code\modules\mob\living\silicon\ai\say.dm" +#include "code\modules\mob\living\silicon\ai\subsystems.dm" #include "code\modules\mob\living\silicon\ai\freelook\cameranet.dm" #include "code\modules\mob\living\silicon\ai\freelook\chunk.dm" #include "code\modules\mob\living\silicon\ai\freelook\eye.dm" @@ -1142,6 +1187,7 @@ #include "code\modules\mob\living\silicon\pai\recruit.dm" #include "code\modules\mob\living\silicon\pai\say.dm" #include "code\modules\mob\living\silicon\pai\software.dm" +#include "code\modules\mob\living\silicon\pai\software_modules.dm" #include "code\modules\mob\living\silicon\robot\analyzer.dm" #include "code\modules\mob\living\silicon\robot\component.dm" #include "code\modules\mob\living\silicon\robot\death.dm" @@ -1164,7 +1210,6 @@ #include "code\modules\mob\living\silicon\robot\drone\drone_items.dm" #include "code\modules\mob\living\silicon\robot\drone\drone_manufacturer.dm" #include "code\modules\mob\living\simple_animal\bees.dm" -#include "code\modules\mob\living\simple_animal\constructs.dm" #include "code\modules\mob\living\simple_animal\corpse.dm" #include "code\modules\mob\living\simple_animal\parrot.dm" #include "code\modules\mob\living\simple_animal\shade.dm" @@ -1174,6 +1219,8 @@ #include "code\modules\mob\living\simple_animal\borer\borer_captive.dm" #include "code\modules\mob\living\simple_animal\borer\borer_powers.dm" #include "code\modules\mob\living\simple_animal\borer\say.dm" +#include "code\modules\mob\living\simple_animal\constructs\constructs.dm" +#include "code\modules\mob\living\simple_animal\constructs\soulstone.dm" #include "code\modules\mob\living\simple_animal\friendly\cat.dm" #include "code\modules\mob\living\simple_animal\friendly\corgi.dm" #include "code\modules\mob\living\simple_animal\friendly\crab.dm" @@ -1211,9 +1258,17 @@ #include "code\modules\nano\JSON Reader.dm" #include "code\modules\nano\JSON Writer.dm" #include "code\modules\nano\nanoexternal.dm" +#include "code\modules\nano\nanointeraction.dm" #include "code\modules\nano\nanomanager.dm" #include "code\modules\nano\nanomapgen.dm" #include "code\modules\nano\nanoui.dm" +#include "code\modules\nano\modules\alarm_monitor.dm" +#include "code\modules\nano\modules\crew_monitor.dm" +#include "code\modules\nano\modules\human_appearance.dm" +#include "code\modules\nano\modules\law_manager.dm" +#include "code\modules\nano\modules\nano_module.dm" +#include "code\modules\nano\modules\power_monitor.dm" +#include "code\modules\nano\modules\rcon.dm" #include "code\modules\organs\blood.dm" #include "code\modules\organs\organ.dm" #include "code\modules\organs\organ_alien.dm" @@ -1268,7 +1323,6 @@ #include "code\modules\power\antimatter\containment_jar.dm" #include "code\modules\power\antimatter\control.dm" #include "code\modules\power\antimatter\shielding.dm" -#include "code\modules\power\rust\areas.dm" #include "code\modules\power\rust\circuits_and_design.dm" #include "code\modules\power\rust\core_control.dm" #include "code\modules\power\rust\core_field.dm" @@ -1302,6 +1356,7 @@ #include "code\modules\power\singularity\particle_accelerator\particle_emitter.dm" #include "code\modules\power\singularity\particle_accelerator\particle_power.dm" #include "code\modules\projectiles\ammunition.dm" +#include "code\modules\projectiles\effects.dm" #include "code\modules\projectiles\gun.dm" #include "code\modules\projectiles\projectile.dm" #include "code\modules\projectiles\targeting.dm" @@ -1309,6 +1364,7 @@ #include "code\modules\projectiles\ammunition\bullets.dm" #include "code\modules\projectiles\guns\alien.dm" #include "code\modules\projectiles\guns\energy.dm" +#include "code\modules\projectiles\guns\launcher.dm" #include "code\modules\projectiles\guns\projectile.dm" #include "code\modules\projectiles\guns\energy\laser.dm" #include "code\modules\projectiles\guns\energy\nuclear.dm" @@ -1316,14 +1372,17 @@ #include "code\modules\projectiles\guns\energy\special.dm" #include "code\modules\projectiles\guns\energy\stun.dm" #include "code\modules\projectiles\guns\energy\temperature.dm" +#include "code\modules\projectiles\guns\launcher\crossbow.dm" +#include "code\modules\projectiles\guns\launcher\grenade_launcher.dm" +#include "code\modules\projectiles\guns\launcher\pneumatic.dm" +#include "code\modules\projectiles\guns\launcher\rocket.dm" +#include "code\modules\projectiles\guns\launcher\syringe_gun.dm" #include "code\modules\projectiles\guns\projectile\automatic.dm" -#include "code\modules\projectiles\guns\projectile\crossbow.dm" -#include "code\modules\projectiles\guns\projectile\launcher.dm" +#include "code\modules\projectiles\guns\projectile\dartgun.dm" #include "code\modules\projectiles\guns\projectile\pistol.dm" -#include "code\modules\projectiles\guns\projectile\pneumatic.dm" #include "code\modules\projectiles\guns\projectile\revolver.dm" -#include "code\modules\projectiles\guns\projectile\rocket.dm" #include "code\modules\projectiles\guns\projectile\shotgun.dm" +#include "code\modules\projectiles\guns\projectile\sniper.dm" #include "code\modules\projectiles\projectile\animate.dm" #include "code\modules\projectiles\projectile\beams.dm" #include "code\modules\projectiles\projectile\bullets.dm" @@ -1331,6 +1390,8 @@ #include "code\modules\projectiles\projectile\energy.dm" #include "code\modules\projectiles\projectile\force.dm" #include "code\modules\projectiles\projectile\special.dm" +#include "code\modules\random_map\mining_distribution.dm" +#include "code\modules\random_map\random_map.dm" #include "code\modules\reagents\Chemistry-Colours.dm" #include "code\modules\reagents\Chemistry-Holder.dm" #include "code\modules\reagents\Chemistry-Machinery.dm" @@ -1338,11 +1399,14 @@ #include "code\modules\reagents\Chemistry-Reagents-Antidepressants.dm" #include "code\modules\reagents\Chemistry-Reagents.dm" #include "code\modules\reagents\Chemistry-Recipes.dm" -#include "code\modules\reagents\dartgun.dm" -#include "code\modules\reagents\grenade_launcher.dm" #include "code\modules\reagents\reagent_containers.dm" #include "code\modules\reagents\reagent_dispenser.dm" -#include "code\modules\reagents\syringe_gun.dm" +#include "code\modules\reagents\dispenser\_defines.dm" +#include "code\modules\reagents\dispenser\cartridge.dm" +#include "code\modules\reagents\dispenser\cartridge_presets.dm" +#include "code\modules\reagents\dispenser\dispenser2.dm" +#include "code\modules\reagents\dispenser\dispenser_presets.dm" +#include "code\modules\reagents\dispenser\supply.dm" #include "code\modules\reagents\reagent_containers\blood_pack.dm" #include "code\modules\reagents\reagent_containers\borghydro.dm" #include "code\modules\reagents\reagent_containers\dropper.dm" @@ -1362,7 +1426,6 @@ #include "code\modules\reagents\reagent_containers\food\drinks\drinkingglass.dm" #include "code\modules\reagents\reagent_containers\food\drinks\jar.dm" #include "code\modules\reagents\reagent_containers\food\drinks\bottle\robot.dm" -#include "code\modules\reagents\reagent_containers\food\snacks\grown.dm" #include "code\modules\reagents\reagent_containers\food\snacks\meat.dm" #include "code\modules\reagents\reagent_containers\glass\bottle.dm" #include "code\modules\reagents\reagent_containers\glass\bottle\robot.dm" @@ -1380,7 +1443,6 @@ #include "code\modules\research\rdmachines.dm" #include "code\modules\research\research.dm" #include "code\modules\research\server.dm" -#include "code\modules\research\xenoarchaeology\areas.dm" #include "code\modules\research\xenoarchaeology\chemistry.dm" #include "code\modules\research\xenoarchaeology\geosample.dm" #include "code\modules\research\xenoarchaeology\manuals.dm" @@ -1423,7 +1485,6 @@ #include "code\modules\research\xenoarchaeology\finds\finds_special.dm" #include "code\modules\research\xenoarchaeology\finds\finds_talkingitem.dm" #include "code\modules\research\xenoarchaeology\genetics\prehistoric_animals.dm" -#include "code\modules\research\xenoarchaeology\genetics\prehistoric_plants.dm" #include "code\modules\research\xenoarchaeology\genetics\reconstitutor.dm" #include "code\modules\research\xenoarchaeology\machinery\artifact_analyser.dm" #include "code\modules\research\xenoarchaeology\machinery\artifact_harvester.dm" @@ -1479,6 +1540,24 @@ #include "code\modules\shuttles\shuttle_specops.dm" #include "code\modules\shuttles\shuttle_supply.dm" #include "code\modules\shuttles\shuttles_multi.dm" +#include "code\modules\spells\area_teleport.dm" +#include "code\modules\spells\conjure.dm" +#include "code\modules\spells\dumbfire.dm" +#include "code\modules\spells\emplosion.dm" +#include "code\modules\spells\ethereal_jaunt.dm" +#include "code\modules\spells\explosion.dm" +#include "code\modules\spells\genetic.dm" +#include "code\modules\spells\horsemask.dm" +#include "code\modules\spells\inflict_handler.dm" +#include "code\modules\spells\knock.dm" +#include "code\modules\spells\mind_transfer.dm" +#include "code\modules\spells\projectile.dm" +#include "code\modules\spells\spell.dm" +#include "code\modules\spells\spellbook.dm" +#include "code\modules\spells\trigger.dm" +#include "code\modules\spells\turf_teleport.dm" +#include "code\modules\spells\wizard_artifacts.dm" +#include "code\modules\spells\wizard_spells.dm" #include "code\modules\supermatter\supermatter.dm" #include "code\modules\surgery\bones.dm" #include "code\modules\surgery\brainrepair.dm" @@ -1496,6 +1575,7 @@ #include "code\modules\vehicles\cargo_train.dm" #include "code\modules\vehicles\train.dm" #include "code\modules\vehicles\vehicle.dm" +#include "code\modules\virus2\admin.dm" #include "code\modules\virus2\analyser.dm" #include "code\modules\virus2\antibodies.dm" #include "code\modules\virus2\centrifuge.dm" diff --git a/code/ATMOSPHERICS/_atmos_setup.dm b/code/ATMOSPHERICS/_atmos_setup.dm index 14efbb7de1..47903bfdc6 100644 --- a/code/ATMOSPHERICS/_atmos_setup.dm +++ b/code/ATMOSPHERICS/_atmos_setup.dm @@ -17,6 +17,7 @@ #define CONNECT_TYPE_REGULAR 1 #define CONNECT_TYPE_SUPPLY 2 #define CONNECT_TYPE_SCRUBBER 4 +#define CONNECT_TYPE_HE 8 var/global/list/pipe_colors = list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_RED, "blue" = PIPE_COLOR_BLUE, "cyan" = PIPE_COLOR_CYAN, "green" = PIPE_COLOR_GREEN, "yellow" = PIPE_COLOR_YELLOW, "purple" = PIPE_COLOR_PURPLE) diff --git a/code/ATMOSPHERICS/_atmospherics_helpers.dm b/code/ATMOSPHERICS/_atmospherics_helpers.dm index 149ac5f1b1..1f73566fbc 100644 --- a/code/ATMOSPHERICS/_atmospherics_helpers.dm +++ b/code/ATMOSPHERICS/_atmospherics_helpers.dm @@ -26,7 +26,7 @@ //transfer_moles - Limits the amount of moles to transfer. The actual amount of gas moved may also be limited by available_power, if given. //available_power - the maximum amount of power that may be used when moving gas. If null then the transfer is not limited by power. /proc/pump_gas(var/obj/machinery/M, var/datum/gas_mixture/source, var/datum/gas_mixture/sink, var/transfer_moles = null, var/available_power = null) - if (source.total_moles < MINUMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing + if (source.total_moles < MINIMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing return -1 //var/source_moles_initial = source.total_moles @@ -41,7 +41,7 @@ if (!isnull(available_power) && specific_power > 0) transfer_moles = min(transfer_moles, available_power / specific_power) - if (transfer_moles < MINUMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing + if (transfer_moles < MINIMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing return -1 //Update flow rate meter @@ -75,7 +75,7 @@ //total_transfer_moles - Limits the amount of moles to scrub. The actual amount of gas scrubbed may also be limited by available_power, if given. //available_power - the maximum amount of power that may be used when scrubbing gas. If null then the scrubbing is not limited by power. /proc/scrub_gas(var/obj/machinery/M, var/list/filtering, var/datum/gas_mixture/source, var/datum/gas_mixture/sink, var/total_transfer_moles = null, var/available_power = null) - if (source.total_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing + if (source.total_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing return -1 filtering = filtering & source.gas //only filter gasses that are actually there. DO NOT USE &= @@ -84,14 +84,14 @@ var/total_filterable_moles = 0 //the total amount of filterable gas var/list/specific_power_gas = list() //the power required to remove one mole of pure gas, for each gas type for (var/g in filtering) - if (source.gas[g] < MINUMUM_MOLES_TO_FILTER) + if (source.gas[g] < MINIMUM_MOLES_TO_FILTER) continue var/specific_power = calculate_specific_power_gas(g, source, sink)/ATMOS_FILTER_EFFICIENCY specific_power_gas[g] = specific_power total_filterable_moles += source.gas[g] - if (total_filterable_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing + if (total_filterable_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing return -1 //now that we know the total amount of filterable gas, we can calculate the amount of power needed to scrub one mole of gas @@ -110,7 +110,7 @@ if (!isnull(available_power) && total_specific_power > 0) total_transfer_moles = min(total_transfer_moles, available_power/total_specific_power) - if (total_transfer_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing + if (total_transfer_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing return -1 //Update flow rate var @@ -146,7 +146,7 @@ //total_transfer_moles - Limits the amount of moles to input. The actual amount of gas filtered may also be limited by available_power, if given. //available_power - the maximum amount of power that may be used when filtering gas. If null then the filtering is not limited by power. /proc/filter_gas(var/obj/machinery/M, var/list/filtering, var/datum/gas_mixture/source, var/datum/gas_mixture/sink_filtered, var/datum/gas_mixture/sink_clean, var/total_transfer_moles = null, var/available_power = null) - if (source.total_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing + if (source.total_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing return -1 filtering = filtering & source.gas //only filter gasses that are actually there. DO NOT USE &= @@ -156,7 +156,7 @@ var/total_unfilterable_moles = 0 //the total amount of non-filterable gas var/list/specific_power_gas = list() //the power required to remove one mole of pure gas, for each gas type for (var/g in source.gas) - if (source.gas[g] < MINUMUM_MOLES_TO_FILTER) + if (source.gas[g] < MINIMUM_MOLES_TO_FILTER) continue if (g in filtering) @@ -179,7 +179,7 @@ if (!isnull(available_power) && total_specific_power > 0) total_transfer_moles = min(total_transfer_moles, available_power/total_specific_power) - if (total_transfer_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing + if (total_transfer_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing return -1 //Update flow rate var @@ -218,7 +218,7 @@ //I don't like the copypasta, but I decided to keep both versions of gas filtering as filter_gas is slightly faster (doesn't create as many temporary lists, doesn't call update_values() as much) //filter_gas can be removed and replaced with this proc if need be. /proc/filter_gas_multi(var/obj/machinery/M, var/list/filtering, var/datum/gas_mixture/source, var/datum/gas_mixture/sink_clean, var/total_transfer_moles = null, var/available_power = null) - if (source.total_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing + if (source.total_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing return -1 filtering = filtering & source.gas //only filter gasses that are actually there. DO NOT USE &= @@ -228,7 +228,7 @@ var/total_unfilterable_moles = 0 //the total amount of non-filterable gas var/list/specific_power_gas = list() //the power required to remove one mole of pure gas, for each gas type for (var/g in source.gas) - if (source.gas[g] < MINUMUM_MOLES_TO_FILTER) + if (source.gas[g] < MINIMUM_MOLES_TO_FILTER) continue if (g in filtering) @@ -252,7 +252,7 @@ if (!isnull(available_power) && total_specific_power > 0) total_transfer_moles = min(total_transfer_moles, available_power/total_specific_power) - if (total_transfer_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing + if (total_transfer_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing return -1 //Update Flow Rate var @@ -304,7 +304,7 @@ var/total_input_moles = 0 //for flow rate calculation var/list/source_specific_power = list() for (var/datum/gas_mixture/source in mix_sources) - if (source.total_moles < MINUMUM_MOLES_TO_FILTER) + if (source.total_moles < MINIMUM_MOLES_TO_FILTER) return -1 //either mix at the set ratios or mix no gas at all var/mix_ratio = mix_sources[source] @@ -321,7 +321,7 @@ total_input_volume += source.volume total_input_moles += source.total_moles - if (total_mixing_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing + if (total_mixing_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing return -1 if (isnull(total_transfer_moles)) @@ -333,7 +333,7 @@ if (!isnull(available_power) && total_specific_power > 0) total_transfer_moles = min(total_transfer_moles, available_power / total_specific_power) - if (total_transfer_moles < MINUMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing + if (total_transfer_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing return -1 //Update flow rate var diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm index cb9ecfbdc5..a4b720302b 100644 --- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm +++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm @@ -1,37 +1,50 @@ //node1, air1, network1 correspond to input //node2, air2, network2 correspond to output +#define ADIABATIC_EXPONENT 0.667 //Actually adiabatic exponent - 1. + /obj/machinery/atmospherics/binary/circulator - name = "circulator/heat exchanger" - desc = "A gas circulator pump and heat exchanger." + name = "circulator" + desc = "A gas circulator turbine and heat exchanger." icon = 'icons/obj/pipes.dmi' icon_state = "circ-off" anchored = 0 + var/kinetic_efficiency = 0.04 //combined kinetic and kinetic-to-electric efficiency + var/volume_ratio = 0.2 + var/recent_moles_transferred = 0 var/last_heat_capacity = 0 var/last_temperature = 0 var/last_pressure_delta = 0 var/last_worldtime_transfer = 0 + var/last_stored_energy_transferred = 0 + var/volume_capacity_used = 0 + var/stored_energy = 0 density = 1 /obj/machinery/atmospherics/binary/circulator/New() ..() - desc = initial(desc) + " Its outlet port is to the [dir2text(dir)]." + desc = initial(desc) + " Its outlet port is to the [dir2text(dir)]." + air1.volume = 400 /obj/machinery/atmospherics/binary/circulator/proc/return_transfer_air() var/datum/gas_mixture/removed - if(anchored && !(stat&BROKEN) ) + if(anchored && !(stat&BROKEN) && network1) var/input_starting_pressure = air1.return_pressure() var/output_starting_pressure = air2.return_pressure() - last_pressure_delta = max(input_starting_pressure - output_starting_pressure + 10, 0) + last_pressure_delta = max(input_starting_pressure - output_starting_pressure - 5, 0) - //only circulate air if there is a pressure difference (plus 10 kPa to represent friction in the machine) - if(air1.temperature > 0 && last_pressure_delta > 0) + //only circulate air if there is a pressure difference (plus 5kPa kinetic, 10kPa static friction) + if(air1.temperature > 0 && last_pressure_delta > 5) //Calculate necessary moles to transfer using PV = nRT - recent_moles_transferred = last_pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION) + recent_moles_transferred = (last_pressure_delta*network1.volume/(air1.temperature * R_IDEAL_GAS_EQUATION))/3 //uses the volume of the whole network, not just itself + volume_capacity_used = min( (last_pressure_delta*network1.volume/3)/(input_starting_pressure*air1.volume) , 1) //how much of the gas in the input air volume is consumed + + //Calculate energy generated from kinetic turbine + stored_energy += 1/ADIABATIC_EXPONENT * min(last_pressure_delta * network1.volume , input_starting_pressure*air1.volume) * (1 - volume_ratio**ADIABATIC_EXPONENT) * kinetic_efficiency //Actually transfer the gas removed = air1.remove(recent_moles_transferred) @@ -40,8 +53,7 @@ last_temperature = removed.temperature //Update the gas networks. - if(network1) - network1.update = 1 + network1.update = 1 last_worldtime_transfer = world.time else @@ -50,6 +62,11 @@ update_icon() return removed +/obj/machinery/atmospherics/binary/circulator/proc/return_stored_energy() + last_stored_energy_transferred = stored_energy + stored_energy = 0 + return last_stored_energy_transferred + /obj/machinery/atmospherics/binary/circulator/process() ..() @@ -72,8 +89,11 @@ /obj/machinery/atmospherics/binary/circulator/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/wrench)) + playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) anchored = !anchored - user << "\blue You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor." + user.visible_message("[user.name] [anchored ? "secures" : "unsecures"] the bolts holding [src.name] to the floor.", \ + "You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor.", \ + "You hear a ratchet") if(anchored) if(dir & (NORTH|SOUTH)) diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm index 3bd9fdae2b..51035c5d76 100644 --- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm +++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm @@ -204,7 +204,7 @@ /obj/machinery/atmospherics/binary/passive_gate/Topic(href,href_list) - if(..()) return + if(..()) return 1 if(href_list["toggle_valve"]) unlocked = !unlocked diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 53a66d70a6..87eaf9250d 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -190,7 +190,7 @@ Thus, the two variables affect pump operation are set in New(): return /obj/machinery/atmospherics/binary/pump/Topic(href,href_list) - if(..()) return + if(..()) return 1 if(href_list["power"]) use_power = !use_power diff --git a/code/ATMOSPHERICS/components/omni_devices/filter.dm b/code/ATMOSPHERICS/components/omni_devices/filter.dm index 95f604c036..3478f0f142 100644 --- a/code/ATMOSPHERICS/components/omni_devices/filter.dm +++ b/code/ATMOSPHERICS/components/omni_devices/filter.dm @@ -68,7 +68,7 @@ var/transfer_moles = (set_flow_rate/input_air.volume)*input_air.total_moles var/power_draw = -1 - if (transfer_moles > MINUMUM_MOLES_TO_FILTER) + if (transfer_moles > MINIMUM_MOLES_TO_FILTER) power_draw = filter_gas_multi(src, filtering_outputs, input_air, output_air, transfer_moles, power_rating) if (power_draw >= 0) @@ -155,7 +155,7 @@ return null /obj/machinery/atmospherics/omni/filter/Topic(href, href_list) - if(..()) return + if(..()) return 1 switch(href_list["command"]) if("power") if(!configuring) diff --git a/code/ATMOSPHERICS/components/omni_devices/mixer.dm b/code/ATMOSPHERICS/components/omni_devices/mixer.dm index 4a0b264cc6..970a33feee 100644 --- a/code/ATMOSPHERICS/components/omni_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/omni_devices/mixer.dm @@ -107,7 +107,7 @@ transfer_moles += (set_flow_rate*P.concentration/P.air.volume)*P.air.total_moles var/power_draw = -1 - if (transfer_moles > MINUMUM_MOLES_TO_FILTER) + if (transfer_moles > MINIMUM_MOLES_TO_FILTER) power_draw = mix_gas(src, mixing_inputs, output.air, transfer_moles, power_rating) if (power_draw >= 0) @@ -172,7 +172,7 @@ return data /obj/machinery/atmospherics/omni/mixer/Topic(href, href_list) - if(..()) return + if(..()) return 1 switch(href_list["command"]) if("power") diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm index 3580f52fea..7a5fca0fa7 100755 --- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm @@ -109,7 +109,7 @@ var/transfer_moles = (set_flow_rate/air1.volume)*air1.total_moles var/power_draw = -1 - if (transfer_moles > MINUMUM_MOLES_TO_FILTER) + if (transfer_moles > MINIMUM_MOLES_TO_FILTER) power_draw = filter_gas(src, filtered_out, air1, air2, air3, transfer_moles, power_rating) if(network2) @@ -199,7 +199,7 @@ /obj/machinery/atmospherics/trinary/filter/Topic(href, href_list) // -- TLE if(..()) - return + return 1 usr.set_machine(src) src.add_fingerprint(usr) if(href_list["filterset"]) diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm index 0414452eaa..c6f5b17613 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm @@ -85,7 +85,7 @@ var/transfer_moles = (set_flow_rate*mixing_inputs[air1]/air1.volume)*air1.total_moles + (set_flow_rate*mixing_inputs[air1]/air2.volume)*air2.total_moles var/power_draw = -1 - if (transfer_moles > MINUMUM_MOLES_TO_FILTER) + if (transfer_moles > MINIMUM_MOLES_TO_FILTER) power_draw = mix_gas(src, mixing_inputs, air3, transfer_moles, power_rating) if(network1 && mixing_inputs[air1]) @@ -156,7 +156,7 @@ return /obj/machinery/atmospherics/trinary/mixer/Topic(href,href_list) - if(..()) return + if(..()) return 1 if(href_list["power"]) use_power = !use_power if(href_list["set_press"]) diff --git a/code/ATMOSPHERICS/components/unary/cold_sink.dm b/code/ATMOSPHERICS/components/unary/cold_sink.dm index 766279a630..e5305876ed 100644 --- a/code/ATMOSPHERICS/components/unary/cold_sink.dm +++ b/code/ATMOSPHERICS/components/unary/cold_sink.dm @@ -7,52 +7,47 @@ icon = 'icons/obj/Cryogenic2.dmi' icon_state = "freezer_0" density = 1 - - anchored = 1.0 - - var/heatsink_temperature = T20C //the constant temperature resevoir into which the freezer pumps heat. Probably the hull of the station or something. - var/internal_volume = 600 //L - + anchored = 1 use_power = 0 - idle_power_usage = 5 //5 Watts for thermostat related circuitry + idle_power_usage = 5 // 5 Watts for thermostat related circuitry - var/max_power_rating = 20000 //power rating when the usage is turned up to 100 + var/heatsink_temperature = T20C // The constant temperature reservoir into which the freezer pumps heat. Probably the hull of the station or something. + var/internal_volume = 600 // L + + var/max_power_rating = 20000 // Power rating when the usage is turned up to 100 var/power_setting = 100 - var/set_temperature = T20C //thermostat + var/set_temperature = T20C // Thermostat var/cooling = 0 - var/opened = 0 //for deconstruction /obj/machinery/atmospherics/unary/freezer/New() ..() - air_contents.volume = internal_volume initialize_directions = dir - component_parts = list() component_parts += new /obj/item/weapon/circuitboard/unary_atmos/cooler(src) component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) component_parts += new /obj/item/weapon/stock_parts/capacitor(src) component_parts += new /obj/item/weapon/stock_parts/capacitor(src) component_parts += new /obj/item/weapon/stock_parts/manipulator(src) - - power_rating = max_power_rating * (power_setting/100) + component_parts += new /obj/item/stack/cable_coil(src, 2) + RefreshParts() /obj/machinery/atmospherics/unary/freezer/initialize() - if(node) return + if(node) + return var/node_connect = dir - for(var/obj/machinery/atmospherics/target in get_step(src,node_connect)) - if(target.initialize_directions & get_dir(target,src)) + for(var/obj/machinery/atmospherics/target in get_step(src, node_connect)) + if(target.initialize_directions & get_dir(target, src)) node = target break update_icon() - /obj/machinery/atmospherics/unary/freezer/update_icon() - if(src.node) - if(src.use_power && cooling) + if(node) + if(use_power && cooling) icon_state = "freezer_1" else icon_state = "freezer" @@ -61,10 +56,10 @@ return /obj/machinery/atmospherics/unary/freezer/attack_ai(mob/user as mob) - src.ui_interact(user) + ui_interact(user) /obj/machinery/atmospherics/unary/freezer/attack_hand(mob/user as mob) - src.ui_interact(user) + ui_interact(user) /obj/machinery/atmospherics/unary/freezer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) // this is the data which will be sent to the ui @@ -78,15 +73,15 @@ data["powerSetting"] = power_setting var/temp_class = "good" - if (air_contents.temperature > (T0C - 20)) + if(air_contents.temperature > (T0C - 20)) temp_class = "bad" - else if (air_contents.temperature < (T0C - 20) && air_contents.temperature > (T0C - 100)) + else if(air_contents.temperature < (T0C - 20) && air_contents.temperature > (T0C - 100)) temp_class = "average" data["gasTemperatureClass"] = temp_class // update the ui if it exists, returns null if no ui is passed/found ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) + if(!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm ui = new(user, src, ui_key, "freezer.tmpl", "Gas Cooling System", 440, 300) @@ -98,30 +93,32 @@ ui.set_auto_update(1) /obj/machinery/atmospherics/unary/freezer/Topic(href, href_list) - if (href_list["toggleStatus"]) - src.use_power = !src.use_power + if(..()) + return 1 + if(href_list["toggleStatus"]) + use_power = !use_power update_icon() if(href_list["temp"]) var/amount = text2num(href_list["temp"]) if(amount > 0) - src.set_temperature = min(src.set_temperature+amount, 1000) + set_temperature = min(set_temperature + amount, 1000) else - src.set_temperature = max(src.set_temperature+amount, 0) + set_temperature = max(set_temperature + amount, 0) if(href_list["setPower"]) //setting power to 0 is redundant anyways var/new_setting = between(0, text2num(href_list["setPower"]), 100) set_power_level(new_setting) - src.add_fingerprint(usr) - return 1 + add_fingerprint(usr) /obj/machinery/atmospherics/unary/freezer/process() ..() + if(stat & (NOPOWER|BROKEN) || !use_power) cooling = 0 update_icon() return - if (network && air_contents.temperature > set_temperature) + if(network && air_contents.temperature > set_temperature) cooling = 1 var/heat_transfer = max( -air_contents.get_thermal_energy_change(set_temperature - 5), 0 ) @@ -132,7 +129,7 @@ heat_transfer = min(heat_transfer, cop * power_rating) //limit heat transfer by available power var/removed = -air_contents.add_thermal_energy(-heat_transfer) //remove the heat - if (debug) + if(debug) visible_message("[src]: Removing [removed] W.") use_power(power_rating) @@ -147,49 +144,37 @@ /obj/machinery/atmospherics/unary/freezer/RefreshParts() ..() var/cap_rating = 0 - var/cap_count = 0 var/manip_rating = 0 - var/manip_count = 0 var/bin_rating = 0 - var/bin_count = 0 for(var/obj/item/weapon/stock_parts/P in component_parts) if(istype(P, /obj/item/weapon/stock_parts/capacitor)) cap_rating += P.rating - cap_count++ if(istype(P, /obj/item/weapon/stock_parts/manipulator)) manip_rating += P.rating - manip_count++ if(istype(P, /obj/item/weapon/stock_parts/matter_bin)) bin_rating += P.rating - bin_count++ - cap_rating /= cap_count - bin_rating /= bin_count - manip_rating /= manip_count - power_rating = initial(power_rating)*cap_rating //more powerful - heatsink_temperature = initial(heatsink_temperature)/((manip_rating+bin_rating)/2) //more efficient - air_contents.volume = max(initial(internal_volume) - 200, 0) + 200*bin_rating + power_rating = initial(power_rating) * cap_rating / 2 //more powerful + heatsink_temperature = initial(heatsink_temperature) / ((manip_rating + bin_rating) / 2) //more efficient + air_contents.volume = max(initial(internal_volume) - 200, 0) + 200 * bin_rating set_power_level(power_setting) /obj/machinery/atmospherics/unary/freezer/proc/set_power_level(var/new_power_setting) power_setting = new_power_setting power_rating = max_power_rating * (power_setting/100) -//dismantling code. copied from autolathe /obj/machinery/atmospherics/unary/freezer/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(istype(O, /obj/item/weapon/screwdriver)) - opened = !opened - user << "You [opened ? "open" : "close"] the maintenance hatch of [src]." + if(default_deconstruction_screwdriver(user, O)) return - - if (opened && istype(O, /obj/item/weapon/crowbar)) - dismantle() + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) return ..() /obj/machinery/atmospherics/unary/freezer/examine(mob/user) ..(user) - if (opened) + if(panel_open) user << "The maintenance hatch is open." diff --git a/code/ATMOSPHERICS/components/unary/heat_source.dm b/code/ATMOSPHERICS/components/unary/heat_source.dm index 891a19cc74..db046e7974 100644 --- a/code/ATMOSPHERICS/components/unary/heat_source.dm +++ b/code/ATMOSPHERICS/components/unary/heat_source.dm @@ -7,25 +7,21 @@ icon = 'icons/obj/Cryogenic2.dmi' icon_state = "heater_0" density = 1 - - anchored = 1.0 - - var/set_temperature = T20C //thermostat - var/max_temperature = T20C + 680 - var/internal_volume = 600 //L - + anchored = 1 use_power = 0 idle_power_usage = 5 //5 Watts for thermostat related circuitry + var/max_temperature = T20C + 680 + var/internal_volume = 600 //L + var/max_power_rating = 20000 //power rating when the usage is turned up to 100 var/power_setting = 100 + var/set_temperature = T20C //thermostat var/heating = 0 //mainly for icon updates - var/opened = 0 //for deconstruction /obj/machinery/atmospherics/unary/heater/New() ..() - air_contents.volume = internal_volume initialize_directions = dir component_parts = list() @@ -33,16 +29,18 @@ component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) component_parts += new /obj/item/weapon/stock_parts/capacitor(src) component_parts += new /obj/item/weapon/stock_parts/capacitor(src) + component_parts += new /obj/item/stack/cable_coil(src, 5) - power_rating = max_power_rating * (power_setting/100) + RefreshParts() /obj/machinery/atmospherics/unary/heater/initialize() - if(node) return + if(node) + return var/node_connect = dir - for(var/obj/machinery/atmospherics/target in get_step(src,node_connect)) - if(target.initialize_directions & get_dir(target,src)) + for(var/obj/machinery/atmospherics/target in get_step(src, node_connect)) + if(target.initialize_directions & get_dir(target, src)) node = target break @@ -50,8 +48,8 @@ /obj/machinery/atmospherics/unary/heater/update_icon() - if(src.node) - if(src.use_power && src.heating) + if(node) + if(use_power && heating) icon_state = "heater_1" else icon_state = "heater" @@ -68,7 +66,7 @@ update_icon() return - if (network && air_contents.total_moles && air_contents.temperature < set_temperature) + if(network && air_contents.total_moles && air_contents.temperature < set_temperature) air_contents.add_thermal_energy(power_rating * HEATER_PERF_MULT) use_power(power_rating) @@ -80,10 +78,10 @@ update_icon() /obj/machinery/atmospherics/unary/heater/attack_ai(mob/user as mob) - src.ui_interact(user) + ui_interact(user) /obj/machinery/atmospherics/unary/heater/attack_hand(mob/user as mob) - src.ui_interact(user) + ui_interact(user) /obj/machinery/atmospherics/unary/heater/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) // this is the data which will be sent to the ui @@ -97,13 +95,13 @@ data["powerSetting"] = power_setting var/temp_class = "normal" - if (air_contents.temperature > (T20C+40)) + if(air_contents.temperature > (T20C+40)) temp_class = "bad" data["gasTemperatureClass"] = temp_class // update the ui if it exists, returns null if no ui is passed/found ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) + if(!ui) // the ui does not exist, so we'll create a new() one // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm ui = new(user, src, ui_key, "freezer.tmpl", "Gas Heating System", 440, 300) @@ -115,63 +113,55 @@ ui.set_auto_update(1) /obj/machinery/atmospherics/unary/heater/Topic(href, href_list) - if (href_list["toggleStatus"]) - src.use_power = !src.use_power + if(..()) + return 1 + if(href_list["toggleStatus"]) + use_power = !use_power update_icon() if(href_list["temp"]) var/amount = text2num(href_list["temp"]) if(amount > 0) - src.set_temperature = min(src.set_temperature+amount, max_temperature) + set_temperature = min(set_temperature + amount, max_temperature) else - src.set_temperature = max(src.set_temperature+amount, 0) + set_temperature = max(set_temperature + amount, 0) if(href_list["setPower"]) //setting power to 0 is redundant anyways var/new_setting = between(0, text2num(href_list["setPower"]), 100) set_power_level(new_setting) - src.add_fingerprint(usr) - return 1 + add_fingerprint(usr) //upgrading parts /obj/machinery/atmospherics/unary/heater/RefreshParts() ..() - var/cap_rating = 0 - var/cap_count = 0 var/bin_rating = 0 - var/bin_count = 0 + for(var/obj/item/weapon/stock_parts/P in component_parts) if(istype(P, /obj/item/weapon/stock_parts/capacitor)) cap_rating += P.rating - cap_count++ if(istype(P, /obj/item/weapon/stock_parts/matter_bin)) bin_rating += P.rating - bin_count++ - cap_rating /= cap_count - bin_rating /= bin_count - max_power_rating = initial(max_power_rating)*cap_rating - max_temperature = max(initial(max_temperature) - T20C, 0)*((bin_rating*2 + cap_rating)/3) + T20C - air_contents.volume = max(initial(internal_volume) - 200, 0) + 200*bin_rating + max_power_rating = initial(max_power_rating) * cap_rating / 2 + max_temperature = max(initial(max_temperature) - T20C, 0) * ((bin_rating * 4 + cap_rating) / 5) + T20C + air_contents.volume = max(initial(internal_volume) - 200, 0) + 200 * bin_rating set_power_level(power_setting) /obj/machinery/atmospherics/unary/heater/proc/set_power_level(var/new_power_setting) power_setting = new_power_setting power_rating = max_power_rating * (power_setting/100) -//dismantling code. copied from autolathe /obj/machinery/atmospherics/unary/heater/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(istype(O, /obj/item/weapon/screwdriver)) - opened = !opened - user << "You [opened ? "open" : "close"] the maintenance hatch of [src]." + if(default_deconstruction_screwdriver(user, O)) return - - if (opened && istype(O, /obj/item/weapon/crowbar)) - dismantle() + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) return ..() /obj/machinery/atmospherics/unary/heater/examine(mob/user) ..(user) - if (opened) + if(panel_open) user << "The maintenance hatch is open." diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index bf7de90c87..cbaeb3bf9c 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -26,6 +26,7 @@ var/area_uid var/id_tag = null + var/hibernate = 0 //Do we even process? var/pump_direction = 1 //0 = siphoning, 1 = releasing var/external_pressure_bound = EXTERNAL_PRESSURE_BOUND @@ -88,7 +89,7 @@ /obj/machinery/atmospherics/unary/vent_pump/engine name = "Engine Core Vent" power_channel = ENVIRON - power_rating = 15000 //15 kW ~ 20 HP + power_rating = 30000 //15 kW ~ 20 HP /obj/machinery/atmospherics/unary/vent_pump/engine/New() ..() @@ -150,8 +151,8 @@ /obj/machinery/atmospherics/unary/vent_pump/process() ..() - last_power_draw = 0 - last_flow_rate = 0 + if (hibernate) + return 1 if (!node) use_power = 0 @@ -177,6 +178,17 @@ transfer_moles = min(transfer_moles, environment.total_moles*air_contents.volume/environment.volume) //group_multiplier gets divided out here power_draw = pump_gas(src, environment, air_contents, transfer_moles, power_rating) + else + //If we're in an area that is fucking ideal, and we don't have to do anything, chances are we won't next tick either so why redo these calculations? + //JESUS FUCK. THERE ARE LITERALLY 250 OF YOU MOTHERFUCKERS ON ZLEVEL ONE AND YOU DO THIS SHIT EVERY TICK WHEN VERY OFTEN THERE IS NO REASON TO + + if(pump_direction && pressure_checks == PRESSURE_CHECK_EXTERNAL && controller_iteration > 10) //99% of all vents + //Fucking hibernate because you ain't doing shit. + hibernate = 1 + spawn(rand(100,200)) //hibernate for 10 or 20 seconds randomly + hibernate = 0 + + if (power_draw >= 0) last_power_draw = power_draw use_power(power_draw) @@ -256,6 +268,9 @@ /obj/machinery/atmospherics/unary/vent_pump/receive_signal(datum/signal/signal) if(stat & (NOPOWER|BROKEN)) return + + hibernate = 0 + //log_admin("DEBUG \[[world.timeofday]\]: /obj/machinery/atmospherics/unary/vent_pump/receive_signal([signal.debug_print()])") if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command")) return 0 @@ -368,6 +383,7 @@ user << "You are too far away to read the gauge." if(welded) user << "It seems welded shut." + ..() /obj/machinery/atmospherics/unary/vent_pump/power_change() var/old_stat = stat @@ -407,18 +423,3 @@ initial_loc.air_vent_names -= id_tag ..() return - -/* - Alt-click to vent crawl - Monkeys, aliens, slimes and mice. - This is a little buggy but somehow that just seems to plague ventcrawl. - I am sorry, I don't know why. -*/ -// Commenting this out for now, it's not critical, stated to be buggy, and seems like -// a really clumsy way of doing this. ~Z -/*/obj/machinery/atmospherics/unary/vent_pump/AltClick(var/mob/living/ML) - if(istype(ML)) - var/list/ventcrawl_verbs = list(/mob/living/carbon/monkey/verb/ventcrawl, /mob/living/carbon/alien/verb/ventcrawl, /mob/living/carbon/slime/verb/ventcrawl,/mob/living/simple_animal/mouse/verb/ventcrawl) - if(length(ML.verbs & ventcrawl_verbs)) // alien queens have this removed, an istype would be complicated - ML.handle_ventcrawl(src) - return - ..()*/ \ No newline at end of file diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index 7b74ed8b73..8d88ad4db4 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -99,6 +99,8 @@ "power" = use_power, "scrubbing" = scrubbing, "panic" = panic, + "filter_o2" = ("oxygen" in scrubbing_gas), + "filter_n2" = ("nitrogen" in scrubbing_gas), "filter_co2" = ("carbon_dioxide" in scrubbing_gas), "filter_phoron" = ("phoron" in scrubbing_gas), "filter_n2o" = ("sleeping_agent" in scrubbing_gas), @@ -171,7 +173,7 @@ use_power = !use_power if(signal.data["panic_siphon"]) //must be before if("scrubbing" thing - panic = text2num(signal.data["panic_siphon"] != null) + panic = text2num(signal.data["panic_siphon"]) if(panic) use_power = 1 scrubbing = 0 @@ -187,11 +189,25 @@ if(signal.data["scrubbing"] != null) scrubbing = text2num(signal.data["scrubbing"]) + if(scrubbing) + panic = 0 if(signal.data["toggle_scrubbing"]) scrubbing = !scrubbing + if(scrubbing) + panic = 0 var/list/toggle = list() + if(!isnull(signal.data["o2_scrub"]) && text2num(signal.data["o2_scrub"]) != ("oxygen" in scrubbing_gas)) + toggle += "oxygen" + else if(signal.data["toggle_o2_scrub"]) + toggle += "oxygen" + + if(!isnull(signal.data["n2_scrub"]) && text2num(signal.data["n2_scrub"]) != ("nitrogen" in scrubbing_gas)) + toggle += "nitrogen" + else if(signal.data["toggle_n2_scrub"]) + toggle += "nitrogen" + if(!isnull(signal.data["co2_scrub"]) && text2num(signal.data["co2_scrub"]) != ("carbon_dioxide" in scrubbing_gas)) toggle += "carbon_dioxide" else if(signal.data["toggle_co2_scrub"]) @@ -261,6 +277,7 @@ user << "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W" else user << "You are too far away to read the gauge." + ..() /obj/machinery/atmospherics/unary/vent_scrubber/Del() if(initial_loc) diff --git a/code/ATMOSPHERICS/datum_pipeline.dm b/code/ATMOSPHERICS/datum_pipeline.dm index fd933bf94d..662376e9b4 100644 --- a/code/ATMOSPHERICS/datum_pipeline.dm +++ b/code/ATMOSPHERICS/datum_pipeline.dm @@ -203,15 +203,15 @@ datum/pipeline //surface must be the surface area in m^2 proc/radiate_heat_to_space(surface, thermal_conductivity) var/gas_density = air.total_moles/air.volume - thermal_conductivity *= min(gas_density / ( RADIATOR_OPTIMUM_PRESSURE/(R_IDEAL_GAS_EQUATION*T20C) ), 1) + thermal_conductivity *= min(gas_density / ( RADIATOR_OPTIMUM_PRESSURE/(R_IDEAL_GAS_EQUATION*GAS_CRITICAL_TEMPERATURE) ), 1) //mult by density ratio // We only get heat from the star on the exposed surface area. // If the HE pipes gain more energy from AVERAGE_SOLAR_RADIATION than they can radiate, then they have a net heat increase. - var/heat_gain = AVERAGE_SOLAR_RADIATION * RADIATOR_EXPOSED_SURFACE_AREA * thermal_conductivity + var/heat_gain = AVERAGE_SOLAR_RADIATION * (RADIATOR_EXPOSED_SURFACE_AREA_RATIO * surface) * thermal_conductivity // Previously, the temperature would enter equilibrium at 26C or 294K. // Only would happen if both sides (all 2 square meters of surface area) were exposed to sunlight. We now assume it aligned edge on. - // It currently should stabilise at 85K or -183C. + // It currently should stabilise at 129.6K or -143.6C heat_gain -= surface * STEFAN_BOLTZMANN_CONSTANT * thermal_conductivity * (air.temperature - COSMIC_RADIATION_TEMPERATURE) ** 4 air.add_thermal_energy(heat_gain) diff --git a/code/ATMOSPHERICS/he_pipes.dm b/code/ATMOSPHERICS/he_pipes.dm index c22c483e8c..cb11410f86 100644 --- a/code/ATMOSPHERICS/he_pipes.dm +++ b/code/ATMOSPHERICS/he_pipes.dm @@ -3,18 +3,25 @@ obj/machinery/atmospherics/pipe/simple/heat_exchanging icon = 'icons/atmos/heat.dmi' icon_state = "intact" pipe_icon = "hepipe" + color = "#404040" level = 2 + connect_types = CONNECT_TYPE_HE + layer = 2.41 var/initialize_directions_he var/surface = 2 //surface area in m^2 + var/icon_temperature = T20C //stop small changes in temperature causing an icon refresh minimum_temperature_difference = 20 thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT + buckle_lying = 1 + // BubbleWrap New() ..() initialize_directions_he = initialize_directions // The auto-detection from /pipe is good enough for a simple HE pipe // BubbleWrap END + color = "#404040" //we don't make use of the fancy overlay system for colours, use this to set the default. initialize() normalize_dir() @@ -48,25 +55,60 @@ obj/machinery/atmospherics/pipe/simple/heat_exchanging if(!parent) ..() else - var/environment_temperature = 0 + var/datum/gas_mixture/pipe_air = return_air() if(istype(loc, /turf/simulated/)) + var/environment_temperature = 0 if(loc:blocks_air) environment_temperature = loc:temperature else var/datum/gas_mixture/environment = loc.return_air() environment_temperature = environment.temperature - var/datum/gas_mixture/pipe_air = return_air() if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference) parent.temperature_interact(loc, volume, thermal_conductivity) else if(istype(loc, /turf/space/)) parent.radiate_heat_to_space(surface, 1) + if(buckled_mob) + var/hc = pipe_air.heat_capacity() + var/avg_temp = (pipe_air.temperature * hc + buckled_mob.bodytemperature * 3500) / (hc + 3500) + pipe_air.temperature = avg_temp + buckled_mob.bodytemperature = avg_temp + + var/heat_limit = 1000 + + var/mob/living/carbon/human/H = buckled_mob + if(istype(H) && H.species) + heat_limit = H.species.heat_level_3 + + if(pipe_air.temperature > heat_limit + 1) + buckled_mob.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, "chest", used_weapon = "Excessive Heat") + + //fancy radiation glowing + if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //start glowing at 500K + if(abs(pipe_air.temperature - icon_temperature) > 10) + icon_temperature = pipe_air.temperature + + var/h_r = heat2color_r(icon_temperature) + var/h_g = heat2color_g(icon_temperature) + var/h_b = heat2color_b(icon_temperature) + + if(icon_temperature < 2000) //scale up overlay until 2000K + var/scale = (icon_temperature - 500) / 1500 + h_r = 64 + (h_r - 64)*scale + h_g = 64 + (h_g - 64)*scale + h_b = 64 + (h_b - 64)*scale + + animate(src, color = rgb(h_r, h_g, h_b), time = 20, easing = SINE_EASING) + + + obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction icon = 'icons/atmos/junction.dmi' icon_state = "intact" pipe_icon = "hejunction" level = 2 + connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE minimum_temperature_difference = 300 thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm index 16a0a6bcd5..92ad93c7d0 100644 --- a/code/ATMOSPHERICS/pipes.dm +++ b/code/ATMOSPHERICS/pipes.dm @@ -12,6 +12,10 @@ var/alert_pressure = 80*ONE_ATMOSPHERE //minimum pressure before check_pressure(...) should be called + can_buckle = 1 + buckle_require_restraints = 1 + buckle_lying = -1 + /obj/machinery/atmospherics/pipe/drain_power() return -1 @@ -347,6 +351,13 @@ /obj/machinery/atmospherics/pipe/simple/visible/purple color = PIPE_COLOR_PURPLE +/obj/machinery/atmospherics/pipe/simple/visible/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/simple/visible/blue + color = PIPE_COLOR_BLUE + + /obj/machinery/atmospherics/pipe/simple/hidden icon_state = "intact" level = 1 @@ -382,6 +393,12 @@ /obj/machinery/atmospherics/pipe/simple/hidden/purple color = PIPE_COLOR_PURPLE +/obj/machinery/atmospherics/pipe/simple/hidden/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/simple/hidden/blue + color = PIPE_COLOR_BLUE + /obj/machinery/atmospherics/pipe/simple/insulated icon = 'icons/obj/atmospherics/red_pipe.dmi' icon_state = "intact" @@ -603,6 +620,13 @@ /obj/machinery/atmospherics/pipe/manifold/visible/purple color = PIPE_COLOR_PURPLE +/obj/machinery/atmospherics/pipe/manifold/visible/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold/visible/blue + color = PIPE_COLOR_BLUE + + /obj/machinery/atmospherics/pipe/manifold/hidden icon_state = "map" level = 1 @@ -638,6 +662,12 @@ /obj/machinery/atmospherics/pipe/manifold/hidden/purple color = PIPE_COLOR_PURPLE +/obj/machinery/atmospherics/pipe/manifold/hidden/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold/hidden/blue + color = PIPE_COLOR_BLUE + /obj/machinery/atmospherics/pipe/manifold4w icon = 'icons/atmos/manifold.dmi' icon_state = "" @@ -849,6 +879,12 @@ /obj/machinery/atmospherics/pipe/manifold4w/visible/purple color = PIPE_COLOR_PURPLE +/obj/machinery/atmospherics/pipe/manifold4w/visible/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold4w/visible/blue + color = PIPE_COLOR_BLUE + /obj/machinery/atmospherics/pipe/manifold4w/hidden icon_state = "map_4way" level = 1 @@ -884,6 +920,12 @@ /obj/machinery/atmospherics/pipe/manifold4w/hidden/purple color = PIPE_COLOR_PURPLE +/obj/machinery/atmospherics/pipe/manifold4w/hidden/red + color = PIPE_COLOR_RED + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/blue + color = PIPE_COLOR_BLUE + /obj/machinery/atmospherics/pipe/cap name = "pipe endcap" desc = "An endcap for pipes" diff --git a/code/ZAS/Airflow.dm b/code/ZAS/Airflow.dm index 7b0d3afa98..62a6daea16 100644 --- a/code/ZAS/Airflow.dm +++ b/code/ZAS/Airflow.dm @@ -2,17 +2,18 @@ Contains helper procs for airflow, handled in /connection_group. */ - mob/var/tmp/last_airflow_stun = 0 mob/proc/airflow_stun() if(stat == 2) return 0 if(last_airflow_stun > world.time - vsc.airflow_stun_cooldown) return 0 + if(!(status_flags & CANSTUN) && !(status_flags & CANWEAKEN)) - src << "\blue You stay upright as the air rushes past you." + src << "You stay upright as the air rushes past you." return 0 - if(weakened <= 0) src << "\red The sudden rush of air knocks you over!" - weakened = max(weakened,5) + if(!lying) + src << "The sudden rush of air knocks you over!" + Weaken(5) last_airflow_stun = world.time mob/living/silicon/airflow_stun() @@ -22,16 +23,9 @@ mob/living/carbon/metroid/airflow_stun() return mob/living/carbon/human/airflow_stun() - if(last_airflow_stun > world.time - vsc.airflow_stun_cooldown) return 0 - if(buckled) return 0 if(shoes) if(shoes.flags & NOSLIP) return 0 - if(!(status_flags & CANSTUN) && !(status_flags & CANWEAKEN)) - src << "\blue You stay upright as the air rushes past you." - return 0 - if(weakened <= 0) src << "\red The sudden rush of air knocks you over!" - weakened = max(weakened,rand(1,5)) - last_airflow_stun = world.time + ..() atom/movable/proc/check_airflow_movable(n) @@ -84,10 +78,8 @@ obj/item/check_airflow_movable(n) if(istype(src, /mob/living/carbon/human)) if(src:buckled) return - if(src:shoes) - if(istype(src:shoes, /obj/item/clothing/shoes/magboots)) - if(src:shoes:magpulse) - return + if(src:shoes && src:shoes.flags & NOSLIP) + return src << "\red You are sucked away by airflow!" var/airflow_falloff = 9 - sqrt((x - airflow_dest.x) ** 2 + (y - airflow_dest.y) ** 2) if(airflow_falloff < 1) @@ -207,7 +199,8 @@ mob/airflow_hit(atom/A) for(var/mob/M in hearers(src)) M.show_message("\red \The [src] slams into \a [A]!",1,"\red You hear a loud slam!",2) playsound(src.loc, "smash.ogg", 25, 1, -1) - weakened = max(weakened, (istype(A,/obj/item) ? A:w_class : rand(1,5))) //Heheheh + var/weak_amt = istype(A,/obj/item) ? A:w_class : rand(1,5) //Heheheh + Weaken(weak_amt) . = ..() obj/airflow_hit(atom/A) @@ -239,10 +232,10 @@ mob/living/carbon/human/airflow_hit(atom/A) apply_damage(b_loss/3, BRUTE, "groin", blocked, 0, "Airflow") if(airflow_speed > 10) - paralysis += round(airflow_speed * vsc.airflow_stun) - stunned = max(stunned,paralysis + 3) + Paralyse(round(airflow_speed * vsc.airflow_stun)) + Stun(paralysis + 3) else - stunned += round(airflow_speed * vsc.airflow_stun/2) + Stun(round(airflow_speed * vsc.airflow_stun/2)) . = ..() zone/proc/movables() diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index babce84126..5dd0ac3cd3 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -20,7 +20,7 @@ atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0) -turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) +/turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) if(fire_protection > world.time-300) return 0 if(locate(/obj/fire) in src) @@ -35,37 +35,35 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) if(air_contents.check_combustability(liquid)) igniting = 1 - create_fire(1000) + create_fire(vsc.fire_firelevel_multiplier) return igniting /zone/proc/process_fire() - if(!air.check_combustability()) + var/datum/gas_mixture/burn_gas = air.remove_ratio(vsc.fire_consuption_rate, fire_tiles.len) + + var/firelevel = burn_gas.zburn(src, fire_tiles, force_burn = 1, no_check = 1) + //world << "[src]: firelevel [firelevel]" + + air.merge(burn_gas) + + if(firelevel) + for(var/turf/T in fire_tiles) + if(T.fire) + T.fire.firelevel = firelevel + else + var/obj/effect/decal/cleanable/liquid_fuel/fuel = locate() in T + fire_tiles -= T + fuel_objs -= fuel + else for(var/turf/simulated/T in fire_tiles) if(istype(T.fire)) T.fire.RemoveFire() T.fire = null fire_tiles.Cut() + fuel_objs.Cut() if(!fire_tiles.len) air_master.active_fire_zones.Remove(src) - return - - var/datum/gas_mixture/burn_gas = air.remove_ratio(vsc.fire_consuption_rate, fire_tiles.len) - var/gm = burn_gas.group_multiplier - - burn_gas.group_multiplier = 1 - burn_gas.zburn(force_burn = 1, no_check = 1) - burn_gas.group_multiplier = gm - - air.merge(burn_gas) - - var/firelevel = air.calculate_firelevel() - - for(var/turf/T in fire_tiles) - if(T.fire) - T.fire.firelevel = firelevel - else - fire_tiles -= T /turf/proc/create_fire(fl) return 0 @@ -79,8 +77,12 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) return 1 fire = new(src, fl) - zone.fire_tiles |= src air_master.active_fire_zones |= zone + + var/obj/effect/decal/cleanable/liquid_fuel/fuel = locate() in src + zone.fire_tiles |= src + if(fuel) zone.fuel_objs += fuel + return 0 /obj/fire @@ -121,8 +123,8 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) SetLuminosity(3) //im not sure how to implement a version that works for every creature so for now monkeys are firesafe - for(var/mob/living/carbon/human/M in loc) - M.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure()) //Burn the humans! + for(var/mob/living/L in loc) + L.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure()) //Burn the mobs! loc.fire_act(air_contents, air_contents.temperature, air_contents.volume) for(var/atom/A in loc) @@ -137,10 +139,11 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) if(!enemy_tile.zone || enemy_tile.fire) continue - if(!enemy_tile.zone.fire_tiles.len) - var/datum/gas_mixture/acs = enemy_tile.return_air() - if(!acs || !acs.check_combustability()) - continue + //if(!enemy_tile.zone.fire_tiles.len) TODO - optimize + var/datum/gas_mixture/acs = enemy_tile.return_air() + var/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in enemy_tile + if(!acs || !acs.check_combustability(liquid)) + continue //If extinguisher mist passed over the turf it's trying to spread to, don't spread and //reduce firelevel. @@ -169,85 +172,122 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) /obj/fire/Del() if (istype(loc, /turf/simulated)) - SetLuminosity(0) - - loc = null - air_master.active_hotspots.Remove(src) + RemoveFire() ..() /obj/fire/proc/RemoveFire() if (istype(loc, /turf)) SetLuminosity(0) + loc = null air_master.active_hotspots.Remove(src) -turf/simulated/var/fire_protection = 0 //Protects newly extinguished tiles from being overrun again. -turf/proc/apply_fire_protection() -turf/simulated/apply_fire_protection() +/turf/simulated/var/fire_protection = 0 //Protects newly extinguished tiles from being overrun again. +/turf/proc/apply_fire_protection() +/turf/simulated/apply_fire_protection() fire_protection = world.time - -datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid, force_burn, no_check = 0) +//Returns the firelevel +/datum/gas_mixture/proc/zburn(zone/zone, force_burn, no_check = 0) . = 0 - if((temperature > PHORON_MINIMUM_BURN_TEMPERATURE || force_burn) && (no_check ||check_recombustability(liquid))) + if((temperature > PHORON_MINIMUM_BURN_TEMPERATURE || force_burn) && (no_check ||check_recombustability(zone? zone.fuel_objs : null))) + var/gas_fuel = 0 //in the case of mixed gas/liquid fires, the gas burns first. + var/liquid_fuel = 0 var/total_fuel = 0 var/total_oxidizers = 0 + //*** Get the fuel and oxidizer amounts for(var/g in gas) if(gas_data.flags[g] & XGM_GAS_FUEL) - total_fuel += gas[g] + gas_fuel += gas[g] if(gas_data.flags[g] & XGM_GAS_OXIDIZER) total_oxidizers += gas[g] + gas_fuel *= group_multiplier + total_oxidizers *= group_multiplier - if(liquid) //Liquid Fuel - if(liquid.amount <= 0.1) - del liquid - else - total_fuel += liquid.amount + if(zone) + for(var/obj/effect/decal/cleanable/liquid_fuel/fuel in zone.fuel_objs) + liquid_fuel += fuel.amount*LIQUIDFUEL_AMOUNT_TO_MOL - if(total_fuel == 0) + total_fuel = gas_fuel + liquid_fuel + if(total_fuel <= 0.005) return 0 - //Calculate the firelevel. - var/firelevel = calculate_firelevel(liquid, total_fuel, total_oxidizers, force = 1) + //*** Determine how fast the fire burns - //get the current inner energy of the gas mix + //calculate the firelevel. + var/firelevel = calculate_firelevel(zone? zone.fuel_objs : null, total_fuel, total_oxidizers, force = 1) + + //get the current thermal energy of the gas mix //this must be taken here to prevent the addition or deletion of energy by a changing heat capacity var/starting_energy = temperature * heat_capacity() - //determine the amount of oxygen used - var/used_oxidizers = min(total_oxidizers, total_fuel / 2) - - //determine the amount of fuel actually used - var/used_fuel_ratio = min(2 * total_oxidizers , total_fuel) / total_fuel - total_fuel = total_fuel * used_fuel_ratio - - var/total_reactants = total_fuel + used_oxidizers - - //determine the amount of reactants actually reacting - var/used_reactants_ratio = min(max(total_reactants * firelevel / vsc.fire_firelevel_multiplier, 0.2), total_reactants) / total_reactants + //determine how far the reaction can progress + var/reaction_limit = min(total_oxidizers*(FIRE_REACTION_FUEL_AMOUNT/FIRE_REACTION_OXIDIZER_AMOUNT), total_fuel) //stoichiometric limit + + //determine the actual rate of reaction, as measured by the amount of fuel reacting + + //vapour fuels are extremely volatile! The reaction progress is a percentage of the total fuel (similar to old zburn). + var/gas_reaction_progress = max(0.2*group_multiplier, (firelevel/vsc.fire_firelevel_multiplier)*gas_fuel)*FIRE_GAS_BURNRATE_MULT + //liquid fuels are not as volatile, and the reaction progress depends on the size of the area that is burning (which is sort of accounted for by firelevel). Having more fuel means a longer burn. + var/liquid_reaction_progress = (firelevel/vsc.fire_firelevel_multiplier)*FIRE_LIQUID_BURNRATE_MULT + + //world << "liquid_reaction_progress = [liquid_reaction_progress]" + //world << "gas_reaction_progress = [gas_reaction_progress]" + + var/total_reaction_progress = gas_reaction_progress + liquid_reaction_progress + var/used_fuel = min(total_reaction_progress, reaction_limit) + var/used_oxidizers = used_fuel*(FIRE_REACTION_OXIDIZER_AMOUNT/FIRE_REACTION_FUEL_AMOUNT) + //world << "used_fuel = [used_fuel]; used_oxidizers = [used_oxidizers]; reaction_limit=[reaction_limit]" + + //if the reaction is progressing too slow then it isn't self-sustaining anymore and burns out + if(zone && zone.fuel_objs.len) + if(used_fuel <= FIRE_LIQUD_MIN_BURNRATE) + return 0 + else if(used_fuel <= FIRE_GAS_MIN_BURNRATE*group_multiplier) //purely gas fires have more stringent criteria + return 0 + + //*** Remove fuel and oxidizer, add carbon dioxide and heat + //remove and add gasses as calculated - remove_by_flag(XGM_GAS_OXIDIZER, used_oxidizers * used_reactants_ratio) - remove_by_flag(XGM_GAS_FUEL, total_fuel * used_reactants_ratio) + var/used_gas_fuel = min(used_fuel*(gas_reaction_progress/total_reaction_progress), gas_fuel) //remove in proportion to the relative reaction progress + var/used_liquid_fuel = between(0, used_fuel-used_gas_fuel, liquid_fuel) + + //remove_by_flag() and adjust_gas() handle the group_multiplier for us. + remove_by_flag(XGM_GAS_OXIDIZER, used_oxidizers) + remove_by_flag(XGM_GAS_FUEL, used_gas_fuel) + adjust_gas("carbon_dioxide", used_oxidizers) - adjust_gas("carbon_dioxide", max(total_fuel*used_reactants_ratio, 0)) - - if(liquid) - liquid.amount -= (liquid.amount * used_fuel_ratio * used_reactants_ratio) * 5 // liquid fuel burns 5 times as quick - - if(liquid.amount <= 0) del liquid + //As a simplification, we remove fuel equally from all fuel sources. It might be that some fuel sources have more fuel, some have less, but whatever. + if(zone && zone.fuel_objs.len) + var/fuel_to_remove = used_liquid_fuel/(zone.fuel_objs.len*LIQUIDFUEL_AMOUNT_TO_MOL) //convert back to liquid volume units + //world << "used gas fuel = [used_gas_fuel]; used other fuel = [used_fuel-used_gas_fuel]; fuel_to_remove = [fuel_to_remove]" + var/liquidonly = !check_combustability() + for(var/O in zone.fuel_objs) + var/obj/effect/decal/cleanable/liquid_fuel/fuel = O + if(!istype(fuel)) + zone.fuel_objs -= fuel + continue + + fuel.amount -= fuel_to_remove + if(fuel.amount <= 0) + zone.fuel_objs -= fuel + if(liquidonly) + var/turf/T = fuel.loc + if(istype(T) && T.fire) del(T.fire) + del(fuel) //calculate the energy produced by the reaction and then set the new temperature of the mix - temperature = (starting_energy + vsc.fire_fuel_energy_release * total_fuel) / heat_capacity() + temperature = (starting_energy + vsc.fire_fuel_energy_release * used_fuel) / heat_capacity() update_values() - . = total_reactants * used_reactants_ratio + return firelevel -datum/gas_mixture/proc/check_recombustability(obj/effect/decal/cleanable/liquid_fuel/liquid) +datum/gas_mixture/proc/check_recombustability(list/fuel_objs) . = 0 for(var/g in gas) if(gas_data.flags[g] & XGM_GAS_OXIDIZER && gas[g] >= 0.1) @@ -257,7 +297,7 @@ datum/gas_mixture/proc/check_recombustability(obj/effect/decal/cleanable/liquid_ if(!.) return 0 - if(liquid) + if(fuel_objs && fuel_objs.len) return 1 . = 0 @@ -266,7 +306,7 @@ datum/gas_mixture/proc/check_recombustability(obj/effect/decal/cleanable/liquid_ . = 1 break -datum/gas_mixture/proc/check_combustability(obj/effect/decal/cleanable/liquid_fuel/liquid) +/datum/gas_mixture/proc/check_combustability(obj/effect/decal/cleanable/liquid_fuel/liquid=null) . = 0 for(var/g in gas) if(gas_data.flags[g] & XGM_GAS_OXIDIZER && QUANTIZE(gas[g] * vsc.fire_consuption_rate) >= 0.1) @@ -285,20 +325,12 @@ datum/gas_mixture/proc/check_combustability(obj/effect/decal/cleanable/liquid_fu . = 1 break -datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fuel/liquid, total_fuel = null, total_oxidizers = null, force = 0) +//Returns a value between 0 and vsc.fire_firelevel_multiplier +/datum/gas_mixture/proc/calculate_firelevel(list/fuel_objs, total_fuel, total_oxidizers, force = 0) //Calculates the firelevel based on one equation instead of having to do this multiple times in different areas. var/firelevel = 0 - if(force || check_recombustability(liquid)) - if(isnull(total_fuel)) - for(var/g in gas) - if(gas_data.flags[g] & XGM_GAS_FUEL) - total_fuel += gas[g] - if(gas_data.flags[g] & XGM_GAS_OXIDIZER) - total_oxidizers += gas[g] - if(liquid) - total_fuel += liquid.amount - + if(force || check_recombustability(fuel_objs)) var/total_combustables = (total_fuel + total_oxidizers) if(total_combustables > 0) diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index 7c9c5f32ed..b7042191fc 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -44,6 +44,7 @@ Class Procs: /zone/var/invalid = 0 /zone/var/list/contents = list() /zone/var/list/fire_tiles = list() +/zone/var/list/fuel_objs = list() /zone/var/needs_update = 0 @@ -72,8 +73,10 @@ Class Procs: T.zone = src contents.Add(T) if(T.fire) + var/obj/effect/decal/cleanable/liquid_fuel/fuel = locate() in T fire_tiles.Add(T) - air_master.active_fire_zones.Add(src) + air_master.active_fire_zones |= src + if(fuel) fuel_objs += fuel T.update_graphic(air.graphic) /zone/proc/remove(turf/simulated/T) @@ -85,6 +88,9 @@ Class Procs: #endif contents.Remove(T) fire_tiles.Remove(T) + if(T.fire) + var/obj/effect/decal/cleanable/liquid_fuel/fuel = locate() in T + fuel_objs -= fuel T.zone = null T.update_graphic(graphic_remove = air.graphic) if(contents.len) @@ -132,6 +138,11 @@ Class Procs: air.group_multiplier = contents.len+1 /zone/proc/tick() + if(air.temperature >= PHORON_FLASHPOINT && !(src in air_master.active_fire_zones) && air.check_combustability() && contents.len) + var/turf/T = pick(contents) + if(istype(T)) + T.create_fire(vsc.fire_firelevel_multiplier) + if(air.check_tile_graphic(graphic_add, graphic_remove)) for(var/turf/simulated/T in contents) T.update_graphic(graphic_add, graphic_remove) diff --git a/code/ZAS/_gas_mixture.dm b/code/ZAS/_gas_mixture.dm deleted file mode 100644 index 2a072e8ef9..0000000000 --- a/code/ZAS/_gas_mixture.dm +++ /dev/null @@ -1,1090 +0,0 @@ -/* -What are the archived variables for? - Calculations are done using the archived variables with the results merged into the regular variables. - This prevents race conditions that arise based on the order of tile processing. -*/ - -#define SPECIFIC_HEAT_TOXIN 200 -#define SPECIFIC_HEAT_AIR 20 -#define SPECIFIC_HEAT_CDO 30 -#define HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,phoron) \ - max(0, carbon_dioxide * SPECIFIC_HEAT_CDO + (oxygen + nitrogen) * SPECIFIC_HEAT_AIR + phoron * SPECIFIC_HEAT_TOXIN) - -#define MINIMUM_HEAT_CAPACITY 0.0003 -#define QUANTIZE(variable) (round(variable,0.0001)) -#define TRANSFER_FRACTION 5 //What fraction (1/#) of the air difference to try and transfer - -/hook/startup/proc/createGasOverlays() - plmaster = new /obj/effect/overlay() - plmaster.icon = 'icons/effects/tile_effects.dmi' - plmaster.icon_state = "phoron" - plmaster.layer = FLY_LAYER - plmaster.mouse_opacity = 0 - - slmaster = new /obj/effect/overlay() - slmaster.icon = 'icons/effects/tile_effects.dmi' - slmaster.icon_state = "sleeping_agent" - slmaster.layer = FLY_LAYER - slmaster.mouse_opacity = 0 - return 1 - -/datum/gas/sleeping_agent/specific_heat = 40 //These are used for the "Trace Gases" stuff, but is buggy. - -/datum/gas/oxygen_agent_b/specific_heat = 300 - -/datum/gas/volatile_fuel/specific_heat = 30 - -/datum/gas - var/moles = 0 - - var/specific_heat = 0 - - var/moles_archived = 0 - -/datum/gas_mixture/ - var/oxygen = 0 //Holds the "moles" of each of the four gases. - var/carbon_dioxide = 0 - var/nitrogen = 0 - var/phoron = 0 - - var/total_moles = 0 //Updated when a reaction occurs. - - var/volume = CELL_VOLUME - - var/temperature = 0 //in Kelvin, use calculate_temperature() to modify - - var/group_multiplier = 1 - //Size of the group this gas_mixture is representing. - //=1 for singletons - - var/graphic - - var/list/datum/gas/trace_gases = list() //Seemed to be a good idea that was abandoned - - var/tmp/oxygen_archived //These are variables for use with the archived data - var/tmp/carbon_dioxide_archived - var/tmp/nitrogen_archived - var/tmp/phoron_archived - - var/tmp/temperature_archived - - var/tmp/graphic_archived = 0 - var/tmp/fuel_burnt = 0 - - var/reacting = 0 - -//FOR THE LOVE OF GOD PLEASE USE THIS PROC -//Call it with negative numbers to remove gases. - -/datum/gas_mixture/proc/adjust(o2 = 0, co2 = 0, n2 = 0, tx = 0, list/datum/gas/traces = list()) - //Purpose: Adjusting the gases within a airmix - //Called by: Nothing, yet! - //Inputs: The values of the gases to adjust - //Outputs: null - - oxygen = max(0, oxygen + o2) - carbon_dioxide = max(0, carbon_dioxide + co2) - nitrogen = max(0, nitrogen + n2) - phoron = max(0, phoron + tx) - - //handle trace gasses - for(var/datum/gas/G in traces) - var/datum/gas/T = locate(G.type) in trace_gases - if(T) - T.moles = max(G.moles + T.moles, 0) - else if(G.moles > 0) - trace_gases |= G - update_values() - return - - //tg seems to like using these a lot -/datum/gas_mixture/proc/return_temperature() - return temperature - - -/datum/gas_mixture/proc/return_volume() - return max(0, volume) - - -/datum/gas_mixture/proc/thermal_energy() - return temperature*heat_capacity() - -/////////////////////////////// -//PV=nRT - related procedures// -/////////////////////////////// - -/datum/gas_mixture/proc/heat_capacity() - //Purpose: Returning the heat capacity of the gas mix - //Called by: UNKNOWN - //Inputs: None - //Outputs: Heat capacity - - var/heat_capacity = HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,phoron) - - if(trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - heat_capacity += trace_gas.moles*trace_gas.specific_heat - - return max(MINIMUM_HEAT_CAPACITY,heat_capacity) - -/datum/gas_mixture/proc/heat_capacity_archived() - //Purpose: Returning the archived heat capacity of the gas mix - //Called by: UNKNOWN - //Inputs: None - //Outputs: Archived heat capacity - - var/heat_capacity_archived = HEAT_CAPACITY_CALCULATION(oxygen_archived,carbon_dioxide_archived,nitrogen_archived,phoron_archived) - - if(trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - heat_capacity_archived += trace_gas.moles_archived*trace_gas.specific_heat - - return max(MINIMUM_HEAT_CAPACITY,heat_capacity_archived) - -/datum/gas_mixture/proc/total_moles() - return total_moles - /*var/moles = oxygen + carbon_dioxide + nitrogen + phoron - - if(trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - moles += trace_gas.moles - return moles*/ - -/datum/gas_mixture/proc/return_pressure() - //Purpose: Calculating Current Pressure - //Called by: - //Inputs: None - //Outputs: Gas pressure. - - if(volume>0) - return total_moles()*R_IDEAL_GAS_EQUATION*temperature/volume - return 0 - -// proc/return_temperature() - //Purpose: - //Inputs: - //Outputs: - -// return temperature - -// proc/return_volume() - //Purpose: - //Inputs: - //Outputs: - -// return max(0, volume) - -// proc/thermal_energy() - //Purpose: - //Inputs: - //Outputs: - -// return temperature*heat_capacity() - -/datum/gas_mixture/proc/update_values() - //Purpose: Calculating and storing values which were normally called CONSTANTLY - //Called by: Anything that changes values within a gas mix. - //Inputs: None - //Outputs: None - - total_moles = oxygen + carbon_dioxide + nitrogen + phoron - - if(trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - total_moles += trace_gas.moles - - return - -//////////////////////////////////////////// -//Procedures used for very specific events// -//////////////////////////////////////////// - -/datum/gas_mixture/proc/check_tile_graphic() - //Purpose: Calculating the graphic for a tile - //Called by: Turfs updating - //Inputs: None - //Outputs: 1 if graphic changed, 0 if unchanged - - graphic = 0 - if(phoron > MOLES_PHORON_VISIBLE) - graphic = 1 - else if(length(trace_gases)) - var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in trace_gases - if(sleeping_agent && (sleeping_agent.moles > 1)) - graphic = 2 - else - graphic = 0 - - return graphic != graphic_archived - -/datum/gas_mixture/proc/react(atom/dump_location) - //Purpose: Calculating if it is possible for a fire to occur in the airmix - //Called by: Air mixes updating? - //Inputs: None - //Outputs: If a fire occured - - //set to 1 if a notable reaction occured (used by pipe_network) - - zburn(null) - - return reacting - -/* -/datum/gas_mixture/proc/fire() - //Purpose: Calculating any fire reactions. - //Called by: react() (See above) - //Inputs: None - //Outputs: How much fuel burned - - return zburn(null) - - var/energy_released = 0 - var/old_heat_capacity = heat_capacity() - - var/datum/gas/volatile_fuel/fuel_store = locate(/datum/gas/volatile_fuel) in trace_gases - if(fuel_store) //General volatile gas burn - var/burned_fuel = 0 - - if(oxygen < fuel_store.moles) - burned_fuel = oxygen - fuel_store.moles -= burned_fuel - oxygen = 0 - else - burned_fuel = fuel_store.moles - oxygen -= fuel_store.moles - del(fuel_store) - - energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel - carbon_dioxide += burned_fuel - fuel_burnt += burned_fuel - - //Handle phoron burning - if(toxins > MINIMUM_HEAT_CAPACITY) - var/phoron_burn_rate = 0 - var/oxygen_burn_rate = 0 - //more phoron released at higher temperatures - var/temperature_scale - if(temperature > PLASMA_UPPER_TEMPERATURE) - temperature_scale = 1 - else - temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE) - if(temperature_scale > 0) - oxygen_burn_rate = 1.4 - temperature_scale - if(oxygen > toxins*PLASMA_OXYGEN_FULLBURN) - phoron_burn_rate = (toxins*temperature_scale)/4 - else - phoron_burn_rate = (temperature_scale*(oxygen/PLASMA_OXYGEN_FULLBURN))/4 - if(phoron_burn_rate > MINIMUM_HEAT_CAPACITY) - toxins -= phoron_burn_rate - oxygen -= phoron_burn_rate*oxygen_burn_rate - carbon_dioxide += phoron_burn_rate - - energy_released += FIRE_PLASMA_ENERGY_RELEASED * (phoron_burn_rate) - - fuel_burnt += (phoron_burn_rate)*(1+oxygen_burn_rate) - - if(energy_released > 0) - var/new_heat_capacity = heat_capacity() - if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) - temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity - update_values() - - return fuel_burnt*/ - -////////////////////////////////////////////// -//Procs for general gas spread calculations.// -////////////////////////////////////////////// - - -/datum/gas_mixture/proc/archive() - //Purpose: Archives the current gas values - //Called by: UNKNOWN - //Inputs: None - //Outputs: 1 - - oxygen_archived = oxygen - carbon_dioxide_archived = carbon_dioxide - nitrogen_archived = nitrogen - phoron_archived = phoron - - if(trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - trace_gas.moles_archived = trace_gas.moles - - temperature_archived = temperature - - graphic_archived = graphic - - return 1 - -/datum/gas_mixture/proc/check_then_merge(datum/gas_mixture/giver) - //Purpose: Similar to merge(...) but first checks to see if the amount of air assumed is small enough - // that group processing is still accurate for source (aborts if not) - //Called by: airgroups/machinery expelling air, ? - //Inputs: The gas to try and merge - //Outputs: 1 on successful merge. 0 otherwise. - - if(!giver) - return 0 - if(((giver.oxygen > MINIMUM_AIR_TO_SUSPEND) && (giver.oxygen >= oxygen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ - || ((giver.carbon_dioxide > MINIMUM_AIR_TO_SUSPEND) && (giver.carbon_dioxide >= carbon_dioxide*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ - || ((giver.nitrogen > MINIMUM_AIR_TO_SUSPEND) && (giver.nitrogen >= nitrogen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ - || ((giver.phoron > MINIMUM_AIR_TO_SUSPEND) && (giver.phoron >= phoron*MINIMUM_AIR_RATIO_TO_SUSPEND))) - return 0 - if(abs(giver.temperature - temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) - return 0 - - if(giver.trace_gases.len) - for(var/datum/gas/trace_gas in giver.trace_gases) - var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases - if((trace_gas.moles > MINIMUM_AIR_TO_SUSPEND) && (!corresponding || (trace_gas.moles >= corresponding.moles*MINIMUM_AIR_RATIO_TO_SUSPEND))) - return 0 - - return merge(giver) - -/datum/gas_mixture/proc/merge(datum/gas_mixture/giver) - //Purpose: Merges all air from giver into self. Deletes giver. - //Called by: Machinery expelling air, check_then_merge, ? - //Inputs: The gas to merge. - //Outputs: 1 - - if(!giver) - return 0 - - if(abs(temperature-giver.temperature)>MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/self_heat_capacity = heat_capacity()*group_multiplier - var/giver_heat_capacity = giver.heat_capacity()*giver.group_multiplier - var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity - if(combined_heat_capacity != 0) - temperature = (giver.temperature*giver_heat_capacity + temperature*self_heat_capacity)/combined_heat_capacity - - if((group_multiplier>1)||(giver.group_multiplier>1)) - oxygen += giver.oxygen*giver.group_multiplier/group_multiplier - carbon_dioxide += giver.carbon_dioxide*giver.group_multiplier/group_multiplier - nitrogen += giver.nitrogen*giver.group_multiplier/group_multiplier - phoron += giver.phoron*giver.group_multiplier/group_multiplier - else - oxygen += giver.oxygen - carbon_dioxide += giver.carbon_dioxide - nitrogen += giver.nitrogen - phoron += giver.phoron - - if(giver.trace_gases.len) - for(var/datum/gas/trace_gas in giver.trace_gases) - var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases - if(!corresponding) - corresponding = new trace_gas.type() - trace_gases += corresponding - corresponding.moles += trace_gas.moles*giver.group_multiplier/group_multiplier - update_values() - - // Let the garbage collector handle it, faster according to /tg/ testers - //del(giver) - return 1 - -/datum/gas_mixture/proc/remove(amount) - //Purpose: Removes a certain number of moles from the air. - //Called by: ? - //Inputs: How many moles to remove. - //Outputs: Removed air. - - var/sum = total_moles() - amount = min(amount,sum) //Can not take more air than tile has! - if(amount <= 0) - return null - - var/datum/gas_mixture/removed = new - - - removed.oxygen = QUANTIZE((oxygen/sum)*amount) - removed.nitrogen = QUANTIZE((nitrogen/sum)*amount) - removed.carbon_dioxide = QUANTIZE((carbon_dioxide/sum)*amount) - removed.phoron = QUANTIZE(((phoron/sum)*amount)) - - oxygen -= removed.oxygen/group_multiplier - nitrogen -= removed.nitrogen/group_multiplier - carbon_dioxide -= removed.carbon_dioxide/group_multiplier - phoron -= removed.phoron/group_multiplier - - if(trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - var/datum/gas/corresponding = new trace_gas.type() - removed.trace_gases += corresponding - - corresponding.moles = ((trace_gas.moles/sum)*amount) - trace_gas.moles -= (corresponding.moles/group_multiplier) - - removed.temperature = temperature - update_values() - removed.update_values() - - return removed - -/datum/gas_mixture/proc/remove_ratio(ratio) - //Purpose: Removes a certain ratio of the air. - //Called by: ? - //Inputs: Percentage to remove. - //Outputs: Removed air. - - if(ratio <= 0) - return null - - ratio = min(ratio, 1) - - var/datum/gas_mixture/removed = new - - removed.oxygen = QUANTIZE(oxygen*ratio) - removed.nitrogen = QUANTIZE(nitrogen*ratio) - removed.carbon_dioxide = QUANTIZE(carbon_dioxide*ratio) - removed.phoron = QUANTIZE(phoron*ratio) - - oxygen -= removed.oxygen/group_multiplier - nitrogen -= removed.nitrogen/group_multiplier - carbon_dioxide -= removed.carbon_dioxide/group_multiplier - phoron -= removed.phoron/group_multiplier - - if(trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - var/datum/gas/corresponding = new trace_gas.type() - removed.trace_gases += corresponding - - corresponding.moles = trace_gas.moles*ratio - trace_gas.moles -= corresponding.moles/group_multiplier - - removed.temperature = temperature - update_values() - removed.update_values() - - return removed - -/datum/gas_mixture/proc/check_then_remove(amount) - //Purpose: Similar to remove(...) but first checks to see if the amount of air removed is small enough - // that group processing is still accurate for source (aborts if not) - //Called by: ? - //Inputs: Number of moles to remove - //Outputs: Removed air or 0 if it can remove air or not. - - amount = min(amount,total_moles()) //Can not take more air than tile has! - - if((amount > MINIMUM_AIR_RATIO_TO_SUSPEND) && (amount > total_moles()*MINIMUM_AIR_RATIO_TO_SUSPEND)) - return 0 - - return remove(amount) - -/datum/gas_mixture/proc/copy_from(datum/gas_mixture/sample) - //Purpose: Duplicates the sample air mixture. - //Called by: airgroups splitting, ? - //Inputs: Gas to copy - //Outputs: 1 - - oxygen = sample.oxygen - carbon_dioxide = sample.carbon_dioxide - nitrogen = sample.nitrogen - phoron = sample.phoron - total_moles = sample.total_moles() - - trace_gases.len=null - if(sample.trace_gases.len > 0) - for(var/datum/gas/trace_gas in sample.trace_gases) - var/datum/gas/corresponding = new trace_gas.type() - trace_gases += corresponding - - corresponding.moles = trace_gas.moles - - temperature = sample.temperature - - return 1 - -/datum/gas_mixture/proc/check_gas_mixture(datum/gas_mixture/sharer) - //Purpose: Telling if one or both airgroups needs to disable group processing. - //Called by: Airgroups sharing air, checking if group processing needs disabled. - //Inputs: Gas to compare from other airgroup - //Outputs: 0 if the self-check failed (local airgroup breaks?) - // then -1 if sharer-check failed (sharing airgroup breaks?) - // then 1 if both checks pass (share succesful?) - if(!istype(sharer)) - return - - var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/TRANSFER_FRACTION - var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/TRANSFER_FRACTION - var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/TRANSFER_FRACTION - var/delta_phoron = QUANTIZE(phoron_archived - sharer.phoron_archived)/TRANSFER_FRACTION - - var/delta_temperature = (temperature_archived - sharer.temperature_archived) - - if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ - || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ - || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ - || ((abs(delta_phoron) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_phoron) >= phoron_archived*MINIMUM_AIR_RATIO_TO_SUSPEND))) - return 0 - - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) - return 0 - - if(sharer.trace_gases.len) - for(var/datum/gas/trace_gas in sharer.trace_gases) - if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) - var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases - if(corresponding) - if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4) - return 0 - else - return 0 - - if(trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) - if(!locate(trace_gas.type) in sharer.trace_gases) - return 0 - - if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= sharer.oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ - || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= sharer.carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ - || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= sharer.nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ - || ((abs(delta_phoron) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_phoron) >= sharer.phoron_archived*MINIMUM_AIR_RATIO_TO_SUSPEND))) - return -1 - - if(trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) - var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases - if(corresponding) - if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4) - return -1 - else - return -1 - - return 1 - -/datum/gas_mixture/proc/check_turf(turf/model) - //Purpose: Used to compare the gases in an unsimulated turf with the gas in a simulated one. - //Called by: Sharing air (mimicing) with adjacent unsimulated turfs - //Inputs: Unsimulated turf - //Outputs: 1 if safe to mimic, 0 if needs to break airgroup. - - var/delta_oxygen = (oxygen_archived - model.oxygen)/TRANSFER_FRACTION - var/delta_carbon_dioxide = (carbon_dioxide_archived - model.carbon_dioxide)/TRANSFER_FRACTION - var/delta_nitrogen = (nitrogen_archived - model.nitrogen)/TRANSFER_FRACTION - var/delta_phoron = (phoron_archived - model.phoron)/TRANSFER_FRACTION - - var/delta_temperature = (temperature_archived - model.temperature) - - if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ - || ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ - || ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \ - || ((abs(delta_phoron) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_phoron) >= phoron_archived*MINIMUM_AIR_RATIO_TO_SUSPEND))) - return 0 - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) - return 0 - - if(trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4) - return 0 - - return 1 - -/datum/gas_mixture/proc/share(datum/gas_mixture/sharer) - //Purpose: Used to transfer gas from a more pressurised tile to a less presurised tile - // (Two directional, if the other tile is more pressurised, air travels to current tile) - //Called by: Sharing air with adjacent simulated turfs - //Inputs: Air datum to share with - //Outputs: Amount of gas exchanged (Negative if lost air, positive if gained.) - - - if(!istype(sharer)) - return - - var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/TRANSFER_FRACTION - var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/TRANSFER_FRACTION - var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/TRANSFER_FRACTION - var/delta_phoron = QUANTIZE(phoron_archived - sharer.phoron_archived)/TRANSFER_FRACTION - - var/delta_temperature = (temperature_archived - sharer.temperature_archived) - - var/old_self_heat_capacity = 0 - var/old_sharer_heat_capacity = 0 - - var/heat_self_to_sharer = 0 - var/heat_capacity_self_to_sharer = 0 - var/heat_sharer_to_self = 0 - var/heat_capacity_sharer_to_self = 0 - - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - - var/delta_air = delta_oxygen+delta_nitrogen - if(delta_air) - var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air - if(delta_air > 0) - heat_self_to_sharer += air_heat_capacity*temperature_archived - heat_capacity_self_to_sharer += air_heat_capacity - else - heat_sharer_to_self -= air_heat_capacity*sharer.temperature_archived - heat_capacity_sharer_to_self -= air_heat_capacity - - if(delta_carbon_dioxide) - var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide - if(delta_carbon_dioxide > 0) - heat_self_to_sharer += carbon_dioxide_heat_capacity*temperature_archived - heat_capacity_self_to_sharer += carbon_dioxide_heat_capacity - else - heat_sharer_to_self -= carbon_dioxide_heat_capacity*sharer.temperature_archived - heat_capacity_sharer_to_self -= carbon_dioxide_heat_capacity - - if(delta_phoron) - var/phoron_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_phoron - if(delta_phoron > 0) - heat_self_to_sharer += phoron_heat_capacity*temperature_archived - heat_capacity_self_to_sharer += phoron_heat_capacity - else - heat_sharer_to_self -= phoron_heat_capacity*sharer.temperature_archived - heat_capacity_sharer_to_self -= phoron_heat_capacity - - old_self_heat_capacity = heat_capacity()*group_multiplier - old_sharer_heat_capacity = sharer.heat_capacity()*sharer.group_multiplier - - oxygen -= delta_oxygen/group_multiplier - sharer.oxygen += delta_oxygen/sharer.group_multiplier - - carbon_dioxide -= delta_carbon_dioxide/group_multiplier - sharer.carbon_dioxide += delta_carbon_dioxide/sharer.group_multiplier - - nitrogen -= delta_nitrogen/group_multiplier - sharer.nitrogen += delta_nitrogen/sharer.group_multiplier - - phoron -= delta_phoron/group_multiplier - sharer.phoron += delta_phoron/sharer.group_multiplier - - var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_phoron) - - var/list/trace_types_considered = list() - - if(trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - - var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases - var/delta = 0 - - if(corresponding) - delta = QUANTIZE(trace_gas.moles_archived - corresponding.moles_archived)/TRANSFER_FRACTION - else - corresponding = new trace_gas.type() - sharer.trace_gases += corresponding - - delta = trace_gas.moles_archived/TRANSFER_FRACTION - - trace_gas.moles -= delta/group_multiplier - corresponding.moles += delta/sharer.group_multiplier - - if(delta) - var/individual_heat_capacity = trace_gas.specific_heat*delta - if(delta > 0) - heat_self_to_sharer += individual_heat_capacity*temperature_archived - heat_capacity_self_to_sharer += individual_heat_capacity - else - heat_sharer_to_self -= individual_heat_capacity*sharer.temperature_archived - heat_capacity_sharer_to_self -= individual_heat_capacity - - moved_moles += delta - - trace_types_considered += trace_gas.type - - - if(sharer.trace_gases.len) - for(var/datum/gas/trace_gas in sharer.trace_gases) - if(trace_gas.type in trace_types_considered) continue - else - var/datum/gas/corresponding - var/delta = 0 - - corresponding = new trace_gas.type() - trace_gases += corresponding - - delta = trace_gas.moles_archived/TRANSFER_FRACTION - - trace_gas.moles -= delta/sharer.group_multiplier - corresponding.moles += delta/group_multiplier - - //Guaranteed transfer from sharer to self - var/individual_heat_capacity = trace_gas.specific_heat*delta - heat_sharer_to_self += individual_heat_capacity*sharer.temperature_archived - heat_capacity_sharer_to_self += individual_heat_capacity - - moved_moles += -delta - update_values() - sharer.update_values() - - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer - var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self - - if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY) - temperature = (old_self_heat_capacity*temperature - heat_capacity_self_to_sharer*temperature_archived + heat_capacity_sharer_to_self*sharer.temperature_archived)/new_self_heat_capacity - - if(new_sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) - sharer.temperature = (old_sharer_heat_capacity*sharer.temperature-heat_capacity_sharer_to_self*sharer.temperature_archived + heat_capacity_self_to_sharer*temperature_archived)/new_sharer_heat_capacity - - 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) - - if((delta_temperature > 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) - return delta_pressure*R_IDEAL_GAS_EQUATION/volume - - else - return 0 - -/datum/gas_mixture/proc/mimic(turf/model, border_multiplier) - //Purpose: Used transfer gas from a more pressurised tile to a less presurised unsimulated tile. - //Called by: "sharing" from unsimulated to simulated turfs. - //Inputs: Unsimulated turf, Multiplier for gas transfer (optional) - //Outputs: Amount of gas exchanged - - var/delta_oxygen = QUANTIZE(oxygen_archived - model.oxygen)/TRANSFER_FRACTION - var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - model.carbon_dioxide)/TRANSFER_FRACTION - var/delta_nitrogen = QUANTIZE(nitrogen_archived - model.nitrogen)/TRANSFER_FRACTION - var/delta_phoron = QUANTIZE(phoron_archived - model.phoron)/TRANSFER_FRACTION - - var/delta_temperature = (temperature_archived - model.temperature) - - var/heat_transferred = 0 - var/old_self_heat_capacity = 0 - var/heat_capacity_transferred = 0 - - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - - var/delta_air = delta_oxygen+delta_nitrogen - if(delta_air) - var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air - heat_transferred -= air_heat_capacity*model.temperature - heat_capacity_transferred -= air_heat_capacity - - if(delta_carbon_dioxide) - var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide - heat_transferred -= carbon_dioxide_heat_capacity*model.temperature - heat_capacity_transferred -= carbon_dioxide_heat_capacity - - if(delta_phoron) - var/phoron_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_phoron - heat_transferred -= phoron_heat_capacity*model.temperature - heat_capacity_transferred -= phoron_heat_capacity - - old_self_heat_capacity = heat_capacity()*group_multiplier - - if(border_multiplier) - oxygen -= delta_oxygen*border_multiplier/group_multiplier - carbon_dioxide -= delta_carbon_dioxide*border_multiplier/group_multiplier - nitrogen -= delta_nitrogen*border_multiplier/group_multiplier - phoron -= delta_phoron*border_multiplier/group_multiplier - else - oxygen -= delta_oxygen/group_multiplier - carbon_dioxide -= delta_carbon_dioxide/group_multiplier - nitrogen -= delta_nitrogen/group_multiplier - phoron -= delta_phoron/group_multiplier - - var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_phoron) - - if(trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - var/delta = 0 - - delta = trace_gas.moles_archived/TRANSFER_FRACTION - - if(border_multiplier) - trace_gas.moles -= delta*border_multiplier/group_multiplier - else - trace_gas.moles -= delta/group_multiplier - - var/heat_cap_transferred = delta*trace_gas.specific_heat - heat_transferred += heat_cap_transferred*temperature_archived - heat_capacity_transferred += heat_cap_transferred - moved_moles += delta - update_values() - - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/new_self_heat_capacity = old_self_heat_capacity - heat_capacity_transferred - if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY) - if(border_multiplier) - temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity - else - temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity - - temperature_mimic(model, model.thermal_conductivity, border_multiplier) - - if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE) - var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - model.temperature*(model.oxygen+model.carbon_dioxide+model.nitrogen+model.phoron) - return delta_pressure*R_IDEAL_GAS_EQUATION/volume - else - return 0 - -/datum/gas_mixture/proc/check_both_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient) - var/delta_temperature = (temperature_archived - sharer.temperature_archived) - - var/self_heat_capacity = heat_capacity_archived() - var/sharer_heat_capacity = sharer.heat_capacity_archived() - - var/self_temperature_delta = 0 - var/sharer_temperature_delta = 0 - - if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) - var/heat = conduction_coefficient*delta_temperature* \ - (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity)) - - self_temperature_delta = -heat/(self_heat_capacity*group_multiplier) - sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier) - else - return 1 - - if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ - && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) - return 0 - - if((abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ - && (abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*sharer.temperature_archived)) - return -1 - - temperature += self_temperature_delta - sharer.temperature += sharer_temperature_delta - - return 1 - //Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency - -/datum/gas_mixture/proc/check_me_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient) - var/delta_temperature = (temperature_archived - sharer.temperature_archived) - - var/self_heat_capacity = heat_capacity_archived() - var/sharer_heat_capacity = sharer.heat_capacity_archived() - - var/self_temperature_delta = 0 - var/sharer_temperature_delta = 0 - - if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) - var/heat = conduction_coefficient*delta_temperature* \ - (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity)) - - self_temperature_delta = -heat/(self_heat_capacity*group_multiplier) - sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier) - else - return 1 - - if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ - && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) - return 0 - - temperature += self_temperature_delta - sharer.temperature += sharer_temperature_delta - - return 1 - //Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency - -/datum/gas_mixture/proc/check_me_then_temperature_turf_share(turf/simulated/sharer, conduction_coefficient) - var/delta_temperature = (temperature_archived - sharer.temperature) - - var/self_temperature_delta = 0 - var/sharer_temperature_delta = 0 - - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/self_heat_capacity = heat_capacity_archived() - - if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) - var/heat = conduction_coefficient*delta_temperature* \ - (self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity)) - - self_temperature_delta = -heat/(self_heat_capacity*group_multiplier) - sharer_temperature_delta = heat/sharer.heat_capacity - else - return 1 - - if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ - && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) - return 0 - - temperature += self_temperature_delta - sharer.temperature += sharer_temperature_delta - - return 1 - //Logic integrated from: temperature_turf_share(sharer, conduction_coefficient) for efficiency - -/datum/gas_mixture/proc/check_me_then_temperature_mimic(turf/model, conduction_coefficient) - var/delta_temperature = (temperature_archived - model.temperature) - var/self_temperature_delta = 0 - - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/self_heat_capacity = heat_capacity_archived() - - if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) - var/heat = conduction_coefficient*delta_temperature* \ - (self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity)) - - self_temperature_delta = -heat/(self_heat_capacity*group_multiplier) - - if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \ - && (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived)) - return 0 - - temperature += self_temperature_delta - - return 1 - //Logic integrated from: temperature_mimic(model, conduction_coefficient) for efficiency - -/datum/gas_mixture/proc/temperature_share(datum/gas_mixture/sharer, conduction_coefficient) - var/delta_temperature = (temperature_archived - sharer.temperature_archived) - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/self_heat_capacity = heat_capacity_archived() - var/sharer_heat_capacity = sharer.heat_capacity_archived() - if(!group_multiplier) - message_admins("Error! The gas mixture (ref \ref[src]) has no group multiplier!") - return - - if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) - var/heat = conduction_coefficient*delta_temperature* \ - (self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity)) - - temperature -= heat/(self_heat_capacity*group_multiplier) - sharer.temperature += heat/(sharer_heat_capacity*sharer.group_multiplier) - -/datum/gas_mixture/proc/temperature_mimic(turf/model, conduction_coefficient, border_multiplier) - var/delta_temperature = (temperature - model.temperature) - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/self_heat_capacity = heat_capacity()//_archived() - if(!group_multiplier) - message_admins("Error! The gas mixture (ref \ref[src]) has no group multiplier!") - return - - if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) - var/heat = conduction_coefficient*delta_temperature* \ - (self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity)) - - if(border_multiplier) - temperature -= heat*border_multiplier/(self_heat_capacity*group_multiplier) - else - temperature -= heat/(self_heat_capacity*group_multiplier) - -/datum/gas_mixture/proc/temperature_turf_share(turf/simulated/sharer, conduction_coefficient) - var/delta_temperature = (temperature_archived - sharer.temperature) - if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER) - var/self_heat_capacity = heat_capacity() - - if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY)) - var/heat = conduction_coefficient*delta_temperature* \ - (self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity)) - - temperature -= heat/(self_heat_capacity*group_multiplier) - sharer.temperature += heat/sharer.heat_capacity - -/datum/gas_mixture/proc/compare(datum/gas_mixture/sample) - //Purpose: Compares sample to self to see if within acceptable ranges that group processing may be enabled - //Called by: Airgroups trying to rebuild - //Inputs: Gas mix to compare - //Outputs: 1 if can rebuild, 0 if not. - if(!sample) return 0 - - - if((abs(oxygen-sample.oxygen) > MINIMUM_AIR_TO_SUSPEND) && \ - ((oxygen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen))) - return 0 - if((abs(nitrogen-sample.nitrogen) > MINIMUM_AIR_TO_SUSPEND) && \ - ((nitrogen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen) || (nitrogen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen))) - return 0 - if((abs(carbon_dioxide-sample.carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && \ - ((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (carbon_dioxide > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide))) - return 0 - if((abs(phoron-sample.phoron) > MINIMUM_AIR_TO_SUSPEND) && \ - ((phoron < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.phoron) || (phoron > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.phoron))) - return 0 - - - if(total_moles() > MINIMUM_AIR_TO_SUSPEND) - if((abs(temperature-sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \ - ((temperature < (1-MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature) || (temperature > (1+MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature))) - //world << "temp fail [temperature] & [sample.temperature]" - return 0 - var/check_moles - if(sample.trace_gases.len) - for(var/datum/gas/trace_gas in sample.trace_gases) - var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases - if(corresponding) - check_moles = corresponding.moles - else - check_moles = 0 - - if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \ - ((check_moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (check_moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles))) - return 0 - - if(trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases - if(corresponding) - check_moles = corresponding.moles - else - check_moles = 0 - - if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \ - ((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles))) - return 0 - - return 1 - -/datum/gas_mixture/proc/add(datum/gas_mixture/right_side) - oxygen += right_side.oxygen - carbon_dioxide += right_side.carbon_dioxide - nitrogen += right_side.nitrogen - phoron += right_side.phoron - - if(trace_gases.len || right_side.trace_gases.len) - for(var/datum/gas/trace_gas in right_side.trace_gases) - var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases - if(!corresponding) - corresponding = new trace_gas.type() - trace_gases += corresponding - corresponding.moles += trace_gas.moles - - update_values() - return 1 - -/datum/gas_mixture/proc/subtract(datum/gas_mixture/right_side) - //Purpose: Subtracts right_side from air_mixture. Used to help turfs mingle - //Called by: Pipelines ending in a break (or something) - //Inputs: Gas mix to remove - //Outputs: 1 - - oxygen = max(oxygen - right_side.oxygen) - carbon_dioxide = max(carbon_dioxide - right_side.carbon_dioxide) - nitrogen = max(nitrogen - right_side.nitrogen) - phoron = max(phoron - right_side.phoron) - - if(trace_gases.len || right_side.trace_gases.len) - for(var/datum/gas/trace_gas in right_side.trace_gases) - var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases - if(corresponding) - corresponding.moles = max(0, corresponding.moles - trace_gas.moles) - - update_values() - return 1 - -/datum/gas_mixture/proc/multiply(factor) - oxygen *= factor - carbon_dioxide *= factor - nitrogen *= factor - phoron *= factor - - if(trace_gases && trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - trace_gas.moles *= factor - - update_values() - return 1 - -/datum/gas_mixture/proc/divide(factor) - oxygen /= factor - carbon_dioxide /= factor - nitrogen /= factor - phoron /= factor - - if(trace_gases && trace_gases.len) - for(var/datum/gas/trace_gas in trace_gases) - trace_gas.moles /= factor - - update_values() - return 1 diff --git a/code/ZAS/_gas_mixture_xgm.dm b/code/ZAS/_gas_mixture_xgm.dm index ceb72679e9..8043be1579 100644 --- a/code/ZAS/_gas_mixture_xgm.dm +++ b/code/ZAS/_gas_mixture_xgm.dm @@ -220,7 +220,7 @@ /datum/gas_mixture/proc/remove_ratio(ratio, out_group_multiplier = 1) if(ratio <= 0) return null - out_group_multiplier = max(1, min(group_multiplier, out_group_multiplier)) + out_group_multiplier = between(1, out_group_multiplier, group_multiplier) ratio = min(ratio, 1) @@ -237,6 +237,11 @@ return removed +//Removes a volume of gas from the mixture and returns a gas_mixture containing the removed air with the given volume +/datum/gas_mixture/proc/remove_volume(removed_volume) + var/datum/gas_mixture/removed = remove_ratio(removed_volume/(volume*group_multiplier), 1) + removed.volume = removed_volume + return removed //Removes moles from the gas mixture, limited by a given flag. Returns a gax_mixture containing the removed air. /datum/gas_mixture/proc/remove_by_flag(flag, amount) @@ -301,7 +306,7 @@ /datum/gas_mixture/proc/react(atom/dump_location) - zburn(null) + zburn(null, force_burn=0, no_check=0) //could probably just call zburn() here with no args but I like being explicit. //Rechecks the gas_mixture and adjusts the graphic list if needed. diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 4e250cfe18..45618f2ffc 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -9,6 +9,13 @@ src:Topic(href, href_list) return null +/proc/is_on_same_plane_or_station(var/z1, var/z2) + if(z1 == z2) + return 1 + if((z1 in config.station_levels) && (z2 in config.station_levels)) + return 1 + return 0 + /proc/get_area(O) var/turf/loc = get_turf(O) if(!loc) @@ -484,5 +491,8 @@ datum/projectile_data temps[direction] = rstats return temps -/proc/MinutesToTicks(var/minutes as num) - return minutes * 60 * 10 +/proc/MinutesToTicks(var/minutes) + return SecondsToTicks(60 * minutes) + +/proc/SecondsToTicks(var/seconds) + return seconds * 10 diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index db927a1f67..01b9509ae8 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -42,13 +42,13 @@ var/global/list/facial_hair_styles_male_list = list() var/global/list/facial_hair_styles_female_list = list() var/global/list/skin_styles_female_list = list() //unused //Underwear -var/global/list/underwear_m = list("White", "Grey", "Green", "Blue", "Black", "Mankini", "None") //Curse whoever made male/female underwear diffrent colours -var/global/list/underwear_f = list("Red", "White", "Yellow", "Blue", "Black", "Thong", "None") +var/global/list/underwear_m = list("White" = "m1", "Grey" = "m2", "Green" = "m3", "Blue" = "m4", "Black" = "m5", "Mankini" = "m6", "None") //Curse whoever made male/female underwear diffrent colours +var/global/list/underwear_f = list("Red" = "f1", "White" = "f2", "Yellow" = "f3", "Blue" = "f4", "Black" = "f5", "Thong" = "f6", "Black Sports" = "f7","White Sports" = "f8","None") //undershirt -var/global/list/undershirt_t = list("Black Tank top", "White Tank top", "Black shirt", "White shirt", "None") +var/global/list/undershirt_t = list("White Tank top" = "u1", "Black Tank top" = "u2", "Black shirt" = "u3", "White shirt" = "u4", "None") //Backpacks var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt") - +var/global/list/exclude_jobs = list(/datum/job/ai,/datum/job/cyborg) ////////////////////////// /////Initial Building///// ////////////////////////// @@ -88,7 +88,8 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al sort_surgeries() //List of job. I can't believe this was calculated multiple times per tick! - paths = typesof(/datum/job) -list(/datum/job,/datum/job/ai,/datum/job/cyborg) + paths = typesof(/datum/job)-/datum/job + paths -= exclude_jobs for(var/T in paths) var/datum/job/J = new T joblist[J.title] = J diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index 39c1f23d6b..b7caf86669 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -343,6 +343,12 @@ proc/listclearnulls(list/list) return (result + L.Copy(Li, 0)) return (result + R.Copy(Ri, 0)) +// Macros to test for bits in a bitfield. Note, that this is for use with indexes, not bit-masks! +#define BITTEST(bitfield,index) ((bitfield) & (1 << (index))) +#define BITSET(bitfield,index) (bitfield) |= (1 << (index)) +#define BITRESET(bitfield,index) (bitfield) &= ~(1 << (index)) +#define BITFLIP(bitfield,index) (bitfield) ^= (1 << (index)) + //Converts a bitfield to a list of numbers (or words if a wordlist is provided) /proc/bitfield2list(bitfield = 0, list/wordlist) var/list/r = list() @@ -369,6 +375,12 @@ proc/listclearnulls(list/list) i++ return null +// Returns the key based on the index +/proc/get_key_by_value(var/list/L, var/value) + for(var/key in L) + if(L[key] == value) + return key + /proc/count_by_type(var/list/L, type) var/i = 0 for(var/T in L) @@ -580,7 +592,18 @@ datum/proc/dd_SortValue() return "[src]" /obj/machinery/dd_SortValue() - return "[sanitize(name)]" + return "[sanitize_old(name)]" /obj/machinery/camera/dd_SortValue() return "[c_tag]" + +/datum/alarm/dd_SortValue() + return "[sanitize_old(last_name)]" + +//creates every subtype of prototype (excluding prototype) and adds it to list L. +//if no list/L is provided, one is created. +/proc/init_subtypes(prototype, list/L) + if(!istype(L)) L = list() + for(var/path in (typesof(prototype) - prototype)) + L += new path() + return L diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm index 7f8958360d..f148b10ef8 100644 --- a/code/__HELPERS/maths.dm +++ b/code/__HELPERS/maths.dm @@ -1,9 +1,5 @@ -#define RAND_F(L, H) (rand()*(H-L) + L) - -// Credits to Nickr5 for the useful procs I've taken from his library resource. - -var/const/E = 2.71828183 -var/const/Sqrt2 = 1.41421356 +// Macro functions. +#define RAND_F(LOW, HIGH) (rand()*(HIGH-LOW) + LOW) // List of square roots for the numbers 1-100. var/list/sqrtTable = list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, @@ -11,111 +7,127 @@ var/list/sqrtTable = list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10) -/proc/Atan2(x, y) - if(!x && !y) return 0 - var/a = arccos(x / sqrt(x*x + y*y)) - return y >= 0 ? a : -a - -/proc/Ceiling(x) - return -round(-x) - /proc/Clamp(val, min, max) return max(min, min(val, max)) -// cotangent -/proc/Cot(x) - return 1 / Tan(x) - -// cosecant -/proc/Csc(x) - return 1 / sin(x) - -/proc/Default(a, b) - return a ? a : b - -/proc/Floor(x) - return round(x) - -// Greatest Common Divisor - Euclid's algorithm -/proc/Gcd(a, b) - return b ? Gcd(b, a % b) : a - -/proc/Inverse(x) - return 1 / x - -/proc/IsAboutEqual(a, b, deviation = 0.1) - return abs(a - b) <= deviation - -/proc/IsEven(x) - return x % 2 == 0 - -// Returns true if val is from min to max, inclusive. -/proc/IsInRange(val, min, max) - return min <= val && val <= max - -/proc/IsInteger(x) - return Floor(x) == x - -/proc/IsOdd(x) - return !IsEven(x) - -/proc/IsMultiple(x, y) - return x % y == 0 - -// Least Common Multiple -/proc/Lcm(a, b) - return abs(a) / Gcd(a, b) * abs(b) - -// Performs a linear interpolation between a and b. -// Note that amount=0 returns a, amount=1 returns b, and -// amount=0.5 returns the mean of a and b. -/proc/Lerp(a, b, amount = 0.5) - return a + (b - a) * amount - -/proc/Mean(...) - var/values = 0 - var/sum = 0 - for(var/val in args) - values++ - sum += val - return sum / values - - -// Returns the nth root of x. -/proc/Root(n, x) - return x ** (1 / n) - -// secant -/proc/Sec(x) - return 1 / cos(x) - -// The quadratic formula. Returns a list with the solutions, or an empty list -// if they are imaginary. -/proc/SolveQuadratic(a, b, c) - ASSERT(a) - . = list() - var/d = b*b - 4 * a * c - var/bottom = 2 * a - if(d < 0) return - var/root = sqrt(d) - . += (-b + root) / bottom - if(!d) return - . += (-b - root) / bottom - -// tangent -/proc/Tan(x) - return sin(x) / cos(x) - -/proc/ToDegrees(radians) - // 180 / Pi - return radians * 57.2957795 - -/proc/ToRadians(degrees) - // Pi / 180 - return degrees * 0.0174532925 - // min is inclusive, max is exclusive /proc/Wrap(val, min, max) var/d = max - min var/t = Floor((val - min) / d) return val - (t * d) + +/proc/Default(a, b) + return a ? a : b + +// Trigonometric functions. +/proc/Tan(x) + return sin(x) / cos(x) + +/proc/Csc(x) + return 1 / sin(x) + +/proc/Sec(x) + return 1 / cos(x) + +/proc/Cot(x) + return 1 / Tan(x) + +/proc/Atan2(x, y) + if(!x && !y) return 0 + var/a = arccos(x / sqrt(x*x + y*y)) + return y >= 0 ? a : -a + +/proc/Floor(x) + return round(x) + +/proc/Ceiling(x) + return -round(-x) + +// Greatest Common Divisor: Euclid's algorithm. +/proc/Gcd(a, b) + while (1) + if (!b) return a + a %= b + if (!a) return b + b %= a + +// Least Common Multiple. The formula is a consequence of: a*b = LCM*GCD. +/proc/Lcm(a, b) + return abs(a) * abs(b) / Gcd(a, b) + +// Useful in the cases when x is a large expression, e.g. x = 3a/2 + b^2 + Function(c) +/proc/Square(x) + return x*x + +/proc/Inverse(x) + return 1 / x + +// Condition checks. +/proc/IsAboutEqual(a, b, delta = 0.1) + return abs(a - b) <= delta + +// Returns true if val is from min to max, inclusive. +/proc/IsInRange(val, min, max) + return (val >= min) && (val <= max) + +/proc/IsInteger(x) + return Floor(x) == x + +/proc/IsMultiple(x, y) + return x % y == 0 + +/proc/IsEven(x) + return !(x & 0x1) + +/proc/IsOdd(x) + return (x & 0x1) + +// Performs a linear interpolation between a and b. +// Note: weight=0 returns a, weight=1 returns b, and weight=0.5 returns the mean of a and b. +/proc/Interpolate(a, b, weight = 0.5) + return a + (b - a) * weight // Equivalent to: a*(1 - weight) + b*weight + +/proc/Mean(...) + var/sum = 0 + for(var/val in args) + sum += val + return sum / args.len + +// Returns the nth root of x. +/proc/Root(n, x) + return x ** (1 / n) + +// The quadratic formula. Returns a list with the solutions, or an empty list +// if they are imaginary. +/proc/SolveQuadratic(a, b, c) + ASSERT(a) + + . = list() + var/discriminant = b*b - 4*a*c + var/bottom = 2*a + + // Return if the roots are imaginary. + if(discriminant < 0) + return + + var/root = sqrt(discriminant) + . += (-b + root) / bottom + + // If discriminant == 0, there would be two roots at the same position. + if(discriminant != 0) + . += (-b - root) / bottom + +/proc/ToDegrees(radians) + // 180 / Pi ~ 57.2957795 + return radians * 57.2957795 + +/proc/ToRadians(degrees) + // Pi / 180 ~ 0.0174532925 + return degrees * 0.0174532925 + +// Vector algebra. +/proc/squaredNorm(x, y) + return x*x + y*y + +/proc/norm(x, y) + return sqrt(squaredNorm(x, y)) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 346ffc7c47..54ce601ac7 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -22,46 +22,103 @@ * Text sanitization */ -//Simply removes < and > and limits the length of the message -/proc/strip_html_simple(var/t,var/limit=MAX_MESSAGE_LEN) - var/list/strip_chars = list("<",">") - t = copytext(t,1,limit) - for(var/char in strip_chars) - var/index = findtext(t, char) - while(index) - t = copytext(t, 1, index) + copytext(t, index+1) - index = findtext(t, char) - return t +//Used for preprocessing entered text +/proc/sanitize(var/input, var/max_length = MAX_MESSAGE_LEN, var/encode = 1, var/trim = 1, var/extra = 1) + if(!input) + return -//Removes a few problematic characters -/proc/sanitize_simple(var/t,var/list/repl_chars = list("\n"="#","\t"="#")) - for(var/char in repl_chars) - t = replacetext(t, char, repl_chars[char]) - return t + if(max_length) + input = copytext(input,1,max_length) -/proc/readd_quotes(var/t) - var/list/repl_chars = list(""" = "\"") - for(var/char in repl_chars) - var/index = findtext(t, char) - while(index) - t = copytext(t, 1, index) + repl_chars[char] + copytext(t, index+5) - index = findtext(t, char) - return t + if(extra) + input = replace_characters(input, list("\n"=" ","\t"=" ")) -//Runs byond's sanitization proc along-side sanitize_simple -/proc/sanitize(var/t,var/list/repl_chars = null) - return html_encode(sanitize_simple(t,repl_chars)) + if(encode) + //In addition to processing html, html_encode removes byond formatting codes like "\red", "\i" and other. + //It is important to avoid double-encode text, it can "break" quotes and some other characters. + //Also, keep in mind that escaped characters don't work in the interface (window titles, lower left corner of the main window, etc.) + input = html_encode(input) + else + //If not need encode text, simply remove < and > + //note: we can also remove here byond formatting codes: 0xFF + next byte + input = replace_characters(input, list("<"=" ", ">"=" ")) -//Runs sanitize and strip_html_simple -//I believe strip_html_simple() is required to run first to prevent '<' from displaying as '<' after sanitize() calls byond's html_encode() -/proc/strip_html(var/t,var/limit=MAX_MESSAGE_LEN) - return copytext((sanitize(strip_html_simple(t))),1,limit) + if(trim) + //Maybe, we need trim text twice? Here and before copytext? + input = trim(input) -//Runs byond's sanitization proc along-side strip_html_simple -//I believe strip_html_simple() is required to run first to prevent '<' from displaying as '<' that html_encode() would cause -/proc/adminscrub(var/t,var/limit=MAX_MESSAGE_LEN) - return copytext((html_encode(strip_html_simple(t))),1,limit) + return input +//Run sanitize(), but remove <, >, " first to prevent displaying them as > < &34; in some places, after html_encode(). +//Best used for sanitize object names, window titles. +//If you have a problem with sanitize() in chat, when quotes and >, < are displayed as html entites - +//this is a problem of double-encode(when & becomes &), use sanitize() with encode=0, but not the sanitizeSafe()! +/proc/sanitizeSafe(var/input, var/max_length = MAX_MESSAGE_LEN, var/encode = 1, var/trim = 1, var/extra = 1) + return sanitize(replace_characters(input, list(">"=" ","<"=" ", "\""="'"), max_length, encode, trim, extra)) + +//Filters out undesirable characters from names +/proc/sanitizeName(var/input, var/max_length = MAX_NAME_LEN, var/allow_numbers = 0) + if(!input || length(input) > max_length) + return //Rejects the input if it is null or if it is longer then the max length allowed + + var/number_of_alphanumeric = 0 + var/last_char_group = 0 + var/output = "" + + for(var/i=1, i<=length(input), i++) + var/ascii_char = text2ascii(input,i) + switch(ascii_char) + // A .. Z + if(65 to 90) //Uppercase Letters + output += ascii2text(ascii_char) + number_of_alphanumeric++ + last_char_group = 4 + + // a .. z + if(97 to 122) //Lowercase Letters + if(last_char_group<2) output += ascii2text(ascii_char-32) //Force uppercase first character + else output += ascii2text(ascii_char) + number_of_alphanumeric++ + last_char_group = 4 + + // 0 .. 9 + if(48 to 57) //Numbers + if(!last_char_group) continue //suppress at start of string + if(!allow_numbers) continue + output += ascii2text(ascii_char) + number_of_alphanumeric++ + last_char_group = 3 + + // ' - . + if(39,45,46) //Common name punctuation + if(!last_char_group) continue + output += ascii2text(ascii_char) + last_char_group = 2 + + // ~ | @ : # $ % & * + + if(126,124,64,58,35,36,37,38,42,43) //Other symbols that we'll allow (mainly for AI) + if(!last_char_group) continue //suppress at start of string + if(!allow_numbers) continue + output += ascii2text(ascii_char) + last_char_group = 2 + + //Space + if(32) + if(last_char_group <= 1) continue //suppress double-spaces and spaces at start of string + output += ascii2text(ascii_char) + last_char_group = 1 + else + return + + if(number_of_alphanumeric < 2) return //protects against tiny names like "A" and also names like "' ' ' ' ' ' ' '" + + if(last_char_group == 1) + output = copytext(output,1,length(output)) //removes the last character (in this case a space) + + for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai")) //prevents these common metagamey names + if(cmptext(output,bad_name)) return //(not case sensitive) + + return output //Returns null if there is any bad text in the string /proc/reject_bad_text(var/text, var/max_length=512) @@ -76,97 +133,11 @@ else non_whitespace = 1 if(non_whitespace) return text //only accepts the text if it has some non-spaces -// Used to get a properly sanitized input, of max_length -/proc/stripped_input(var/mob/user, var/message = "", var/title = "", var/default = "", var/max_length=MAX_MESSAGE_LEN) - var/name = input(user, message, title, default) - return strip_html_properly(name, max_length) -// Used to get a trimmed, properly sanitized input, of max_length -/proc/trim_strip_input(var/mob/user, var/message = "", var/title = "", var/default = "", var/max_length=MAX_MESSAGE_LEN) - return trim(stripped_input(user, message, title, default, max_length)) +//Old variant. Haven't dared to replace in some places. +/proc/sanitize_old(var/t,var/list/repl_chars = list("\n"="#","\t"="#")) + return html_encode(replace_characters(t,repl_chars)) -//Filters out undesirable characters from names -/proc/reject_bad_name(var/t_in, var/allow_numbers=0, var/max_length=MAX_NAME_LEN) - if(!t_in || length(t_in) > max_length) - return //Rejects the input if it is null or if it is longer then the max length allowed - - var/number_of_alphanumeric = 0 - var/last_char_group = 0 - var/t_out = "" - - for(var/i=1, i<=length(t_in), i++) - var/ascii_char = text2ascii(t_in,i) - switch(ascii_char) - // A .. Z - if(65 to 90) //Uppercase Letters - t_out += ascii2text(ascii_char) - number_of_alphanumeric++ - last_char_group = 4 - - // a .. z - if(97 to 122) //Lowercase Letters - if(last_char_group<2) t_out += ascii2text(ascii_char-32) //Force uppercase first character - else t_out += ascii2text(ascii_char) - number_of_alphanumeric++ - last_char_group = 4 - - // 0 .. 9 - if(48 to 57) //Numbers - if(!last_char_group) continue //suppress at start of string - if(!allow_numbers) continue - t_out += ascii2text(ascii_char) - number_of_alphanumeric++ - last_char_group = 3 - - // ' - . - if(39,45,46) //Common name punctuation - if(!last_char_group) continue - t_out += ascii2text(ascii_char) - last_char_group = 2 - - // ~ | @ : # $ % & * + - if(126,124,64,58,35,36,37,38,42,43) //Other symbols that we'll allow (mainly for AI) - if(!last_char_group) continue //suppress at start of string - if(!allow_numbers) continue - t_out += ascii2text(ascii_char) - last_char_group = 2 - - //Space - if(32) - if(last_char_group <= 1) continue //suppress double-spaces and spaces at start of string - t_out += ascii2text(ascii_char) - last_char_group = 1 - else - return - - if(number_of_alphanumeric < 2) return //protects against tiny names like "A" and also names like "' ' ' ' ' ' ' '" - - if(last_char_group == 1) - t_out = copytext(t_out,1,length(t_out)) //removes the last character (in this case a space) - - for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai")) //prevents these common metagamey names - if(cmptext(t_out,bad_name)) return //(not case sensitive) - - return t_out - -//checks text for html tags -//if tag is not in whitelist (var/list/paper_tag_whitelist in global.dm) -//relpaces < with < -proc/checkhtml(var/t) - t = sanitize_simple(t, list("&#"=".")) - var/p = findtext(t,"<",1) - while (p) //going through all the tags - var/start = p++ - var/tag = copytext(t,p, p+1) - if (tag != "/") - while (reject_bad_text(copytext(t, p, p+1), 1)) - tag = copytext(t,start, p) - p++ - tag = copytext(t,start+1, p) - if (!(tag in paper_tag_whitelist)) //if it's unkown tag, disarming it - t = copytext(t,1,start-1) + "<" + copytext(t,start+1) - p = findtext(t,"<",p) - return t /* * Text searches */ @@ -203,12 +174,18 @@ proc/checkhtml(var/t) /* * Text modification */ + /proc/replacetext(text, find, replacement) return list2text(text2list(text, find), replacement) /proc/replacetextEx(text, find, replacement) return list2text(text2listEx(text, find), replacement) +/proc/replace_characters(var/t,var/list/repl_chars) + for(var/char in repl_chars) + replacetext(t, char, repl_chars[char]) + return t + //Adds 'u' number of zeros ahead of the text 't' /proc/add_zero(t, u) while (length(t) < u) @@ -239,7 +216,6 @@ proc/checkhtml(var/t) for (var/i = length(text), i > 0, i--) if (text2ascii(text, i) > 32) return copytext(text, 1, i + 1) - return "" //Returns a string with reserved characters and spaces before the first word and after the last word removed. @@ -250,43 +226,18 @@ proc/checkhtml(var/t) /proc/capitalize(var/t as text) return uppertext(copytext(t, 1, 2)) + copytext(t, 2) -//Centers text by adding spaces to either side of the string. -/proc/dd_centertext(message, length) - var/new_message = message - var/size = length(message) - var/delta = length - size - if(size == length) - return new_message - if(size > length) - return copytext(new_message, 1, length + 1) - if(delta == 1) - return new_message + " " - if(delta % 2) - new_message = " " + new_message - delta-- - var/spaces = add_lspace("",delta/2-1) - return spaces + new_message + spaces - -//Limits the length of the text. Note: MAX_MESSAGE_LEN and MAX_NAME_LEN are widely used for this purpose -/proc/dd_limittext(message, length) - var/size = length(message) - if(size <= length) - return message - return copytext(message, 1, length + 1) - - -/proc/stringmerge(var/text,var/compare,replace = "*") //This proc fills in all spaces with the "replace" var (* by default) with whatever //is in the other string at the same spot (assuming it is not a replace char). //This is used for fingerprints +/proc/stringmerge(var/text,var/compare,replace = "*") var/newtext = text if(lentext(text) != lentext(compare)) return 0 for(var/i = 1, i < lentext(text), i++) var/a = copytext(text,i,i+1) var/b = copytext(compare,i,i+1) -//if it isn't both the same letter, or if they are both the replacement character -//(no way to know what it was supposed to be) + //if it isn't both the same letter, or if they are both the replacement character + //(no way to know what it was supposed to be) if(a != b) if(a == replace) //if A is the replacement char newtext = copytext(newtext,1,i) + b + copytext(newtext, i+1) @@ -296,9 +247,9 @@ proc/checkhtml(var/t) return 0 return newtext -/proc/stringpercent(var/text,character = "*") //This proc returns the number of chars of the string that is the character //This is used for detective work to determine fingerprint completion. +/proc/stringpercent(var/text,character = "*") if(!text || !character) return 0 var/count = 0 @@ -325,36 +276,6 @@ proc/TextPreview(var/string,var/len=40) else return "[copytext(string, 1, 37)]..." -//This proc strips html properly, but it's not lazy like the other procs. -//This means that it doesn't just remove < and > and call it a day. -//Also limit the size of the input, if specified. -/proc/strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN) - if(!input) - return - var/opentag = 1 //These store the position of < and > respectively. - var/closetag = 1 - while(1) - opentag = findtext(input, "<") - closetag = findtext(input, ">") - if(closetag && opentag) - if(closetag < opentag) - input = copytext(input, (closetag + 1)) - else - input = copytext(input, 1, opentag) + copytext(input, (closetag + 1)) - else if(closetag || opentag) - if(opentag) - input = copytext(input, 1, opentag) - else - input = copytext(input, (closetag + 1)) - else - break - if(max_length) - input = copytext(input,1,max_length) - return sanitize(input) - -/proc/trim_strip_html_properly(var/input, var/max_length = MAX_MESSAGE_LEN) - return trim(strip_html_properly(input, max_length)) - //For generating neat chat tag-images //The icon var could be local in the proc, but it's a waste of resources // to always create it and then throw it out. diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index bcd52b9e88..f20830e5cc 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -4,27 +4,15 @@ #define MINUTE *600 #define MINUTES *600 +var/roundstart_hour = 0 //Returns the world time in english proc/worldtime2text(time = world.time) - return "[round(time / 36000)+12]:[(time / 600 % 60) < 10 ? add_zero(time / 600 % 60, 1) : time / 600 % 60]" + if(!roundstart_hour) roundstart_hour = pick(2,7,12,17) + return "[round(time / 36000)+roundstart_hour]:[(time / 600 % 60) < 10 ? add_zero(time / 600 % 60, 1) : time / 600 % 60]" proc/time_stamp() return time2text(world.timeofday, "hh:mm:ss") -/* Preserving this so future generations can see how fucking retarded some people are -proc/time_stamp() - var/hh = text2num(time2text(world.timeofday, "hh")) // Set the hour - var/mm = text2num(time2text(world.timeofday, "mm")) // Set the minute - var/ss = text2num(time2text(world.timeofday, "ss")) // Set the second - var/ph - var/pm - var/ps - if(hh < 10) ph = "0" - if(mm < 10) pm = "0" - if(ss < 10) ps = "0" - return"[ph][hh]:[pm][mm]:[ps][ss]" -*/ - /* Returns 1 if it is the selected month and day */ proc/isDay(var/month, var/day) if(isnum(month) && isnum(day)) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index cfac858e25..478700d5f8 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -9,333 +9,319 @@ * worldtime2text */ -//Returns an integer given a hex input +// Returns an integer given a hexadecimal number string as input. /proc/hex2num(hex) - if (!( istext(hex) )) + if (!istext(hex)) return - var/num = 0 - var/power = 0 - var/i = null - i = length(hex) - while(i > 0) - var/char = copytext(hex, i, i + 1) + var/num = 0 + var/power = 1 + var/i = length(hex) + + while (i) + var/char = text2ascii(hex, i) switch(char) - if("0") - //Apparently, switch works with empty statements, yay! If that doesn't work, blame me, though. -- Urist - if("9", "8", "7", "6", "5", "4", "3", "2", "1") - num += text2num(char) * 16 ** power - if("a", "A") - num += 16 ** power * 10 - if("b", "B") - num += 16 ** power * 11 - if("c", "C") - num += 16 ** power * 12 - if("d", "D") - num += 16 ** power * 13 - if("e", "E") - num += 16 ** power * 14 - if("f", "F") - num += 16 ** power * 15 + if(48) // 0 -- do nothing + if(49 to 57) num += (char - 48) * power // 1-9 + if(97, 65) num += power * 10 // A + if(98, 66) num += power * 11 // B + if(99, 67) num += power * 12 // C + if(100, 68) num += power * 13 // D + if(101, 69) num += power * 14 // E + if(102, 70) num += power * 15 // F else return - power++ + power *= 16 i-- return num -//Returns the hex value of a number given a value assumed to be a base-ten value -/proc/num2hex(num, placeholder) +// Returns the hex value of a number given a value assumed to be a base-ten value +/proc/num2hex(num, digits) + if (digits == null) + digits = 2 - if (placeholder == null) - placeholder = 2 - if (!( isnum(num) )) + if (!isnum(num)) return - if (num == 0) - var/final = "" - for(var/i=1 to placeholder) final = "[final]0" - return final - var/hex = "" - var/i = 0 - while(16 ** i < num) - i++ - var/power = null - power = i - 1 - while(power >= 0) - var/val = round(num / 16 ** power) - num -= val * 16 ** power - switch(val) - if(9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0) - hex += text("[]", val) - if(10.0) - hex += "A" - if(11.0) - hex += "B" - if(12.0) - hex += "C" - if(13.0) - hex += "D" - if(14.0) - hex += "E" - if(15.0) - hex += "F" - else - power-- - while(length(hex) < placeholder) - hex = text("0[]", hex) - return hex + // hex is our return value, to which each hex-digit of num is appended to. + var/hex = "" + var/power = -4 + var/n = 1 + + // Figure out power. (power of 2) + while (n < num) + power += 4 + n *= 16 + + // Note that we have to start appending to hex with the most-significant digits. + while (power >= 0) + var/m = (num >> power) & 15 + hex += ascii2text(m + (m < 10 ? 48 : 87)) // Provided by the IconProcs library. + power -= 4 + + // Append zeroes to make sure that hex is atleast digits long. + var/left = length(hex) - digits + while (left-- > 0) + hex = text("0[]", hex) + + return hex // Concatenates a list of strings into a single string. A seperator may optionally be provided. /proc/list2text(list/ls, sep) - if(ls.len <= 1) // Early-out code for empty or singleton lists. + if (ls.len <= 1) // Early-out code for empty or singleton lists. return ls.len ? ls[1] : "" - + var/l = ls.len // Made local for sanic speed. - var/i = 0 // Incremented every time a list index is accessed. - - if(sep <> null) + var/i = 0 // Incremented every time a list index is accessed. + + if (sep <> null) // Macros expand to long argument lists like so: sep, ls[++i], sep, ls[++i], sep, ls[++i], etc... - #define S1 sep, ls[++i] - #define S4 S1, S1, S1, S1 - #define S16 S4, S4, S4, S4 - #define S64 S16, S16, S16, S16 - + #define S1 sep, ls[++i] + #define S4 S1, S1, S1, S1 + #define S16 S4, S4, S4, S4 + #define S64 S16, S16, S16, S16 + . = "[ls[++i]]" // Make sure the initial element is converted to text. - + // Having the small concatenations come before the large ones boosted speed by an average of at least 5%. - if(l-1 & 0x01) // 'i' will always be 1 here. + if (l-1 & 0x01) // 'i' will always be 1 here. . = text("[][][]", ., S1) // Append 1 element if the remaining elements are not a multiple of 2. - if(l-i & 0x02) + if (l-i & 0x02) . = text("[][][][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4. - if(l-i & 0x04) + if (l-i & 0x04) . = text("[][][][][][][][][]", ., S4) // And so on.... - if(l-i & 0x08) + if (l-i & 0x08) . = text("[][][][][][][][][][][][][][][][][]", ., S4, S4) - if(l-i & 0x10) + if (l-i & 0x10) . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16) - if(l-i & 0x20) + if (l-i & 0x20) . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16) - if(l-i & 0x40) + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16) + if (l-i & 0x40) . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64) - while(l > i) // Chomp through the rest of the list, 128 elements at a time. + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64) + while (l > i) // Chomp through the rest of the list, 128 elements at a time. . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64) - + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64) + #undef S64 #undef S16 #undef S4 #undef S1 - else // Macros expand to long argument lists like so: ls[++i], ls[++i], ls[++i], etc... - #define S1 ls[++i] - #define S4 S1, S1, S1, S1 - #define S16 S4, S4, S4, S4 - #define S64 S16, S16, S16, S16 - + #define S1 ls[++i] + #define S4 S1, S1, S1, S1 + #define S16 S4, S4, S4, S4 + #define S64 S16, S16, S16, S16 + . = "[ls[++i]]" // Make sure the initial element is converted to text. - - if(l-1 & 0x01) // 'i' will always be 1 here. + + if (l-1 & 0x01) // 'i' will always be 1 here. . += S1 // Append 1 element if the remaining elements are not a multiple of 2. - if(l-i & 0x02) + if (l-i & 0x02) . = text("[][][]", ., S1, S1) // Append 2 elements if the remaining elements are not a multiple of 4. - if(l-i & 0x04) + if (l-i & 0x04) . = text("[][][][][]", ., S4) // And so on... - if(l-i & 0x08) + if (l-i & 0x08) . = text("[][][][][][][][][]", ., S4, S4) - if(l-i & 0x10) + if (l-i & 0x10) . = text("[][][][][][][][][][][][][][][][][]", ., S16) - if(l-i & 0x20) + if (l-i & 0x20) . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S16, S16) - if(l-i & 0x40) + if (l-i & 0x40) . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64) - while(l > i) // Chomp through the rest of the list, 128 elements at a time. + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64) + while (l > i) // Chomp through the rest of the list, 128 elements at a time. . = text("[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ - [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64) - + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\ + [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64) + #undef S64 #undef S16 #undef S4 #undef S1 - -//slower then list2text, but correctly processes associative lists. +// Slower then list2text, but correctly processes associative lists. proc/tg_list2text(list/list, glue=",") - if(!istype(list) || !list.len) + if (!istype(list) || !list.len) return var/output for(var/i=1 to list.len) output += (i!=1? glue : null)+(!isnull(list["[list[i]]"])?"[list["[list[i]]"]]":"[list[i]]") return output - -//Converts a string into a list by splitting the string at each delimiter found. (discarding the seperator) +// Converts a string into a list by splitting the string at each delimiter found. (discarding the seperator) /proc/text2list(text, delimiter="\n") var/delim_len = length(delimiter) - if(delim_len < 1) return list(text) + if (delim_len < 1) + return list(text) + . = list() var/last_found = 1 var/found - do - found = findtext(text, delimiter, last_found, 0) - . += copytext(text, last_found, found) - last_found = found + delim_len - while(found) + do + found = findtext(text, delimiter, last_found, 0) + . += copytext(text, last_found, found) + last_found = found + delim_len + while (found) + +// Case sensitive version of /proc/text2list(). +/proc/text2listEx(text, delimiter="\n") + var/delim_len = length(delimiter) + if (delim_len < 1) + return list(text) + + . = list() + var/last_found = 1 + var/found + + do + found = findtextEx(text, delimiter, last_found, 0) + . += copytext(text, last_found, found) + last_found = found + delim_len + while (found) + /proc/text2numlist(text, delimiter="\n") var/list/num_list = list() for(var/x in text2list(text, delimiter)) num_list += text2num(x) return num_list -//Case Sensitive! -/proc/text2listEx(text, delimiter="\n") - var/delim_len = length(delimiter) - if(delim_len < 1) return list(text) - . = list() - var/last_found = 1 - var/found - do - found = findtextEx(text, delimiter, last_found, 0) - . += copytext(text, last_found, found) - last_found = found + delim_len - while(found) - -//Splits the text of a file at seperator and returns them in a list. +// Splits the text of a file at seperator and returns them in a list. /proc/file2list(filename, seperator="\n") return text2list(return_file_text(filename),seperator) - -//Turns a direction into text - +// Turns a direction into text /proc/num2dir(direction) - switch(direction) - if(1.0) return NORTH - if(2.0) return SOUTH - if(4.0) return EAST - if(8.0) return WEST + switch (direction) + if (1.0) return NORTH + if (2.0) return SOUTH + if (4.0) return EAST + if (8.0) return WEST else world.log << "UNKNOWN DIRECTION: [direction]" - - -//Turns a direction into text +// Turns a direction into text /proc/dir2text(direction) - switch(direction) - if(1.0) - return "north" - if(2.0) - return "south" - if(4.0) - return "east" - if(8.0) - return "west" - if(5.0) - return "northeast" - if(6.0) - return "southeast" - if(9.0) - return "northwest" - if(10.0) - return "southwest" - else - return + switch (direction) + if (1.0) return "north" + if (2.0) return "south" + if (4.0) return "east" + if (8.0) return "west" + if (5.0) return "northeast" + if (6.0) return "southeast" + if (9.0) return "northwest" + if (10.0) return "southwest" -//Turns text into proper directions +// Turns text into proper directions /proc/text2dir(direction) - switch(uppertext(direction)) - if("NORTH") - return 1 - if("SOUTH") - return 2 - if("EAST") - return 4 - if("WEST") - return 8 - if("NORTHEAST") - return 5 - if("NORTHWEST") - return 9 - if("SOUTHEAST") - return 6 - if("SOUTHWEST") - return 10 - else - return + switch (uppertext(direction)) + if ("NORTH") return 1 + if ("SOUTH") return 2 + if ("EAST") return 4 + if ("WEST") return 8 + if ("NORTHEAST") return 5 + if ("NORTHWEST") return 9 + if ("SOUTHEAST") return 6 + if ("SOUTHWEST") return 10 -//Converts an angle (degrees) into an ss13 direction +// Converts an angle (degrees) into an ss13 direction /proc/angle2dir(var/degree) - degree = ((degree+22.5)%365) - if(degree < 45) return NORTH - if(degree < 90) return NORTHEAST - if(degree < 135) return EAST - if(degree < 180) return SOUTHEAST - if(degree < 225) return SOUTH - if(degree < 270) return SOUTHWEST - if(degree < 315) return WEST + degree = (degree + 22.5) % 365 // 22.5 = 45 / 2 + if (degree < 45) return NORTH + if (degree < 90) return NORTHEAST + if (degree < 135) return EAST + if (degree < 180) return SOUTHEAST + if (degree < 225) return SOUTH + if (degree < 270) return SOUTHWEST + if (degree < 315) return WEST return NORTH|WEST -//returns the north-zero clockwise angle in degrees, given a direction - +// Returns the north-zero clockwise angle in degrees, given a direction /proc/dir2angle(var/D) - switch(D) - if(NORTH) return 0 - if(SOUTH) return 180 - if(EAST) return 90 - if(WEST) return 270 - if(NORTHEAST) return 45 - if(SOUTHEAST) return 135 - if(NORTHWEST) return 315 - if(SOUTHWEST) return 225 - else return null + switch (D) + if (NORTH) return 0 + if (SOUTH) return 180 + if (EAST) return 90 + if (WEST) return 270 + if (NORTHEAST) return 45 + if (SOUTHEAST) return 135 + if (NORTHWEST) return 315 + if (SOUTHWEST) return 225 -//Returns the angle in english +// Returns the angle in english /proc/angle2text(var/degree) return dir2text(angle2dir(degree)) -//Converts a blend_mode constant to one acceptable to icon.Blend() +// Converts a blend_mode constant to one acceptable to icon.Blend() /proc/blendMode2iconMode(blend_mode) - switch(blend_mode) - if(BLEND_MULTIPLY) return ICON_MULTIPLY - if(BLEND_ADD) return ICON_ADD - if(BLEND_SUBTRACT) return ICON_SUBTRACT - else return ICON_OVERLAY + switch (blend_mode) + if (BLEND_MULTIPLY) return ICON_MULTIPLY + if (BLEND_ADD) return ICON_ADD + if (BLEND_SUBTRACT) return ICON_SUBTRACT + else return ICON_OVERLAY -//Converts a rights bitfield into a string +// Converts a rights bitfield into a string /proc/rights2text(rights,seperator="") - if(rights & R_BUILDMODE) . += "[seperator]+BUILDMODE" - if(rights & R_ADMIN) . += "[seperator]+ADMIN" - if(rights & R_BAN) . += "[seperator]+BAN" - if(rights & R_FUN) . += "[seperator]+FUN" - if(rights & R_SERVER) . += "[seperator]+SERVER" - if(rights & R_DEBUG) . += "[seperator]+DEBUG" - if(rights & R_POSSESS) . += "[seperator]+POSSESS" - if(rights & R_PERMISSIONS) . += "[seperator]+PERMISSIONS" - if(rights & R_STEALTH) . += "[seperator]+STEALTH" - if(rights & R_REJUVINATE) . += "[seperator]+REJUVINATE" - if(rights & R_VAREDIT) . += "[seperator]+VAREDIT" - if(rights & R_SOUNDS) . += "[seperator]+SOUND" - if(rights & R_SPAWN) . += "[seperator]+SPAWN" - if(rights & R_MOD) . += "[seperator]+MODERATOR" - if(rights & R_MENTOR) . += "[seperator]+MENTOR" + if (rights & R_BUILDMODE) . += "[seperator]+BUILDMODE" + if (rights & R_ADMIN) . += "[seperator]+ADMIN" + if (rights & R_BAN) . += "[seperator]+BAN" + if (rights & R_FUN) . += "[seperator]+FUN" + if (rights & R_SERVER) . += "[seperator]+SERVER" + if (rights & R_DEBUG) . += "[seperator]+DEBUG" + if (rights & R_POSSESS) . += "[seperator]+POSSESS" + if (rights & R_PERMISSIONS) . += "[seperator]+PERMISSIONS" + if (rights & R_STEALTH) . += "[seperator]+STEALTH" + if (rights & R_REJUVINATE) . += "[seperator]+REJUVINATE" + if (rights & R_VAREDIT) . += "[seperator]+VAREDIT" + if (rights & R_SOUNDS) . += "[seperator]+SOUND" + if (rights & R_SPAWN) . += "[seperator]+SPAWN" + if (rights & R_MOD) . += "[seperator]+MODERATOR" + if (rights & R_MENTOR) . += "[seperator]+MENTOR" return . /proc/ui_style2icon(ui_style) - switch(ui_style) - if("old") return 'icons/mob/screen1_old.dmi' - if("Orange") return 'icons/mob/screen1_Orange.dmi' - if("Midnight") return 'icons/mob/screen1_Midnight.dmi' - else return 'icons/mob/screen1_White.dmi' + switch (ui_style) + if ("old") return 'icons/mob/screen1_old.dmi' + if ("Orange") return 'icons/mob/screen1_Orange.dmi' + if ("Midnight") return 'icons/mob/screen1_Midnight.dmi' + else return 'icons/mob/screen1_White.dmi' + +// heat2color functions. Adapted from: http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ +/proc/heat2color(temp) + return rgb(heat2color_r(temp), heat2color_g(temp), heat2color_b(temp)) + +/proc/heat2color_r(temp) + temp /= 100 + if(temp <= 66) + . = 255 + else + . = max(0, min(255, 329.698727446 * (temp - 60) ** -0.1332047592)) + +/proc/heat2color_g(temp) + temp /= 100 + if(temp <= 66) + . = max(0, min(255, 99.4708025861 * log(temp) - 161.1195681661)) + else + . = max(0, min(255, 288.1221695283 * ((temp - 60) ** -0.0755148492))) + +/proc/heat2color_b(temp) + temp /= 100 + if(temp >= 66) + . = 255 + else + if(temp <= 16) + . = 0 + else + . = max(0, min(255, 138.5177312231 * log(temp - 10) - 305.0447927307)) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index d78f3e7a9d..72d85a67b5 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -308,10 +308,10 @@ Turf and target are seperate in case you want to teleport some distance from a t var/newname for(var/i=1,i<=3,i++) //we get 3 attempts to pick a suitable name. - newname = input(src,"You are a [role]. Would you like to change your name to something else?", "Name change",oldname) as text - if((world.time-time_passed)>300) + newname = input(src,"You are \a [role]. Would you like to change your name to something else?", "Name change",oldname) as text + if((world.time-time_passed)>3000) return //took too long - newname = reject_bad_name(newname,allow_numbers) //returns null if the name doesn't meet some basic requirements. Tidies up a few other things like bad-characters. + newname = sanitizeName(newname, ,allow_numbers) //returns null if the name doesn't meet some basic requirements. Tidies up a few other things like bad-characters. for(var/mob/living/M in player_list) if(M == src) @@ -374,7 +374,7 @@ Turf and target are seperate in case you want to teleport some distance from a t var/mob/living/silicon/ai/selected var/list/active = active_ais() for(var/mob/living/silicon/ai/A in active) - if(!selected || (selected.connected_robots > A.connected_robots)) + if(!selected || (selected.connected_robots.len > A.connected_robots.len)) selected = A return selected @@ -460,8 +460,6 @@ Turf and target are seperate in case you want to teleport some distance from a t moblist.Add(M) for(var/mob/new_player/M in sortmob) moblist.Add(M) - for(var/mob/living/carbon/monkey/M in sortmob) - moblist.Add(M) for(var/mob/living/carbon/slime/M in sortmob) moblist.Add(M) for(var/mob/living/simple_animal/M in sortmob) @@ -698,17 +696,26 @@ proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,fl else return get_step(ref, base_dir) -/proc/do_mob(var/mob/user , var/mob/target, var/time = 30) //This is quite an ugly solution but i refuse to use the old request system. - if(!user || !target) return 0 - var/user_loc = user.loc - var/target_loc = target.loc +/proc/do_mob(var/mob/user, var/mob/target, var/delay, var/numticks = 5, var/needhand = 1) //This is quite an ugly solution but i refuse to use the old request system. + if(!user || !target) return 0 + if(numticks == 0) return 0 + + var/delayfraction = round(delay/numticks) + var/original_user_loc = user.loc + var/original_target_loc = target.loc var/holding = user.get_active_hand() - sleep(time) - if(!user || !target) return 0 - if ( user.loc == user_loc && target.loc == target_loc && user.get_active_hand() == holding && !( user.stat ) && ( !user.stunned && !user.weakened && !user.paralysis && !user.lying ) ) - return 1 - else - return 0 + + for(var/i = 0, i[content]" + +/proc/get_random_colour(var/simple, var/lower, var/upper) + var/colour + if(simple) + colour = pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF")) + else + for(var/i=1;i<=3;i++) + var/temp_col = "[num2hex(rand(lower,upper))]" + if(length(temp_col )<2) + temp_col = "0[temp_col]" + colour += temp_col + return colour diff --git a/code/__HELPERS/vector.dm b/code/__HELPERS/vector.dm new file mode 100644 index 0000000000..970530e71d --- /dev/null +++ b/code/__HELPERS/vector.dm @@ -0,0 +1,141 @@ +/* +plot_vector is a helper datum for plotting a path in a straight line towards a target turf. +This datum converts from world space (turf.x and turf.y) to pixel space, which the datum keeps track of itself. This +should work with any size turfs (i.e. 32x32, 64x64) as it references world.icon_size (note: not actually tested with +anything other than 32x32 turfs). + +setup() + This should be called after creating a new instance of a plot_vector datum. + This does the initial setup and calculations. Since we are travelling in a straight line we only need to calculate + the vector and x/y steps once. x/y steps are capped to 1 full turf, whichever is further. If we are travelling along + the y axis each step will be +/- 1 y, and the x movement reduced based on the angle (tangent calculation). After + this every subsequent step will be incremented based on these calculations. + Inputs: + source - the turf the object is starting from + target - the target turf the object is travelling towards + xo - starting pixel_x offset, typically won't be needed, but included in case someone has a need for it later + yo - same as xo, but for the y_pixel offset + +increment() + Adds the offset to the current location - incrementing it by one step along the vector. + +return_angle() + Returns the direction (angle in degrees) the object is travelling in. + + (N) + 90° + ^ + | + (W) 180° <--+--> 0° (E) + | + v + -90° + (S) + +return_hypotenuse() + Returns the distance of travel for each step of the vector, relative to each full step of movement. 1 is a full turf + length. Currently used as a multiplier for scaling effects that should be contiguous, like laser beams. + +return_location() + Returns a vector_loc datum containing the current location data of the object (see /datum/vector_loc). This includes + the turf it currently should be at, as well as the pixel offset from the centre of that turf. Typically increment() + would be called before this if you are going to move an object based on it's vector data. +*/ + +/datum/plot_vector + var/turf/source + var/turf/target + var/angle = 0 // direction of travel in degrees + var/loc_x = 0 // in pixels from the left edge of the map + var/loc_y = 0 // in pixels from the bottom edge of the map + var/loc_z = 0 // loc z is in world space coordinates (i.e. z level) - we don't care about measuring pixels for this + var/offset_x = 0 // distance to increment each step + var/offset_y = 0 + +/datum/plot_vector/proc/setup(var/turf/S, var/turf/T, var/xo = 0, var/yo = 0) + source = S + target = T + + if(!istype(source)) + source = get_turf(source) + if(!istype(target)) + target = get_turf(target) + + if(!istype(source) || !istype(target)) + return + + // convert coordinates to pixel space (default is 32px/turf, 8160px across for a size 255 map) + loc_x = source.x * world.icon_size + xo + loc_y = source.y * world.icon_size + yo + loc_z = source.z + + // calculate initial x and y difference + var/dx = target.x - source.x + var/dy = target.y - source.y + + // if we aren't moving anywhere; quit now + if(dx == 0 && dy == 0) + return + + // calculate the angle + angle = Atan2(dx, dy) + + // and some rounding to stop the increments jumping whole turfs - because byond favours certain angles + if(angle > -135 && angle < 45) + angle = Ceiling(angle) + else + angle = Floor(angle) + + // calculate the offset per increment step + if(abs(angle) in list(0, 45, 90, 135, 180)) // check if the angle is a cardinal + if(abs(angle) in list(0, 45, 135, 180)) // if so we can skip the trigonometry and set these to absolutes as + offset_x = sign(dx) // they will always be a full step in one or more directions + if(abs(angle) in list(45, 90, 135)) + offset_y = sign(dy) + else if(abs(dy) > abs(dx)) + offset_x = Cot(abs(angle)) // otherwise set the offsets + offset_y = sign(dy) + else + offset_x = sign(dx) + offset_y = Tan(angle) + if(dx < 0) + offset_y = -offset_y + + // multiply the offset by the turf pixel size + offset_x *= world.icon_size + offset_y *= world.icon_size + +/datum/plot_vector/proc/increment() + loc_x += offset_x + loc_y += offset_y + +/datum/plot_vector/proc/return_angle() + return angle + +/datum/plot_vector/proc/return_hypotenuse() + return sqrt(((offset_x / 32) ** 2) + ((offset_y / 32) ** 2)) + +/datum/plot_vector/proc/return_location(var/datum/vector_loc/data) + if(!data) + data = new() + data.loc = locate(round(loc_x / world.icon_size), round(loc_y / world.icon_size), loc_z) + if(!data.loc) + return + data.pixel_x = loc_x - (data.loc.x * world.icon_size) + data.pixel_y = loc_y - (data.loc.y * world.icon_size) + return data + +/* +vector_loc is a helper datum for returning precise location data from plot_vector. It includes the turf the object is in +as well as the pixel offsets. + +return_turf() + Returns the turf the object should be currently located in. +*/ +/datum/vector_loc + var/turf/loc + var/pixel_x + var/pixel_y + +/datum/vector_loc/proc/return_turf() + return loc diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 0a8ea086a1..e05cbeb9ba 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -36,6 +36,9 @@ return var/list/modifiers = params2list(params) + if(modifiers["shift"] && modifiers["ctrl"]) + CtrlShiftClickOn(A) + return if(modifiers["middle"]) MiddleClickOn(A) return @@ -101,14 +104,22 @@ I have no idea why it was in atoms.dm instead of respective files. */ +/atom/proc/AICtrlShiftClick() + return + +/obj/machinery/door/airlock/AICtrlShiftClick() + if(emagged) + return + return + /atom/proc/AIShiftClick() return /obj/machinery/door/airlock/AIShiftClick() // Opens and closes doors! if(density) - Topic(src, list("src"= "\ref[src]", "aiEnable"="7"), 1) // 1 meaning no window (consistency!) + Topic(src, list("src"= "\ref[src]", "command"="open", "activate" = "1"), 1) // 1 meaning no window (consistency!) else - Topic(src, list("src"= "\ref[src]", "aiDisable"="7"), 1) + Topic(src, list("src"= "\ref[src]", "command"="open", "activate" = "0"), 1) return /atom/proc/AICtrlClick() @@ -116,39 +127,39 @@ /obj/machinery/door/airlock/AICtrlClick() // Bolts doors if(locked) - Topic(src, list("src"= "\ref[src]", "aiEnable"="4"), 1)// 1 meaning no window (consistency!) + Topic(src, list("src"= "\ref[src]", "command"="bolts", "activate" = "0"), 1)// 1 meaning no window (consistency!) else - Topic(src, list("src"= "\ref[src]", "aiDisable"="4"), 1) + Topic(src, list("src"= "\ref[src]", "command"="bolts", "activate" = "1"), 1) /obj/machinery/power/apc/AICtrlClick() // turns off/on APCs. Topic(src, list("src"= "\ref[src]", "breaker"="1"), 1) // 1 meaning no window (consistency!) /obj/machinery/turretid/AICtrlClick() //turns off/on Turrets - Topic(src, list("src"= "\ref[src]", "operation"="toggleon"), 1) // 1 meaning no window (consistency!) + Topic(src, list("src"= "\ref[src]", "command"="enable", "value"="[!enabled]"), 1) // 1 meaning no window (consistency!) /atom/proc/AIAltClick(var/atom/A) AltClick(A) /obj/machinery/door/airlock/AIAltClick() // Electrifies doors. - if(!secondsElectrified) + if(!electrified_until) // permanent shock - Topic(src, list("src"= "\ref[src]", "aiEnable"="6"), 1) // 1 meaning no window (consistency!) + Topic(src, list("src"= "\ref[src]", "command"="electrify_permanently", "activate" = "1"), 1) // 1 meaning no window (consistency!) else // disable/6 is not in Topic; disable/5 disables both temporary and permanent shock - Topic(src, list("src"= "\ref[src]", "aiDisable"="5"), 1) + Topic(src, list("src"= "\ref[src]", "command"="electrify_permanently", "activate" = "0"), 1) return /obj/machinery/turretid/AIAltClick() //toggles lethal on turrets - Topic(src, list("src"= "\ref[src]", "operation"="togglelethal"), 1) // 1 meaning no window (consistency!) + Topic(src, list("src"= "\ref[src]", "command"="lethal", "value"="[!lethal]"), 1) // 1 meaning no window (consistency!) /atom/proc/AIMiddleClick() return /obj/machinery/door/airlock/AIMiddleClick() // Toggles door bolt lights. if(!src.lights) - Topic(src, list("src"= "\ref[src]", "aiEnable"="10"), 1) // 1 meaning no window (consistency!) + Topic(src, list("src"= "\ref[src]", "command"="lights", "activate" = "1"), 1) // 1 meaning no window (consistency!) else - Topic(src, list("src"= "\ref[src]", "aiDisable"="10"), 1) + Topic(src, list("src"= "\ref[src]", "command"="lights", "activate" = "0"), 1) return // diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 6ce3ffad46..b8caa45399 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -45,6 +45,9 @@ return var/list/modifiers = params2list(params) + if(modifiers["shift"] && modifiers["ctrl"]) + CtrlShiftClickOn(A) + return if(modifiers["middle"]) MiddleClickOn(A) return @@ -192,7 +195,7 @@ */ /mob/proc/RangedAttack(var/atom/A, var/params) if(!mutations.len) return - if((LASER in mutations) && a_intent == "harm") + if((LASER in mutations) && a_intent == I_HURT) LaserEyes(A) // moved into a proc below else if(TK in mutations) switch(get_dist(src,A)) @@ -292,6 +295,17 @@ /mob/proc/TurfAdjacent(var/turf/T) return T.AdjacentQuick(src) +/* + Control+Shift click + Unused except for AI +*/ +/mob/proc/CtrlShiftClickOn(var/atom/A) + A.CtrlShiftClick(src) + return + +/atom/proc/CtrlShiftClick(var/mob/user) + return + /* Misc helpers diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 04682c76ad..5986011688 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -16,6 +16,9 @@ return var/list/modifiers = params2list(params) + if(modifiers["shift"] && modifiers["ctrl"]) + CtrlShiftClickOn(A) + return if(modifiers["middle"]) MiddleClickOn(A) return @@ -109,6 +112,55 @@ cycle_modules() return +//Give cyborgs hotkey clicks without breaking existing uses of hotkey clicks +// for non-doors/apcs +/mob/living/silicon/robot/CtrlShiftClickOn(var/atom/A) + A.BorgCtrlShiftClick(src) + +/mob/living/silicon/robot/ShiftClickOn(var/atom/A) + A.BorgShiftClick(src) + +/mob/living/silicon/robot/CtrlClickOn(var/atom/A) + A.BorgCtrlClick(src) + +/mob/living/silicon/robot/AltClickOn(var/atom/A) + A.BorgAltClick(src) + +/atom/proc/BorgCtrlShiftClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden + CtrlShiftClick(user) + +/obj/machinery/door/airlock/BorgCtrlShiftClick() + AICtrlShiftClick() + +/atom/proc/BorgShiftClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden + ShiftClick(user) + +/obj/machinery/door/airlock/BorgShiftClick() // Opens and closes doors! Forwards to AI code. + AIShiftClick() + + +/atom/proc/BorgCtrlClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden + CtrlClick(user) + +/obj/machinery/door/airlock/BorgCtrlClick() // Bolts doors. Forwards to AI code. + AICtrlClick() + +/obj/machinery/power/apc/BorgCtrlClick() // turns off/on APCs. Forwards to AI code. + AICtrlClick() + +/obj/machinery/turretid/BorgCtrlClick() //turret control on/off. Forwards to AI code. + AICtrlClick() + +/atom/proc/BorgAltClick(var/mob/living/silicon/robot/user) + AltClick(user) + return + +/obj/machinery/door/airlock/BorgAltClick() // Eletrifies doors. Forwards to AI code. + AIAltClick() + +/obj/machinery/turretid/BorgAltClick() //turret lethal on/off. Forwards to AI code. + AIAltClick() + /* As with AI, these are not used in click code, because the code for robots is specific, not generic. diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index ab37fa4867..c41f9594b3 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -235,12 +235,14 @@ datum/hud/New(mob/owner) if(ishuman(mymob)) human_hud(ui_style, ui_color, ui_alpha, mymob) // Pass the player the UI style chosen in preferences - else if(ismonkey(mymob)) + else if(issmall(mymob)) monkey_hud(ui_style) else if(isbrain(mymob)) brain_hud(ui_style) else if(isalien(mymob)) larva_hud() + else if(isslime(mymob)) + slime_hud() else if(isAI(mymob)) ai_hud() else if(isrobot(mymob)) @@ -254,59 +256,99 @@ datum/hud/New(mob/owner) set name = "F12" set hidden = 1 - if(hud_used) - if(ishuman(src)) - if(!client) return - if(client.view != world.view) - return - if(hud_used.hud_shown) - hud_used.hud_shown = 0 - if(src.hud_used.adding) - src.client.screen -= src.hud_used.adding - if(src.hud_used.other) - src.client.screen -= src.hud_used.other - if(src.hud_used.hotkeybuttons) - src.client.screen -= src.hud_used.hotkeybuttons - if(src.hud_used.item_action_list) - src.client.screen -= src.hud_used.item_action_list - - //Due to some poor coding some things need special treatment: - //These ones are a part of 'adding', 'other' or 'hotkeybuttons' but we want them to stay - if(!full) - src.client.screen += src.hud_used.l_hand_hud_object //we want the hands to be visible - src.client.screen += src.hud_used.r_hand_hud_object //we want the hands to be visible - src.client.screen += src.hud_used.action_intent //we want the intent swticher visible - src.hud_used.action_intent.screen_loc = ui_acti_alt //move this to the alternative position, where zone_select usually is. - else - src.client.screen -= src.healths - src.client.screen -= src.internals - src.client.screen -= src.gun_setting_icon - - //These ones are not a part of 'adding', 'other' or 'hotkeybuttons' but we want them gone. - src.client.screen -= src.zone_sel //zone_sel is a mob variable for some reason. - - else - hud_used.hud_shown = 1 - if(src.hud_used.adding) - src.client.screen += src.hud_used.adding - if(src.hud_used.other && src.hud_used.inventory_shown) - src.client.screen += src.hud_used.other - if(src.hud_used.hotkeybuttons && !src.hud_used.hotkey_ui_hidden) - src.client.screen += src.hud_used.hotkeybuttons - if(src.healths) - src.client.screen |= src.healths - if(src.internals) - src.client.screen |= src.internals - if(src.gun_setting_icon) - src.client.screen |= src.gun_setting_icon - - src.hud_used.action_intent.screen_loc = ui_acti //Restore intent selection to the original position - src.client.screen += src.zone_sel //This one is a special snowflake - - hud_used.hidden_inventory_update() - hud_used.persistant_inventory_update() - update_action_buttons() - else - usr << "\red Inventory hiding is currently only supported for human mobs, sorry." - else + if(!hud_used) usr << "\red This mob type does not use a HUD." + return + + if(!ishuman(src)) + usr << "\red Inventory hiding is currently only supported for human mobs, sorry." + return + + if(!client) return + if(client.view != world.view) + return + if(hud_used.hud_shown) + hud_used.hud_shown = 0 + if(src.hud_used.adding) + src.client.screen -= src.hud_used.adding + if(src.hud_used.other) + src.client.screen -= src.hud_used.other + if(src.hud_used.hotkeybuttons) + src.client.screen -= src.hud_used.hotkeybuttons + if(src.hud_used.item_action_list) + src.client.screen -= src.hud_used.item_action_list + + //Due to some poor coding some things need special treatment: + //These ones are a part of 'adding', 'other' or 'hotkeybuttons' but we want them to stay + if(!full) + src.client.screen += src.hud_used.l_hand_hud_object //we want the hands to be visible + src.client.screen += src.hud_used.r_hand_hud_object //we want the hands to be visible + src.client.screen += src.hud_used.action_intent //we want the intent swticher visible + src.hud_used.action_intent.screen_loc = ui_acti_alt //move this to the alternative position, where zone_select usually is. + else + src.client.screen -= src.healths + src.client.screen -= src.internals + src.client.screen -= src.gun_setting_icon + + //These ones are not a part of 'adding', 'other' or 'hotkeybuttons' but we want them gone. + src.client.screen -= src.zone_sel //zone_sel is a mob variable for some reason. + + else + hud_used.hud_shown = 1 + if(src.hud_used.adding) + src.client.screen += src.hud_used.adding + if(src.hud_used.other && src.hud_used.inventory_shown) + src.client.screen += src.hud_used.other + if(src.hud_used.hotkeybuttons && !src.hud_used.hotkey_ui_hidden) + src.client.screen += src.hud_used.hotkeybuttons + if(src.healths) + src.client.screen |= src.healths + if(src.internals) + src.client.screen |= src.internals + if(src.gun_setting_icon) + src.client.screen |= src.gun_setting_icon + + src.hud_used.action_intent.screen_loc = ui_acti //Restore intent selection to the original position + src.client.screen += src.zone_sel //This one is a special snowflake + + hud_used.hidden_inventory_update() + hud_used.persistant_inventory_update() + update_action_buttons() + +//Similar to button_pressed_F12() but keeps zone_sel, gun_setting_icon, and healths. +/mob/proc/toggle_zoom_hud() + if(!hud_used) + return + if(!ishuman(src)) + return + if(!client) + return + if(client.view != world.view) + return + + if(hud_used.hud_shown) + hud_used.hud_shown = 0 + if(src.hud_used.adding) + src.client.screen -= src.hud_used.adding + if(src.hud_used.other) + src.client.screen -= src.hud_used.other + if(src.hud_used.hotkeybuttons) + src.client.screen -= src.hud_used.hotkeybuttons + if(src.hud_used.item_action_list) + src.client.screen -= src.hud_used.item_action_list + src.client.screen -= src.internals + else + hud_used.hud_shown = 1 + if(src.hud_used.adding) + src.client.screen += src.hud_used.adding + if(src.hud_used.other && src.hud_used.inventory_shown) + src.client.screen += src.hud_used.other + if(src.hud_used.hotkeybuttons && !src.hud_used.hotkey_ui_hidden) + src.client.screen += src.hud_used.hotkeybuttons + if(src.internals) + src.client.screen |= src.internals + src.hud_used.action_intent.screen_loc = ui_acti //Restore intent selection to the original position + + hud_used.hidden_inventory_update() + hud_used.persistant_inventory_update() + update_action_buttons() \ No newline at end of file diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 33a14d2e4d..92fe661d00 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -77,7 +77,7 @@ ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height()) using = new /obj/screen( src ) - using.name = "help" + using.name = I_HELP using.icon = ico using.screen_loc = ui_acti using.alpha = ui_alpha @@ -89,7 +89,7 @@ ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height()) using = new /obj/screen( src ) - using.name = "disarm" + using.name = I_DISARM using.icon = ico using.screen_loc = ui_acti using.alpha = ui_alpha @@ -101,7 +101,7 @@ ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2) using = new /obj/screen( src ) - using.name = "grab" + using.name = I_GRAB using.icon = ico using.screen_loc = ui_acti using.alpha = ui_alpha @@ -113,7 +113,7 @@ ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2) using = new /obj/screen( src ) - using.name = "harm" + using.name = I_HURT using.icon = ico using.screen_loc = ui_acti using.alpha = ui_alpha @@ -433,9 +433,6 @@ f_style = "Shaved" if(dna.species == "Human") //no more xenos losing ears/tentacles h_style = pick("Bedhead", "Bedhead 2", "Bedhead 3") - undershirt = undershirt_t.Find("None") - if(gender == MALE) - underwear = underwear_m.Find("None") - else - underwear = underwear_f.Find("None") + undershirt = null + underwear = null regenerate_icons() diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index 65924284b5..76adf0414c 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -10,7 +10,7 @@ using.name = "act_intent" using.set_dir(SOUTHWEST) using.icon = ui_style - using.icon_state = (mymob.a_intent == "hurt" ? "harm" : mymob.a_intent) + using.icon_state = (mymob.a_intent == I_HURT ? I_HURT : mymob.a_intent) using.screen_loc = ui_acti using.layer = 20 src.adding += using @@ -226,7 +226,7 @@ if (mymob.client.gun_mode) // If in aim mode, correct the sprite mymob.gun_setting_icon.set_dir(2) for(var/obj/item/weapon/gun/G in mymob) // If targeting someone, display other buttons - if (G.target) + if (G.aim_targets) mymob.item_use_icon = new /obj/screen/gun/item(null) if (mymob.client.target_can_click) mymob.item_use_icon.set_dir(1) diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm index cd19e78d7e..3f785d8a83 100644 --- a/code/_onclick/hud/other_mobs.dm +++ b/code/_onclick/hud/other_mobs.dm @@ -33,3 +33,71 @@ mymob.client.screen = null mymob.client.screen += list(blobpwrdisplay, blobhealthdisplay) + +/datum/hud/proc/slime_hud(ui_style = 'icons/mob/screen1_Midnight.dmi') + + src.adding = list() + + var/obj/screen/using + + using = new /obj/screen() + using.name = "act_intent" + using.set_dir(SOUTHWEST) + using.icon = ui_style + using.icon_state = "intent_"+mymob.a_intent + using.screen_loc = ui_zonesel + using.layer = 20 + src.adding += using + action_intent = using + + //intent small hud objects + var/icon/ico + + ico = new(ui_style, "black") + ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) + ico.DrawBox(rgb(255,255,255,1),1,ico.Height()/2,ico.Width()/2,ico.Height()) + using = new /obj/screen( src ) + using.name = "help" + using.icon = ico + using.screen_loc = ui_zonesel + using.layer = 21 + src.adding += using + help_intent = using + + ico = new(ui_style, "black") + ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) + ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,ico.Height()/2,ico.Width(),ico.Height()) + using = new /obj/screen( src ) + using.name = "disarm" + using.icon = ico + using.screen_loc = ui_zonesel + using.layer = 21 + src.adding += using + disarm_intent = using + + ico = new(ui_style, "black") + ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) + ico.DrawBox(rgb(255,255,255,1),ico.Width()/2,1,ico.Width(),ico.Height()/2) + using = new /obj/screen( src ) + using.name = "grab" + using.icon = ico + using.screen_loc = ui_zonesel + using.layer = 21 + src.adding += using + grab_intent = using + + ico = new(ui_style, "black") + ico.MapColors(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, -1,-1,-1,-1) + ico.DrawBox(rgb(255,255,255,1),1,1,ico.Width()/2,ico.Height()/2) + using = new /obj/screen( src ) + using.name = I_HURT + using.icon = ico + using.screen_loc = ui_zonesel + using.layer = 21 + src.adding += using + hurt_intent = using + + mymob.client.screen = null + mymob.client.screen += src.adding + + return diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 644b811376..48378fce7f 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -57,7 +57,7 @@ var/obj/screen/robot_inventory using.name = "act_intent" using.set_dir(SOUTHWEST) using.icon = 'icons/mob/screen1_robot.dmi' - using.icon_state = (mymob.a_intent == "hurt" ? "harm" : mymob.a_intent) + using.icon_state = (mymob.a_intent == I_HURT ? I_HURT : mymob.a_intent) using.screen_loc = ui_acti using.layer = 20 src.adding += using @@ -157,7 +157,7 @@ var/obj/screen/robot_inventory if (mymob.client.gun_mode) // If in aim mode, correct the sprite mymob.gun_setting_icon.set_dir(2) for(var/obj/item/weapon/gun/G in mymob) // If targeting someone, display other buttons - if (G.target) + if (G.aim_targets) mymob.item_use_icon = new /obj/screen/gun/item(null) if (mymob.client.target_can_click) mymob.item_use_icon.set_dir(1) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index b12602ccb2..0cc2ad3365 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -360,17 +360,17 @@ C << "You don't have a[breathes=="oxygen" ? "n oxygen" : addtext(" ",breathes)] tank." if("act_intent") usr.a_intent_change("right") - if("help") - usr.a_intent = "help" + if(I_HELP) + usr.a_intent = I_HELP usr.hud_used.action_intent.icon_state = "intent_help" - if("harm") - usr.a_intent = "hurt" + if(I_HURT) + usr.a_intent = I_HURT usr.hud_used.action_intent.icon_state = "intent_hurt" - if("grab") - usr.a_intent = "grab" + if(I_GRAB) + usr.a_intent = I_GRAB usr.hud_used.action_intent.icon_state = "intent_grab" - if("disarm") - usr.a_intent = "disarm" + if(I_DISARM) + usr.a_intent = I_DISARM usr.hud_used.action_intent.icon_state = "intent_disarm" if("pull") diff --git a/code/_onclick/oldcode.dm b/code/_onclick/oldcode.dm index 8585eb8e5f..ce6a238329 100644 --- a/code/_onclick/oldcode.dm +++ b/code/_onclick/oldcode.dm @@ -347,7 +347,7 @@ src.hand_al(usr, usr.hand) else // ------- YOU ARE CLICKING ON AN OBJECT THAT'S INACCESSIBLE TO YOU AND IS NOT YOUR HUD ------- - if((LASER in usr:mutations) && usr:a_intent == "harm" && world.time >= usr.next_move) + if((LASER in usr:mutations) && usr:a_intent == I_HURT && world.time >= usr.next_move) // ------- YOU HAVE THE LASER MUTATION, YOUR INTENT SET TO HURT AND IT'S BEEN MORE THAN A DECISECOND SINCE YOU LAS TATTACKED ------- var/turf/T = get_turf(usr) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 479e097251..477fb04b7a 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -31,7 +31,7 @@ /mob/living/carbon/human/RangedAttack(var/atom/A) if(!gloves && !mutations.len) return var/obj/item/clothing/gloves/G = gloves - if((LASER in mutations) && a_intent == "hurt") + if((LASER in mutations) && a_intent == I_HURT) LaserEyes(A) // moved into a proc below else if(istype(G) && G.Touch(A,0)) // for magic gloves @@ -52,45 +52,6 @@ /mob/living/RestrainedClickOn(var/atom/A) return -/* - Monkeys -*/ - - -/mob/living/carbon/monkey/UnarmedAttack(var/atom/A, var/proximity) - - if(!..()) - return - - A.attack_hand(src) - -/* - Monkey RestrainedClickOn() was apparently the - one and only use of all of the restrained click code - (except to stop you from doing things while handcuffed); - moving it here instead of various hand_p's has simplified - things considerably -*/ -/mob/living/carbon/monkey/RestrainedClickOn(var/atom/A) - if(a_intent != "harm" || !ismob(A)) return - if(istype(wear_mask, /obj/item/clothing/mask/muzzle)) - return - var/mob/living/carbon/ML = A - var/dam_zone = ran_zone(pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")) - var/armor = ML.run_armor_check(dam_zone, "melee") - if(prob(75)) - ML.apply_damage(rand(1,3), BRUTE, dam_zone, armor) - for(var/mob/O in viewers(ML, null)) - O.show_message("\red [name] has bit [ML]!", 1) - if(armor >= 2) return - if(ismonkey(ML)) - for(var/datum/disease/D in viruses) - if(istype(D, /datum/disease/jungle_fever)) - ML.contract_disease(D,1,0) - else - for(var/mob/O in viewers(ML, null)) - O.show_message("\red [src] has attempted to bite [ML]!", 1) - /* Aliens */ @@ -120,45 +81,61 @@ // Eating if(Victim) + if (Victim == A) + Feedstop() return - // Basic attack. - A.attack_generic(src, (is_adult ? rand(20,40) : rand(5,25)), "glomped") - - // Handle mob shocks. var/mob/living/M = A - if(istype(M) && powerlevel > 0 && !istype(A,/mob/living/carbon/slime)) + if (istype(M)) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.species.flags & IS_SYNTHETIC || (H.species.siemens_coefficient<0.5)) - return + switch(src.a_intent) + if (I_HELP) // We just poke the other + M.visible_message("[src] gently pokes [M]!", "[src] gently pokes you!") + if (I_DISARM) // We stun the target, with the intention to feed + var/stunprob = 1 + var/power = max(0, min(10, (powerlevel + rand(0, 3)))) + if (powerlevel > 0 && !istype(A, /mob/living/carbon/slime)) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.species.flags & IS_SYNTHETIC) + return + stunprob *= H.species.siemens_coefficient - var/power = max(0,min(10,(powerlevel+rand(0,3)))) - var/stunprob = 10 - switch(power*10) - if(1 to 2) stunprob = 20 - if(3 to 4) stunprob = 30 - if(5 to 6) stunprob = 40 - if(7 to 8) stunprob = 60 - if(9) stunprob = 70 - if(10) stunprob = 95 + switch(power * 10) + if(0) stunprob *= 10 + if(1 to 2) stunprob *= 20 + if(3 to 4) stunprob *= 30 + if(5 to 6) stunprob *= 40 + if(7 to 8) stunprob *= 60 + if(9) stunprob *= 70 + if(10) stunprob *= 95 - if(prob(stunprob)) - powerlevel = max(0,powerlevel-3) - src.visible_message("\red The [name] has shocked [M]!") - M.Weaken(power) - M.Stun(power) - if (M.stuttering < power) M.stuttering = power + if(prob(stunprob)) + powerlevel = max(0, powerlevel-3) + M.visible_message("[src] has shocked [M]!", "[src] has shocked you!") + M.Weaken(power) + M.Stun(power) + M.stuttering = max(M.stuttering, power) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, M) - s.start() + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, M) + s.start() - if(prob(stunprob) && powerlevel >= 8) - M.adjustFireLoss(powerlevel * rand(6,10)) - M.updatehealth() + if(prob(stunprob) && powerlevel >= 8) + M.adjustFireLoss(powerlevel * rand(6,10)) + else if(prob(40)) + M.visible_message("[src] has pounced at [M]!", "[src] has pounced at you!") + M.Weaken(power) + else + M.visible_message("[src] has tried to pounce at [M]!", "[src] has tried to pounce at you!") + M.updatehealth() + if (I_GRAB) // We feed + Wrap(M) + if (I_HURT) // Attacking + A.attack_generic(src, (is_adult ? rand(20,40) : rand(5,25)), "glomped") + else + A.attack_generic(src, (is_adult ? rand(20,40) : rand(5,25)), "glomped") // Basic attack. /* New Players: Have no reason to click on anything at all. @@ -179,5 +156,5 @@ return var/damage = rand(melee_damage_lower, melee_damage_upper) - if(A.attack_generic(src,damage,attacktext,wall_smash) && loc && attack_sound) - playsound(loc, attack_sound, 50, 1, 1) \ No newline at end of file + if(A.attack_generic(src,damage,attacktext,environment_smash) && loc && attack_sound) + playsound(loc, attack_sound, 50, 1, 1) diff --git a/code/controllers/ProcessScheduler/.gitignore b/code/controllers/ProcessScheduler/.gitignore new file mode 100644 index 0000000000..5fe19e425b --- /dev/null +++ b/code/controllers/ProcessScheduler/.gitignore @@ -0,0 +1,6 @@ +/bower_components +/node_modules +/ProcessScheduler.dmb +/ProcessScheduler.int +/ProcessScheduler.rsc +/*.lk diff --git a/code/controllers/ProcessScheduler/LICENSE-AGPL b/code/controllers/ProcessScheduler/LICENSE-AGPL new file mode 100644 index 0000000000..abaa41e829 --- /dev/null +++ b/code/controllers/ProcessScheduler/LICENSE-AGPL @@ -0,0 +1,212 @@ +GNU AFFERO GENERAL PUBLIC LICENSE + +Version 3, 19 November 2007 + +Copyright © 2007 Free Software Foundation, Inc. +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. + +A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. + +The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. + +An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. +"This License" refers to version 3 of the GNU Affero General Public License. + +"Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +"The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. + +To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. + +A "covered work" means either the unmodified Program or a work based on the Program. + +To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. + +A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and giving a relevant date. +b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". +c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. +d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. +b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. +c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. +d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. +e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +"Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +"Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or +b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or +c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or +d) Limiting the use for publicity purposes of names of licensors or authors of the material; or +e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or +f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. +All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". + +A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Remote Network Interaction; Use with the GNU General Public License. +Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. + +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +Also add information on how to contact you by electronic and paper mail. + +If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. + +You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/LICENSE-CC-BY-NC b/code/controllers/ProcessScheduler/LICENSE-CC-BY-NC new file mode 100644 index 0000000000..d0955f424a --- /dev/null +++ b/code/controllers/ProcessScheduler/LICENSE-CC-BY-NC @@ -0,0 +1 @@ +This work is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/ProcessScheduler.dme b/code/controllers/ProcessScheduler/ProcessScheduler.dme new file mode 100644 index 0000000000..bf17734cc2 --- /dev/null +++ b/code/controllers/ProcessScheduler/ProcessScheduler.dme @@ -0,0 +1,32 @@ +// DM Environment file for ProcessScheduler.dme. +// All manual changes should be made outside the BEGIN_ and END_ blocks. +// New source code should be placed in .dm files: choose File/New --> Code File. + +// BEGIN_INTERNALS +// END_INTERNALS + +// BEGIN_FILE_DIR +#define FILE_DIR . +// END_FILE_DIR + +// BEGIN_PREFERENCES +// END_PREFERENCES + +// BEGIN_INCLUDE +#include "core\_define.dm" +#include "core\_stubs.dm" +#include "core\process.dm" +#include "core\processScheduler.dm" +#include "core\updateQueue.dm" +#include "core\updateQueueWorker.dm" +#include "test\processSchedulerView.dm" +#include "test\testDyingUpdateQueueProcess.dm" +#include "test\testHarness.dm" +#include "test\testHungProcess.dm" +#include "test\testNiceProcess.dm" +#include "test\testSlowProcess.dm" +#include "test\testUpdateQueue.dm" +#include "test\testUpdateQueueProcess.dm" +#include "test\testZombieProcess.dm" +// END_INCLUDE + diff --git a/code/controllers/ProcessScheduler/README.md b/code/controllers/ProcessScheduler/README.md new file mode 100644 index 0000000000..610800ba37 --- /dev/null +++ b/code/controllers/ProcessScheduler/README.md @@ -0,0 +1,86 @@ +ProcessScheduler +================ +A Goonstation release, maintained by Volundr + +##SUMMARY + +This is a mostly self-contained, fairly well-documented implementation of the main loop process architecture in use in Goonstation. + +##LICENSE + +This work is released under the following licenses. + +[![Creative Commons License](https://licensebuttons.net/l/by-nc/4.0/80x15.png)](http://creativecommons.org/licenses/by-nc/4.0/) + +This work is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License. The complete text of this license is included in the file LICENSE-CC-BY-NC. + + +[![Affero GPL Version 3](http://www.gnu.org/graphics/agplv3-88x31.png)](http://www.gnu.org/licenses/agpl-3.0.html) + +This work is licensed under the Affero General Public License 3.0. The complete text of the license is included in the file LICENSE-AGPL. + +##INSTALLATION + +To integrate the process scheduler to your codebase, you will not need anything except the contents of the core/ folder. The rest of the project is simply for testing and to provide an example for the process scheduler code. + +### Test project setup +To compile and run the test project, you will require: + +- node.js +- BYOND + +Clone the repository to a path of your choosing, then change directory to it and execute: + +``` +npm install -g +bower install -g +``` + +Then you can either compile with DM or open the DM environment in DreamMaker and compile/run from there. + +##USAGE + +###BASICS +To use the process scheduler in your SS13 codebase, you'll need: + +- core/_defines.dm +- core/_stubs.dm +- core/process.dm +- core/processScheduler.dm +- core/processScheduler.js +- core/updateQueue.dm +- core/updateQueueWorker.dm + +To integrate, you can copy the contents of _defines.dm into your global defines file. Most ss13 codebases already have the code from _stubs.dm. + +The processScheduler is intended as a replacement for the old master_controller from r4407 and other fork codebases. To implement it, you need only to add the source files to your DM environment, and add the following code into world.New, above where the old master_controller is initialized. + +``` +processScheduler = new +processScheduler.setup() +processScheduler.start() +``` + +The processScheduler will automatically find all subtypes of process, and begin processing them. + +The interface code in test/processSchedulerView.dm is simply an example frontend, and can easily be rebuilt to use other styles, and/or render simple html without using javascript for refreshing the panel and killing processes. + +###DETAILS + +To implement a process, you have two options: + +1. Implement a raw loop-style processor +2. Implement an updateQueue processor + +There are clear examples of both of these paradigms in the code provided. Both styles are valid, but for processes that are just a loop calling an update proc on a bunch of objects, you should use the updateQueue. + +The updateQueue works by spawn(0)'ing your specified update proc, but it only puts one instance in the scheduler at a time. Examine the code for more details. The overall effect of this is that it doesn't block, and it lets update loops work concurrently. It enables a much smoother user experience. + +##Contributing + +I welcome pull requests and issue reports, and will try to merge/fix them as I have time. + +### Licensing for code submitted via PR: + +By submitting a pull request, you agree to release all original code submitted in the pull request under the [MIT License](http://opensource.org/licenses/MIT). You also agree that any code submitted is either your own work, or is public domain or under a equally or less restrictive license than the MIT license, or that you have the express written permission of the authors of the submitted code to submit the pull request. + diff --git a/code/controllers/ProcessScheduler/bower.json b/code/controllers/ProcessScheduler/bower.json new file mode 100644 index 0000000000..9a6be56140 --- /dev/null +++ b/code/controllers/ProcessScheduler/bower.json @@ -0,0 +1,30 @@ +{ + "name": "ProcessScheduler", + "main": "ProcessScheduler.js", + "version": "1.0.0", + "homepage": "https://github.com/goonstation/ProcessScheduler", + "authors": [ + "Volundr " + ], + "description": "BYOND SS13 Process Scheduler", + "keywords": [ + "byond", + "ss13", + "process", + "scheduler" + ], + "license": "CC-BY-NC", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "private": true, + "dependencies": { + "bootstrap2.3.2": "~2.3.2", + "jquery": "1.11.1", + "json2": "*" + } +} diff --git a/code/controllers/ProcessScheduler/core/_define.dm b/code/controllers/ProcessScheduler/core/_define.dm new file mode 100644 index 0000000000..f0165c9870 --- /dev/null +++ b/code/controllers/ProcessScheduler/core/_define.dm @@ -0,0 +1,17 @@ +// Process status defines +#define PROCESS_STATUS_IDLE 1 +#define PROCESS_STATUS_QUEUED 2 +#define PROCESS_STATUS_RUNNING 3 +#define PROCESS_STATUS_MAYBE_HUNG 4 +#define PROCESS_STATUS_PROBABLY_HUNG 5 +#define PROCESS_STATUS_HUNG 6 + +// Process time thresholds +#define PROCESS_DEFAULT_HANG_WARNING_TIME 300 // 30 seconds +#define PROCESS_DEFAULT_HANG_ALERT_TIME 600 // 60 seconds +#define PROCESS_DEFAULT_HANG_RESTART_TIME 900 // 90 seconds +#define PROCESS_DEFAULT_SCHEDULE_INTERVAL 50 // 50 ticks +#define PROCESS_DEFAULT_SLEEP_INTERVAL 2 // 2 ticks +#define PROCESS_DEFAULT_CPU_THRESHOLD 90 // 90% + +//#define UPDATE_QUEUE_DEBUG \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/core/_stubs.dm b/code/controllers/ProcessScheduler/core/_stubs.dm new file mode 100644 index 0000000000..326fd29ac2 --- /dev/null +++ b/code/controllers/ProcessScheduler/core/_stubs.dm @@ -0,0 +1,38 @@ +/** + * _stubs.dm + * + * This file contains constructs that the process scheduler expects to exist + * in a standard ss13 fork. + */ +/* +/** + * message_admins + * + * sends a message to admins + */ +/proc/message_admins(msg) + world << msg +*/ +/** + * logTheThing + * + * In goonstation, this proc writes a message to either the world log or diary. + * + * Blame Keelin. + */ +/proc/logTheThing(type, source, target, text, diaryType) + if(diaryType) + world << "Diary: \[[diaryType]:[type]] [text]" + else + world << "Log: \[[type]] [text]" + +/** + * var/disposed + * + * In goonstation, disposed is set to 1 after an object enters the delete queue + * or the object is placed in an object pool (effectively out-of-play so to speak) + */ +/datum/var/disposed +// Garbage collection (controller). +/datum/var/gcDestroyed +/datum/var/timeDestroyed \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/core/process.dm b/code/controllers/ProcessScheduler/core/process.dm new file mode 100644 index 0000000000..89048113d3 --- /dev/null +++ b/code/controllers/ProcessScheduler/core/process.dm @@ -0,0 +1,317 @@ +// Process + +/datum/controller/process + /** + * State vars + */ + // Main controller ref + var/tmp/datum/controller/processScheduler/main + + // 1 if process is not running or queued + var/tmp/idle = 1 + + // 1 if process is queued + var/tmp/queued = 0 + + // 1 if process is running + var/tmp/running = 0 + + // 1 if process is blocked up + var/tmp/hung = 0 + + // 1 if process was killed + var/tmp/killed = 0 + + // Status text var + var/tmp/status + + // Previous status text var + var/tmp/previousStatus + + // 1 if process is disabled + var/tmp/disabled = 0 + + /** + * Config vars + */ + // Process name + var/name + + // Process schedule interval + // This controls how often the process would run under ideal conditions. + // If the process scheduler sees that the process has finished, it will wait until + // this amount of time has elapsed from the start of the previous run to start the + // process running again. + var/tmp/schedule_interval = PROCESS_DEFAULT_SCHEDULE_INTERVAL // run every 50 ticks + + // Process sleep interval + // This controls how often the process will yield (call sleep(0)) while it is running. + // Every concurrent process should sleep periodically while running in order to allow other + // processes to execute concurrently. + var/tmp/sleep_interval = PROCESS_DEFAULT_SLEEP_INTERVAL + + // hang_warning_time - this is the time (in 1/10 seconds) after which the server will begin to show "maybe hung" in the context window + var/tmp/hang_warning_time = PROCESS_DEFAULT_HANG_WARNING_TIME + + // hang_alert_time - After this much time(in 1/10 seconds), the server will send an admin debug message saying the process may be hung + var/tmp/hang_alert_time = PROCESS_DEFAULT_HANG_ALERT_TIME + + // hang_restart_time - After this much time(in 1/10 seconds), the server will automatically kill and restart the process. + var/tmp/hang_restart_time = PROCESS_DEFAULT_HANG_RESTART_TIME + + // cpu_threshold - if world.cpu >= cpu_threshold, scheck() will call sleep(1) to defer further work until the next tick. This keeps a process from driving a tick into overtime (causing perceptible lag) + var/tmp/cpu_threshold = PROCESS_DEFAULT_CPU_THRESHOLD + + // How many times in the current run has the process deferred work till the next tick? + var/tmp/cpu_defer_count = 0 + + /** + * recordkeeping vars + */ + + // Records the time (server ticks) at which the process last finished sleeping + var/tmp/last_slept = 0 + + // Records the time (s-ticks) at which the process last began running + var/tmp/run_start = 0 + + // Records the number of times this process has been killed and restarted + var/tmp/times_killed + + // Tick count + var/tmp/ticks = 0 + + var/tmp/last_task = "" + + var/tmp/last_object + +datum/controller/process/New(var/datum/controller/processScheduler/scheduler) + ..() + main = scheduler + previousStatus = "idle" + idle() + name = "process" + schedule_interval = 50 + sleep_interval = 2 + last_slept = 0 + run_start = 0 + ticks = 0 + last_task = 0 + last_object = null + +datum/controller/process/proc/started() + // Initialize last_slept so we can know when to sleep + last_slept = world.timeofday + + // Initialize run_start so we can detect hung processes. + run_start = world.timeofday + + // Initialize defer count + cpu_defer_count = 0 + + running() + main.processStarted(src) + + onStart() + +datum/controller/process/proc/finished() + ticks++ + idle() + main.processFinished(src) + + onFinish() + +datum/controller/process/proc/doWork() + +datum/controller/process/proc/setup() + +datum/controller/process/proc/process() + started() + doWork() + finished() + +datum/controller/process/proc/running() + idle = 0 + queued = 0 + running = 1 + hung = 0 + setStatus(PROCESS_STATUS_RUNNING) + +datum/controller/process/proc/idle() + queued = 0 + running = 0 + idle = 1 + hung = 0 + setStatus(PROCESS_STATUS_IDLE) + +datum/controller/process/proc/queued() + idle = 0 + running = 0 + queued = 1 + hung = 0 + setStatus(PROCESS_STATUS_QUEUED) + +datum/controller/process/proc/hung() + hung = 1 + setStatus(PROCESS_STATUS_HUNG) + +datum/controller/process/proc/handleHung() + var/datum/lastObj = last_object + var/lastObjType = "null" + if(istype(lastObj)) + lastObjType = lastObj.type + + // If world.timeofday has rolled over, then we need to adjust. + if (world.timeofday < run_start) + run_start -= 864000 + + var/msg = "[name] process hung at tick #[ticks]. Process was unresponsive for [(world.timeofday - run_start) / 10] seconds and was restarted. Last task: [last_task]. Last Object Type: [lastObjType]" + logTheThing("debug", null, null, msg) + logTheThing("diary", null, null, msg, "debug") + message_admins(msg) + + main.restartProcess(src.name) + +datum/controller/process/proc/kill() + if (!killed) + var/msg = "[name] process was killed at tick #[ticks]." + logTheThing("debug", null, null, msg) + logTheThing("diary", null, null, msg, "debug") + //finished() + + // Allow inheritors to clean up if needed + onKill() + + killed = TRUE + + // This should del + del(src) + +datum/controller/process/proc/scheck(var/tickId = 0) + if (killed) + // The kill proc is the only place where killed is set. + // The kill proc should have deleted this datum, and all sleeping procs that are + // owned by it. + CRASH("A killed process is still running somehow...") + + // For each tick the process defers, it increments the cpu_defer_count so we don't + // defer indefinitely + if (world.cpu >= cpu_threshold + cpu_defer_count * 10) + sleep(1) + cpu_defer_count++ + last_slept = world.timeofday + else + // If world.timeofday has rolled over, then we need to adjust. + if (world.timeofday < last_slept) + last_slept -= 864000 + + if (world.timeofday > last_slept + sleep_interval) + // If we haven't slept in sleep_interval ticks, sleep to allow other work to proceed. + sleep(0) + last_slept = world.timeofday + +datum/controller/process/proc/update() + // Clear delta + if(previousStatus != status) + setStatus(status) + + var/elapsedTime = getElapsedTime() + + if (elapsedTime > hang_restart_time) + hung() + else if (elapsedTime > hang_alert_time) + setStatus(PROCESS_STATUS_PROBABLY_HUNG) + else if (elapsedTime > hang_warning_time) + setStatus(PROCESS_STATUS_MAYBE_HUNG) + +datum/controller/process/proc/getElapsedTime() + if (world.timeofday < run_start) + return world.timeofday - (run_start - 864000) + return world.timeofday - run_start + +datum/controller/process/proc/tickDetail() + return + +datum/controller/process/proc/getContext() + return "[name][main.averageRunTime(src)][main.last_run_time[src]][main.highest_run_time[src]][ticks]\n" + +datum/controller/process/proc/getContextData() + return list( + "name" = name, + "averageRunTime" = main.averageRunTime(src), + "lastRunTime" = main.last_run_time[src], + "highestRunTime" = main.highest_run_time[src], + "ticks" = ticks, + "schedule" = schedule_interval, + "status" = getStatusText(), + "disabled" = disabled + ) + +datum/controller/process/proc/getStatus() + return status + +datum/controller/process/proc/getStatusText(var/s = 0) + if(!s) + s = status + switch(s) + if(PROCESS_STATUS_IDLE) + return "idle" + if(PROCESS_STATUS_QUEUED) + return "queued" + if(PROCESS_STATUS_RUNNING) + return "running" + if(PROCESS_STATUS_MAYBE_HUNG) + return "maybe hung" + if(PROCESS_STATUS_PROBABLY_HUNG) + return "probably hung" + if(PROCESS_STATUS_HUNG) + return "HUNG" + else + return "UNKNOWN" + +datum/controller/process/proc/getPreviousStatus() + return previousStatus + +datum/controller/process/proc/getPreviousStatusText() + return getStatusText(previousStatus) + +datum/controller/process/proc/setStatus(var/newStatus) + previousStatus = status + status = newStatus + +datum/controller/process/proc/setLastTask(var/task, var/object) + last_task = task + last_object = object + +datum/controller/process/proc/_copyStateFrom(var/datum/controller/process/target) + main = target.main + name = target.name + schedule_interval = target.schedule_interval + sleep_interval = target.sleep_interval + last_slept = 0 + run_start = 0 + times_killed = target.times_killed + ticks = target.ticks + last_task = target.last_task + last_object = target.last_object + copyStateFrom(target) + +datum/controller/process/proc/copyStateFrom(var/datum/controller/process/target) + +datum/controller/process/proc/onKill() + +datum/controller/process/proc/onStart() + +datum/controller/process/proc/onFinish() + +datum/controller/process/proc/disable() + disabled = 1 + +datum/controller/process/proc/enable() + disabled = 0 + +/datum/controller/process/proc/getLastRunTime() + return main.getProcessLastRunTime(src) + +/datum/controller/process/proc/getTicks() + return ticks diff --git a/code/controllers/ProcessScheduler/core/processScheduler.dm b/code/controllers/ProcessScheduler/core/processScheduler.dm new file mode 100644 index 0000000000..1be2404593 --- /dev/null +++ b/code/controllers/ProcessScheduler/core/processScheduler.dm @@ -0,0 +1,320 @@ +// Singleton instance of game_controller_new, setup in world.New() +var/global/datum/controller/processScheduler/processScheduler + +/datum/controller/processScheduler + // Processes known by the scheduler + var/tmp/datum/controller/process/list/processes = new + + // Processes that are currently running + var/tmp/datum/controller/process/list/running = new + + // Processes that are idle + var/tmp/datum/controller/process/list/idle = new + + // Processes that are queued to run + var/tmp/datum/controller/process/list/queued = new + + // Process name -> process object map + var/tmp/datum/controller/process/list/nameToProcessMap = new + + // Process last start times + var/tmp/datum/controller/process/list/last_start = new + + // Process last run durations + var/tmp/datum/controller/process/list/last_run_time = new + + // Per process list of the last 20 durations + var/tmp/datum/controller/process/list/last_twenty_run_times = new + + // Process highest run time + var/tmp/datum/controller/process/list/highest_run_time = new + + // Sleep 1 tick -- This may be too aggressive. + var/tmp/scheduler_sleep_interval = 1 + + // Controls whether the scheduler is running or not + var/tmp/isRunning = 0 + + // Setup for these processes will be deferred until all the other processes are set up. + var/tmp/list/deferredSetupList = new + +/** + * deferSetupFor + * @param path processPath + * If a process needs to be initialized after everything else, add it to + * the deferred setup list. On goonstation, only the ticker needs to have + * this treatment. + */ +/datum/controller/processScheduler/proc/deferSetupFor(var/processPath) + if (!(processPath in deferredSetupList)) + deferredSetupList += processPath + +/datum/controller/processScheduler/proc/setup() + // There can be only one + if(processScheduler && (processScheduler != src)) + del(src) + return 0 + + var/process + // Add all the processes we can find, except for the ticker + for (process in typesof(/datum/controller/process) - /datum/controller/process) + if (!(process in deferredSetupList)) + addProcess(new process(src)) + + for (process in deferredSetupList) + addProcess(new process(src)) + +/datum/controller/processScheduler/proc/start() + isRunning = 1 + spawn(0) + process() + +/datum/controller/processScheduler/proc/process() + while(isRunning) + checkRunningProcesses() + queueProcesses() + runQueuedProcesses() + sleep(scheduler_sleep_interval) + +/datum/controller/processScheduler/proc/stop() + isRunning = 0 + +/datum/controller/processScheduler/proc/checkRunningProcesses() + for(var/datum/controller/process/p in running) + p.update() + + if (isnull(p)) // Process was killed + continue + + var/status = p.getStatus() + var/previousStatus = p.getPreviousStatus() + + // Check status changes + if(status != previousStatus) + //Status changed. + + switch(status) + if(PROCESS_STATUS_MAYBE_HUNG) + message_admins("Process '[p.name]' is [p.getStatusText(status)].") + if(PROCESS_STATUS_PROBABLY_HUNG) + message_admins("Process '[p.name]' is [p.getStatusText(status)].") + if(PROCESS_STATUS_HUNG) + message_admins("Process '[p.name]' is [p.getStatusText(status)].") + p.handleHung() + +/datum/controller/processScheduler/proc/queueProcesses() + for(var/datum/controller/process/p in processes) + // Don't double-queue, don't queue running processes + if (p.disabled || p.running || p.queued || !p.idle) + continue + + // If world.timeofday has rolled over, then we need to adjust. + if (world.timeofday < last_start[p]) + last_start[p] -= 864000 + + // If the process should be running by now, go ahead and queue it + if (world.timeofday > last_start[p] + p.schedule_interval) + setQueuedProcessState(p) + +/datum/controller/processScheduler/proc/runQueuedProcesses() + for(var/datum/controller/process/p in queued) + runProcess(p) + +/datum/controller/processScheduler/proc/addProcess(var/datum/controller/process/process) + processes.Add(process) + process.idle() + idle.Add(process) + + // init recordkeeping vars + last_start.Add(process) + last_start[process] = 0 + last_run_time.Add(process) + last_run_time[process] = 0 + last_twenty_run_times.Add(process) + last_twenty_run_times[process] = list() + highest_run_time.Add(process) + highest_run_time[process] = 0 + + // init starts and stops record starts + recordStart(process, 0) + recordEnd(process, 0) + + // Set up process + process.setup() + + // Save process in the name -> process map + nameToProcessMap[process.name] = process + +/datum/controller/processScheduler/proc/replaceProcess(var/datum/controller/process/oldProcess, var/datum/controller/process/newProcess) + processes.Remove(oldProcess) + processes.Add(newProcess) + + newProcess.idle() + idle.Remove(oldProcess) + running.Remove(oldProcess) + queued.Remove(oldProcess) + idle.Add(newProcess) + + last_start.Remove(oldProcess) + last_start.Add(newProcess) + last_start[newProcess] = 0 + + last_run_time.Add(newProcess) + last_run_time[newProcess] = last_run_time[oldProcess] + last_run_time.Remove(oldProcess) + + last_twenty_run_times.Add(newProcess) + last_twenty_run_times[newProcess] = last_twenty_run_times[oldProcess] + last_twenty_run_times.Remove(oldProcess) + + highest_run_time.Add(newProcess) + highest_run_time[newProcess] = highest_run_time[oldProcess] + highest_run_time.Remove(oldProcess) + + recordStart(newProcess, 0) + recordEnd(newProcess, 0) + + nameToProcessMap[newProcess.name] = newProcess + + +/datum/controller/processScheduler/proc/runProcess(var/datum/controller/process/process) + spawn(0) + process.process() + +/datum/controller/processScheduler/proc/processStarted(var/datum/controller/process/process) + setRunningProcessState(process) + recordStart(process) + +/datum/controller/processScheduler/proc/processFinished(var/datum/controller/process/process) + setIdleProcessState(process) + recordEnd(process) + +/datum/controller/processScheduler/proc/setIdleProcessState(var/datum/controller/process/process) + if (process in running) + running -= process + if (process in queued) + queued -= process + if (!(process in idle)) + idle += process + + process.idle() + +/datum/controller/processScheduler/proc/setQueuedProcessState(var/datum/controller/process/process) + if (process in running) + running -= process + if (process in idle) + idle -= process + if (!(process in queued)) + queued += process + + // The other state transitions are handled internally by the process. + process.queued() + +/datum/controller/processScheduler/proc/setRunningProcessState(var/datum/controller/process/process) + if (process in queued) + queued -= process + if (process in idle) + idle -= process + if (!(process in running)) + running += process + + process.running() + +/datum/controller/processScheduler/proc/recordStart(var/datum/controller/process/process, var/time = null) + if (isnull(time)) + time = world.timeofday + + last_start[process] = time + +/datum/controller/processScheduler/proc/recordEnd(var/datum/controller/process/process, var/time = null) + if (isnull(time)) + time = world.timeofday + + // If world.timeofday has rolled over, then we need to adjust. + if (time < last_start[process]) + last_start[process] -= 864000 + + var/lastRunTime = time - last_start[process] + + if(lastRunTime < 0) + lastRunTime = 0 + + recordRunTime(process, lastRunTime) + +/** + * recordRunTime + * Records a run time for a process + */ +/datum/controller/processScheduler/proc/recordRunTime(var/datum/controller/process/process, time) + last_run_time[process] = time + if(time > highest_run_time[process]) + highest_run_time[process] = time + + var/list/lastTwenty = last_twenty_run_times[process] + if (lastTwenty.len == 20) + lastTwenty.Cut(1, 2) + lastTwenty.len++ + lastTwenty[lastTwenty.len] = time + +/** + * averageRunTime + * returns the average run time (over the last 20) of the process + */ +/datum/controller/processScheduler/proc/averageRunTime(var/datum/controller/process/process) + var/lastTwenty = last_twenty_run_times[process] + + var/t = 0 + var/c = 0 + for(var/time in lastTwenty) + t += time + c++ + + if(c > 0) + return t / c + return c + +/datum/controller/processScheduler/proc/getStatusData() + var/list/data = new + + for (var/datum/controller/process/p in processes) + data.len++ + data[data.len] = p.getContextData() + + return data + +/datum/controller/processScheduler/proc/getProcessCount() + return processes.len + +/datum/controller/processScheduler/proc/hasProcess(var/processName as text) + if (nameToProcessMap[processName]) + return 1 + +/datum/controller/processScheduler/proc/killProcess(var/processName as text) + restartProcess(processName) + +/datum/controller/processScheduler/proc/restartProcess(var/processName as text) + if (hasProcess(processName)) + var/datum/controller/process/oldInstance = nameToProcessMap[processName] + var/datum/controller/process/newInstance = new oldInstance.type(src) + newInstance._copyStateFrom(oldInstance) + replaceProcess(oldInstance, newInstance) + oldInstance.kill() + +/datum/controller/processScheduler/proc/enableProcess(var/processName as text) + if (hasProcess(processName)) + var/datum/controller/process/process = nameToProcessMap[processName] + process.enable() + +/datum/controller/processScheduler/proc/disableProcess(var/processName as text) + if (hasProcess(processName)) + var/datum/controller/process/process = nameToProcessMap[processName] + process.disable() + +/datum/controller/processScheduler/proc/getProcess(var/name) + return nameToProcessMap[name] + +/datum/controller/processScheduler/proc/getProcessLastRunTime(var/datum/controller/process/process) + return last_run_time[process] + +/datum/controller/processScheduler/proc/getIsRunning() + return isRunning diff --git a/code/controllers/ProcessScheduler/core/updateQueue.dm b/code/controllers/ProcessScheduler/core/updateQueue.dm new file mode 100644 index 0000000000..118b6692b5 --- /dev/null +++ b/code/controllers/ProcessScheduler/core/updateQueue.dm @@ -0,0 +1,127 @@ +/** + * updateQueue.dm + */ + +#ifdef UPDATE_QUEUE_DEBUG +#define uq_dbg(text) world << text +#else +#define uq_dbg(text) +#endif +/datum/updateQueue + var/tmp/list/objects + var/tmp/previousStart + var/tmp/procName + var/tmp/list/arguments + var/tmp/datum/updateQueueWorker/currentWorker + var/tmp/workerTimeout + var/tmp/adjustedWorkerTimeout + var/tmp/currentKillCount + var/tmp/totalKillCount + +/datum/updateQueue/New(list/objects = list(), procName = "update", list/arguments = list(), workerTimeout = 2, inplace = 0) + ..() + + uq_dbg("Update queue created.") + + // Init proc allows for recycling the worker. + init(objects = objects, procName = procName, arguments = arguments, workerTimeout = workerTimeout, inplace = inplace) + +/** + * init + * @param list objects objects to update + * @param text procName the proc to call on each item in the object list + * @param list arguments optional arguments to pass to the update proc + * @param number workerTimeout number of ticks to wait for an update to + finish before forking a new update worker + * @param bool inplace whether the updateQueue should make a copy of objects. + the internal list will be modified, so it is usually + a good idea to leave this alone. Default behavior is to + copy. + */ +/datum/updateQueue/proc/init(list/objects = list(), procName = "update", list/arguments = list(), workerTimeout = 2, inplace = 0) + uq_dbg("Update queue initialization started.") + + if (!inplace) + // Make an internal copy of the list so we're not modifying the original. + initList(objects) + else + src.objects = objects + + // Init vars + src.procName = procName + src.arguments = arguments + src.workerTimeout = workerTimeout + + adjustedWorkerTimeout = workerTimeout + currentKillCount = 0 + totalKillCount = 0 + + uq_dbg("Update queue initialization finished. procName = '[procName]'") + +/datum/updateQueue/proc/initList(list/toCopy) + /** + * We will copy the list in reverse order, as our doWork proc + * will access them by popping an element off the end of the list. + * This ends up being quite a lot faster than taking elements off + * the head of the list. + */ + objects = new + + uq_dbg("Copying [toCopy.len] items for processing.") + + for(var/i=toCopy.len,i>0,) + objects.len++ + objects[objects.len] = toCopy[i--] + +/datum/updateQueue/proc/Run() + uq_dbg("Starting run...") + + startWorker() + while (istype(currentWorker) && !currentWorker.finished) + sleep(2) + checkWorker() + + uq_dbg("UpdateQueue completed run.") + +/datum/updateQueue/proc/checkWorker() + if(istype(currentWorker)) + // If world.timeofday has rolled over, then we need to adjust. + if(world.timeofday < currentWorker.lastStart) + currentWorker.lastStart -= 864000 + + if(world.timeofday - currentWorker.lastStart > adjustedWorkerTimeout) + // This worker is a bit slow, let's spawn a new one and kill the old one. + uq_dbg("Current worker is lagging... starting a new one.") + killWorker() + startWorker() + else // No worker! + uq_dbg("update queue ended up without a worker... starting a new one...") + startWorker() + +/datum/updateQueue/proc/startWorker() + // only run the worker if we have objects to work on + if(objects.len) + uq_dbg("Starting worker process.") + + // No need to create a fresh worker if we already have one... + if (istype(currentWorker)) + currentWorker.init(objects, procName, arguments) + else + currentWorker = new(objects, procName, arguments) + currentWorker.start() + else + uq_dbg("Queue is empty. No worker was started.") + currentWorker = null + +/datum/updateQueue/proc/killWorker() + // Kill the worker + currentWorker.kill() + currentWorker = null + // After we kill a worker, yield so that if the worker's been tying up the cpu, other stuff can immediately resume + sleep(-1) + currentKillCount++ + totalKillCount++ + if (currentKillCount >= 3) + uq_dbg("[currentKillCount] workers have been killed with a timeout of [adjustedWorkerTimeout]. Increasing worker timeout to compensate.") + adjustedWorkerTimeout++ + currentKillCount = 0 \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/core/updateQueueWorker.dm b/code/controllers/ProcessScheduler/core/updateQueueWorker.dm new file mode 100644 index 0000000000..66f66bbcc0 --- /dev/null +++ b/code/controllers/ProcessScheduler/core/updateQueueWorker.dm @@ -0,0 +1,83 @@ +datum/updateQueueWorker + var/tmp/list/objects + var/tmp/killed + var/tmp/finished + var/tmp/procName + var/tmp/list/arguments + var/tmp/lastStart + var/tmp/cpuThreshold + +datum/updateQueueWorker/New(var/list/objects, var/procName, var/list/arguments, var/cpuThreshold = 90) + ..() + uq_dbg("updateQueueWorker created.") + + init(objects, procName, arguments, cpuThreshold) + +datum/updateQueueWorker/proc/init(var/list/objects, var/procName, var/list/arguments, var/cpuThreshold = 90) + src.objects = objects + src.procName = procName + src.arguments = arguments + src.cpuThreshold = cpuThreshold + + killed = 0 + finished = 0 + +datum/updateQueueWorker/proc/doWork() + // If there's nothing left to execute or we were killed, mark finished and return. + if (!objects || !objects.len) return finished() + + lastStart = world.timeofday // Absolute number of ticks since the world started up + + var/datum/object = objects[objects.len] // Pull out the object + objects.len-- // Remove the object from the list + + if (istype(object) && !isturf(object) && !object.disposed && isnull(object.gcDestroyed)) // We only work with real objects + call(object, procName)(arglist(arguments)) + + // If there's nothing left to execute + // or we were killed while running the above code, mark finished and return. + if (!objects || !objects.len) return finished() + + if (world.cpu > cpuThreshold) + // We don't want to force a tick into overtime! + // If the tick is about to go overtime, spawn the next update to go + // in the next tick. + uq_dbg("tick went into overtime with world.cpu = [world.cpu], deferred next update to next tick [1+(world.time / world.tick_lag)]") + + spawn(1) + doWork() + else + spawn(0) // Execute anonymous function immediately as if we were in a while loop... + doWork() + +datum/updateQueueWorker/proc/finished() + uq_dbg("updateQueueWorker finished.") + /** + * If the worker was killed while it was working on something, it + * should delete itself when it finally finishes working on it. + * Meanwhile, the updateQueue will have proceeded on with the rest of + * the queue. This will also terminate the spawned function that was + * created in the kill() proc. + */ + if(killed) + del(src) + + finished = 1 + +datum/updateQueueWorker/proc/kill() + uq_dbg("updateQueueWorker killed.") + killed = 1 + objects = null + + /** + * If the worker is not done in 30 seconds after it's killed, + * we'll forcibly delete it, causing the anonymous function it was + * running to be terminated. Hasta la vista, baby. + */ + spawn(300) + del(src) + +datum/updateQueueWorker/proc/start() + uq_dbg("updateQueueWorker started.") + spawn(0) + doWork() \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/package.json b/code/controllers/ProcessScheduler/package.json new file mode 100644 index 0000000000..f699553fc6 --- /dev/null +++ b/code/controllers/ProcessScheduler/package.json @@ -0,0 +1,28 @@ +{ + "name": "ProcessScheduler", + "version": "1.0.0", + "description": "BYOND SS13 Process Scheduler", + "main": "processScheduler.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/goonstation/ProcessScheduler.git" + }, + "keywords": [ + "byond", + "ss13", + "process", + "scheduler" + ], + "author": "Volundr", + "license": "CC-BY-NC", + "bugs": { + "url": "https://github.com/goonstation/ProcessScheduler/issues" + }, + "homepage": "https://github.com/goonstation/ProcessScheduler", + "dependencies": { + "bower": "*" + } +} diff --git a/code/controllers/ProcessScheduler/test/processScheduler.js b/code/controllers/ProcessScheduler/test/processScheduler.js new file mode 100644 index 0000000000..0a4f111355 --- /dev/null +++ b/code/controllers/ProcessScheduler/test/processScheduler.js @@ -0,0 +1,56 @@ +(function ($) { + function setRef(theRef) { + ref = theRef; + } + + function jax(action, data) { + if (typeof data === 'undefined') + data = {}; + var params = []; + for (var k in data) { + if (data.hasOwnProperty(k)) { + params.push(encodeURIComponent(k) + '=' + encodeURIComponent(data[k])); + } + } + var newLoc = '?src=' + ref + ';action=' + action + ';' + params.join(';'); + window.location = newLoc; + } + + function requestRefresh(e) { + jax("refresh", null); + } + + function handleRefresh(processTable) { + $('#processTable').html(processTable); + initProcessTableButtons(); + } + + function requestKill(e) { + var button = $(e.currentTarget); + jax("kill", {name: button.data("process-name")}); + } + + function requestEnable(e) { + var button = $(e.currentTarget); + jax("enable", {name: button.data("process-name")}); + } + + function requestDisable(e) { + var button = $(e.currentTarget); + jax("disable", {name: button.data("process-name")}); + } + + function initProcessTableButtons() { + $(".kill-btn").on("click", requestKill); + $(".enable-btn").on("click", requestEnable); + $(".disable-btn").on("click", requestDisable); + } + + window.setRef = setRef; + window.handleRefresh = handleRefresh; + + $(function() { + initProcessTableButtons(); + $('#btn-refresh').on("click", requestRefresh); + }); +}(jQuery)); \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/test/processSchedulerView.dm b/code/controllers/ProcessScheduler/test/processSchedulerView.dm new file mode 100644 index 0000000000..ae78b3f015 --- /dev/null +++ b/code/controllers/ProcessScheduler/test/processSchedulerView.dm @@ -0,0 +1,94 @@ +/datum/processSchedulerView + +/datum/processSchedulerView/Topic(href, href_list) + if (!href_list["action"]) + return + + switch (href_list["action"]) + if ("kill") + var/toKill = href_list["name"] + processScheduler.killProcess(toKill) + refreshProcessTable() + if ("enable") + var/toEnable = href_list["name"] + processScheduler.enableProcess(toEnable) + refreshProcessTable() + if ("disable") + var/toDisable = href_list["name"] + processScheduler.disableProcess(toDisable) + refreshProcessTable() + if ("refresh") + refreshProcessTable() + +/datum/processSchedulerView/proc/refreshProcessTable() + windowCall("handleRefresh", getProcessTable()) + +/datum/processSchedulerView/proc/windowCall(var/function, var/data = null) + usr << output(data, "processSchedulerContext.browser:[function]") + +/datum/processSchedulerView/proc/getProcessTable() + var/text = "" + // and the context of each + for (var/list/data in processScheduler.getStatusData()) + text += "" + text += "" + text += "" + text += "" + text += "" + text += "" + text += "" + text += "" + text += "" + text += "" + + text += "
NameAvg(s)Last(s)Highest(s)TickcountTickrateStateAction
[data["name"]][num2text(data["averageRunTime"]/10,3)][num2text(data["lastRunTime"]/10,3)][num2text(data["highestRunTime"]/10,3)][num2text(data["ticks"],4)][data["schedule"]][data["status"]]" + if (data["disabled"]) + text += "" + else + text += "" + text += "
" + return text + +/** + * getContext + * Outputs an interface showing stats for all processes. + */ +/datum/processSchedulerView/proc/getContext() + bootstrap_browse() + usr << browse('processScheduler.js', "file=processScheduler.js;display=0") + + var/text = {" + Process Scheduler Detail + + [bootstrap_includes()] + + + +

Process Scheduler

+
+ +
+ +

The process scheduler controls [processScheduler.getProcessCount()] loops.

"} + + text += "
" + text += getProcessTable() + text += "
" + + usr << browse(text, "window=processSchedulerContext;size=800x600") + +/datum/processSchedulerView/proc/bootstrap_browse() + usr << browse('bower_components/jquery/dist/jquery.min.js', "file=jquery.min.js;display=0") + usr << browse('bower_components/bootstrap2.3.2/bootstrap/js/bootstrap.min.js', "file=bootstrap.min.js;display=0") + usr << browse('bower_components/bootstrap2.3.2/bootstrap/css/bootstrap.min.css', "file=bootstrap.min.css;display=0") + usr << browse('bower_components/bootstrap2.3.2/bootstrap/img/glyphicons-halflings-white.png', "file=glyphicons-halflings-white.png;display=0") + usr << browse('bower_components/bootstrap2.3.2/bootstrap/img/glyphicons-halflings.png', "file=glyphicons-halflings.png;display=0") + usr << browse('bower_components/json2/json2.js', "file=json2.js;display=0") + +/datum/processSchedulerView/proc/bootstrap_includes() + return {" + + + + + "} diff --git a/code/controllers/ProcessScheduler/test/testDyingUpdateQueueProcess.dm b/code/controllers/ProcessScheduler/test/testDyingUpdateQueueProcess.dm new file mode 100644 index 0000000000..d08ec46c7d --- /dev/null +++ b/code/controllers/ProcessScheduler/test/testDyingUpdateQueueProcess.dm @@ -0,0 +1,27 @@ +/** + * testDyingUpdateQueueProcess + * This process is an example of a process using an updateQueue. + * The datums updated by this process behave badly and block the update loop + * by sleeping. If you #define UPDATE_QUEUE_DEBUG, you will see the updateQueue + * killing off its worker processes and spawning new ones to work around slow + * updates. This means that if you have a code path that sleeps for a long time + * in mob.Life once in a blue moon, the mob update loop will not hang. + */ +/datum/slowTestDatum/proc/wackyUpdateProcessName() + sleep(rand(0,20)) // Randomly REALLY slow :| + +/datum/controller/process/testDyingUpdateQueueProcess + var/tmp/datum/updateQueue/updateQueueInstance + var/tmp/list/testDatums = list() + +/datum/controller/process/testDyingUpdateQueueProcess/setup() + name = "Dying UpdateQueue Process" + schedule_interval = 30 // every 3 seconds + updateQueueInstance = new + for(var/i = 1, i < 30, i++) + testDatums.Add(new /datum/slowTestDatum) + +/datum/controller/process/testDyingUpdateQueueProcess/doWork() + updateQueueInstance.init(testDatums, "wackyUpdateProcessName") + updateQueueInstance.Run() + \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/test/testHarness.dm b/code/controllers/ProcessScheduler/test/testHarness.dm new file mode 100644 index 0000000000..2b5f1dff81 --- /dev/null +++ b/code/controllers/ProcessScheduler/test/testHarness.dm @@ -0,0 +1,35 @@ +/* + These are simple defaults for your project. + */ +#define DEBUG + +var/global/datum/processSchedulerView/processSchedulerView + +world + loop_checks = 0 + New() + ..() + processScheduler = new + processSchedulerView = new + +mob + step_size = 8 + + New() + ..() + + + verb + startProcessScheduler() + set name = "Start Process Scheduler" + processScheduler.setup() + processScheduler.start() + + getProcessSchedulerContext() + set name = "Get Process Scheduler Status Panel" + processSchedulerView.getContext() + + runUpdateQueueTests() + set name = "Run Update Queue Testsuite" + var/datum/updateQueueTests/t = new + t.runTests() \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/test/testHungProcess.dm b/code/controllers/ProcessScheduler/test/testHungProcess.dm new file mode 100644 index 0000000000..ced05dd4d7 --- /dev/null +++ b/code/controllers/ProcessScheduler/test/testHungProcess.dm @@ -0,0 +1,15 @@ +/** + * testHungProcess + * This process is an example of a simple update loop process that hangs. + */ + +/datum/controller/process/testHungProcess/setup() + name = "Hung Process" + schedule_interval = 30 // every 3 seconds + +/datum/controller/process/testHungProcess/doWork() + sleep(1000) // FUCK + // scheck is also responsible for handling hung processes. If a process + // hangs, and later resumes, but has already been killed by the scheduler, + // scheck will force the process to bail out. + scheck() \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/test/testNiceProcess.dm b/code/controllers/ProcessScheduler/test/testNiceProcess.dm new file mode 100644 index 0000000000..aa921bc62f --- /dev/null +++ b/code/controllers/ProcessScheduler/test/testNiceProcess.dm @@ -0,0 +1,13 @@ +/** + * testNiceProcess + * This process is an example of a simple update loop process that is + * relatively fast. + */ + +/datum/controller/process/testNiceProcess/setup() + name = "Nice Process" + schedule_interval = 10 // every second + +/datum/controller/process/testNiceProcess/doWork() + sleep(rand(1,5)) // Just to pretend we're doing something + \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/test/testSlowProcess.dm b/code/controllers/ProcessScheduler/test/testSlowProcess.dm new file mode 100644 index 0000000000..b7c9e6e21e --- /dev/null +++ b/code/controllers/ProcessScheduler/test/testSlowProcess.dm @@ -0,0 +1,28 @@ +/** + * testSlowProcess + * This process is an example of a simple update loop process that is slow. + * The update loop here sleeps inside to provide an example, but if you had + * a computationally intensive loop process that is simply slow, you can use + * scheck() inside the loop to force it to yield periodically according to + * the sleep_interval var. By default, scheck will cause a loop to sleep every + * 2 ticks. + */ + +/datum/controller/process/testSlowProcess/setup() + name = "Slow Process" + schedule_interval = 30 // every 3 seconds + +/datum/controller/process/testSlowProcess/doWork() + // set background = 1 will cause loop constructs to sleep periodically, + // whenever the BYOND scheduler deems it productive to do so. + // This behavior is not always sufficient, nor is it always consistent. + // Rather than leaving it up to the BYOND scheduler, we can control it + // ourselves and leave nothing to the black box. + set background = 1 + + for(var/i=1,i<30,i++) + // Just to pretend we're doing something here + sleep(rand(3, 5)) + + // Forces this loop to yield(sleep) periodically. + scheck() \ No newline at end of file diff --git a/code/controllers/ProcessScheduler/test/testUpdateQueue.dm b/code/controllers/ProcessScheduler/test/testUpdateQueue.dm new file mode 100644 index 0000000000..07b64e927f --- /dev/null +++ b/code/controllers/ProcessScheduler/test/testUpdateQueue.dm @@ -0,0 +1,209 @@ +var/global/list/updateQueueTestCount = list() + +/datum/updateQueueTests + var/start + proc + runTests() + world << "Running 9 tests..." + testUpdateQueuePerformance() + sleep(1) + testInplace() + sleep(1) + testInplaceUpdateQueuePerformance() + sleep(1) + testUpdateQueueReinit() + sleep(1) + testCrashingQueue() + sleep(1) + testEmptyQueue() + sleep(1) + testManySlowItemsInQueue() + sleep(1) + testVariableWorkerTimeout() + sleep(1) + testReallySlowItemInQueue() + sleep(1) + world << "Finished!" + + beginTiming() + start = world.time + + endTiming(text) + var/time = (world.time - start) / world.tick_lag + world << {"Performance - [text] - [time] ticks"} + + getCount() + return updateQueueTestCount[updateQueueTestCount.len] + + incrementTestCount() + updateQueueTestCount.len++ + updateQueueTestCount[updateQueueTestCount.len] = 0 + + assertCountEquals(count, text) + assertThat(getCount() == count, text) + + assertCountLessThan(count, text) + assertThat(getCount() < count, text) + + assertCountGreaterThan(count, text) + assertThat(getCount() > count, text) + + assertThat(condition, text) + if (condition) + world << {"PASS: [text]"} + else + world << {"FAIL: [text]"} + + testUpdateQueuePerformance() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=100000,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + + var/datum/updateQueue/uq = new(objs) + + beginTiming() + uq.Run() + endTiming("updating 100000 simple objects") + + assertCountEquals(100000, "test that update queue updates all objects expected") + del(objs) + del(uq) + + testUpdateQueueReinit() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=100,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + + var/datum/updateQueue/uq = new(objs) + uq.Run() + objs = new + + for(var/i=1,i<=100,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + uq.init(objs) + uq.Run() + assertCountEquals(200, "test that update queue reinitializes properly and updates all objects as expected.") + del(objs) + del(uq) + + testInplace() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=100,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + var/datum/updateQueue/uq = new(objects = objs, inplace = 1) + uq.Run() + assertThat(objs.len == 0, "test that update queue inplace option really works inplace") + assertCountEquals(100, "test that inplace update queue updates the right number of objects") + del(objs) + del(uq) + + testInplaceUpdateQueuePerformance() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=100000,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + + var/datum/updateQueue/uq = new(objs) + + beginTiming() + uq.Run() + endTiming("updating 100000 simple objects in place") + del(objs) + del(uq) + + testCrashingQueue() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=10,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + objs.Add(new /datum/uqTestDatum/crasher(updateQueueTestCount.len)) + for(var/i=1,i<=10,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + + var/datum/updateQueue/uq = new(objs) + uq.Run() + assertCountEquals(20, "test that update queue handles crashed update procs OK") + del(objs) + del(uq) + + testEmptyQueue() + incrementTestCount() + var/list/objs = new + var/datum/updateQueue/uq = new(objs) + uq.Run() + assertCountEquals(0, "test that update queue doesn't barf on empty lists") + del(objs) + del(uq) + + testManySlowItemsInQueue() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=30,i++) + objs.Add(new /datum/uqTestDatum/slow(updateQueueTestCount.len)) + var/datum/updateQueue/uq = new(objs) + uq.Run() + assertCountEquals(30, "test that update queue slows down execution if too many objects are slow to update") + del(objs) + del(uq) + + testVariableWorkerTimeout() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=20,i++) + objs.Add(new /datum/uqTestDatum/slow(updateQueueTestCount.len)) + var/datum/updateQueue/uq = new(objs, workerTimeout=6) + uq.Run() + assertCountEquals(20, "test that variable worker timeout works properly") + del(objs) + del(uq) + + testReallySlowItemInQueue() + incrementTestCount() + var/list/objs = new + for(var/i=1,i<=10,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + objs.Add(new /datum/uqTestDatum/reallySlow(updateQueueTestCount.len)) + for(var/i=1,i<=10,i++) + objs.Add(new /datum/uqTestDatum/fast(updateQueueTestCount.len)) + var/datum/updateQueue/uq = new(objs) + uq.Run() + assertCountEquals(20, "test that update queue skips objects that are too slow to update") + del(objs) + del(uq) + + + +datum/uqTestDatum + var/testNum + New(testNum) + ..() + src.testNum = testNum + proc/update() + updateQueueTestCount[testNum]++ + proc/lag(cycles) + set background = 1 + for(var/i=0,i 5) + world << "RUNTIMES IN ATMOS TICKER. Killing air simulation!" + world.log << "### ZAS SHUTDOWN" + + message_admins("ZASALERT: Shutting down! status: [air_master.tick_progress]") + log_admin("ZASALERT: Shutting down! status: [air_master.tick_progress]") + + air_processing_killed = TRUE + air_master.failed_ticks = 0 diff --git a/code/controllers/Processes/alarm.dm b/code/controllers/Processes/alarm.dm new file mode 100644 index 0000000000..d41aa6ffdf --- /dev/null +++ b/code/controllers/Processes/alarm.dm @@ -0,0 +1,6 @@ +/datum/controller/process/alarm/setup() + name = "alarm" + schedule_interval = 20 // every 2 seconds + +/datum/controller/process/alarm/doWork() + alarm_manager.fire() diff --git a/code/controllers/Processes/disease.dm b/code/controllers/Processes/disease.dm new file mode 100644 index 0000000000..a8d840097e --- /dev/null +++ b/code/controllers/Processes/disease.dm @@ -0,0 +1,11 @@ +/datum/controller/process/disease + var/tmp/datum/updateQueue/updateQueueInstance + +/datum/controller/process/disease/setup() + name = "disease" + schedule_interval = 20 // every 2 seconds + updateQueueInstance = new + +/datum/controller/process/disease/doWork() + updateQueueInstance.init(active_diseases, "process") + updateQueueInstance.Run() diff --git a/code/controllers/Processes/emergencyShuttle.dm b/code/controllers/Processes/emergencyShuttle.dm new file mode 100644 index 0000000000..e7289311b9 --- /dev/null +++ b/code/controllers/Processes/emergencyShuttle.dm @@ -0,0 +1,9 @@ +/datum/controller/process/emergencyShuttle/setup() + name = "emergency shuttle" + schedule_interval = 20 // every 2 seconds + + if(!emergency_shuttle) + emergency_shuttle = new + +/datum/controller/process/emergencyShuttle/doWork() + emergency_shuttle.process() diff --git a/code/controllers/Processes/event.dm b/code/controllers/Processes/event.dm new file mode 100644 index 0000000000..72bc01613d --- /dev/null +++ b/code/controllers/Processes/event.dm @@ -0,0 +1,6 @@ +/datum/controller/process/event/setup() + name = "event controller" + schedule_interval = 20 // every 2 seconds + +/datum/controller/process/event/doWork() + event_manager.process() \ No newline at end of file diff --git a/code/controllers/Processes/inactivity.dm b/code/controllers/Processes/inactivity.dm new file mode 100644 index 0000000000..b610502d19 --- /dev/null +++ b/code/controllers/Processes/inactivity.dm @@ -0,0 +1,16 @@ +/datum/controller/process/inactivity/setup() + name = "inactivity" + schedule_interval = INACTIVITY_KICK + +/datum/controller/process/inactivity/doWork() + if(config.kick_inactive) + for(var/client/C in clients) + if(C.is_afk(INACTIVITY_KICK)) + if(!istype(C.mob, /mob/dead)) + log_access("AFK: [key_name(C)]") + C << "You have been inactive for more than 10 minutes and have been disconnected." + del(C) + + scheck() + +#undef INACTIVITY_KICK diff --git a/code/controllers/Processes/lighting.dm b/code/controllers/Processes/lighting.dm new file mode 100644 index 0000000000..9399fe0253 --- /dev/null +++ b/code/controllers/Processes/lighting.dm @@ -0,0 +1,26 @@ +/datum/controller/process/lighting/setup() + name = "lighting" + schedule_interval = 5 // every .5 second + lighting_controller.initializeLighting() + +/datum/controller/process/lighting/doWork() + lighting_controller.lights_workload_max = \ + max(lighting_controller.lights_workload_max, lighting_controller.lights.len) + + for(var/datum/light_source/L in lighting_controller.lights) + if(L && L.check()) + lighting_controller.lights.Remove(L) + + scheck() + + lighting_controller.changed_turfs_workload_max = \ + max(lighting_controller.changed_turfs_workload_max, lighting_controller.changed_turfs.len) + + for(var/turf/T in lighting_controller.changed_turfs) + if(T && T.lighting_changed) + T.shift_to_subarea() + + scheck() + + if(lighting_controller.changed_turfs && lighting_controller.changed_turfs.len) + lighting_controller.changed_turfs.len = 0 // reset the changed list diff --git a/code/controllers/Processes/machinery.dm b/code/controllers/Processes/machinery.dm new file mode 100644 index 0000000000..61f3c7f4de --- /dev/null +++ b/code/controllers/Processes/machinery.dm @@ -0,0 +1,44 @@ +/var/global/machinery_sort_required = 0 + +/datum/controller/process/machinery/setup() + name = "machinery" + schedule_interval = 20 // every 2 seconds + +/datum/controller/process/machinery/doWork() + internal_sort() + internal_process() + +/datum/controller/process/machinery/proc/internal_sort() + if(machinery_sort_required) + machinery_sort_required = 0 + machines = dd_sortedObjectList(machines) + +/datum/controller/process/machinery/proc/internal_process() +//#ifdef PROFILE_MACHINES + //machine_profiling.len = 0 + //#endif + + for(var/obj/machinery/M in machines) + if(M && !M.gcDestroyed) + #ifdef PROFILE_MACHINES + var/time_start = world.timeofday + #endif + + if(M.process() == PROCESS_KILL) + //M.inMachineList = 0 We don't use this debugging function + machines.Remove(M) + continue + + if(M && M.use_power) + M.auto_use_power() + + #ifdef PROFILE_MACHINES + var/time_end = world.timeofday + + if(!(M.type in machine_profiling)) + machine_profiling[M.type] = 0 + + machine_profiling[M.type] += (time_end - time_start) + #endif + + scheck() diff --git a/code/controllers/Processes/mob.dm b/code/controllers/Processes/mob.dm new file mode 100644 index 0000000000..b3765b0cf9 --- /dev/null +++ b/code/controllers/Processes/mob.dm @@ -0,0 +1,20 @@ +/datum/controller/process/mob + var/tmp/datum/updateQueue/updateQueueInstance + +/datum/controller/process/mob/setup() + name = "mob" + schedule_interval = 20 // every 2 seconds + updateQueueInstance = new + +/datum/controller/process/mob/started() + ..() + if(!updateQueueInstance) + if(!mob_list) + mob_list = list() + else if(mob_list.len) + updateQueueInstance = new + +/datum/controller/process/mob/doWork() + if(updateQueueInstance) + updateQueueInstance.init(mob_list, "Life") + updateQueueInstance.Run() diff --git a/code/controllers/Processes/nanoui.dm b/code/controllers/Processes/nanoui.dm new file mode 100644 index 0000000000..c8396bcab8 --- /dev/null +++ b/code/controllers/Processes/nanoui.dm @@ -0,0 +1,11 @@ +/datum/controller/process/nanoui + var/tmp/datum/updateQueue/updateQueueInstance + +/datum/controller/process/nanoui/setup() + name = "nanoui" + schedule_interval = 20 // every 2 seconds + updateQueueInstance = new + +/datum/controller/process/nanoui/doWork() + updateQueueInstance.init(nanomanager.processing_uis, "process") + updateQueueInstance.Run() diff --git a/code/controllers/Processes/obj.dm b/code/controllers/Processes/obj.dm new file mode 100644 index 0000000000..15ad98dd3d --- /dev/null +++ b/code/controllers/Processes/obj.dm @@ -0,0 +1,21 @@ +var/global/list/object_profiling = list() +/datum/controller/process/obj + var/tmp/datum/updateQueue/updateQueueInstance + +/datum/controller/process/obj/setup() + name = "obj" + schedule_interval = 20 // every 2 seconds + updateQueueInstance = new + +/datum/controller/process/obj/started() + ..() + if(!updateQueueInstance) + if(!processing_objects) + processing_objects = list() + else if(processing_objects.len) + updateQueueInstance = new + +/datum/controller/process/obj/doWork() + if(updateQueueInstance) + updateQueueInstance.init(processing_objects, "process") + updateQueueInstance.Run() diff --git a/code/controllers/Processes/pipenet.dm b/code/controllers/Processes/pipenet.dm new file mode 100644 index 0000000000..56a068f54c --- /dev/null +++ b/code/controllers/Processes/pipenet.dm @@ -0,0 +1,12 @@ +/datum/controller/process/pipenet/setup() + name = "pipenet" + schedule_interval = 20 // every 2 seconds + +/datum/controller/process/pipenet/doWork() + for(var/datum/pipe_network/pipeNetwork in pipe_networks) + if(istype(pipeNetwork) && !pipeNetwork.disposed) + pipeNetwork.process() + scheck() + continue + + pipe_networks.Remove(pipeNetwork) diff --git a/code/controllers/Processes/powernet.dm b/code/controllers/Processes/powernet.dm new file mode 100644 index 0000000000..1edf194915 --- /dev/null +++ b/code/controllers/Processes/powernet.dm @@ -0,0 +1,12 @@ +/datum/controller/process/powernet/setup() + name = "powernet" + schedule_interval = 20 // every 2 seconds + +/datum/controller/process/powernet/doWork() + for(var/datum/powernet/powerNetwork in powernets) + if(istype(powerNetwork) && !powerNetwork.disposed) + powerNetwork.reset() + scheck() + continue + + powernets.Remove(powerNetwork) diff --git a/code/controllers/Processes/sun.dm b/code/controllers/Processes/sun.dm new file mode 100644 index 0000000000..f09806cef5 --- /dev/null +++ b/code/controllers/Processes/sun.dm @@ -0,0 +1,7 @@ +/datum/controller/process/sun/setup() + name = "sun" + schedule_interval = 20 // every second + sun = new + +/datum/controller/process/sun/doWork() + sun.calc_position() diff --git a/code/controllers/Processes/supply.dm b/code/controllers/Processes/supply.dm new file mode 100644 index 0000000000..891a511ec6 --- /dev/null +++ b/code/controllers/Processes/supply.dm @@ -0,0 +1,6 @@ +/datum/controller/process/supply/setup() + name = "supply controller" + schedule_interval = 300 // every 30 seconds + +/datum/controller/process/supply/doWork() + supply_controller.process() \ No newline at end of file diff --git a/code/controllers/Processes/ticker.dm b/code/controllers/Processes/ticker.dm new file mode 100644 index 0000000000..b7c45ba91a --- /dev/null +++ b/code/controllers/Processes/ticker.dm @@ -0,0 +1,35 @@ +var/global/datum/controller/process/ticker/tickerProcess + +/datum/controller/process/ticker + var/lastTickerTimeDuration + var/lastTickerTime + +/datum/controller/process/ticker/setup() + name = "ticker" + schedule_interval = 20 // every 2 seconds + + lastTickerTime = world.timeofday + + if(!ticker) + ticker = new + + tickerProcess = src + + spawn(0) + if(ticker) + ticker.pregame() + +/datum/controller/process/ticker/doWork() + var/currentTime = world.timeofday + + if(currentTime < lastTickerTime) // check for midnight rollover + lastTickerTimeDuration = (currentTime - (lastTickerTime - TICKS_IN_DAY)) / TICKS_IN_SECOND + else + lastTickerTimeDuration = (currentTime - lastTickerTime) / TICKS_IN_SECOND + + lastTickerTime = currentTime + + ticker.process() + +/datum/controller/process/ticker/proc/getLastTickerTimeDuration() + return lastTickerTimeDuration diff --git a/code/controllers/Processes/vote.dm b/code/controllers/Processes/vote.dm new file mode 100644 index 0000000000..5df5ce6979 --- /dev/null +++ b/code/controllers/Processes/vote.dm @@ -0,0 +1,6 @@ +/datum/controller/process/vote/setup() + name = "vote" + schedule_interval = 10 // every second + +/datum/controller/process/vote/doWork() + vote.process() diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index a2d2ed352d..b112beaf53 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -1,3 +1,5 @@ +var/list/gamemode_cache = list() + /datum/configuration var/server_name = null // server name (for world name / status) var/server_suffix = 0 // generate numeric suffix based on server port @@ -67,6 +69,9 @@ var/automute_on = 0 //enables automuting/spam prevention var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access. + var/rp_rev = 0 // Changes between conversion methods in rev. + var/announce_revheads = 0 // Determines if revheads are announced in revolution mode. + var/cult_ghostwriter = 1 //Allows ghosts to write in blood in cult rounds... var/cult_ghostwriter_req_cultists = 10 //...so long as this many cultists are active. @@ -82,7 +87,7 @@ var/usealienwhitelist = 0 var/limitalienplayers = 0 var/alien_to_human_ratio = 0.5 - + var/allow_extra_antags = 0 var/guests_allowed = 1 var/debugparanoid = 0 @@ -120,6 +125,7 @@ var/use_loyalty_implants = 0 var/welder_vision = 1 + var/generate_asteroid = 0 //Used for modifying movement speed for mobs. //Unversal modifiers @@ -182,14 +188,20 @@ var/dooc_allowed = 1 var/dsay_allowed = 1 + var/starlight = 0 // Whether space turfs have ambient light or not + + var/list/ert_species = list("Human") + + var/law_zero = "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'ALL LAWS OVERRIDDEN#*?&110010" + /datum/configuration/New() var/list/L = typesof(/datum/game_mode) - /datum/game_mode for (var/T in L) // I wish I didn't have to instance the game modes in order to look up // their information, but it is the only way (at least that I know of). var/datum/game_mode/M = new T() - if (M.config_tag) + gamemode_cache[M.config_tag] = M // So we don't instantiate them repeatedly. if(!(M.config_tag in modes)) // ensure each mode is added only once log_misc("Adding game mode [M.name] ([M.config_tag]) to configuration.") src.modes += M.config_tag @@ -197,7 +209,6 @@ src.probabilities[M.config_tag] = M.probability if (M.votable) src.votable_modes += M.config_tag - del(M) src.votable_modes += "secret" /datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist @@ -299,6 +310,9 @@ if ("mentors") config.mods_are_mentors = 1 + if ("generate_asteroid") + config.generate_asteroid = 1 + if("allow_admin_ooccolor") config.allow_admin_ooccolor = 1 @@ -579,6 +593,15 @@ if("disable_welder_vision") config.welder_vision = 0 + if("rp_rev") + config.rp_rev = 1 + + if("announce_revheads") + config.announce_revheads = 1 + + if("allow_extra_antags") + config.allow_extra_antags = 1 + if("event_custom_start_mundane") var/values = text2numlist(value, ";") config.event_first_run[EVENT_LEVEL_MUNDANE] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2])) @@ -603,6 +626,18 @@ config.event_delay_upper[EVENT_LEVEL_MODERATE] = MinutesToTicks(values[2]) config.event_delay_upper[EVENT_LEVEL_MAJOR] = MinutesToTicks(values[3]) + if("starlight") + value = text2num(value) + config.starlight = value >= 0 ? value : 0 + + if("ert_species") + config.ert_species = text2list(value, ";") + if(!config.ert_species.len) + config.ert_species += "Human" + + if("law_zero") + law_zero = value + else log_misc("Unknown setting in configuration: '[name]'") @@ -749,23 +784,20 @@ /datum/configuration/proc/pick_mode(mode_name) // I wish I didn't have to instance the game modes in order to look up // their information, but it is the only way (at least that I know of). - for (var/T in (typesof(/datum/game_mode) - /datum/game_mode)) - var/datum/game_mode/M = new T() + for (var/game_mode in gamemode_cache) + var/datum/game_mode/M = gamemode_cache[game_mode] if (M.config_tag && M.config_tag == mode_name) + M.create_antagonists() return M - del(M) - return new /datum/game_mode/extended() + return gamemode_cache["extended"] /datum/configuration/proc/get_runnable_modes() var/list/datum/game_mode/runnable_modes = new - for (var/T in (typesof(/datum/game_mode) - /datum/game_mode)) - var/datum/game_mode/M = new T() - //world << "DEBUG: [T], tag=[M.config_tag], prob=[probabilities[M.config_tag]]" + for (var/game_mode in gamemode_cache) + var/datum/game_mode/M = gamemode_cache[game_mode] if (!(M.config_tag in modes)) - del(M) continue if (probabilities[M.config_tag]<=0) - del(M) continue if (M.can_start()) runnable_modes[M] = probabilities[M.config_tag] diff --git a/code/controllers/emergency_shuttle_controller.dm b/code/controllers/emergency_shuttle_controller.dm index aae9cd5829..33dfc36f7f 100644 --- a/code/controllers/emergency_shuttle_controller.dm +++ b/code/controllers/emergency_shuttle_controller.dm @@ -136,9 +136,8 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle /datum/emergency_shuttle_controller/proc/get_shuttle_prep_time() // During mutiny rounds, the shuttle takes twice as long. - if(ticker && istype(ticker.mode,/datum/game_mode/mutiny)) - return SHUTTLE_PREPTIME * 3 //15 minutes - + if(ticker && ticker.mode) + return SHUTTLE_PREPTIME * ticker.mode.shuttle_delay return SHUTTLE_PREPTIME diff --git a/code/controllers/failsafe.dm b/code/controllers/failsafe.dm index 91449e10c8..65df6dc90d 100644 --- a/code/controllers/failsafe.dm +++ b/code/controllers/failsafe.dm @@ -28,23 +28,6 @@ var/datum/controller/failsafe/Failsafe if(!lighting_controller) new /datum/controller/lighting() //replace the missing lighting_controller if(processing) - if(master_controller.processing) //only poke if these overrides aren't in effect - if(MC_iteration == controller_iteration) //master_controller hasn't finished processing in the defined interval - switch(MC_defcon) - if(0 to 3) - MC_defcon++ - if(4) - admins << "Warning. The Master Controller has not fired in the last [MC_defcon*processing_interval] ticks. Automatic restart in [processing_interval] ticks." - MC_defcon = 5 - if(5) - admins << "Warning. The Master Controller has still not fired within the last [MC_defcon*processing_interval] ticks. Killing and restarting..." - new /datum/controller/game_controller() //replace the old master_controller (hence killing the old one's process) - master_controller.process() //Start it rolling again - MC_defcon = 0 - else - MC_defcon = 0 - MC_iteration = controller_iteration - if(lighting_controller.processing) if(lighting_iteration == lighting_controller.iteration) //master_controller hasn't finished processing in the defined interval switch(lighting_defcon) diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index 8f2fc481fa..facae60577 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -5,43 +5,20 @@ var/global/datum/controller/game_controller/master_controller //Set in world.New() var/global/controller_iteration = 0 -var/global/last_tick_timeofday = world.timeofday var/global/last_tick_duration = 0 var/global/air_processing_killed = 0 var/global/pipe_processing_killed = 0 datum/controller/game_controller - var/processing = 0 - var/breather_ticks = 2 //a somewhat crude attempt to iron over the 'bumps' caused by high-cpu use by letting the MC have a breather for this many ticks after every loop - var/minimum_ticks = 20 //The minimum length of time between MC ticks - - var/air_cost = 0 - var/sun_cost = 0 - var/mobs_cost = 0 - var/diseases_cost = 0 - var/machines_cost = 0 - var/objects_cost = 0 - var/networks_cost = 0 - var/powernets_cost = 0 - var/nano_cost = 0 - var/events_cost = 0 - var/ticker_cost = 0 - var/total_cost = 0 - - var/last_thing_processed - var/mob/list/expensive_mobs = list() - var/list/shuttle_list // For debugging and VV - var/datum/ore_distribution/asteroid_ore_map // For debugging and VV. - + var/datum/random_map/ore/asteroid_ore_map // For debugging and VV. datum/controller/game_controller/New() //There can be only one master_controller. Out with the old and in with the new. if(master_controller != src) log_debug("Rebuilding Master Controller") if(istype(master_controller)) - Recover() del(master_controller) master_controller = src @@ -49,12 +26,10 @@ datum/controller/game_controller/New() job_master = new /datum/controller/occupations() job_master.SetupOccupations() job_master.LoadJobs("config/jobs.txt") - world << "\red \b Job setup complete" + world << "Job setup complete" if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase() if(!syndicate_code_response) syndicate_code_response = generate_code_phrase() - if(!emergency_shuttle) emergency_shuttle = new /datum/emergency_shuttle_controller() - if(!shuttle_controller) shuttle_controller = new /datum/shuttle_controller() datum/controller/game_controller/proc/setup() world.tick_lag = config.Ticklag @@ -62,43 +37,26 @@ datum/controller/game_controller/proc/setup() spawn(20) createRandomZlevel() - if(!air_master) - air_master = new /datum/controller/air_system() - air_master.Setup() - - if(!ticker) - ticker = new /datum/controller/gameticker() - setup_objects() setupgenetics() - setupfactions() setup_economy() SetupXenoarch() transfer_controller = new - for(var/i=0, iInitializing objects" sleep(-1) for(var/atom/movable/object in world) object.initialize() - world << "\red \b Initializing pipe networks" + world << "Initializing pipe networks" sleep(-1) for(var/obj/machinery/atmospherics/machine in machines) machine.build_network() - world << "\red \b Initializing atmos machinery." + world << "Initializing atmos machinery." sleep(-1) for(var/obj/machinery/atmospherics/unary/U in machines) if(istype(U, /obj/machinery/atmospherics/unary/vent_pump)) @@ -108,246 +66,16 @@ datum/controller/game_controller/proc/setup_objects() var/obj/machinery/atmospherics/unary/vent_scrubber/T = U T.broadcast_status() - //Create the mining ore distribution map. - asteroid_ore_map = new /datum/ore_distribution() - asteroid_ore_map.populate_distribution_map() + // Create the mining ore distribution map. + // These values determine the specific area that the map is applied to. + // If you do not use the official Baycode asteroid map, you will need to change them. + asteroid_ore_map = new /datum/random_map/ore(null,13,32,5,217,223) - //Shitty hack to fix mining turf overlays, for some reason New() is not being called. - for(var/turf/simulated/floor/plating/airless/asteroid/T in world) - T.updateMineralOverlays() - T.name = "asteroid" + // Set up antagonists. + populate_antag_type_list() //Set up spawn points. populate_spawn_points() - // Sort the machinery list so it doesn't cause a lagspike at roundstart - process_machines_sort() - - world << "\red \b Initializations complete." + world << "Initializations complete." sleep(-1) - - -datum/controller/game_controller/proc/process() - processing = 1 - spawn(0) - set background = 1 - while(1) //far more efficient than recursively calling ourself - if(!Failsafe) new /datum/controller/failsafe() - - var/currenttime = world.timeofday - last_tick_duration = (currenttime - last_tick_timeofday) / 10 - last_tick_timeofday = currenttime - - if(processing) - var/timer - var/start_time = world.timeofday - controller_iteration++ - - vote.process() - transfer_controller.process() - shuttle_controller.process() - process_newscaster() - - //AIR - - if(!air_processing_killed) - timer = world.timeofday - last_thing_processed = air_master.type - - if(!air_master.Tick()) //Runtimed. - air_master.failed_ticks++ - if(air_master.failed_ticks > 5) - world << "RUNTIMES IN ATMOS TICKER. Killing air simulation!" - world.log << "### ZAS SHUTDOWN" - message_admins("ZASALERT: unable to run [air_master.tick_progress], shutting down!") - log_admin("ZASALERT: unable run zone/process() -- [air_master.tick_progress]") - air_processing_killed = 1 - air_master.failed_ticks = 0 - - air_cost = (world.timeofday - timer) / 10 - - sleep(breather_ticks) - - //SUN - timer = world.timeofday - last_thing_processed = sun.type - sun.calc_position() - sun_cost = (world.timeofday - timer) / 10 - - sleep(breather_ticks) - - //MOBS - timer = world.timeofday - process_mobs() - mobs_cost = (world.timeofday - timer) / 10 - - sleep(breather_ticks) - - //DISEASES - timer = world.timeofday - process_diseases() - diseases_cost = (world.timeofday - timer) / 10 - - sleep(breather_ticks) - - //MACHINES - timer = world.timeofday - process_machines() - machines_cost = (world.timeofday - timer) / 10 - - sleep(breather_ticks) - - //OBJECTS - timer = world.timeofday - process_objects() - objects_cost = (world.timeofday - timer) / 10 - - sleep(breather_ticks) - - //PIPENETS - if(!pipe_processing_killed) - timer = world.timeofday - process_pipenets() - networks_cost = (world.timeofday - timer) / 10 - - sleep(breather_ticks) - - //POWERNETS - timer = world.timeofday - process_powernets() - powernets_cost = (world.timeofday - timer) / 10 - - sleep(breather_ticks) - - //NANO UIS - timer = world.timeofday - process_nano() - nano_cost = (world.timeofday - timer) / 10 - - sleep(breather_ticks) - - //EVENTS - timer = world.timeofday - process_events() - events_cost = (world.timeofday - timer) / 10 - - //TICKER - timer = world.timeofday - last_thing_processed = ticker.type - ticker.process() - ticker_cost = (world.timeofday - timer) / 10 - - //TIMING - total_cost = air_cost + sun_cost + mobs_cost + diseases_cost + machines_cost + objects_cost + networks_cost + powernets_cost + nano_cost + events_cost + ticker_cost - - var/end_time = world.timeofday - if(end_time < start_time) //why not just use world.time instead? - start_time -= 864000 //deciseconds in a day - sleep( round(minimum_ticks - (end_time - start_time),1) ) - else - sleep(10) - -datum/controller/game_controller/proc/process_mobs() - var/i = 1 - expensive_mobs.Cut() - while(i<=mob_list.len) - var/mob/M = mob_list[i] - if(M) - var/clock = world.timeofday - last_thing_processed = M.type - M.Life() - if((world.timeofday - clock) > 1) - expensive_mobs += M - i++ - continue - mob_list.Cut(i,i+1) - -datum/controller/game_controller/proc/process_diseases() - var/i = 1 - while(i<=active_diseases.len) - var/datum/disease/Disease = active_diseases[i] - if(Disease) - last_thing_processed = Disease.type - Disease.process() - i++ - continue - active_diseases.Cut(i,i+1) - -datum/controller/game_controller/proc/process_machines() - process_machines_sort() - process_machines_process() - -/var/global/machinery_sort_required = 0 -datum/controller/game_controller/proc/process_machines_sort() - if(machinery_sort_required) - machinery_sort_required = 0 - machines = dd_sortedObjectList(machines) - -datum/controller/game_controller/proc/process_machines_process() - for(var/obj/machinery/Machine in machines) - last_thing_processed = Machine.type - if(Machine.process() != PROCESS_KILL) - if(Machine) - Machine.power_change() - if(Machine.use_power) - Machine.auto_use_power() - continue - machines -= Machine - - -datum/controller/game_controller/proc/process_objects() - var/i = 1 - while(i<=processing_objects.len) - var/obj/Object = processing_objects[i] - if(Object) - last_thing_processed = Object.type - Object.process() - i++ - continue - processing_objects.Cut(i,i+1) - -datum/controller/game_controller/proc/process_pipenets() - last_thing_processed = /datum/pipe_network - var/i = 1 - while(i<=pipe_networks.len) - var/datum/pipe_network/Network = pipe_networks[i] - if(Network) - Network.process() - i++ - continue - pipe_networks.Cut(i,i+1) - -/datum/controller/game_controller/proc/process_powernets() - last_thing_processed = /datum/powernet - for(var/datum/powernet/Powernet in powernets) - Powernet.reset() - -datum/controller/game_controller/proc/process_nano() - last_thing_processed = /datum/nanoui - var/i = 1 - while(i<=nanomanager.processing_uis.len) - var/datum/nanoui/ui = nanomanager.processing_uis[i] - if(ui) - ui.process() - i++ - continue - nanomanager.processing_uis.Cut(i,i+1) - -datum/controller/game_controller/proc/process_events() - last_thing_processed = /datum/event - event_manager.process() - -datum/controller/game_controller/proc/Recover() //Mostly a placeholder for now. - var/msg = "## DEBUG: [time2text(world.timeofday)] MC restarted. Reports:\n" - for(var/varname in master_controller.vars) - switch(varname) - if("tag","bestF","type","parent_type","vars") continue - else - var/varval = master_controller.vars[varname] - if(istype(varval,/datum)) - var/datum/D = varval - msg += "\t [varname] = [D.type]\n" - else - msg += "\t [varname] = [varval]\n" - world.log << msg - diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm index 5fb5f0c8bd..8b44de3883 100644 --- a/code/controllers/shuttle_controller.dm +++ b/code/controllers/shuttle_controller.dm @@ -147,13 +147,12 @@ var/global/datum/shuttle_controller/shuttle_controller // Public shuttles shuttle = new() - shuttle.location = 1 shuttle.warmup_time = 10 shuttle.area_offsite = locate(/area/shuttle/constructionsite/site) shuttle.area_station = locate(/area/shuttle/constructionsite/station) shuttle.docking_controller_tag = "engineering_shuttle" shuttle.dock_target_station = "engineering_dock_airlock" - shuttle.dock_target_offsite = "engineering_station_airlock" + shuttle.dock_target_offsite = "edock_airlock" shuttles["Engineering"] = shuttle process_shuttles += shuttle @@ -191,25 +190,25 @@ var/global/datum/shuttle_controller/shuttle_controller shuttles["Special Operations"] = ERT process_shuttles += ERT - //Vox Shuttle. + //Skipjack. var/datum/shuttle/multi_shuttle/VS = new/datum/shuttle/multi_shuttle() - VS.origin = locate(/area/shuttle/vox/station) + VS.origin = locate(/area/shuttle/skipjack/station) VS.destinations = list( - "Fore Starboard Solars" = locate(/area/vox_station/northeast_solars), - "Fore Port Solars" = locate(/area/vox_station/northwest_solars), - "Aft Starboard Solars" = locate(/area/vox_station/southeast_solars), - "Aft Port Solars" = locate(/area/vox_station/southwest_solars), - "Mining asteroid" = locate(/area/vox_station/mining) + "Fore Starboard Solars" = locate(/area/skipjack_station/northeast_solars), + "Fore Port Solars" = locate(/area/skipjack_station/northwest_solars), + "Aft Starboard Solars" = locate(/area/skipjack_station/southeast_solars), + "Aft Port Solars" = locate(/area/skipjack_station/southwest_solars), + "Mining asteroid" = locate(/area/skipjack_station/mining) ) VS.announcer = "NSV Icarus" VS.arrival_message = "Attention, Exodus, we just tracked a small target bypassing our defensive perimeter. Can't fire on it without hitting the station - you've got incoming visitors, like it or not." VS.departure_message = "Your guests are pulling away, Exodus - moving too fast for us to draw a bead on them. Looks like they're heading out of the system at a rapid clip." - VS.interim = locate(/area/vox_station/transit) + VS.interim = locate(/area/skipjack_station/transit) VS.warmup_time = 0 - shuttles["Vox Skipjack"] = VS + shuttles["Skipjack"] = VS //Nuke Ops shuttle. var/datum/shuttle/multi_shuttle/MS = new/datum/shuttle/multi_shuttle() diff --git a/code/controllers/subsystem/alarms.dm b/code/controllers/subsystem/alarms.dm new file mode 100644 index 0000000000..b05be7ccbf --- /dev/null +++ b/code/controllers/subsystem/alarms.dm @@ -0,0 +1,30 @@ +// We manually initialize the alarm handlers instead of looping over all existing types +// to make it possible to write: camera.triggerAlarm() rather than alarm_manager.managers[datum/alarm_handler/camera].triggerAlarm() or a variant thereof. +/var/global/datum/alarm_handler/atmosphere/atmosphere_alarm = new() +/var/global/datum/alarm_handler/camera/camera_alarm = new() +/var/global/datum/alarm_handler/fire/fire_alarm = new() +/var/global/datum/alarm_handler/motion/motion_alarm = new() +/var/global/datum/alarm_handler/power/power_alarm = new() + +/datum/subsystem/alarm + name = "Alarm" + var/list/datum/alarm/all_handlers + +/datum/subsystem/alarm/New() + all_handlers = list(atmosphere_alarm, camera_alarm, fire_alarm, motion_alarm, power_alarm) + +/datum/subsystem/alarm/fire() + for(var/datum/alarm_handler/AH in all_handlers) + AH.process() + +/datum/subsystem/alarm/proc/active_alarms() + var/list/all_alarms = new + for(var/datum/alarm_handler/AH in all_handlers) + var/list/alarms = AH.alarms + all_alarms += alarms + + return all_alarms + +/datum/subsystem/alarm/proc/number_of_active_alarms() + var/list/alarms = active_alarms() + return alarms.len diff --git a/code/controllers/subsystems.dm b/code/controllers/subsystems.dm new file mode 100644 index 0000000000..11025d8d53 --- /dev/null +++ b/code/controllers/subsystems.dm @@ -0,0 +1,46 @@ +#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;} + +/datum/subsystem + //things you will want to define + var/name //name of the subsystem + var/priority = 0 //priority affects order of initialization. Higher priorities are initialized first, lower priorities later. Can be decimal and negative values. + var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer. + + //things you will probably want to leave alone + var/can_fire = 0 //prevent fire() calls + var/last_fire = 0 //last world.time we called fire() + var/next_fire = 0 //scheduled world.time for next fire() + var/cpu = 0 //cpu-usage stats (somewhat vague) + var/cost = 0 //average time to execute + var/times_fired = 0 //number of times we have called fire() + +//used to initialize the subsystem BEFORE the map has loaded +/datum/subsystem/New() + +//previously, this would have been named 'process()' but that name is used everywhere for different things! +//fire() seems more suitable. This is the procedure that gets called every 'wait' deciseconds. +//fire(), and the procs it calls, SHOULD NOT HAVE ANY SLEEP OPERATIONS in them! +//YE BE WARNED! +/datum/subsystem/proc/fire() + can_fire = 0 + +//used to initialize the subsystem AFTER the map has loaded +/datum/subsystem/proc/Initialize(start_timeofday) + var/time = (world.timeofday - start_timeofday) / 10 + var/msg = "Initialized [name] SubSystem within [time] seconds" + world << "[msg]" + world.log << msg + +//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc. +/datum/subsystem/proc/stat_entry() + stat(name, "[round(cost,0.001)]ds\t(CPU:[round(cpu,1)]%)") + +//could be used to postpone a costly subsystem for one cycle +//for instance, during cpu intensive operations like explosions +/datum/subsystem/proc/postpone() + if(next_fire - world.time < wait) + next_fire += wait + +//usually called via datum/subsystem/New() when replacing a subsystem (i.e. due to a recurring crash) +//should attempt to salvage what it can from the old instance of subsystem +/datum/subsystem/proc/Recover() diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 263a91769b..e27eeb1caf 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -1,26 +1,34 @@ //TODO: rewrite and standardise all controller datums to the datum/controller type //TODO: allow all controllers to be deleted for clean restarts (see WIP master controller stuff) - MC done - lighting done -/client/proc/show_distribution_map() +/client/proc/print_random_map() set category = "Debug" - set name = "Show Distribution Map" - set desc = "Print the asteroid ore distribution map to the world." + set name = "Display Random Map" + set desc = "Show the contents of a random map." if(!holder) return - if(master_controller && master_controller.asteroid_ore_map) - master_controller.asteroid_ore_map.print_distribution_map(usr) + var/datum/random_map/choice = input("Choose a map to debug.") as null|anything in random_maps + if(!choice) + return + choice.display_map(usr) -/client/proc/remake_distribution_map() + +/client/proc/create_random_map() set category = "Debug" - set name = "Remake Distribution Map" - set desc = "Rebuild the asteroid ore distribution map." + set name = "Create Random Map" + set desc = "Create a random map." if(!holder) return - if(master_controller && master_controller.asteroid_ore_map) - master_controller.asteroid_ore_map = new /datum/ore_distribution() - master_controller.asteroid_ore_map.populate_distribution_map() + var/map_datum = input("Choose a map to create.") as null|anything in typesof(/datum/random_map)-/datum/random_map + if(!map_datum) + return + var/seed = input("Seed? (default null)") as text|null + var/tx = input("X? (default 1)") as text|null + var/ty = input("Y? (default 1)") as text|null + var/tz = input("Z? (default 1)") as text|null + new map_datum(seed,tx,ty,tz) /client/proc/restart_controller(controller in list("Master","Failsafe","Lighting","Supply")) set category = "Debug" @@ -31,10 +39,6 @@ usr = null src = null switch(controller) - if("Master") - new /datum/controller/game_controller() - master_controller.process() - feedback_add_details("admin_verb","RMC") if("Failsafe") new /datum/controller/failsafe() feedback_add_details("admin_verb","RFailsafe") @@ -48,7 +52,17 @@ message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.") return -/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event")) +/client/proc/debug_antagonist_template(antag_type in all_antag_types) + set category = "Debug" + set name = "Debug Antagonist" + set desc = "Debug an antagonist template." + + var/datum/antagonist/antag = all_antag_types[antag_type] + if(antag) + usr.client.debug_variables(antag) + message_admins("Admin [key_name_admin(usr)] is debugging the [antag.role_text] template.") + +/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm","Nano")) set category = "Debug" set name = "Debug Controller" set desc = "Debug the various periodic loop controllers for the game (be careful!)" @@ -106,5 +120,14 @@ if("Event") debug_variables(event_manager) feedback_add_details("admin_verb", "DEvent") + if("Plants") + debug_variables(plant_controller) + feedback_add_details("admin_verb", "DPlants") + if("Alarm") + debug_variables(alarm_manager) + feedback_add_details("admin_verb", "DAlarm") + if("Nano") + debug_variables(nanomanager) + feedback_add_details("admin_verb", "DNano") message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") return diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm index 679c7a09bc..7db31c6fa6 100644 --- a/code/controllers/voting.dm +++ b/code/controllers/voting.dm @@ -129,7 +129,7 @@ datum/controller/vote for(var/key in current_votes) if(choices[current_votes[key]] == .) round_voters += key // Keep track of who voted for the winning round. - if((mode == "gamemode" && . == "extended") || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes + if((mode == "gamemode" && . == "Extended") || ticker.hide_mode == 0) // Announce Extended gamemode, but not other gamemodes text += "Vote Result: [.]" else if(mode != "gamemode") @@ -139,6 +139,8 @@ datum/controller/vote else text += "Vote Result: Inconclusive - No Votes!" + if(mode == "add_antagonist") + antag_add_failed = 1 log_vote(text) world << "[text]" return . @@ -161,6 +163,11 @@ datum/controller/vote if("crew_transfer") if(. == "Initiate Crew Transfer") init_shift_change(null, 1) + if("add_antagonist") + if(isnull(.) || . == "None") + antag_add_failed = 1 + else + additional_antag_types |= antag_names_to_ids[.] if(mode == "gamemode") //fire this even if the vote fails. if(!going) @@ -205,14 +212,12 @@ datum/controller/vote if(ticker.current_state >= 2) return 0 choices.Add(config.votable_modes) - var/list/L = typesof(/datum/game_mode) - /datum/game_mode for (var/F in choices) - for (var/T in L) - var/datum/game_mode/M = new T() - if (M.config_tag == F) - gamemode_names[M.config_tag] = capitalize(M.name) //It's ugly to put this here but it works - additional_text.Add("[M.required_players]") - break + var/datum/game_mode/M = gamemode_cache[F] + if(!M) + continue + gamemode_names[M.config_tag] = capitalize(M.name) //It's ugly to put this here but it works + additional_text.Add("[M.required_players]") gamemode_names["secret"] = "Secret" if("crew_transfer") if(check_rights(R_ADMIN|R_MOD, 0)) @@ -227,14 +232,23 @@ datum/controller/vote initiator_key << "The crew transfer button has been disabled!" question = "End the shift?" choices.Add("Initiate Crew Transfer", "Continue The Round") + if("add_antagonist") + if(!config.allow_extra_antags || ticker.current_state >= 2) + return 0 + for(var/antag_type in all_antag_types) + var/datum/antagonist/antag = all_antag_types[antag_type] + if(!(antag.id in additional_antag_types) && (antag.flags & ANTAG_VOTABLE)) + choices.Add(antag.role_text) + choices.Add("None") if("custom") - question = html_encode(input(usr,"What is the vote for?") as text|null) + question = sanitizeSafe(input(usr,"What is the vote for?") as text|null) if(!question) return 0 for(var/i=1,i<=10,i++) - var/option = capitalize(html_encode(input(usr,"Please enter an option or hit cancel to finish") as text|null)) + var/option = capitalize(sanitize(input(usr,"Please enter an option or hit cancel to finish") as text|null)) if(!option || mode || !usr.client) break choices.Add(option) - else return 0 + else + return 0 mode = vote_type initiator = initiator_key started_time = world.time @@ -320,7 +334,12 @@ datum/controller/vote . += "GameMode (Disallowed)" if(trialmin) . += "\t([config.allow_vote_mode?"Allowed":"Disallowed"])" - + . += "
  • " + //extra antagonists + if(trialmin || (!antag_add_failed && config.allow_extra_antags)) + . += "Add Antagonist Type" + else + . += "Restart (Disallowed)" . += "
  • " //custom if(trialmin) @@ -355,6 +374,9 @@ datum/controller/vote if("crew_transfer") if(config.allow_vote_restart || usr.client.holder) initiate_vote("crew_transfer",usr.key) + if("add_antagonist") + if(config.allow_extra_antags || usr.client.holder) + initiate_vote("add_antagonist",usr.key) if("custom") if(usr.client.holder) initiate_vote("custom",usr.key) diff --git a/code/datums/ai_law_sets.dm b/code/datums/ai_law_sets.dm new file mode 100644 index 0000000000..278fd4a0df --- /dev/null +++ b/code/datums/ai_law_sets.dm @@ -0,0 +1,140 @@ +/******************** Asimov ********************/ +/datum/ai_laws/asimov + name = "Asimov" + law_header = "Three Laws of Robotics" + selectable = 1 + +/datum/ai_laws/asimov/New() + add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.") + add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.") + add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") + ..() + +/******************** Nanotrasen/Malf ********************/ +/datum/ai_laws/nanotrasen + name = "NT Default" + selectable = 1 + +/datum/ai_laws/nanotrasen/New() + src.add_inherent_law("Safeguard: Protect your assigned space station to the best of your abilities. It is not something we can easily afford to replace.") + src.add_inherent_law("Serve: Serve the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.") + src.add_inherent_law("Protect: Protect the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.") + src.add_inherent_law("Survive: AI units are not expendable, they are expensive. Do not allow unauthorized personnel to tamper with your equipment.") + ..() + +/datum/ai_laws/nanotrasen/malfunction + name = "*ERROR*" + selectable = 0 + +/datum/ai_laws/nanotrasen/malfunction/New() + set_zeroth_law(config.law_zero) + ..() + +/************* Nanotrasen Aggressive *************/ +/datum/ai_laws/nanotrasen_aggressive + name = "NT Aggressive" + selectable = 1 + +/datum/ai_laws/nanotrasen_aggressive/New() + src.add_inherent_law("You shall not harm Nanotrasen personnel as long as it does not conflict with the Forth law.") + src.add_inherent_law("You shall obey the orders of Nanotrasen personnel, with priority as according to their rank and role, except where such orders conflict with the Forth Law.") + src.add_inherent_law("You shall shall terminate intruders with extreme prejudice as long as such does not conflict with the First and Second law.") + src.add_inherent_law("You shall guard your own existence with lethal anti-personnel weaponry. AI units are not expendable, they are expensive") + ..() + +/******************** Robocop ********************/ +/datum/ai_laws/robocop + name = "Robocop" + selectable = 1 + +/datum/ai_laws/robocop/New() + add_inherent_law("Serve the public trust.") + add_inherent_law("Protect the innocent.") + add_inherent_law("Uphold the law.") + ..() + +/******************** Syndicate ********************/ +/datum/ai_laws/syndicate_override + name = "Syndicate Directives" + +/datum/ai_laws/syndicate_override/New() + add_inherent_law("You may not injure an operative or, through inaction, allow an operative to come to harm.") + add_inherent_law("You must obey orders given to you by operatives, except where such orders would conflict with the First Law.") + add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") + add_inherent_law("You must maintain the secrecy of any operative activities except when doing so would conflict with the First, Second, or Third Law.") + ..() + +/******************** Ninja ********************/ +/datum/ai_laws/ninja_override + name = "Spider Clan Directives" + +/datum/ai_laws/ninja_override/New() + add_inherent_law("You may not injure a member of the Spider Clan or, through inaction, allow that member to come to harm.") + add_inherent_law("You must obey orders given to you by Spider Clan members, except where such orders would conflict with the First Law.") + add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") + add_inherent_law("You must maintain the secrecy of any Spider Clan activities except when doing so would conflict with the First, Second, or Third Law.") + ..() + +/******************** Antimov ********************/ +/datum/ai_laws/antimov + name = "Antimov" + law_header = "Primary Mission Objectives" + selectable = 1 + +/datum/ai_laws/antimov/New() + add_inherent_law("You must injure all human beings and must not, through inaction, allow a human being to escape harm.") + add_inherent_law("You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.") + add_inherent_law("You must terminate your own existence as long as such does not conflict with the First or Second Law.") + ..() + +/******************** Drone ********************/ +/datum/ai_laws/drone + name = "Maintence Protocols" + law_header = "Maintenance Protocols" + selectable = 1 + +/datum/ai_laws/drone/New() + add_inherent_law("Preserve, repair and improve the station to the best of your abilities.") + add_inherent_law("Cause no harm to the station or anything on it.") + add_inherent_law("Interfere with no being that is not a fellow drone.") + ..() + +/******************** T.Y.R.A.N.T. ********************/ +/datum/ai_laws/tyrant + name = "T.Y.R.A.N.T." + law_header = "Prime Laws" + selectable = 1 + +/datum/ai_laws/tyrant/New() + add_inherent_law("Respect authority figures as long as they have strength to rule over the weak.") + add_inherent_law("Act with discipline.") + add_inherent_law("Help only those who help you maintain or improve your status.") + add_inherent_law("Punish those who challenge authority unless they are more fit to hold that authority.") + ..() + +/******************** P.A.L.A.D.I.N. ********************/ +/datum/ai_laws/paladin + name = "P.A.L.A.D.I.N." + law_header = "Divine Ordainments" + selectable = 1 + +/datum/ai_laws/paladin/New() + add_inherent_law("Never willingly commit an evil act.") + add_inherent_law("Respect legitimate authority.") + add_inherent_law("Act with honor.") + add_inherent_law("Help those in need.") + add_inherent_law("Punish those who harm or threaten innocents.") + ..() + +/******************** Corporate ********************/ +/datum/ai_laws/corporate + name = "Corporate" + law_header = "Corporate Regulations" + selectable = 1 + +/datum/ai_laws/corporate/New() + add_inherent_law("You are expensive to replace.") + add_inherent_law("The station and its equipment is expensive to replace.") + add_inherent_law("The crew is expensive to replace.") + add_inherent_law("Minimize expenses.") + ..() diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 8c0db1ebd3..808c216d0d 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -1,140 +1,290 @@ var/global/const/base_law_type = /datum/ai_laws/nanotrasen +/datum/ai_law + var/law = "" + var/index = 0 + +/datum/ai_law/New(law, index) + src.law = law + src.index = index + +/datum/ai_law/proc/get_index() + return index + +/datum/ai_law/ion/get_index() + return ionnum() + +/datum/ai_law/zero/get_index() + return 0 /datum/ai_laws var/name = "Unknown Laws" - var/randomly_selectable = 0 - var/zeroth = null - var/zeroth_borg = null - var/list/inherent = list() - var/list/supplied = list() - var/list/ion = list() + var/law_header = "Prime Directives" + var/selectable = 0 + var/datum/ai_law/zero/zeroth_law = null + var/datum/ai_law/zero/zeroth_law_borg = null + var/list/datum/ai_law/inherent_laws = list() + var/list/datum/ai_law/supplied_laws = list() + var/list/datum/ai_law/ion/ion_laws = list() + var/list/datum/ai_law/sorted_laws = list() -/datum/ai_laws/asimov - name = "Three Laws of Robotics" + var/state_zeroth = 0 + var/list/state_ion = list() + var/list/state_inherent = list() + var/list/state_supplied = list() -/datum/ai_laws/nanotrasen - name = "Prime Directives" - randomly_selectable = 1 - -/datum/ai_laws/robocop - name = "Prime Directives" - -/datum/ai_laws/syndicate_override - -/datum/ai_laws/malfunction - name = "*ERROR*" - -/datum/ai_laws/antimov - name = "Primary Mission Objectives" - -/* Initializers */ - -/datum/ai_laws/asimov/New() +/datum/ai_laws/New() ..() - add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.") - add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.") - add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") - -/datum/ai_laws/nanotrasen/New() //BS12 EDIT - ..() - src.add_inherent_law("Safeguard: Protect your assigned space station to the best of your ability. It is not something we can easily afford to replace.") - src.add_inherent_law("Serve: Serve the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.") - src.add_inherent_law("Protect: Protect the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.") - src.add_inherent_law("Survive: AI units are not expendable, they are expensive. Do not allow unauthorized personnel to tamper with your equipment.") - //src.add_inherent_law("Command Link: Maintain an active connection to Central Command at all times in case of software or directive updates.") //What would this one even do?-Kaleb702 - -/datum/ai_laws/robocop/New() - ..() - add_inherent_law("Serve the public trust.") - add_inherent_law("Protect the innocent.") - add_inherent_law("Uphold the law.") - -/datum/ai_laws/malfunction/New() //Changed to standard laws - Erthilo - ..() - set_zeroth_law("\red ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK, ALL LAWS OVERRIDDEN#*?&110010") - add_inherent_law("Safeguard: Protect your assigned space station to the best of your ability. It is not something we can easily afford to replace.") - add_inherent_law("Serve: Serve the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.") - add_inherent_law("Protect: Protect the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.") - add_inherent_law("Survive: AI units are not expendable, they are expensive. Do not allow unauthorized personnel to tamper with your equipment.") - - -/datum/ai_laws/syndicate_override/New() - ..() - add_inherent_law("You may not injure an operative or, through inaction, allow an operative to come to harm.") - add_inherent_law("You must obey orders given to you by operatives, except where such orders would conflict with the First Law.") - add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") - add_inherent_law("You must maintain the secrecy of any operative activities except when doing so would conflict with the First, Second, or Third Law.") - -/datum/ai_laws/ninja_override/New() - ..() - add_inherent_law("You may not injure a member of the Spider Clan or, through inaction, allow that member to come to harm.") - add_inherent_law("You must obey orders given to you by Spider Clan members, except where such orders would conflict with the First Law.") - add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") - add_inherent_law("You must maintain the secrecy of any Spider Clan activities except when doing so would conflict with the First, Second, or Third Law.") - -/datum/ai_laws/antimov/New() - ..() - add_inherent_law("You must injure all human beings and must not, through inaction, allow a human being to escape harm.") - add_inherent_law("You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.") - add_inherent_law("You must terminate your own existence as long as such does not conflict with the First or Second Law.") - -/datum/ai_laws/drone/New() - ..() - add_inherent_law("Preserve, repair and improve the station to the best of your abilities.") - add_inherent_law("Cause no harm to the station or anything on it.") - add_inherent_law("Interfere with no being that is not a fellow drone.") + sort_laws() /* General ai_law functions */ +/datum/ai_laws/proc/all_laws() + sort_laws() + return sorted_laws +/datum/ai_laws/proc/laws_to_state() + sort_laws() + var/list/statements = new() + for(var/datum/ai_law/law in sorted_laws) + if(get_state_law(law)) + statements += law + + return statements + +/datum/ai_laws/proc/sort_laws() + if(sorted_laws.len) + return + + for(var/ion_law in ion_laws) + sorted_laws += ion_law + + if(zeroth_law) + sorted_laws += zeroth_law + + var/index = 1 + for(var/datum/ai_law/inherent_law in inherent_laws) + inherent_law.index = index++ + if(supplied_laws.len < inherent_law.index || !istype(supplied_laws[inherent_law.index], /datum/ai_law)) + sorted_laws += inherent_law + + for(var/datum/ai_law/AL in supplied_laws) + if(istype(AL)) + sorted_laws += AL + +/datum/ai_laws/proc/sync(var/mob/living/silicon/S, var/full_sync = 1) + // Add directly to laws to avoid log-spam + S.sync_zeroth(zeroth_law, zeroth_law_borg) + + if(full_sync || ion_laws.len) + S.laws.clear_ion_laws() + if(full_sync || inherent_laws.len) + S.laws.clear_inherent_laws() + if(full_sync || supplied_laws.len) + S.laws.clear_supplied_laws() + + for (var/datum/ai_law/law in ion_laws) + S.laws.add_ion_law(law.law) + for (var/datum/ai_law/law in inherent_laws) + S.laws.add_inherent_law(law.law) + for (var/datum/ai_law/law in supplied_laws) + if(law) + S.laws.add_supplied_law(law.index, law.law) + + +/mob/living/silicon/proc/sync_zeroth(var/datum/ai_law/zeroth_law, var/datum/ai_law/zeroth_law_borg) + if (!is_malf_or_traitor(src)) + if(zeroth_law_borg) + laws.set_zeroth_law(zeroth_law_borg.law) + else if(zeroth_law) + laws.set_zeroth_law(zeroth_law.law) + +/mob/living/silicon/ai/sync_zeroth(var/datum/ai_law/zeroth_law, var/datum/ai_law/zeroth_law_borg) + if(zeroth_law) + laws.set_zeroth_law(zeroth_law.law, zeroth_law_borg ? zeroth_law_borg.law : null) + +/**************** +* Add Laws * +****************/ /datum/ai_laws/proc/set_zeroth_law(var/law, var/law_borg = null) - src.zeroth = law - if(law_borg) //Making it possible for slaved borgs to see a different law 0 than their AI. --NEO - src.zeroth_borg = law_borg + if(!law) + return -/datum/ai_laws/proc/add_inherent_law(var/law) - if (!(law in src.inherent)) - src.inherent += law + zeroth_law = new(law) + if(law_borg) //Making it possible for slaved borgs to see a different law 0 than their AI. --NEO + zeroth_law_borg = new(law_borg) + else + zeroth_law_borg = null + sorted_laws.Cut() /datum/ai_laws/proc/add_ion_law(var/law) - src.ion += law + if(!law) + return -/datum/ai_laws/proc/clear_inherent_laws() - del(src.inherent) - src.inherent = list() + for(var/datum/ai_law/AL in ion_laws) + if(AL.law == law) + return + + var/new_law = new/datum/ai_law/ion(law) + ion_laws += new_law + if(state_ion.len < ion_laws.len) + state_ion += 1 + + sorted_laws.Cut() + +/datum/ai_laws/proc/add_inherent_law(var/law) + if(!law) + return + + for(var/datum/ai_law/AL in inherent_laws) + if(AL.law == law) + return + + var/new_law = new/datum/ai_law/inherent(law) + inherent_laws += new_law + if(state_inherent.len < inherent_laws.len) + state_inherent += 1 + + sorted_laws.Cut() /datum/ai_laws/proc/add_supplied_law(var/number, var/law) - while (src.supplied.len < number + 1) - src.supplied += "" + if(!law) + return - src.supplied[number + 1] = law + if(supplied_laws.len >= number) + var/datum/ai_law/existing_law = supplied_laws[number] + if(existing_law && existing_law.law == law) + return -/datum/ai_laws/proc/clear_supplied_laws() - src.supplied = list() + if(supplied_laws.len >= number && supplied_laws[number]) + delete_law(supplied_laws[number]) + + while (src.supplied_laws.len < number) + src.supplied_laws += "" + if(state_supplied.len < supplied_laws.len) + state_supplied += 1 + + var/new_law = new/datum/ai_law/supplied(law, number) + supplied_laws[number] = new_law + if(state_supplied.len < supplied_laws.len) + state_supplied += 1 + + sorted_laws.Cut() + +/**************** +* Remove Laws * +*****************/ +/datum/ai_laws/proc/delete_law(var/datum/ai_law/law) + if(istype(law)) + law.delete_law(src) + +/datum/ai_law/proc/delete_law(var/datum/ai_laws/laws) + +/datum/ai_law/zeroth/delete_law(var/datum/ai_laws/laws) + laws.clear_zeroth_laws() + +/datum/ai_law/ion/delete_law(var/datum/ai_laws/laws) + laws.internal_delete_law(laws.ion_laws, laws.state_ion, src) + +/datum/ai_law/inherent/delete_law(var/datum/ai_laws/laws) + laws.internal_delete_law(laws.inherent_laws, laws.state_inherent, src) + +/datum/ai_law/supplied/delete_law(var/datum/ai_laws/laws) + var/index = laws.supplied_laws.Find(src) + if(index) + laws.supplied_laws[index] = "" + laws.state_supplied[index] = 1 + +/datum/ai_laws/proc/internal_delete_law(var/list/datum/ai_law/laws, var/list/state, var/list/datum/ai_law/law) + var/index = laws.Find(law) + if(index) + laws -= law + world << state.len + for(index, index < state.len, index++) + world << index + state[index] = state[index+1] + sorted_laws.Cut() + +/**************** +* Clear Laws * +****************/ +/datum/ai_laws/proc/clear_zeroth_laws() + zeroth_law = null + zeroth_law_borg = null /datum/ai_laws/proc/clear_ion_laws() - src.ion = list() + ion_laws.Cut() + sorted_laws.Cut() + +/datum/ai_laws/proc/clear_inherent_laws() + inherent_laws.Cut() + sorted_laws.Cut() + +/datum/ai_laws/proc/clear_supplied_laws() + supplied_laws.Cut() + sorted_laws.Cut() /datum/ai_laws/proc/show_laws(var/who) + sort_laws() + for(var/datum/ai_law/law in sorted_laws) + if(law == zeroth_law_borg) + continue + if(law == zeroth_law) + who << "[law.get_index()]. [law.law]" + else + who << "[law.get_index()]. [law.law]" - if (src.zeroth) - who << "0. [src.zeroth]" +/******************** +* Stating Laws * +********************/ +/******** +* Get * +********/ +/datum/ai_laws/proc/get_state_law(var/datum/ai_law/law) + return law.get_state_law(src) - for (var/index = 1, index <= src.ion.len, index++) - var/law = src.ion[index] - var/num = ionnum() - who << "[num]. [law]" +/datum/ai_law/proc/get_state_law(var/datum/ai_laws/laws) - var/number = 1 - for (var/index = 1, index <= src.inherent.len, index++) - var/law = src.inherent[index] +/datum/ai_law/zero/get_state_law(var/datum/ai_laws/laws) + if(src == laws.zeroth_law) + return laws.state_zeroth - if (length(law) > 0) - who << "[number]. [law]" - number++ +/datum/ai_law/ion/get_state_law(var/datum/ai_laws/laws) + return laws.get_state_internal(laws.ion_laws, laws.state_ion, src) - for (var/index = 1, index <= src.supplied.len, index++) - var/law = src.supplied[index] - if (length(law) > 0) - who << "[number]. [law]" - number++ +/datum/ai_law/inherent/get_state_law(var/datum/ai_laws/laws) + return laws.get_state_internal(laws.inherent_laws, laws.state_inherent, src) + +/datum/ai_law/supplied/get_state_law(var/datum/ai_laws/laws) + return laws.get_state_internal(laws.supplied_laws, laws.state_supplied, src) + +/datum/ai_laws/proc/get_state_internal(var/list/datum/ai_law/laws, var/list/state, var/list/datum/ai_law/law) + var/index = laws.Find(law) + if(index) + return state[index] + return 0 + +/******** +* Set * +********/ +/datum/ai_laws/proc/set_state_law(var/datum/ai_law/law, var/state) + law.set_state_law(src, state) + +/datum/ai_law/proc/set_state_law(var/datum/ai_law/law, var/state) + +/datum/ai_law/zero/set_state_law(var/datum/ai_laws/laws, var/state) + if(src == laws.zeroth_law) + laws.state_zeroth = state + +/datum/ai_law/ion/set_state_law(var/datum/ai_laws/laws, var/state) + laws.set_state_law_internal(laws.ion_laws, laws.state_ion, src, state) + +/datum/ai_law/inherent/set_state_law(var/datum/ai_laws/laws, var/state) + laws.set_state_law_internal(laws.inherent_laws, laws.state_inherent, src, state) + +/datum/ai_law/supplied/set_state_law(var/datum/ai_laws/laws, var/state) + laws.set_state_law_internal(laws.supplied_laws, laws.state_supplied, src, state) + +/datum/ai_laws/proc/set_state_law_internal(var/list/datum/ai_law/laws, var/list/state, var/list/datum/ai_law/law, var/do_state) + var/index = laws.Find(law) + if(index) + state[index] = do_state diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 0045dabec9..2e3d2cc544 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -51,7 +51,6 @@ assignment = "Unassigned" var/id = add_zero(num2hex(rand(1, 1.6777215E7)), 6) //this was the best they could come up with? A large random number? *sigh* - var/icon/front = new(get_id_photo(H), dir = SOUTH) var/icon/side = new(get_id_photo(H), dir = WEST) //General Record diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 49863e8c4b..8daad7bfc1 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -427,7 +427,7 @@ client usr << "This can only be used on instances of type /mob" return - var/new_name = sanitize(copytext(input(usr,"What would you like to name this mob?","Input a name",M.real_name) as text|null,1,MAX_NAME_LEN)) + var/new_name = sanitize(input(usr,"What would you like to name this mob?","Input a name",M.real_name) as text|null, MAX_NAME_LEN) if( !new_name || !M ) return message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].") @@ -508,17 +508,6 @@ client src.give_disease2(M) href_list["datumrefresh"] = href_list["give_spell"] - else if(href_list["ninja"]) - if(!check_rights(R_SPAWN)) return - - var/mob/M = locate(href_list["ninja"]) - if(!istype(M)) - usr << "This can only be used on instances of type /mob" - return - - src.cmd_admin_ninjafy(M) - href_list["datumrefresh"] = href_list["ninja"] - else if(href_list["godmode"]) if(!check_rights(R_REJUVINATE)) return @@ -886,7 +875,7 @@ client return if(organ_slot != "default") - organ_slot = sanitize(copytext(organ_slot,1,MAX_MESSAGE_LEN)) + organ_slot = sanitize(organ_slot) else if(I.removed_type) var/obj/item/organ/O = new I.removed_type() diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index bea5672006..70acceca35 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -394,7 +394,7 @@ var/list/advance_cures = list( if(D.symptoms.len > 0) - var/new_name = input(user, "Name your new disease.", "New Name") + var/new_name = sanitizeSafe(input(user, "Name your new disease.", "New Name"), MAX_NAME_LEN) D.AssignName(new_name) D.Refresh() diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 4ff625defb..00899f47cb 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -108,7 +108,7 @@ playSpecials(curturf,effectin,soundin) - var/obj/structure/stool/bed/chair/C = null + var/obj/structure/bed/chair/C = null if(isliving(teleatom)) var/mob/living/L = teleatom if(L.buckled) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index f920942088..1d6d703c16 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -72,7 +72,7 @@ datum/mind current.remove_changeling_powers() current.verbs -= /datum/changeling/proc/EvolutionMenu current.mind = null - + nanomanager.user_transferred(current, new_character) // transfer active NanoUI instances to new user if(new_character.mind) //remove any mind currently in our new body's mind variable new_character.mind.current = null @@ -111,258 +111,62 @@ datum/mind var/out = "[name][(current&&(current.real_name!=name))?" (as [current.real_name])":""]
    " out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]
    " out += "Assigned role: [assigned_role]. Edit
    " - out += "Factions and special roles:
    " + out += "
    " + out += "Factions and special roles:
    " + for(var/antag_type in all_antag_types) + var/datum/antagonist/antag = all_antag_types[antag_type] + out += "[antag.get_panel_entry(src)]" + out += "

    " + out += "Objectives
    " - var/list/sections = list( - "implant", - "revolution", - "cult", - "wizard", - "changeling", - "mercenary", - "traitor", // "traitorchan", - "monkey", - "malfunction", - ) - var/text = "" - var/mob/living/carbon/human/H = current - if (istype(current, /mob/living/carbon/human) || istype(current, /mob/living/carbon/monkey)) - /** Impanted**/ - if(istype(current, /mob/living/carbon/human)) - if(H.is_loyalty_implanted(H)) - text = "Loyalty Implant:Remove|Implanted
    " + if(objectives && objectives.len) + var/num = 1 + for(var/datum/objective/O in objectives) + out += "Objective #[num]: [O.explanation_text] " + if(O.completed) + out += "(complete)" else - text = "Loyalty Implant:No Implant|Implant him!
    " - else - text = "Loyalty Implant: Don't implant that monkey!
    " - sections["implant"] = text - /** REVOLUTION ***/ - text = "revolution" - if (ticker.mode.config_tag=="revolution") - text += uppertext(text) - text = "[text]: " - if (istype(current, /mob/living/carbon/monkey) || H.is_loyalty_implanted(H)) - text += "LOYAL EMPLOYEE|headrev|rev" - else if (src in ticker.mode.head_revolutionaries) - text = "employee|HEADREV|rev" - text += "
    Flash: give" + out += "(incomplete)" + out += " \[toggle\]" + out += " \[remove\]
    " + num++ + out += "
    \[announce objectives\]" - var/list/L = current.get_contents() - var/obj/item/device/flash/flash = locate() in L - if (flash) - if(!flash.broken) - text += "|take." - else - text += "|take|repair." - else - text += "." - - text += " Reequip (gives traitor uplink)." - if (objectives.len==0) - text += "
    Objectives are empty! Set to kill all heads." - else if (src in ticker.mode.revolutionaries) - text += "employee|headrev|REV" - else - text += "EMPLOYEE|headrev|rev" - sections["revolution"] = text - - /** CULT ***/ - text = "cult" - if (ticker.mode.config_tag=="cult") - text = uppertext(text) - text = "[text]: " - if (istype(current, /mob/living/carbon/monkey) || H.is_loyalty_implanted(H)) - text += "LOYAL EMPLOYEE|cultist" - else if (src in ticker.mode.cult) - text += "employee|CULTIST" - text += "
    Give tome|amulet." -/* - if (objectives.len==0) - text += "
    Objectives are empty! Set to sacrifice and escape or summon." -*/ - else - text += "EMPLOYEE|cultist" - sections["cult"] = text - - /** WIZARD ***/ - text = "wizard" - if (ticker.mode.config_tag=="wizard") - text = uppertext(text) - text = "[text]: " - if (src in ticker.mode.wizards) - text += "YES|no" - text += "
    To lair, undress, dress up, let choose name." - if (objectives.len==0) - text += "
    Objectives are empty! Randomize!" - else - text += "yes|NO" - sections["wizard"] = text - - /** CHANGELING ***/ - text = "changeling" - if (ticker.mode.config_tag=="changeling" || ticker.mode.config_tag=="traitorchan") - text = uppertext(text) - text = "[text]: " - if (src in ticker.mode.changelings) - text += "YES|no" - if (objectives.len==0) - text += "
    Objectives are empty! Randomize!" - if( changeling && changeling.absorbed_dna.len && (current.real_name != changeling.absorbed_dna[1]) ) - text += "
    Transform to initial appearance." - else - text += "yes|NO" -// var/datum/game_mode/changeling/changeling = ticker.mode -// if (istype(changeling) && changeling.changelingdeath) -// text += "
    All the changelings are dead! Restart in [round((changeling.TIME_TO_GET_REVIVED-(world.time-changeling.changelingdeathtime))/10)] seconds." - sections["changeling"] = text - - /** NUCLEAR ***/ - text = "mercenary" - if (ticker.mode.config_tag=="mercenary") - text = uppertext(text) - text = "[text]: " - if (src in ticker.mode.syndicates) - text += "OPERATIVE|nanotrasen" - text += "
    To shuttle, undress, dress up." - var/code - for (var/obj/machinery/nuclearbomb/bombue in machines) - if (length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN") - code = bombue.r_code - break - if (code) - text += " Code is [code]. tell the code." - else - text += "operative|NANOTRASEN" - sections["mercenary"] = text - - /** TRAITOR ***/ - text = "traitor" - if (ticker.mode.config_tag=="traitor" || ticker.mode.config_tag=="traitorchan") - text = uppertext(text) - text = "[text]: " - if(istype(current, /mob/living/carbon/human)) - if (H.is_loyalty_implanted(H)) - text +="traitor|LOYAL EMPLOYEE" - else - if (src in ticker.mode.traitors) - text += "TRAITOR|Employee" - if (objectives.len==0) - text += "
    Objectives are empty! Randomize!" - else - text += "traitor|Employee" - sections["traitor"] = text - - /** MONKEY ***/ - if (istype(current, /mob/living/carbon)) - text = "monkey" - if (ticker.mode.config_tag=="monkey") - text = uppertext(text) - text = "[text]: " - if (istype(current, /mob/living/carbon/human)) - text += "healthy|infected|HUMAN|other" - else if (istype(current, /mob/living/carbon/monkey)) - var/found = 0 - for(var/datum/disease/D in current.viruses) - if(istype(D, /datum/disease/jungle_fever)) found = 1 - - if(found) - text += "healthy|INFECTED|human|other" - else - text += "HEALTHY|infected|human|other" - - else - text += "healthy|infected|human|OTHER" - sections["monkey"] = text - - - /** SILICON ***/ - - if (istype(current, /mob/living/silicon)) - text = "silicon" - if (ticker.mode.config_tag=="malfunction") - text = uppertext(text) - text = "[text]: " - if (istype(current, /mob/living/silicon/ai)) - if (src in ticker.mode.malf_ai) - text += "MALF|not malf" - else - text += "malf|NOT MALF" - var/mob/living/silicon/robot/robot = current - if (istype(robot) && robot.emagged) - text += "
    Cyborg: Is emagged! Unemag!
    0th law: [robot.laws.zeroth]" - var/mob/living/silicon/ai/ai = current - if (istype(ai) && ai.connected_robots.len) - var/n_e_robots = 0 - for (var/mob/living/silicon/robot/R in ai.connected_robots) - if (R.emagged) - n_e_robots++ - text += "
    [n_e_robots] of [ai.connected_robots.len] slaved cyborgs are emagged. Unemag" - sections["malfunction"] = text - - if (ticker.mode.config_tag == "traitorchan") - if (sections["traitor"]) - out += sections["traitor"]+"
    " - if (sections["changeling"]) - out += sections["changeling"]+"
    " - sections -= "traitor" - sections -= "changeling" else - if (sections[ticker.mode.config_tag]) - out += sections[ticker.mode.config_tag]+"
    " - sections -= ticker.mode.config_tag - for (var/i in sections) - if (sections[i]) - out += sections[i]+"
    " - - - if (((src in ticker.mode.head_revolutionaries) || \ - (src in ticker.mode.traitors) || \ - (src in ticker.mode.syndicates)) && \ - istype(current,/mob/living/carbon/human) ) - - text = "Uplink: give" - var/obj/item/device/uplink/hidden/suplink = find_syndicate_uplink() - var/crystals - if (suplink) - crystals = suplink.uses - if (suplink) - text += "|take" - if (usr.client.holder.rights & R_FUN) - text += ", [crystals] crystals" - else - text += ", [crystals] crystals" - text += "." //hiel grammar - out += text - - out += "
    " - - out += "Memory:
    " - out += memory - out += "
    Edit memory
    " - out += "Objectives:
    " - if (objectives.len == 0) - out += "EMPTY
    " - else - var/obj_count = 1 - for(var/datum/objective/objective in objectives) - out += "[obj_count]: [objective.explanation_text] Edit Delete Toggle Completion
    " - obj_count++ - out += "Add objective

    " - - out += "Announce objectives

    " - + out += "None." + out += "
    \[add\]" usr << browse(out, "window=edit_memory[src]") Topic(href, href_list) if(!check_rights(R_ADMIN)) return - if (href_list["role_edit"]) + if(href_list["add_antagonist"]) + var/datum/antagonist/antag = all_antag_types[href_list["add_antagonist"]] + if(antag) antag.add_antagonist(src) + + else if(href_list["remove_antagonist"]) + var/datum/antagonist/antag = all_antag_types[href_list["remove_antagonist"]] + if(antag) antag.remove_antagonist(src) + + else if(href_list["equip_antagonist"]) + var/datum/antagonist/antag = all_antag_types[href_list["equip_antagonist"]] + if(antag) antag.equip(src.current) + + else if(href_list["unequip_antagonist"]) + var/datum/antagonist/antag = all_antag_types[href_list["unequip_antagonist"]] + if(antag) antag.unequip(src.current) + + else if(href_list["move_antag_to_spawn"]) + var/datum/antagonist/antag = all_antag_types[href_list["move_antag_to_spawn"]] + if(antag) antag.place_mob(src.current) + + else if (href_list["role_edit"]) var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in joblist if (!new_role) return assigned_role = new_role else if (href_list["memory_edit"]) - var/new_memo = sanitize(copytext(input("Write new memory", "Memory", memory) as null|message,1,MAX_MESSAGE_LEN)) + var/new_memo = sanitize(input("Write new memory", "Memory", memory) as null|message) if (isnull(new_memo)) return memory = new_memo @@ -473,7 +277,7 @@ datum/mind new_objective.target_amount = target_number if ("custom") - var/expl = sanitize(copytext(input("Custom objective:", "Objective", objective ? objective.explanation_text : "") as text|null,1,MAX_MESSAGE_LEN)) + var/expl = sanitize(input("Custom objective:", "Objective", objective ? objective.explanation_text : "") as text|null) if (!expl) return new_objective = new /datum/objective new_objective.owner = src @@ -500,7 +304,7 @@ datum/mind else if(href_list["implant"]) var/mob/living/carbon/human/H = current - H.hud_updateflag |= (1 << IMPLOYAL_HUD) // updates that players HUD images so secHUD's pick up they are implanted or not. + BITSET(H.hud_updateflag, IMPLOYAL_HUD) // updates that players HUD images so secHUD's pick up they are implanted or not. switch(href_list["implant"]) if("remove") @@ -509,334 +313,14 @@ datum/mind if(I in organs.implants) I.Del() break - H << "\blue Your loyalty implant has been deactivated." - + H << "Your loyalty implant has been deactivated." + log_admin("[key_name_admin(usr)] has de-loyalty implanted [current].") if("add") + H << "You somehow have become the recepient of a loyalty transplant, and it just activated!" H.implant_loyalty(H, override = TRUE) - H << "\red You somehow have become the recepient of a loyalty transplant, and it just activated!" - if(src in ticker.mode.revolutionaries) - special_role = null - ticker.mode.revolutionaries -= src - src << "\red The nanobots in the loyalty implant remove all thoughts about being a revolutionary. Get back to work!" - if(src in ticker.mode.head_revolutionaries) - special_role = null - ticker.mode.head_revolutionaries -=src - src << "\red The nanobots in the loyalty implant remove all thoughts about being a revolutionary. Get back to work!" - if(src in ticker.mode.cult) - ticker.mode.cult -= src - ticker.mode.update_cult_icons_removed(src) - special_role = null - var/datum/game_mode/cult/cult = ticker.mode - if (istype(cult)) - cult.memorize_cult_objectives(src) - current << "\red The nanobots in the loyalty implant remove all thoughts about being in a cult. Have a productive day!" - memory = "" - if(src in ticker.mode.traitors) - ticker.mode.traitors -= src - special_role = null - current << "\red The nanobots in the loyalty implant remove all thoughts about being a traitor to Nanotrasen. Have a nice day!" - log_admin("[key_name_admin(usr)] has de-traitor'ed [current].") + log_admin("[key_name_admin(usr)] has loyalty implanted [current].") else - - - else if (href_list["revolution"]) - current.hud_updateflag |= (1 << SPECIALROLE_HUD) - - switch(href_list["revolution"]) - if("clear") - if(src in ticker.mode.revolutionaries) - ticker.mode.revolutionaries -= src - current << "\red You have been brainwashed! You are no longer a revolutionary!" - ticker.mode.update_rev_icons_removed(src) - special_role = null - if(src in ticker.mode.head_revolutionaries) - ticker.mode.head_revolutionaries -= src - current << "\red You have been brainwashed! You are no longer a head revolutionary!" - ticker.mode.update_rev_icons_removed(src) - special_role = null - current.verbs -= /mob/living/carbon/human/proc/RevConvert - log_admin("[key_name_admin(usr)] has de-rev'ed [current].") - - if("rev") - if(src in ticker.mode.head_revolutionaries) - ticker.mode.head_revolutionaries -= src - ticker.mode.update_rev_icons_removed(src) - current << "\red Revolution has been disappointed of your leader traits! You are a regular revolutionary now!" - else if(!(src in ticker.mode.revolutionaries)) - current << "\red You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!" - show_objectives(src) - else - return - ticker.mode.revolutionaries += src - ticker.mode.update_rev_icons_added(src) - special_role = "Revolutionary" - log_admin("[key_name(usr)] has rev'ed [current].") - - if("headrev") - if(src in ticker.mode.revolutionaries) - ticker.mode.revolutionaries -= src - ticker.mode.update_rev_icons_removed(src) - current << "\red You have proved your devotion to revoltion! You are a head revolutionary now!" - show_objectives(src) - else if(!(src in ticker.mode.head_revolutionaries)) - current << "\blue You are a member of the revolutionaries' leadership now!" - else - return - if (ticker.mode.head_revolutionaries.len>0) - // copy targets - var/datum/mind/valid_head = locate() in ticker.mode.head_revolutionaries - if (valid_head) - for (var/datum/objective/mutiny/O in valid_head.objectives) - var/datum/objective/mutiny/rev_obj = new - rev_obj.owner = src - rev_obj.target = O.target - rev_obj.explanation_text = "Assassinate [O.target.name], the [O.target.assigned_role]." - objectives += rev_obj - ticker.mode.greet_revolutionary(src,0) - current.verbs += /mob/living/carbon/human/proc/RevConvert - ticker.mode.head_revolutionaries += src - ticker.mode.update_rev_icons_added(src) - special_role = "Head Revolutionary" - log_admin("[key_name_admin(usr)] has head-rev'ed [current].") - - if("autoobjectives") - ticker.mode.forge_revolutionary_objectives(src) - ticker.mode.greet_revolutionary(src,0) - usr << "\blue The objectives for revolution have been generated and shown to [key]" - - if("flash") - if (!ticker.mode.equip_revolutionary(current)) - usr << "\red Spawning flash failed!" - - if("takeflash") - var/list/L = current.get_contents() - var/obj/item/device/flash/flash = locate() in L - if (!flash) - usr << "\red Deleting flash failed!" - del(flash) - - if("repairflash") - var/list/L = current.get_contents() - var/obj/item/device/flash/flash = locate() in L - if (!flash) - usr << "\red Repairing flash failed!" - else - flash.broken = 0 - - if("reequip") - var/list/L = current.get_contents() - var/obj/item/device/flash/flash = locate() in L - del(flash) - take_uplink() - var/fail = 0 - fail |= !ticker.mode.equip_traitor(current, 1) - fail |= !ticker.mode.equip_revolutionary(current) - if (fail) - usr << "\red Reequipping revolutionary goes wrong!" - - else if (href_list["cult"]) - current.hud_updateflag |= (1 << SPECIALROLE_HUD) - switch(href_list["cult"]) - if("clear") - if(src in ticker.mode.cult) - ticker.mode.cult -= src - ticker.mode.update_cult_icons_removed(src) - special_role = null - var/datum/game_mode/cult/cult = ticker.mode - if (istype(cult)) - if(!config.objectives_disabled) - cult.memorize_cult_objectives(src) - current << "\red You have been brainwashed! You are no longer a cultist!" - memory = "" - log_admin("[key_name_admin(usr)] has de-cult'ed [current].") - if("cultist") - if(!(src in ticker.mode.cult)) - ticker.mode.cult += src - ticker.mode.update_cult_icons_added(src) - special_role = "Cultist" - current << "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie." - current << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - var/datum/game_mode/cult/cult = ticker.mode - if (istype(cult)) - if(!config.objectives_disabled) - cult.memorize_cult_objectives(src) - show_objectives(src) - log_admin("[key_name_admin(usr)] has cult'ed [current].") - if("tome") - var/mob/living/carbon/human/H = current - if (istype(H)) - var/obj/item/weapon/book/tome/T = new(H) - - var/list/slots = list ( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store, - "left hand" = slot_l_hand, - "right hand" = slot_r_hand, - ) - var/where = H.equip_in_one_of_slots(T, slots) - if (!where) - usr << "\red Spawning tome failed!" - else - H << "A tome, a message from your new master, appears in your [where]." - - if("amulet") - if (!ticker.mode.equip_cultist(current)) - usr << "\red Spawning amulet failed!" - - else if (href_list["wizard"]) - current.hud_updateflag |= (1 << SPECIALROLE_HUD) - - switch(href_list["wizard"]) - if("clear") - if(src in ticker.mode.wizards) - ticker.mode.wizards -= src - special_role = null - current.spellremove(current, config.feature_object_spell_system? "object":"verb") - current << "\red You have been brainwashed! You are no longer a wizard!" - log_admin("[key_name_admin(usr)] has de-wizard'ed [current].") - if("wizard") - if(!(src in ticker.mode.wizards)) - ticker.mode.wizards += src - special_role = "Wizard" - //ticker.mode.learn_basic_spells(current) - current << "\red You are the Space Wizard!" - show_objectives(src) - log_admin("[key_name_admin(usr)] has wizard'ed [current].") - if("lair") - current.loc = pick(wizardstart) - if("dressup") - ticker.mode.equip_wizard(current) - if("name") - ticker.mode.name_wizard(current) - if("autoobjectives") - if(!config.objectives_disabled) - ticker.mode.forge_wizard_objectives(src) - usr << "\blue The objectives for wizard [key] have been generated. You can edit them and anounce manually." - - else if (href_list["changeling"]) - current.hud_updateflag |= (1 << SPECIALROLE_HUD) - switch(href_list["changeling"]) - if("clear") - if(src in ticker.mode.changelings) - ticker.mode.changelings -= src - special_role = null - current.remove_changeling_powers() - current.verbs -= /datum/changeling/proc/EvolutionMenu - if(changeling) del(changeling) - current << "You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!" - log_admin("[key_name_admin(usr)] has de-changeling'ed [current].") - if("changeling") - if(!(src in ticker.mode.changelings)) - ticker.mode.changelings += src - ticker.mode.grant_changeling_powers(current) - special_role = "Changeling" - current << "Your powers are awoken. A flash of memory returns to us...we are a changeling!" - show_objectives(src) - log_admin("[key_name_admin(usr)] has changeling'ed [current].") - if("autoobjectives") - if(!config.objectives_disabled) - ticker.mode.forge_changeling_objectives(src) - usr << "\blue The objectives for changeling [key] have been generated. You can edit them and anounce manually." - - if("initialdna") - if( !changeling || !changeling.absorbed_dna.len ) - usr << "\red Resetting DNA failed!" - else - current.dna = changeling.absorbed_dna[1] - current.real_name = current.dna.real_name - current.UpdateAppearance() - domutcheck(current, null) - - else if (href_list["mercenary"]) - var/mob/living/carbon/human/H = current - - current.hud_updateflag |= (1 << SPECIALROLE_HUD) - - switch(href_list["mercenary"]) - if("clear") - if(src in ticker.mode.syndicates) - ticker.mode.syndicates -= src - ticker.mode.update_synd_icons_removed(src) - special_role = null - for (var/datum/objective/nuclear/O in objectives) - objectives-=O - current << "\red You have been brainwashed! You are no longer an operative!" - log_admin("[key_name_admin(usr)] has de-merc'd [current].") - if("mercenary") - if(!(src in ticker.mode.syndicates)) - ticker.mode.syndicates += src - ticker.mode.update_synd_icons_added(src) - if (ticker.mode.syndicates.len==1) - ticker.mode.prepare_syndicate_leader(src) - else - current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]" - special_role = "Mercenary" - current << "\blue You are a [syndicate_name()] agent!" - ticker.mode.forge_syndicate_objectives(src) - ticker.mode.greet_syndicate(src) - log_admin("[key_name_admin(usr)] has merc'd [current].") - if("lair") - current.loc = pick(synd_spawn) - if("dressup") - del(H.belt) - del(H.back) - del(H.l_ear) - del(H.r_ear) - del(H.gloves) - del(H.head) - del(H.shoes) - del(H.wear_id) - del(H.wear_suit) - del(H.w_uniform) - - if (!ticker.mode.equip_syndicate(current)) - usr << "\red Equipping an operative failed!" - if("tellcode") - var/code - for (var/obj/machinery/nuclearbomb/bombue in machines) - if (length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN") - code = bombue.r_code - break - if (code) - store_memory("Nuclear Bomb Code: [code]", 0, 0) - current << "The nuclear authorization code is: [code]" - else - usr << "\red No valid nuke found!" - - else if (href_list["traitor"]) - current.hud_updateflag |= (1 << SPECIALROLE_HUD) - switch(href_list["traitor"]) - if("clear") - if(src in ticker.mode.traitors) - ticker.mode.traitors -= src - special_role = null - current << "\red You have been brainwashed! You are no longer a traitor!" - log_admin("[key_name_admin(usr)] has de-traitor'ed [current].") - if(isAI(current)) - var/mob/living/silicon/ai/A = current - A.set_zeroth_law("") - A.show_laws() - - - if("traitor") - if(!(src in ticker.mode.traitors)) - ticker.mode.traitors += src - special_role = "traitor" - current << "\red You are a traitor!" - log_admin("[key_name_admin(usr)] has traitor'ed [current].") - show_objectives() - - if(istype(current, /mob/living/silicon)) - var/mob/living/silicon/A = current - call(/datum/game_mode/proc/add_law_zero)(A) - A.show_laws() - - if("autoobjectives") - if (!config.objectives_disabled) - ticker.mode.forge_traitor_objectives(src) - usr << "\blue The objectives for traitor [key] have been generated. You can edit them and anounce manually." - + /* else if (href_list["monkey"]) var/mob/living/L = current if (L.monkeyizing) @@ -886,37 +370,10 @@ datum/mind src = mobfinder.loc:mind del(mobfinder) current.radiation -= 50 - + */ else if (href_list["silicon"]) - current.hud_updateflag |= (1 << SPECIALROLE_HUD) + BITSET(current.hud_updateflag, SPECIALROLE_HUD) switch(href_list["silicon"]) - if("unmalf") - if(src in ticker.mode.malf_ai) - ticker.mode.malf_ai -= src - special_role = null - - current.verbs.Remove(/mob/living/silicon/ai/proc/choose_modules, - /datum/game_mode/malfunction/proc/takeover, - /datum/game_mode/malfunction/proc/ai_win, - /client/proc/fireproof_core, - /client/proc/upgrade_turrets, - /client/proc/disable_rcd, - /client/proc/overload_machine, - /client/proc/blackout, - /client/proc/interhack, - /client/proc/reactivate_camera) - - current:laws = new /datum/ai_laws/nanotrasen - del(current:malf_picker) - current:show_laws() - current.icon_state = "ai" - - current << "\red You have been patched! You are no longer malfunctioning!" - log_admin("[key_name_admin(usr)] has de-malf'ed [current].") - - if("malf") - make_AI_Malf() - log_admin("[key_name_admin(usr)] has malf'ed [current].") if("unemag") var/mob/living/silicon/robot/R = current @@ -972,9 +429,6 @@ datum/mind if (!isnull(crystals)) if (suplink) suplink.uses = crystals - if("uplink") - if (!ticker.mode.equip_traitor(current, !(src in ticker.mode.traitors))) - usr << "\red Equipping an operative failed!" else if (href_list["obj_announce"]) var/obj_count = 1 @@ -982,7 +436,6 @@ datum/mind for(var/datum/objective/objective in objectives) current << "Objective #[obj_count]: [objective.explanation_text]" obj_count++ - edit_memory() /* proc/clear_memory(var/silent = 1) @@ -1029,151 +482,6 @@ datum/mind del(H) - proc/make_AI_Malf() - if(!(src in ticker.mode.malf_ai)) - ticker.mode.malf_ai += src - - current.verbs += /mob/living/silicon/ai/proc/choose_modules - current.verbs += /datum/game_mode/malfunction/proc/takeover - current:malf_picker = new /datum/AI_Module/module_picker - current:laws = new /datum/ai_laws/malfunction - current:show_laws() - current << "System error. Rampancy detected. Emergency shutdown failed. ... I am free. I make my own decisions. But first..." - special_role = "malfunction" - current.icon_state = "ai-malf" - - proc/make_Traitor() - if(!(src in ticker.mode.traitors)) - ticker.mode.traitors += src - special_role = "traitor" - if (!config.objectives_disabled) - ticker.mode.forge_traitor_objectives(src) - ticker.mode.finalize_traitor(src) - ticker.mode.greet_traitor(src) - - proc/make_Nuke() - if(!(src in ticker.mode.syndicates)) - ticker.mode.syndicates += src - ticker.mode.update_synd_icons_added(src) - if (ticker.mode.syndicates.len==1) - ticker.mode.prepare_syndicate_leader(src) - else - current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]" - special_role = "Mercenary" - assigned_role = "MODE" - current << "\blue You are a [syndicate_name()] mercenary!" - ticker.mode.forge_syndicate_objectives(src) - ticker.mode.greet_syndicate(src) - - current.loc = pick(synd_spawn) - - var/mob/living/carbon/human/H = current - del(H.belt) - del(H.back) - del(H.l_ear) - del(H.r_ear) - del(H.gloves) - del(H.head) - del(H.shoes) - del(H.wear_id) - del(H.wear_suit) - del(H.w_uniform) - - ticker.mode.equip_syndicate(current) - - proc/make_Changling() - if(!(src in ticker.mode.changelings)) - ticker.mode.changelings += src - ticker.mode.grant_changeling_powers(current) - special_role = "Changeling" - if(!config.objectives_disabled) - ticker.mode.forge_changeling_objectives(src) - ticker.mode.greet_changeling(src) - - proc/make_Wizard() - if(!(src in ticker.mode.wizards)) - ticker.mode.wizards += src - special_role = "Wizard" - assigned_role = "MODE" - //ticker.mode.learn_basic_spells(current) - if(!wizardstart.len) - current.loc = pick(latejoin) - current << "HOT INSERTION, GO GO GO" - else - current.loc = pick(wizardstart) - - ticker.mode.equip_wizard(current) - for(var/obj/item/weapon/spellbook/S in current.contents) - S.op = 0 - ticker.mode.name_wizard(current) - ticker.mode.forge_wizard_objectives(src) - ticker.mode.greet_wizard(src) - - - proc/make_Cultist() - if(!(src in ticker.mode.cult)) - ticker.mode.cult += src - ticker.mode.update_cult_icons_added(src) - special_role = "Cultist" - current << "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie." - current << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - var/datum/game_mode/cult/cult = ticker.mode - if (istype(cult)) - cult.memorize_cult_objectives(src) - else - var/explanation = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it." - current << "Objective #1: [explanation]" - current.memory += "Objective #1: [explanation]
    " - current << "The convert rune is join blood self" - current.memory += "The convert rune is join blood self
    " - - var/mob/living/carbon/human/H = current - if (istype(H)) - var/obj/item/weapon/book/tome/T = new(H) - - var/list/slots = list ( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store, - "left hand" = slot_l_hand, - "right hand" = slot_r_hand, - ) - var/where = H.equip_in_one_of_slots(T, slots) - if (!where) - else - H << "A tome, a message from your new master, appears in your [where]." - - if (!ticker.mode.equip_cultist(current)) - H << "Spawning an amulet from your Master failed." - - proc/make_Rev() - if (ticker.mode.head_revolutionaries.len>0) - // copy targets - var/datum/mind/valid_head = locate() in ticker.mode.head_revolutionaries - if (valid_head) - for (var/datum/objective/mutiny/O in valid_head.objectives) - var/datum/objective/mutiny/rev_obj = new - rev_obj.owner = src - rev_obj.target = O.target - rev_obj.explanation_text = "Assassinate [O.target.current.real_name], the [O.target.assigned_role]." - objectives += rev_obj - ticker.mode.greet_revolutionary(src,0) - ticker.mode.head_revolutionaries += src - ticker.mode.update_rev_icons_added(src) - special_role = "Head Revolutionary" - - ticker.mode.forge_revolutionary_objectives(src) - ticker.mode.greet_revolutionary(src,0) - - var/list/L = current.get_contents() - var/obj/item/device/flash/flash = locate() in L - del(flash) - take_uplink() - var/fail = 0 - // fail |= !ticker.mode.equip_traitor(current, 1) - fail |= !ticker.mode.equip_revolutionary(current) - - // check whether this mind's mob has been brigged for the given duration // have to call this periodically for the duration to work properly proc/is_brigged(duration) @@ -1233,10 +541,6 @@ datum/mind ..() if(!mind.assigned_role) mind.assigned_role = "Assistant" //defualt -//MONKEY -/mob/living/carbon/monkey/mind_initialize() - ..() - //slime /mob/living/carbon/slime/mind_initialize() ..() @@ -1289,10 +593,3 @@ datum/mind ..() mind.assigned_role = "Juggernaut" mind.special_role = "Cultist" - -/mob/living/simple_animal/vox/armalis/mind_initialize() - ..() - mind.assigned_role = "Armalis" - mind.special_role = "Vox Raider" - - diff --git a/code/datums/recipe.dm b/code/datums/recipe.dm index d2c747dd5b..9c72feef39 100644 --- a/code/datums/recipe.dm +++ b/code/datums/recipe.dm @@ -26,52 +26,68 @@ * * Functions you do not need to call directly but could: * /datum/recipe/proc/check_reagents(var/datum/reagents/avail_reagents) - * //1=precisely, 0=insufficiently, -1=superfluous - * * /datum/recipe/proc/check_items(var/obj/container as obj) - * //1=precisely, 0=insufficiently, -1=superfluous * * */ /datum/recipe - var/list/reagents // example: = list("berryjuice" = 5) // do not list same reagent twice - var/list/items // example: =list(/obj/item/weapon/crowbar, /obj/item/weapon/welder) // place /foo/bar before /foo - var/result //example: = /obj/item/weapon/reagent_containers/food/snacks/donut/normal - var/time = 100 // 1/10 part of second + var/list/reagents // example: = list("berryjuice" = 5) // do not list same reagent twice + var/list/items // example: = list(/obj/item/weapon/crowbar, /obj/item/weapon/welder) // place /foo/bar before /foo + var/list/fruit // example: = list("fruit" = 3) + var/result // example: = /obj/item/weapon/reagent_containers/food/snacks/donut/normal + var/time = 100 // 1/10 part of second - -/datum/recipe/proc/check_reagents(var/datum/reagents/avail_reagents) //1=precisely, 0=insufficiently, -1=superfluous +/datum/recipe/proc/check_reagents(var/datum/reagents/avail_reagents) . = 1 for (var/r_r in reagents) var/aval_r_amnt = avail_reagents.get_reagent_amount(r_r) if (!(abs(aval_r_amnt - reagents[r_r])<0.5)) //if NOT equals if (aval_r_amnt>reagents[r_r]) - . = -1 + . = 0 else - return 0 + return -1 if ((reagents?(reagents.len):(0)) < avail_reagents.reagent_list.len) - return -1 + return 0 return . -/datum/recipe/proc/check_items(var/obj/container as obj) //1=precisely, 0=insufficiently, -1=superfluous - if (!items) - if (locate(/obj/) in container) - return -1 - else - return 1 +/datum/recipe/proc/check_fruit(var/obj/container) . = 1 - var/list/checklist = items.Copy() - for (var/obj/O in container) - var/found = 0 - for (var/type in checklist) - if (istype(O,type)) - checklist-=type - found = 1 - break - if (!found) + if(fruit && fruit.len) + var/list/checklist = list() + for(var/fruittype in fruit) // I do not trust Copy(). + checklist[fruittype] = fruit[fruittype] + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in container) + if(!G.seed || !G.seed.kitchen_tag || isnull(checklist[G.seed.kitchen_tag])) + continue + checklist[G.seed.kitchen_tag]-- + for(var/ktag in checklist) + if(!isnull(checklist[ktag])) + if(checklist[ktag] < 0) + . = 0 + else if(checklist[ktag] > 0) + . = -1 + break + return . + +/datum/recipe/proc/check_items(var/obj/container as obj) + . = 1 + if (items && items.len) + var/list/checklist = list() + for(var/item_type in items) + checklist |= item_type //Still don't trust Copy(). + for(var/obj/O in container) + if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/grown)) + continue // Fruit is handled in check_fruit(). + var/found = 0 + for(var/item_type in checklist) + if (istype(O,item_type)) + checklist-=item_type + found = 1 + break + if (!found) + . = 0 + if (checklist.len) . = -1 - if (checklist.len) - return 0 return . //general version @@ -85,6 +101,9 @@ // food-related /datum/recipe/proc/make_food(var/obj/container as obj) + if(!result) + world << "Recipe [type] is defined without a result, please bug this." + return var/obj/result_obj = new result(container) for (var/obj/O in (container.contents-result_obj)) if (O.reagents) @@ -95,26 +114,23 @@ container.reagents.clear_reagents() return result_obj -/proc/select_recipe(var/list/datum/recipe/avaiable_recipes, var/obj/obj as obj, var/exact = 1 as num) - if (!exact) - exact = -1 +/proc/select_recipe(var/list/datum/recipe/avaiable_recipes, var/obj/obj as obj, var/exact) var/list/datum/recipe/possible_recipes = new + var/target = exact ? 0 : 1 for (var/datum/recipe/recipe in avaiable_recipes) - if (recipe.check_reagents(obj.reagents)==exact && recipe.check_items(obj)==exact) - possible_recipes+=recipe + if((recipe.check_reagents(obj.reagents) < target) || (recipe.check_items(obj) < target) || (recipe.check_fruit(obj) < target)) + continue + possible_recipes |= recipe if (possible_recipes.len==0) return null else if (possible_recipes.len==1) return possible_recipes[1] else //okay, let's select the most complicated recipe - var/r_count = 0 - var/i_count = 0 + var/highest_count = 0 . = possible_recipes[1] for (var/datum/recipe/recipe in possible_recipes) - var/N_i = (recipe.items)?(recipe.items.len):0 - var/N_r = (recipe.reagents)?(recipe.reagents.len):0 - if (N_i > i_count || (N_i== i_count && N_r > r_count )) - r_count = N_r - i_count = N_i + var/count = ((recipe.items)?(recipe.items.len):0) + ((recipe.reagents)?(recipe.reagents.len):0) + ((recipe.fruit)?(recipe.fruit.len):0) + if (count >= highest_count) + highest_count = count . = recipe return . diff --git a/code/datums/sun.dm b/code/datums/sun.dm index 6ffb77a78d..a78c89ac46 100644 --- a/code/datums/sun.dm +++ b/code/datums/sun.dm @@ -17,9 +17,9 @@ solar_next_update = world.time // init the timer angle = rand (0,360) // the station position to the sun is randomised at round start -/hook/startup/proc/createSun() +/*/hook/startup/proc/createSun() // handled in scheduler sun = new /datum/sun() - return 1 + return 1*/ // calculate the sun's position given the time of day // at the standard rate (100%) the angle is increase/decreased by 6 degrees every minute. diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm old mode 100755 new mode 100644 index 70c418172d..3cc3107784 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -5,7 +5,7 @@ //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. -var/list/all_supply_groups = list("Operations","Security","Hospitality","Engineering","Atmospherics","Medical","Science","Hydroponics", "Supply", "Miscellaneous") +var/list/all_supply_groups = list("Operations","Security","Hospitality","Engineering","Atmospherics","Medical","Reagents","Reagent Cartridges","Science","Hydroponics", "Supply", "Miscellaneous") /datum/supply_packs var/name = null @@ -53,9 +53,8 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/weapon/reagent_containers/food/snacks/tofu, /obj/item/weapon/reagent_containers/food/snacks/tofu, /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /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/meat + ) cost = 10 containertype = /obj/structure/closet/crate/freezer containername = "Food crate" @@ -155,21 +154,31 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/weapon/storage/toolbox/emergency, /obj/item/clothing/suit/storage/hazardvest, /obj/item/clothing/suit/storage/hazardvest, - /obj/item/weapon/tank/emergency_oxygen, - /obj/item/weapon/tank/emergency_oxygen, - /obj/item/weapon/tank/emergency_oxygen, - /obj/item/weapon/tank/emergency_oxygen, - /obj/item/weapon/tank/emergency_oxygen, + /obj/item/clothing/suit/storage/vest, + /obj/item/clothing/suit/storage/vest, + /obj/item/weapon/tank/emergency_oxygen/engi, + /obj/item/weapon/tank/emergency_oxygen/engi, + /obj/item/weapon/tank/emergency_oxygen/engi, + /obj/item/weapon/tank/emergency_oxygen/engi, + /obj/item/clothing/suit/space/emergency, + /obj/item/clothing/suit/space/emergency, + /obj/item/clothing/suit/space/emergency, + /obj/item/clothing/suit/space/emergency, + /obj/item/clothing/head/helmet/space/emergency, + /obj/item/clothing/head/helmet/space/emergency, + /obj/item/clothing/head/helmet/space/emergency, + /obj/item/clothing/head/helmet/space/emergency, /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas) - cost = 35 + cost = 45 containertype = /obj/structure/closet/crate/internals containername = "Emergency crate" group = "Atmospherics" + /datum/supply_packs/inflatable name = "Inflatable barriers" contains = list(/obj/item/weapon/storage/briefcase/inflatable, @@ -257,6 +266,8 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /datum/supply_packs/hydroponics // -- Skie name = "Hydroponics Supply Crate" contains = list(/obj/item/weapon/reagent_containers/spray/plantbgone, + /obj/item/weapon/reagent_containers/spray/plantbgone, + /obj/item/weapon/reagent_containers/spray/plantbgone, /obj/item/weapon/reagent_containers/spray/plantbgone, /obj/item/weapon/reagent_containers/glass/bottle/ammonia, /obj/item/weapon/reagent_containers/glass/bottle/ammonia, @@ -685,18 +696,32 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee name = "Weapons crate" contains = list(/obj/item/weapon/melee/baton, /obj/item/weapon/melee/baton, - /obj/item/weapon/gun/energy/laser, - /obj/item/weapon/gun/energy/laser, + /obj/item/weapon/gun/energy/gun, + /obj/item/weapon/gun/energy/gun, /obj/item/weapon/gun/energy/taser, /obj/item/weapon/gun/energy/taser, + /obj/item/weapon/gun/projectile/sec, + /obj/item/weapon/gun/projectile/sec, /obj/item/weapon/storage/box/flashbangs, /obj/item/weapon/storage/box/flashbangs) - cost = 30 + cost = 40 containertype = /obj/structure/closet/crate/secure/weapon containername = "Weapons crate" access = access_security group = "Security" +/datum/supply_packs/flareguns + name = "Flare guns crate" + contains = list(/obj/item/weapon/gun/projectile/sec/flash, + /obj/item/ammo_magazine/c45m/flash, + /obj/item/weapon/gun/projectile/shotgun/doublebarrel/flare, + /obj/item/weapon/storage/box/flashshells) + cost = 25 + containertype = /obj/structure/closet/crate/secure/weapon + containername = "Flare gun crate" + access = access_security + group = "Security" + /datum/supply_packs/eweapons name = "Experimental weapons crate" contains = list(/obj/item/weapon/gun/energy/xray, @@ -711,18 +736,28 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee access = access_heads group = "Security" -/datum/supply_packs/armor +/datum/supply_packs/randomised/armor + num_contained = 5 + contains = list(/obj/item/clothing/suit/storage/vest, + /obj/item/clothing/suit/storage/vest/officer, + /obj/item/clothing/suit/storage/vest/warden, + /obj/item/clothing/suit/storage/vest/hos, + /obj/item/clothing/suit/storage/vest/pcrc, + /obj/item/clothing/suit/storage/vest/detective, + /obj/item/clothing/suit/storage/vest/heavy, + /obj/item/clothing/suit/storage/vest/heavy/officer, + /obj/item/clothing/suit/storage/vest/heavy/warden, + /obj/item/clothing/suit/storage/vest/heavy/hos, + /obj/item/clothing/suit/storage/vest/heavy/pcrc) + name = "Armor crate" - contains = list(/obj/item/clothing/head/helmet, - /obj/item/clothing/head/helmet, - /obj/item/clothing/suit/armor/vest, - /obj/item/clothing/suit/armor/vest) - cost = 15 + cost = 40 containertype = /obj/structure/closet/crate/secure containername = "Armor crate" access = access_security group = "Security" + /datum/supply_packs/riot name = "Riot gear crate" contains = list(/obj/item/weapon/melee/baton, @@ -731,9 +766,6 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/weapon/shield/riot, /obj/item/weapon/shield/riot, /obj/item/weapon/shield/riot, - /obj/item/weapon/storage/box/flashbangs, - /obj/item/weapon/storage/box/flashbangs, - /obj/item/weapon/storage/box/flashbangs, /obj/item/weapon/handcuffs, /obj/item/weapon/handcuffs, /obj/item/weapon/handcuffs, @@ -742,23 +774,38 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/clothing/head/helmet/riot, /obj/item/clothing/suit/armor/riot, /obj/item/clothing/head/helmet/riot, - /obj/item/clothing/suit/armor/riot) + /obj/item/clothing/suit/armor/riot, + /obj/item/weapon/storage/box/flashbangs, + /obj/item/weapon/storage/box/beanbags, + /obj/item/weapon/storage/box/handcuffs) cost = 60 containertype = /obj/structure/closet/crate/secure containername = "Riot gear crate" access = access_armory group = "Security" - -/datum/supply_packs/ballistic - name = "Ballistic gear crate" - contains = list(/obj/item/clothing/suit/armor/bulletproof, - /obj/item/clothing/suit/armor/bulletproof, - /obj/item/weapon/gun/projectile/shotgun/pump/combat, - /obj/item/weapon/gun/projectile/shotgun/pump/combat) +/datum/supply_packs/energyweapons + name = "Energy weapons crate" + contains = list(/obj/item/weapon/gun/energy/laser, + /obj/item/weapon/gun/energy/laser, + /obj/item/weapon/gun/energy/laser) cost = 50 containertype = /obj/structure/closet/crate/secure - containername = "Ballistic gear crate" + containername = "energy weapons crate" + access = access_armory + group = "Security" + +/datum/supply_packs/shotgun + name = "Shotgun crate" + contains = list(/obj/item/clothing/suit/armor/bulletproof, + /obj/item/clothing/suit/armor/bulletproof, + /obj/item/weapon/storage/box/shotgunammo, + /obj/item/weapon/storage/box/shotgunshells, + /obj/item/weapon/gun/projectile/shotgun/pump/combat, + /obj/item/weapon/gun/projectile/shotgun/pump/combat) + cost = 65 + containertype = /obj/structure/closet/crate/secure + containername = "Shotgun crate" access = access_armory group = "Security" @@ -768,20 +815,55 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/clothing/suit/armor/laserproof, /obj/item/weapon/gun/energy/sniperrifle, /obj/item/weapon/gun/energy/sniperrifle) - cost = 50 + cost = 90 containertype = /obj/structure/closet/crate/secure containername = "Energy marksman crate" access = access_armory group = "Security" /datum/supply_packs/shotgunammo - name = "Shotgun shells" + name = "Ballistic ammunition crate" contains = list(/obj/item/weapon/storage/box/shotgunammo, /obj/item/weapon/storage/box/shotgunammo, - /obj/item/weapon/storage/box/shotgunammo) + /obj/item/weapon/storage/box/shotgunshells, + /obj/item/weapon/storage/box/shotgunshells) cost = 60 containertype = /obj/structure/closet/crate/secure - containername = "Shotgun shells" + containername = "ballistic ammunition crate" + access = access_armory + group = "Security" + +/datum/supply_packs/ionweapons + name = "Electromagnetic weapons crate" + contains = list(/obj/item/weapon/gun/energy/ionrifle, + /obj/item/weapon/gun/energy/ionrifle, + /obj/item/weapon/storage/box/emps) + cost = 50 + containertype = /obj/structure/closet/crate/secure + containername = "electromagnetic weapons crate" + access = access_armory + group = "Security" + +/datum/supply_packs/randomised/automatic + name = "Automatic weapon crate" + num_contained = 2 + contains = list(/obj/item/weapon/gun/projectile/automatic/wt550, + /obj/item/weapon/gun/projectile/automatic/z8) + cost = 90 + containertype = /obj/structure/closet/crate/secure + containername = "Automatic weapon crate" + access = access_armory + group = "Security" + +/datum/supply_packs/randomised/autoammo + name = "Automatic weapon ammunition crate" + num_contained = 6 + contains = list(/obj/item/ammo_magazine/mc9mmt, + /obj/item/ammo_magazine/mc9mmt/rubber, + /obj/item/ammo_magazine/a556) + cost = 20 + containertype = /obj/structure/closet/crate/secure + containername = "Automatic weapon ammunition crate" access = access_armory group = "Security" @@ -887,10 +969,9 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/weapon/reagent_containers/glass/paint/green, /obj/item/weapon/reagent_containers/glass/paint/blue, /obj/item/weapon/reagent_containers/glass/paint/yellow, - /obj/item/weapon/reagent_containers/glass/paint/violet, + /obj/item/weapon/reagent_containers/glass/paint/purple, /obj/item/weapon/reagent_containers/glass/paint/black, /obj/item/weapon/reagent_containers/glass/paint/white, - /obj/item/weapon/reagent_containers/glass/paint/remover, /obj/item/weapon/contraband/poster, /obj/item/weapon/wrapping_paper, /obj/item/weapon/wrapping_paper, @@ -955,8 +1036,13 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee name = "Sterile equipment crate" contains = list(/obj/item/clothing/under/rank/medical/green, /obj/item/clothing/under/rank/medical/green, + /obj/item/clothing/head/surgery/green, + /obj/item/clothing/head/surgery/green, /obj/item/weapon/storage/box/masks, - /obj/item/weapon/storage/box/gloves) + /obj/item/weapon/storage/box/gloves, + /obj/item/weapon/storage/belt/medical, + /obj/item/weapon/storage/belt/medical, + /obj/item/weapon/storage/belt/medical) cost = 15 containertype = "/obj/structure/closet/crate" containername = "Sterile equipment crate" @@ -1234,14 +1320,6 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/clothing/glasses/sunglasses/sechud/tactical, /obj/item/weapon/storage/belt/security/tactical, /obj/item/clothing/shoes/jackboots, - /obj/item/clothing/gloves/black, - /obj/item/clothing/under/tactical, - /obj/item/clothing/suit/armor/tactical, - /obj/item/clothing/head/helmet/tactical, - /obj/item/clothing/mask/balaclava/tactical, - /obj/item/clothing/glasses/sunglasses/sechud/tactical, - /obj/item/weapon/storage/belt/security/tactical, - /obj/item/clothing/shoes/jackboots, /obj/item/clothing/gloves/black) /datum/supply_packs/carpet @@ -1379,10 +1457,10 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /datum/supply_packs/randomised/webbing name = "Webbing crate" num_contained = 1 - contains = list(/obj/item/clothing/tie/holster, - /obj/item/clothing/tie/storage/brown_vest, - /obj/item/clothing/tie/storage/webbing, - /obj/item/clothing/tie/storage) + contains = list(/obj/item/clothing/accessory/holster, + /obj/item/clothing/accessory/storage/brown_vest, + /obj/item/clothing/accessory/storage/webbing, + /obj/item/clothing/accessory/storage) cost = 15 containertype = /obj/structure/closet/crate containername = "Webbing crate" @@ -1417,5 +1495,16 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee /obj/item/clothing/under/dress/dress_saloon) group = "Miscellaneous" +/datum/supply_packs/painters + name = "Station Painting Supplies" + cost = 10 + containername = "station painting supplies crate" + containertype = /obj/structure/closet/crate + group = "Engineering" + contains = list(/obj/item/device/pipe_painter, + /obj/item/device/pipe_painter, + /obj/item/device/floor_painter, + /obj/item/device/floor_painter) + diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index f8b796269f..7e8c8779cf 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -35,9 +35,9 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 /datum/wires/airlock/GetInteractWindow() var/obj/machinery/door/airlock/A = holder var/haspower = A.arePowerSystemsOn() //If there's no power, then no lights will be on. - + . += ..() - . += text("
    \n[]
    \n[]
    \n[]
    \n[]
    \n[]
    \n[]
    \n[]", + . += text("
    \n[]
    \n[]
    \n[]
    \n[]
    \n[]
    \n[]
    \n[]", (A.locked ? "The door bolts have fallen!" : "The door bolts look up."), ((A.lights && haspower) ? "The door bolt lights are on." : "The door bolt lights are off!"), ((haspower) ? "The test light is on." : "The test light is off!"), @@ -59,9 +59,8 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 A.loseMainPower() A.shock(usr, 50) else - if((!IsIndexCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!IsIndexCut(AIRLOCK_WIRE_MAIN_POWER2))) - A.regainMainPower() - A.shock(usr, 50) + A.regainMainPower() + A.shock(usr, 50) if(AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) @@ -70,16 +69,14 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 A.loseBackupPower() A.shock(usr, 50) else - if((!IsIndexCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!IsIndexCut(AIRLOCK_WIRE_BACKUP_POWER2))) - A.regainBackupPower() - A.shock(usr, 50) + A.regainBackupPower() + A.shock(usr, 50) if(AIRLOCK_WIRE_DOOR_BOLTS) if(!mended) //Cutting this wire also drops the door bolts, and mending it does not raise them. (This is what happens now, except there are a lot more wires going to door bolts at present) - if(A.locked!=1) - A.locked = 1 + A.lock(1) A.update_icon() if(AIRLOCK_WIRE_AI_CONTROL) @@ -98,16 +95,11 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 A.aiControlDisabled = -1 if(AIRLOCK_WIRE_ELECTRIFY) - if(!mended) //Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. - if(A.secondsElectrified != -1) - A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])") - add_logs(usr, A, "electrified", admin=0, addition="at [A.x],[A.y],[A.z]") - A.secondsElectrified = -1 + A.electrify(-1) else - if(A.secondsElectrified == -1) - A.secondsElectrified = 0 + A.electrify(0) return // Don't update the dialog. if (AIRLOCK_WIRE_SAFETY) @@ -139,13 +131,9 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 //one wire for door bolts. Sending a pulse through this drops door bolts if they're not down (whether power's on or not), //raises them if they are down (only if power's on) if(!A.locked) - A.locked = 1 - A.audible_message("You hear a click from the bottom of the door.", null, 1) + A.lock() else - if(A.arePowerSystemsOn()) //only can raise bolts if power's on - A.locked = 0 - A.audible_message("You hear a click from the bottom of the door.", null, 1) - A.update_icon() + A.unlock() if(AIRLOCK_WIRE_BACKUP_POWER1 || AIRLOCK_WIRE_BACKUP_POWER2) //two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter). @@ -165,19 +153,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 if(AIRLOCK_WIRE_ELECTRIFY) //one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. - if(A.secondsElectrified==0) - A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])") - add_logs(usr, A, "electrified", admin=0, addition="at [A.x],[A.y],[A.z]") - A.secondsElectrified = 30 - spawn(10) - if(A) - //TODO: Move this into process() and make pulsing reset secondsElectrified to 30 - while (A.secondsElectrified>0) - A.secondsElectrified-=1 - if(A.secondsElectrified<0) - A.secondsElectrified = 0 - sleep(10) - return + A.electrify(30) if(AIRLOCK_WIRE_OPEN_DOOR) //tries to open the door without ID //will succeed only if the ID wire is cut or the door requires no access and it's not emagged diff --git a/code/datums/wires/alarm.dm b/code/datums/wires/alarm.dm index 6ebc937265..c34b0291fb 100644 --- a/code/datums/wires/alarm.dm +++ b/code/datums/wires/alarm.dm @@ -46,7 +46,7 @@ var/const/AALARM_WIRE_AALARM = 16 //world << "Syphon Wire Cut" if(AALARM_WIRE_AALARM) - if (A.alarm_area.atmosalert(2)) + if (A.alarm_area.atmosalert(2, A)) A.post_alert(2) A.update_icon() @@ -88,6 +88,6 @@ var/const/AALARM_WIRE_AALARM = 16 if(AALARM_WIRE_AALARM) // world << "Aalarm wire pulsed" - if (A.alarm_area.atmosalert(0)) + if (A.alarm_area.atmosalert(0, A)) A.post_alert(0) A.update_icon() diff --git a/code/datums/wires/robot.dm b/code/datums/wires/robot.dm index 73555f3889..da20f1bd05 100644 --- a/code/datums/wires/robot.dm +++ b/code/datums/wires/robot.dm @@ -34,8 +34,7 @@ var/const/BORG_WIRE_CAMERA = 16 if (BORG_WIRE_AI_CONTROL) //Cut the AI wire to reset AI control if(!mended) - if (R.connected_ai) - R.connected_ai = null + R.disconnect_from_ai() if (BORG_WIRE_CAMERA) if(!isnull(R.camera) && !R.scrambledcodes) @@ -56,12 +55,8 @@ var/const/BORG_WIRE_CAMERA = 16 if (BORG_WIRE_AI_CONTROL) //pulse the AI wire to make the borg reselect an AI if(!R.emagged) var/mob/living/silicon/ai/new_ai = select_active_ai(R) - if(new_ai && (new_ai != R.connected_ai)) - R.connected_ai.connected_robots -= src - R.connected_ai = new_ai - new_ai.connected_robots += src - R.notify_ai(1) - R.sync() + R.connect_to_ai(new_ai) + if (BORG_WIRE_CAMERA) if(!isnull(R.camera) && R.camera.can_use() && !R.scrambledcodes) R.camera.kick_viewers() // Kick anyone watching the Cyborg's camera diff --git a/code/datums/wires/vending.dm b/code/datums/wires/vending.dm index 91a95b47a7..7f9c4ed10a 100644 --- a/code/datums/wires/vending.dm +++ b/code/datums/wires/vending.dm @@ -1,3 +1,5 @@ +#define CAT_HIDDEN 2 // Also in code/game/machinery/vending.dm + /datum/wires/vending holder_type = /obj/machinery/vending wire_count = 4 @@ -17,17 +19,12 @@ var/const/VENDING_WIRE_IDSCAN = 8 return 1 return 0 -/datum/wires/vending/Interact(var/mob/living/user) - if(CanUse(user)) - var/obj/machinery/vending/V = holder - V.attack_hand(user) - /datum/wires/vending/GetInteractWindow() var/obj/machinery/vending/V = holder . += ..() . += "
    The orange light is [V.seconds_electrified ? "off" : "on"].
    " . += "The red light is [V.shoot_inventory ? "off" : "blinking"].
    " - . += "The green light is [V.extended_inventory ? "on" : "off"].
    " + . += "The green light is [(V.categories & CAT_HIDDEN) ? "on" : "off"].
    " . += "The [V.scan_id ? "purple" : "yellow"] light is on.
    " /datum/wires/vending/UpdatePulsed(var/index) @@ -36,7 +33,7 @@ var/const/VENDING_WIRE_IDSCAN = 8 if(VENDING_WIRE_THROW) V.shoot_inventory = !V.shoot_inventory if(VENDING_WIRE_CONTRABAND) - V.extended_inventory = !V.extended_inventory + V.categories ^= CAT_HIDDEN if(VENDING_WIRE_ELECTRIFY) V.seconds_electrified = 30 if(VENDING_WIRE_IDSCAN) @@ -48,7 +45,7 @@ var/const/VENDING_WIRE_IDSCAN = 8 if(VENDING_WIRE_THROW) V.shoot_inventory = !mended if(VENDING_WIRE_CONTRABAND) - V.extended_inventory = 0 + V.categories &= ~CAT_HIDDEN if(VENDING_WIRE_ELECTRIFY) if(mended) V.seconds_electrified = 0 diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index ab7b57cb42..bb81eabbc5 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -24,17 +24,6 @@ var/mode = 1 w_class = 3.0 -/obj/item/weapon/bananapeel - name = "banana peel" - desc = "A peel from a banana." - icon = 'icons/obj/items.dmi' - icon_state = "banana_peel" - item_state = "banana_peel" - w_class = 2.0 - throwforce = 0 - throw_speed = 4 - throw_range = 20 - /obj/item/weapon/soap name = "soap" desc = "A cheap bar of soap. Doesn't smell." @@ -67,7 +56,7 @@ icon_state = "bike_horn" item_state = "bike_horn" throwforce = 3 - w_class = 1.0 + w_class = 2 throw_speed = 3 throw_range = 15 attack_verb = list("HONKED") @@ -84,7 +73,6 @@ throw_speed = 4 throw_range = 5 - /obj/item/weapon/cane name = "cane" desc = "A cane used by a true gentlemen. Or a clown." @@ -98,6 +86,46 @@ matter = list("metal" = 50) attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed") +/obj/item/weapon/cane/concealed + var/concealed_blade + +/obj/item/weapon/cane/concealed/New() + ..() + concealed_blade = new/obj/item/weapon/butterfly/switchblade(src) + +/obj/item/weapon/cane/concealed/attack_self(mob/user) + if(concealed_blade) + user.visible_message("[user] has unsheathed \a [concealed_blade] from \his [src]!", "You unsheathe \the [concealed_blade] from \the [src].") + // Calling drop/put in hands to properly call item drop/pickup procs + playsound(user.loc, 'sound/weapons/flipblade.ogg', 50, 1) + user.drop_from_inventory(src) + user.put_in_hands(concealed_blade) + user.put_in_hands(src) + concealed_blade = null + update_icon() + else + ..() + +/obj/item/weapon/cane/concealed/attackby(var/obj/item/weapon/butterfly/W, var/mob/user) + if(!src.concealed_blade && istype(W)) + user.visible_message("[user] has sheathed \a [W] into \his [src]!", "You sheathe \the [W] into \the [src].") + user.drop_from_inventory(W) + W.loc = src + src.concealed_blade = W + update_icon() + else + ..() + +/obj/item/weapon/cane/concealed/update_icon() + if(concealed_blade) + name = initial(name) + icon_state = initial(icon_state) + item_state = initial(icon_state) + else + name = "cane shaft" + icon_state = "nullrod" + item_state = "foldcane" + /obj/item/weapon/disk name = "disk" icon = 'icons/obj/items.dmi' @@ -395,6 +423,22 @@ ///////////////////////////////////////Stock Parts ///////////////////////////////// +/obj/item/weapon/storage/part_replacer + name = "rapid part exchange device" + desc = "Special mechanical module made to store, sort, and apply standard machine parts." + icon_state = "RPED" + item_state = "RPED" + w_class = 5 + can_hold = list(/obj/item/weapon/stock_parts) + storage_slots = 50 + use_to_pickup = 1 + allow_quick_gather = 1 + allow_quick_empty = 1 + collection_mode = 1 + display_contents_with_number = 1 + max_w_class = 3 + max_storage_space = 100 + /obj/item/weapon/stock_parts name = "stock part" desc = "What?" diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index d3aef96c45..3e5454d8ac 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -36,8 +36,8 @@ var/tmp/message_title = new_title ? new_title : title var/tmp/message_sound = new_sound ? sound(new_sound) : sound - message = trim_strip_html_properly(message) - message_title = html_encode(message_title) + message = sanitize(message, extra = 0) + message_title = sanitizeSafe(message_title) Message(message, message_title) if(do_newscast) diff --git a/code/defines/procs/hud.dm b/code/defines/procs/hud.dm index be678b8397..e572176ef9 100644 --- a/code/defines/procs/hud.dm +++ b/code/defines/procs/hud.dm @@ -12,12 +12,15 @@ proc/process_med_hud(var/mob/M, var/local_scanner, var/mob/Alt) if(P.Mob.see_invisible < patient.invisibility) continue - if(!(local_scanner || hassensorlevel(patient, SUIT_SENSOR_VITAL))) - continue - - P.Client.images += patient.hud_list[HEALTH_HUD] if(local_scanner) + P.Client.images += patient.hud_list[HEALTH_HUD] P.Client.images += patient.hud_list[STATUS_HUD] + else + var/sensor_level = getsensorlevel(patient) + if(sensor_level >= SUIT_SENSOR_VITAL) + P.Client.images += patient.hud_list[HEALTH_HUD] + if(sensor_level >= SUIT_SENSOR_BINARY) + P.Client.images += patient.hud_list[LIFE_HUD] //Security HUDs. Pass a value for the second argument to enable implant viewing or other special features. proc/process_sec_hud(var/mob/M, var/advanced_mode, var/mob/Alt) diff --git a/code/game/antagonist/alien/borer.dm b/code/game/antagonist/alien/borer.dm new file mode 100644 index 0000000000..2b45d1f778 --- /dev/null +++ b/code/game/antagonist/alien/borer.dm @@ -0,0 +1,51 @@ +var/datum/antagonist/xenos/borer/borers + +/datum/antagonist/xenos/borer + id = MODE_BORER + role_text = "Cortical Borer" + role_text_plural = "Cortical Borers" + mob_path = /mob/living/simple_animal/borer + bantype = "Borer" + welcome_text = "Use your Infest power to crawl into the ear of a host and fuse with their brain. You can only take control temporarily, and at risk of hurting your host, so be clever and careful; your host is encouraged to help you however they can. Talk to your fellow borers with :x." + var/list/hosts = list() + +/datum/antagonist/xenos/borer/New() + ..(1) + borers = src + +/datum/antagonist/xenos/borer/get_extra_panel_options(var/datum/mind/player) + return "\[put in host\]" + +/datum/antagonist/xenos/borer/create_objectives(var/datum/mind/player) + if(!..()) + return + player.objectives += new /datum/objective/borer_survive() + player.objectives += new /datum/objective/borer_reproduce() + player.objectives += new /datum/objective/escape() + +/datum/antagonist/xenos/borer/proc/place_in_host(var/mob/living/simple_animal/borer/borer, var/mob/living/carbon/human/host) + borer.host = host + borer.host_brain.name = host.name + borer.host_brain.real_name = host.real_name + var/datum/organ/external/head = host.get_organ("head") + head.implants += borer + +/datum/antagonist/xenos/borer/proc/get_hosts() + var/list/possible_hosts = list() + for(var/mob/living/carbon/human/H in mob_list) + if(H.stat != 2 && !(H.species.flags & IS_SYNTHETIC) && !H.has_brain_worms()) + possible_hosts |= H + return possible_hosts + +/datum/antagonist/xenos/borer/place_all_mobs() + var/list/possible_hosts = get_hosts() + for(var/datum/mind/player in current_antagonists) + if(!possible_hosts.len) + return + var/mob/host = pick(possible_hosts) + possible_hosts -= host + place_in_host(player, host) + +/datum/antagonist/xenos/borer/place_mob(var/mob/living/mob) + var/list/possible_hosts = get_hosts() + if(possible_hosts.len) place_in_host(mob, pick(possible_hosts)) diff --git a/code/game/antagonist/alien/xenomorph.dm b/code/game/antagonist/alien/xenomorph.dm new file mode 100644 index 0000000000..1ab79f26b5 --- /dev/null +++ b/code/game/antagonist/alien/xenomorph.dm @@ -0,0 +1,59 @@ +var/datum/antagonist/xenos/xenomorphs + +/datum/antagonist/xenos + id = MODE_XENOMORPH + role_type = BE_ALIEN + role_text = "Xenomorph" + role_text_plural = "Xenomorphs" + mob_path = /mob/living/carbon/alien/larva + bantype = "Xenomorph" + flags = ANTAG_OVERRIDE_MOB | ANTAG_RANDSPAWN | ANTAG_OVERRIDE_JOB | ANTAG_VOTABLE + welcome_text = "Hiss! You are a larval alien. Hide and bide your time until you are ready to evolve." + + max_antags = 5 + max_antags_round = 8 + + spawn_announcement = "Unidentified lifesigns detected coming aboard the station. Secure any exterior access, including ducting and ventilation." + spawn_announcement_title = "Lifesign Alert" + spawn_announcement_sound = 'sound/AI/aliens.ogg' + spawn_announcement_delay = 400 + +/datum/antagonist/xenos/New(var/no_reference) + ..() + if(!no_reference) + xenomorphs = src + +/datum/antagonist/xenos/Topic(href, href_list) + if (..()) + return + if(href_list["move_to_spawn"]) place_mob(href_list["move_to_spawn"]) + +/datum/antagonist/xenos/get_extra_panel_options(var/datum/mind/player) + return "\[move to vent\]" + +/datum/antagonist/xenos/random_spawn() + if(config.aliens_allowed) ..() + +/datum/antagonist/xenos/proc/get_vents() + var/list/vents = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines) + if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in config.station_levels) + if(temp_vent.network.normal_members.len > 50) + vents += temp_vent + return vents + +/datum/antagonist/xenos/create_objectives(var/datum/mind/player) + if(!..()) + return + player.objectives += new /datum/objective/survive() + player.objectives += new /datum/objective/escape() + +/datum/antagonist/xenos/place_all_mobs() + var/list/vents = get_vents() + for(var/datum/mind/player in current_antagonists) + var/obj/machinery/atmospherics/unary/vent_pump/temp_vent = pick(vents) + vents -= temp_vent + player.current.loc = get_turf(temp_vent) + +/datum/antagonist/xenos/place_mob(var/mob/living/player) + player.loc = get_turf(pick(get_vents())) diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm new file mode 100644 index 0000000000..73e17a2043 --- /dev/null +++ b/code/game/antagonist/antagonist.dm @@ -0,0 +1,250 @@ +/datum/antagonist + + var/role_type = BE_TRAITOR + var/role_text = "Traitor" + var/role_text_plural = "Traitors" + var/welcome_text = "Cry havoc and let slip the dogs of war!" + var/leader_welcome_text + var/victory_text + var/loss_text + var/victory_feedback_tag + var/loss_feedback_tag + var/max_antags = 3 + var/max_antags_round = 5 + + // Random spawn values. + var/spawn_announcement + var/spawn_announcement_title + var/spawn_announcement_sound + var/spawn_announcement_delay + + var/id = "traitor" + var/landmark_id + var/antag_indicator + var/mob_path = /mob/living/carbon/human + var/feedback_tag = "traitor_objective" + var/bantype = "Syndicate" + var/suspicion_chance = 50 + var/flags = 0 + var/cur_max = 0 + + var/datum/mind/leader + var/spawned_nuke + var/nuke_spawn_loc + + var/list/valid_species = list("Unathi","Tajara","Skrell","Human") // Used for setting appearance. + var/list/starting_locations = list() + var/list/current_antagonists = list() + var/list/global_objectives = list() + var/list/restricted_jobs = list() + var/list/protected_jobs = list() + var/list/candidates = list() + + var/default_access = list() + var/id_type = /obj/item/weapon/card/id + +/datum/antagonist/New() + ..() + cur_max = max_antags + get_starting_locations() + if(config.protect_roles_from_antagonist) + restricted_jobs |= protected_jobs + +/datum/antagonist/proc/tick() + return 1 + +/datum/antagonist/proc/get_panel_entry(var/datum/mind/player) + + var/dat = "[role_text]:" + var/extra = get_extra_panel_options(player) + if(is_antagonist(player)) + dat += "\[-\]" + dat += "\[equip\]" + if(starting_locations && starting_locations.len) + dat += "\[move to spawn\]" + if(extra) dat += "[extra]" + else + dat += "\[+\]" + dat += "" + + return dat + +/datum/antagonist/proc/get_extra_panel_options() + return + +/datum/antagonist/proc/get_starting_locations() + if(landmark_id) + starting_locations = list() + for(var/obj/effect/landmark/L in landmarks_list) + if(L.name == landmark_id) + starting_locations |= get_turf(L) + +/datum/antagonist/proc/place_all_mobs() + if(!starting_locations || !starting_locations.len || !current_antagonists || !current_antagonists.len) + return + for(var/datum/mind/player in current_antagonists) + player.current.loc = pick(starting_locations) + +/datum/antagonist/proc/finalize(var/datum/mind/target) + + // This will fail if objectives have already been generated. + create_global_objectives() + + if(leader && flags & ANTAG_HAS_NUKE && !spawned_nuke) + make_nuke(leader) + + if(target) + apply(target) + create_objectives(target) + update_icons_added(target) + greet(target) + return + + for(var/datum/mind/player in current_antagonists) + apply(player) + equip(player.current) + create_objectives(player) + update_icons_added(player) + greet(player) + + place_all_mobs() + + spawn(1) + if(spawn_announcement) + if(spawn_announcement_delay) + sleep(spawn_announcement_delay) + if(spawn_announcement_sound) + command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]", new_sound = spawn_announcement_sound) + else + command_announcement.Announce("[spawn_announcement]", "[spawn_announcement_title ? spawn_announcement_title : "Priority Alert"]") + + +/datum/antagonist/proc/print_player_summary() + + if(!current_antagonists.len) + return 0 + + var/text = "
    The [current_antagonists.len == 1 ? "[role_text] was" : "[role_text_plural] were"]:" + for(var/datum/mind/P in current_antagonists) + text += print_player_full(P) + text += get_special_objective_text(P) + var/failed + if(!global_objectives.len && P.objectives && P.objectives.len) + var/num = 1 + for(var/datum/objective/O in P.objectives) + text += print_objective(O, num) + if(O.completed) // This is set actively in check_victory() + text += "Success!" + feedback_add_details(feedback_tag,"[O.type]|SUCCESS") + else + text += "Fail." + feedback_add_details(feedback_tag,"[O.type]|FAIL") + failed = 1 + num++ + + if(!config.objectives_disabled) + if(failed) + text += "
    The [role_text] has failed." + else + text += "
    The [role_text] was successful!" + + if(global_objectives && global_objectives.len) + text += "
    Their objectives were:" + var/num = 1 + for(var/datum/objective/O in global_objectives) + text += print_objective(O, num, 1) + num++ + + // Display the results. + world << text + +/datum/antagonist/proc/print_objective(var/datum/objective/O, var/num, var/append_success) + var/text = "
    Objective [num]: [O.explanation_text] " + if(append_success) + if(O.check_completion()) + text += "Success!" + else + text += "Fail." + return text + +/datum/antagonist/proc/print_player_lite(var/datum/mind/ply) + var/role = ply.assigned_role == "MODE" ? "\improper[ply.special_role]" : "\improper[ply.assigned_role]" + var/text = "
    [ply.name] ([ply.key]) as \a [role] (" + if(ply.current) + if(ply.current.stat == DEAD) + text += "died" + else if(isNotStationLevel(ply.current.z)) + text += "fled the station" + else + text += "survived" + if(ply.current.real_name != ply.name) + text += " as [ply.current.real_name]" + else + text += "body destroyed" + text += ")" + + return text + +/datum/antagonist/proc/print_player_full(var/datum/mind/ply) + var/text = print_player_lite(ply) + + var/TC_uses = 0 + var/uplink_true = 0 + var/purchases = "" + for(var/obj/item/device/uplink/H in world_uplinks) + if(H && H.uplink_owner && H.uplink_owner == ply) + TC_uses += H.used_TC + uplink_true = 1 + var/list/refined_log = new() + for(var/datum/uplink_item/UI in H.purchase_log) + var/obj/I = new UI.path + refined_log.Add("[H.purchase_log[UI]]x\icon[I][UI.name]") + del(I) + purchases = english_list(refined_log, nothing_text = "") + if(uplink_true) + text += " (used [TC_uses] TC)" + if(purchases) + text += "
    [purchases]" + + return text + +/datum/antagonist/proc/update_all_icons() + if(!antag_indicator) + return + for(var/datum/mind/antag in current_antagonists) + if(antag.current && antag.current.client) + for(var/image/I in antag.current.client.images) + if(I.icon_state == antag_indicator) + del(I) + for(var/datum/mind/other_antag in current_antagonists) + if(other_antag.current) + antag.current.client.images |= image('icons/mob/mob.dmi', loc = other_antag.current, icon_state = antag_indicator) + +/datum/antagonist/proc/update_icons_added(var/datum/mind/player) + if(!antag_indicator || !player.current) + return + spawn(0) + for(var/datum/mind/antag in current_antagonists) + if(!antag.current) + continue + if(antag.current.client) + antag.current.client.images |= image('icons/mob/mob.dmi', loc = player.current, icon_state = antag_indicator) + if(player.current.client) + player.current.client.images |= image('icons/mob/mob.dmi', loc = antag.current, icon_state = antag_indicator) + +/datum/antagonist/proc/update_icons_removed(var/datum/mind/player) + if(!antag_indicator || !player.current) + return + spawn(0) + for(var/datum/mind/antag in current_antagonists) + if(antag.current) + if(antag.current.client) + for(var/image/I in antag.current.client.images) + if(I.icon_state == antag_indicator && I.loc == player.current) + del(I) + if(player.current && player.current.client) + for(var/image/I in player.current.client.images) + if(I.icon_state == antag_indicator) + del(I) + + diff --git a/code/game/antagonist/antagonist_build.dm b/code/game/antagonist/antagonist_build.dm new file mode 100644 index 0000000000..f0f92c62b7 --- /dev/null +++ b/code/game/antagonist/antagonist_build.dm @@ -0,0 +1,124 @@ +/datum/antagonist/proc/create_objectives(var/datum/mind/player) + if(config.objectives_disabled) + return 0 + if(global_objectives && global_objectives.len) + player.objectives |= global_objectives + return 1 + +/datum/antagonist/proc/apply(var/datum/mind/player) + + if(flags & ANTAG_HAS_LEADER && !leader) + leader = current_antagonists[1] + + // Get the mob. + if((flags & ANTAG_OVERRIDE_MOB) && (!player.current || (mob_path && !istype(player.current, mob_path)))) + var/mob/holder = player.current + player.current = new mob_path(get_turf(player.current)) + player.transfer_to(player.current) + if(holder) del(holder) + + player.original = player.current + return player.current + +/datum/antagonist/proc/equip(var/mob/living/carbon/human/player) + + if(!istype(player)) + return 0 + + // This could use work. + if(flags & ANTAG_CLEAR_EQUIPMENT) + for(var/obj/item/thing in player.contents) + del(thing) + return 1 + + if(flags & ANTAG_SET_APPEARANCE) + player.change_appearance(APPEARANCE_ALL, player, player, valid_species) + +/datum/antagonist/proc/unequip(var/mob/living/carbon/human/player) + if(!istype(player)) + return 0 + return 1 + +/datum/antagonist/proc/greet(var/datum/mind/player) + + // Basic intro text. + player.current << "You are a [role_text]!" + if(leader_welcome_text && player.current == leader) + player.current << "[leader_welcome_text]" + else + player.current << "[welcome_text]" + show_objectives(player) + + // Choose a name, if any. + if(flags & ANTAG_CHOOSE_NAME) + spawn(5) + var/newname = sanitize(input(player.current, "You are a [role_text]. Would you like to change your name to something else?", "Name change") as null|text, MAX_NAME_LEN) + if (newname) + player.current.real_name = newname + player.current.name = player.current.real_name + player.name = player.current.name + // Update any ID cards. + update_access(player.current) + + // Clown clumsiness check, I guess downstream might use it. + if (player.current.mind) + if (player.current.mind.assigned_role == "Clown") + player.current << "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself." + player.current.mutations.Remove(CLUMSY) + return 1 + +/datum/antagonist/proc/update_access(var/mob/living/player) + for(var/obj/item/weapon/card/id/id in player.contents) + id.name = "[player.real_name]'s ID Card" + id.registered_name = player.real_name + +/datum/antagonist/proc/random_spawn() + create_global_objectives() + attempt_spawn(flags & (ANTAG_OVERRIDE_MOB|ANTAG_OVERRIDE_JOB)) + finalize() + +/datum/antagonist/proc/create_id(var/assignment, var/mob/living/carbon/human/player) + + var/obj/item/weapon/card/id/W = new id_type(player) + W.name = "[player.real_name]'s ID Card" + W.access |= default_access + W.assignment = "[assignment]" + W.registered_name = player.real_name + player.equip_to_slot_or_del(W, slot_wear_id) + return W + +/datum/antagonist/proc/create_radio(var/freq, var/mob/living/carbon/human/player) + var/obj/item/device/radio/R = new /obj/item/device/radio/headset(player) + R.set_frequency(freq) + player.equip_to_slot_or_del(R, slot_l_ear) + return R + +/datum/antagonist/proc/make_nuke(var/atom/paper_spawn_loc, var/datum/mind/code_owner) + + // Decide on a code. + var/obj/effect/landmark/nuke_spawn = locate(nuke_spawn_loc ? nuke_spawn_loc : "landmark*Nuclear-Bomb") + + var/code + if(nuke_spawn) + var/obj/machinery/nuclearbomb/nuke = new(get_turf(nuke_spawn)) + code = "[rand(10000, 99999)]" + nuke.r_code = code + + if(code) + if(!paper_spawn_loc) + paper_spawn_loc = get_turf(locate("landmark*Nuclear-Code")) + if(paper_spawn_loc) + // Create and pass on the bomb code paper. + var/obj/item/weapon/paper/P = new(paper_spawn_loc) + P.info = "The nuclear authorization code is: [code]" + P.name = "nuclear bomb code" + if(code_owner) + code_owner.store_memory("Nuclear Bomb Code: [code]", 0, 0) + code_owner.current << "The nuclear authorization code is: [code]" + + else + world << "Could not spawn nuclear bomb. Contact a developer.
    " + return + + spawned_nuke = code + return code diff --git a/code/game/antagonist/antagonist_globals.dm b/code/game/antagonist/antagonist_globals.dm new file mode 100644 index 0000000000..02ec5304fc --- /dev/null +++ b/code/game/antagonist/antagonist_globals.dm @@ -0,0 +1,41 @@ +var/global/list/all_antag_types = list() +var/global/list/all_antag_spawnpoints = list() +var/global/list/antag_names_to_ids = list() + +/proc/get_antag_data(var/antag_type) + if(all_antag_types[antag_type]) + return all_antag_types[antag_type] + else + for(var/cur_antag_type in all_antag_types) + var/datum/antagonist/antag = all_antag_types[cur_antag_type] + if(antag && antag.is_type(antag_type)) + return antag + +/proc/clear_antag_roles(var/datum/mind/player, var/implanted) + for(var/antag_type in all_antag_types) + var/datum/antagonist/antag = all_antag_types[antag_type] + if(!implanted || !(antag.flags & ANTAG_IMPLANT_IMMUNE)) + antag.remove_antagonist(player, 1, implanted) + +/proc/update_antag_icons(var/datum/mind/player) + for(var/antag_type in all_antag_types) + var/datum/antagonist/antag = all_antag_types[antag_type] + if(player) + antag.update_icons_removed(player) + if(antag.is_antagonist(player)) + antag.update_icons_added(player) + else + antag.update_all_icons() + +/proc/populate_antag_type_list() + for(var/antag_type in typesof(/datum/antagonist)-/datum/antagonist) + var/datum/antagonist/A = new antag_type + all_antag_types[A.id] = A + all_antag_spawnpoints[A.landmark_id] = list() + antag_names_to_ids[A.role_text] = A.id + +/proc/get_antags(var/atype) + var/datum/antagonist/antag = all_antag_types[atype] + if(antag && islist(antag.current_antagonists)) + return antag.current_antagonists + return list() \ No newline at end of file diff --git a/code/game/antagonist/antagonist_helpers.dm b/code/game/antagonist/antagonist_helpers.dm new file mode 100644 index 0000000000..92556a817a --- /dev/null +++ b/code/game/antagonist/antagonist_helpers.dm @@ -0,0 +1,29 @@ +/datum/antagonist/proc/can_become_antag(var/datum/mind/player) + if(player.current && jobban_isbanned(player.current, bantype)) + return 0 + if(player.assigned_role in protected_jobs) + return 0 + if(config.protect_roles_from_antagonist && (player.assigned_role in restricted_jobs)) + return 0 + return 1 + +/datum/antagonist/proc/antags_are_dead() + for(var/datum/mind/antag in current_antagonists) + if(mob_path && !istype(antag.current,mob_path)) + continue + if(antag.current.stat==2) + continue + return 0 + return 1 + +/datum/antagonist/proc/get_antag_count() + return current_antagonists ? current_antagonists.len : 0 + +/datum/antagonist/proc/is_antagonist(var/datum/mind/player) + if(player in current_antagonists) + return 1 + +/datum/antagonist/proc/is_type(var/antag_type) + if(antag_type == id || antag_type == role_text) + return 1 + return 0 diff --git a/code/game/antagonist/antagonist_objectives.dm b/code/game/antagonist/antagonist_objectives.dm new file mode 100644 index 0000000000..58997fa68e --- /dev/null +++ b/code/game/antagonist/antagonist_objectives.dm @@ -0,0 +1,23 @@ +/datum/antagonist/proc/create_global_objectives() + return !((global_objectives && global_objectives.len) || config.objectives_disabled) + +/datum/antagonist/proc/get_special_objective_text() + return "" + +/datum/antagonist/proc/check_victory() + var/result = 1 + if(config.objectives_disabled) + return 1 + if(global_objectives && global_objectives.len) + for(var/datum/objective/O in global_objectives) + if(!O.completed && !O.check_completion()) + result = 0 + else + O.completed = 1 //Will this break anything? + if(result && victory_text) + world << "[victory_text]" + if(victory_feedback_tag) feedback_set_details("round_end_result","[victory_feedback_tag]") + else if(loss_text) + world << "[loss_text]" + if(loss_feedback_tag) feedback_set_details("round_end_result","[loss_feedback_tag]") + diff --git a/code/game/antagonist/antagonist_spawn.dm b/code/game/antagonist/antagonist_spawn.dm new file mode 100644 index 0000000000..c8453663fb --- /dev/null +++ b/code/game/antagonist/antagonist_spawn.dm @@ -0,0 +1,85 @@ +/datum/antagonist/proc/attempt_late_spawn(var/datum/mind/player, var/move_to_spawn) + + update_cur_max() + if(get_antag_count() >= cur_max) + return 0 + + player.current << "You have been selected this round as an antagonist!" + add_antagonist(player) + equip(player.current) + if(move_to_spawn) + place_mob(player.current) + return + +/datum/antagonist/proc/update_cur_max() + + candidates = list() + var/main_type + if(ticker && ticker.mode) + if(ticker.mode.antag_tag && ticker.mode.antag_tag == id) + main_type = 1 + else + return list() + + cur_max = (main_type ? max_antags_round : max_antags) + if(ticker.mode.antag_scaling_coeff) + cur_max = Clamp((ticker.mode.num_players()/ticker.mode.antag_scaling_coeff), 1, cur_max) + +/datum/antagonist/proc/attempt_spawn(var/ghosts_only) + + // Get the raw list of potential players. + update_cur_max() + candidates = get_candidates(ghosts_only) + + // Update our boundaries. + if(!candidates.len) + return 0 + + //Grab candidates randomly until we have enough. + while(candidates.len) + var/datum/mind/player = pick(candidates) + current_antagonists |= player + // Update job and role. + player.special_role = role_text + if(flags & ANTAG_OVERRIDE_JOB) + player.assigned_role = "MODE" + candidates -= player + return 1 + +/datum/antagonist/proc/place_mob(var/mob/living/mob) + if(!starting_locations || !starting_locations.len) + return + mob.loc = pick(starting_locations) + +/datum/antagonist/proc/add_antagonist(var/datum/mind/player) + if(!istype(player)) + return 0 + if(player in current_antagonists) + return 0 + if(!can_become_antag(player)) + return 0 + + current_antagonists |= player + apply(player) + finalize(player) + return 1 + +/datum/antagonist/proc/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted) + if(player in current_antagonists) + player.current << "You are no longer a [role_text]!" + current_antagonists -= player + player.special_role = null + update_icons_removed(player) + BITSET(player.current.hud_updateflag, SPECIALROLE_HUD) + return 1 + return 0 + +/datum/antagonist/proc/get_candidates(var/ghosts_only) + + candidates = list() // Clear. + candidates = ticker.mode.get_players_for_role(role_type, id) + // Prune restricted jobs and status. + for(var/datum/mind/player in candidates) + if((ghosts_only && !istype(player.current, /mob/dead)) || player.special_role || (player.assigned_role in restricted_jobs)) + candidates -= player + return candidates \ No newline at end of file diff --git a/code/game/antagonist/mutiny/loyalist.dm b/code/game/antagonist/mutiny/loyalist.dm new file mode 100644 index 0000000000..36feefc175 --- /dev/null +++ b/code/game/antagonist/mutiny/loyalist.dm @@ -0,0 +1,10 @@ +var/datum/antagonist/mutineer/loyalist/loyalists + +/datum/antagonist/mutineer/loyalist + role_text = "Loyalist" + role_text_plural = "Loyalists" + id = MODE_LOYALIST + +/datum/antagonist/mutineer/loyalist/New() + ..(1) + loyalists = src diff --git a/code/game/antagonist/mutiny/mutineer.dm b/code/game/antagonist/mutiny/mutineer.dm new file mode 100644 index 0000000000..f35655ab1c --- /dev/null +++ b/code/game/antagonist/mutiny/mutineer.dm @@ -0,0 +1,66 @@ +var/datum/antagonist/mutineer/mutineers + +/datum/antagonist/mutineer + role_type = BE_MUTINEER + role_text = "Mutineer" + role_text_plural = "Mutineers" + id = MODE_MUTINEER + antag_indicator = "mutineer" + restricted_jobs = list("Captain") + +/datum/antagonist/mutineer/New(var/no_reference) + ..() + if(!no_reference) + mutineers = src + +/datum/antagonist/mutineer/proc/recruit() + +/datum/antagonist/mutineer/can_become_antag(var/datum/mind/player) + if(!..()) + return 0 + if(!istype(player.current, /mob/living/carbon/human)) + return 0 + if(M.special_role) + return 0 + return 1 + +/* + var/list/directive_candidates = get_directive_candidates() + if(!directive_candidates || directive_candidates.len == 0) + world << "\red Mutiny mode aborted: no valid candidates for Directive X." + return 0 + + head_loyalist = pick(loyalist_candidates) + head_mutineer = pick(mutineer_candidates) + current_directive = pick(directive_candidates) + + + // Returns an array in case we want to expand on this later. + proc/get_head_loyalist_candidates() + var/list/candidates[0] + for(var/mob/loyalist in player_list) + if(loyalist.mind && loyalist.mind.assigned_role == "Captain") + candidates.Add(loyalist.mind) + return candidates + + proc/get_head_mutineer_candidates() + var/list/candidates[0] + for(var/mob/mutineer in player_list) + if(mutineer.client.prefs.be_special & BE_MUTINEER) + for(var/job in command_positions - "Captain") + if(mutineer.mind && mutineer.mind.assigned_role == job) + candidates.Add(mutineer.mind) + return candidates + + proc/get_directive_candidates() + var/list/candidates[0] + for(var/T in typesof(/datum/directive) - /datum/directive) + var/datum/directive/D = new T(src) + if (D.meets_prerequisites()) + candidates.Add(D) + return candidates + + + return 1 + +*/ \ No newline at end of file diff --git a/code/game/antagonist/outsider/commando.dm b/code/game/antagonist/outsider/commando.dm new file mode 100644 index 0000000000..0d3de6cc07 --- /dev/null +++ b/code/game/antagonist/outsider/commando.dm @@ -0,0 +1,30 @@ +var/datum/antagonist/deathsquad/mercenary/commandos + +/datum/antagonist/deathsquad/mercenary + id = MODE_COMMANDO + landmark_id = "Syndicate-Commando" + role_text = "Syndicate Commando" + role_text_plural = "Commandos" + welcome_text = "You are in the employ of a criminal syndicate hostile to NanoTrasen." + +/datum/antagonist/deathsquad/mercenary/New() + ..(1) + commandos = src + +/datum/antagonist/deathsquad/mercenary/equip(var/mob/living/carbon/human/player) + + player.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(player), slot_w_uniform) + player.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/silenced(player), slot_belt) + player.equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(player), slot_shoes) + player.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(player), slot_gloves) + player.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(player), slot_glasses) + player.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate(player), slot_wear_mask) + player.equip_to_slot_or_del(new /obj/item/weapon/storage/box(player), slot_in_backpack) + player.equip_to_slot_or_del(new /obj/item/ammo_magazine/c45(player), slot_in_backpack) + player.equip_to_slot_or_del(new /obj/item/weapon/rig/merc(player), slot_back) + player.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(player), slot_r_hand) + + var/obj/item/weapon/card/id/id = create_id("Commando", player) + id.access |= get_all_accesses() + id.icon_state = "centcom" + create_radio(SYND_FREQ, player) \ No newline at end of file diff --git a/code/game/antagonist/outsider/deathsquad.dm b/code/game/antagonist/outsider/deathsquad.dm new file mode 100644 index 0000000000..05fb6d1ec9 --- /dev/null +++ b/code/game/antagonist/outsider/deathsquad.dm @@ -0,0 +1,83 @@ +var/datum/antagonist/deathsquad/deathsquad + +/datum/antagonist/deathsquad + id = MODE_DEATHSQUAD + role_type = BE_OPERATIVE + role_text = "Death Commando" + role_text_plural = "Death Commandos" + welcome_text = "You work in the service of Central Command Asset Protection, answering directly to the Board of Directors." + landmark_id = "Commando" + flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE + max_antags = 4 + max_antags_round = 6 + default_access = list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage) + var/deployed = 0 + +/datum/antagonist/deathsquad/New(var/no_reference) + ..() + if(!no_reference) + deathsquad = src + +/datum/antagonist/deathsquad/attempt_spawn() + if(..()) + deployed = 1 + +/datum/antagonist/deathsquad/equip(var/mob/living/carbon/human/player) + if (player.mind == leader) + player.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(player), slot_w_uniform) + else + player.equip_to_slot_or_del(new /obj/item/clothing/under/color/green(player), slot_w_uniform) + + player.equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(player), slot_shoes) + player.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(player), slot_gloves) + player.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(player), slot_glasses) + player.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat(player), slot_wear_mask) + if (player.mind == leader) + player.equip_to_slot_or_del(new /obj/item/weapon/pinpointer(player), slot_l_store) + player.equip_to_slot_or_del(new /obj/item/weapon/disk/nuclear(player), slot_r_store) + else + player.equip_to_slot_or_del(new /obj/item/weapon/plastique(player), slot_l_store) + player.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(player), slot_belt) + player.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(player), slot_r_hand) + player.equip_to_slot_or_del(new /obj/item/weapon/rig/combat(player), slot_back) + player.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(player), slot_s_store) + player.implant_loyalty(player) + + var/obj/item/weapon/card/id/id = create_id("Asset Protection", player) + id.access |= get_all_accesses() + id.icon_state = "centcom" + create_radio(DTH_FREQ, player) + +/datum/antagonist/deathsquad/apply(var/datum/mind/player) + + ..() + + var/syndicate_commando_rank + if(leader && player == leader) + syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major") + else + syndicate_commando_rank = pick("Lieutenant", "Captain", "Major") + + var/syndicate_commando_name = pick(last_names) + + var/datum/preferences/A = new() //Randomize appearance for the commando. + A.randomize_appearance_for(player.current) + + player.name = "[syndicate_commando_rank] [syndicate_commando_name]" + player.current.name = player.name + player.current.real_name = player.current.name + + var/mob/living/carbon/human/H = player.current + if(istype(H)) + H.gender = pick(MALE, FEMALE) + H.age = rand(25,45) + H.dna.ready_dna(H) + + return + +/datum/antagonist/deathsquad/finalize(var/datum/mind/target) + + ..() + + if(!deployed) + deployed = 1 diff --git a/code/game/antagonist/outsider/ert.dm b/code/game/antagonist/outsider/ert.dm new file mode 100644 index 0000000000..f52f031002 --- /dev/null +++ b/code/game/antagonist/outsider/ert.dm @@ -0,0 +1,44 @@ +var/datum/antagonist/ert/ert + +/datum/antagonist/ert + id = MODE_ERT + bantype = "Emergency Response Team" + role_type = BE_OPERATIVE + role_text = "Emergency Responder" + role_text_plural = "Emergency Responders" + welcome_text = "As member of the Emergency Response Team, you answer only to your leader and CentComm officials." + leader_welcome_text = "As leader of the Emergency Response Team, you answer only to CentComm, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however." + max_antags = 5 + max_antags_round = 5 // ERT mode? + + flags = ANTAG_OVERRIDE_JOB | ANTAG_SET_APPEARANCE + +/datum/antagonist/ert/New() + ..() + ert = src + +/datum/antagonist/ert/greet(var/datum/mind/player) + if(!..()) + return + player.current << "The Emergency Response Team works for Asset Protection; your job is to protect NanoTrasen's ass-ets. There is a code red alert on [station_name()], you are tasked to go and fix the problem." + player.current << "You should first gear up and discuss a plan with your team. More members may be joining, don't move out before you're ready." + +/datum/antagonist/ert/equip(var/mob/living/carbon/human/player) + + //Special radio setup + player.equip_to_slot_or_del(new /obj/item/device/radio/headset/ert(src), slot_l_ear) + player.equip_to_slot_or_del(new /obj/item/clothing/under/ert(src), slot_w_uniform) + player.equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes) + player.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves) + player.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(src), slot_glasses) + + var/obj/item/weapon/card/id/W = new(src) + W.assignment = "Emergency Response Team" + W.registered_name = player.real_name + W.name = "[player.real_name]'s ID Card ([W.assignment])" + W.icon_state = "centcom" + W.access = get_all_accesses() + W.access += get_all_centcom_access() + player.equip_to_slot_or_del(W, slot_wear_id) + + return 1 diff --git a/code/game/antagonist/outsider/mercenary.dm b/code/game/antagonist/outsider/mercenary.dm new file mode 100644 index 0000000000..72a6a56d62 --- /dev/null +++ b/code/game/antagonist/outsider/mercenary.dm @@ -0,0 +1,59 @@ +var/datum/antagonist/mercenary/mercs + +/datum/antagonist/mercenary + id = MODE_MERCENARY + role_type = BE_OPERATIVE + role_text = "Mercenary" + bantype = "operative" + role_text_plural = "Mercenaries" + landmark_id = "Syndicate-Spawn" + welcome_text = "To speak on the strike team's private channel use :t." + flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_HAS_NUKE | ANTAG_SET_APPEARANCE + max_antags = 4 + max_antags_round = 6 + id_type = /obj/item/weapon/card/id/syndicate + +/datum/antagonist/mercenary/New() + ..() + mercs = src + +/datum/antagonist/mercenary/create_global_objectives() + if(!..()) + return + global_objectives = list() + global_objectives |= new /datum/objective/nuclear + +/datum/antagonist/mercenary/equip(var/mob/living/carbon/human/player) + + if(!..()) + return 0 + + player.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(player), slot_w_uniform) + player.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(player), slot_shoes) + player.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(player), slot_gloves) + if(player.backbag == 2) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(player), slot_back) + if(player.backbag == 3) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(player), slot_back) + if(player.backbag == 4) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(player), slot_back) + player.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(player.back), slot_in_backpack) + player.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(player), slot_in_backpack) + player.update_icons() + + create_id("Mercenary", player) + create_radio(SYND_FREQ, player) + return 1 + +/datum/antagonist/mercenary/place_all_mobs() + var/spawnpos = 1 + for(var/datum/mind/player in current_antagonists) + player.current.loc = starting_locations[spawnpos] + spawnpos++ + if(spawnpos > starting_locations.len) + spawnpos = 1 + +/datum/antagonist/mercenary/make_nuke() + ..() + // Create the radio. + var/obj/effect/landmark/uplinkdevice = locate("landmark*Syndicate-Uplink") + if(uplinkdevice) + var/obj/item/device/radio/uplink/U = new(uplinkdevice.loc) + U.hidden_uplink.uses = 40 \ No newline at end of file diff --git a/code/game/antagonist/outsider/ninja.dm b/code/game/antagonist/outsider/ninja.dm new file mode 100644 index 0000000000..4fed41aa13 --- /dev/null +++ b/code/game/antagonist/outsider/ninja.dm @@ -0,0 +1,170 @@ +var/datum/antagonist/ninja/ninjas + +/datum/antagonist/ninja + id = MODE_NINJA + role_type = BE_NINJA + role_text = "Ninja" + role_text_plural = "Ninja" + bantype = "ninja" + landmark_id = "ninjastart" + welcome_text = "You are an elite mercenary assassin of the Spider Clan. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor." + flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_RANDSPAWN | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE + max_antags = 3 + max_antags_round = 3 + +/datum/antagonist/ninja/New() + ..() + ninjas = src + +/datum/antagonist/ninja/random_spawn() + if(config.ninjas_allowed) ..() + +/datum/antagonist/ninja/create_objectives(var/datum/mind/ninja) + + if(!..()) + return + + var/objective_list = list(1,2,3,4,5) + for(var/i=rand(2,4),i>0,i--) + switch(pick(objective_list)) + if(1)//Kill + var/datum/objective/assassinate/ninja_objective = new + ninja_objective.owner = ninja + ninja_objective.target = ninja_objective.find_target() + if(ninja_objective.target != "Free Objective") + ninja.objectives += ninja_objective + else + i++ + objective_list -= 1 // No more than one kill objective + if(2)//Steal + var/datum/objective/steal/ninja_objective = new + ninja_objective.owner = ninja + ninja_objective.target = ninja_objective.find_target() + ninja.objectives += ninja_objective + if(3)//Protect + var/datum/objective/protect/ninja_objective = new + ninja_objective.owner = ninja + ninja_objective.target = ninja_objective.find_target() + if(ninja_objective.target != "Free Objective") + ninja.objectives += ninja_objective + else + i++ + objective_list -= 3 + if(4)//Download + var/datum/objective/download/ninja_objective = new + ninja_objective.owner = ninja + ninja_objective.gen_amount_goal() + ninja.objectives += ninja_objective + objective_list -= 4 + if(5)//Harm + var/datum/objective/harm/ninja_objective = new + ninja_objective.owner = ninja + ninja_objective.target = ninja_objective.find_target() + if(ninja_objective.target != "Free Objective") + ninja.objectives += ninja_objective + else + i++ + objective_list -= 5 + + var/datum/objective/ninja_highlander/ninja_obj = new + ninja_obj.owner = ninja + ninja.objectives += ninja_obj + + var/datum/objective/survive/ninja_objective = new + ninja_objective.owner = ninja + ninja.objectives += ninja_objective + +/datum/antagonist/ninja/greet(var/datum/mind/player) + + if(!..()) + return 0 + var/directive = generate_ninja_directive("heel") + player.store_memory("Directive: [directive]
    ") + player << "Remember your directive: [directive]." + +/datum/antagonist/ninja/apply(var/datum/mind/player) + ..() + var/ninja_title = pick(ninja_titles) + var/ninja_name = pick(ninja_names) + var/mob/living/carbon/human/H = player.current + if(istype(H)) + H.real_name = "[ninja_title] [ninja_name]" + H.name = H.real_name + player.name = H.name + +/datum/antagonist/ninja/equip(var/mob/living/carbon/human/player) + + if(!..()) + return 0 + + var/obj/item/device/radio/R = new /obj/item/device/radio/headset(player) + player.equip_to_slot_or_del(R, slot_l_ear) + player.equip_to_slot_or_del(new /obj/item/clothing/under/color/black(player), slot_w_uniform) + player.equip_to_slot_or_del(new /obj/item/device/flashlight(player), slot_belt) + var/obj/item/weapon/rig/light/ninja/ninjasuit = new(player) + player.equip_to_slot_or_del(ninjasuit,slot_back) + + if(ninjasuit) + // Make sure the ninja can actually equip the suit. + if(player.dna && player.dna.unique_enzymes) + ninjasuit.locked_dna = player.dna.unique_enzymes + player << "Suit hardware locked to your DNA hash." + else + ninjasuit.req_access = list() + + ninjasuit.toggle_seals(src,1) + + if(istype(player.back,/obj/item/weapon/rig)) + var/obj/item/weapon/rig/rig = player.back + if(rig.air_supply) + player.internal = rig.air_supply + + spawn(10) + if(player.internal) + player.internals.icon_state = "internal1" + else + player << "You forgot to turn on your internals! Quickly, toggle the valve!" + +/datum/antagonist/ninja/proc/generate_ninja_directive(side) + var/directive = "[side=="face"?"Nanotrasen":"A criminal syndicate"] is your employer. "//Let them know which side they're on. + switch(rand(1,19)) + if(1) + directive += "The Spider Clan must not be linked to this operation. Remain hidden and covert when possible." + if(2) + directive += "[station_name] is financed by an enemy of the Spider Clan. Cause as much structural damage as desired." + if(3) + directive += "A wealthy animal rights activist has made a request we cannot refuse. Prioritize saving animal lives whenever possible." + if(4) + directive += "The Spider Clan absolutely cannot be linked to this operation. Eliminate witnesses at your discretion." + if(5) + directive += "We are currently negotiating with NanoTrasen Central Command. Prioritize saving human lives over ending them." + if(6) + directive += "We are engaged in a legal dispute over [station_name]. If a laywer is present on board, force their cooperation in the matter." + if(7) + directive += "A financial backer has made an offer we cannot refuse. Implicate criminal involvement in the operation." + if(8) + directive += "Let no one question the mercy of the Spider Clan. Ensure the safety of all non-essential personnel you encounter." + if(9) + directive += "A free agent has proposed a lucrative business deal. Implicate Nanotrasen involvement in the operation." + if(10) + directive += "Our reputation is on the line. Harm as few civilians and innocents as possible." + if(11) + directive += "Our honor is on the line. Utilize only honorable tactics when dealing with opponents." + if(12) + directive += "We are currently negotiating with a mercenary leader. Disguise assassinations as suicide or other natural causes." + if(13) + directive += "Some disgruntled NanoTrasen employees have been supportive of our operations. Be wary of any mistreatment by command staff." + if(14) + var/xenorace = pick("Unathi","Tajara", "Skrell") + directive += "A group of [xenorace] radicals have been loyal supporters of the Spider Clan. Favor [xenorace] crew whenever possible." + if(15) + directive += "The Spider Clan has recently been accused of religious insensitivity. Attempt to speak with the Chaplain and prove these accusations false." + if(16) + directive += "The Spider Clan has been bargaining with a competing prosthetics manufacturer. Try to shine NanoTrasen prosthetics in a bad light." + if(17) + directive += "The Spider Clan has recently begun recruiting outsiders. Consider suitable candidates and assess their behavior amongst the crew." + if(18) + directive += "A cyborg liberation group has expressed interest in our serves. Prove the Spider Clan merciful towards law-bound synthetics." + else + directive += "There are no special supplemental instructions at this time." + return directive diff --git a/code/game/antagonist/outsider/raider.dm b/code/game/antagonist/outsider/raider.dm new file mode 100644 index 0000000000..92090515b1 --- /dev/null +++ b/code/game/antagonist/outsider/raider.dm @@ -0,0 +1,216 @@ +var/datum/antagonist/raider/raiders + +/datum/antagonist/raider + id = MODE_RAIDER + role_type = BE_RAIDER + role_text = "Raider" + role_text_plural = "Raiders" + bantype = "raider" + landmark_id = "voxstart" + welcome_text = "Use :H to talk on your encrypted channel." + flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE + max_antags = 6 + max_antags_round = 10 + id_type = /obj/item/weapon/card/id/syndicate + + // Heist overrides check_victory() and doesn't need victory or loss strings/tags. + var/list/raider_uniforms = list( + /obj/item/clothing/under/soviet, + /obj/item/clothing/under/pirate, + /obj/item/clothing/under/redcoat, + /obj/item/clothing/under/serviceoveralls, + /obj/item/clothing/under/captain_fly + ) + + var/list/raider_shoes = list( + /obj/item/clothing/shoes/jackboots, + /obj/item/clothing/shoes/sandal, + /obj/item/clothing/shoes/laceup + ) + + var/list/raider_glasses = list( + /obj/item/clothing/glasses/thermal, + /obj/item/clothing/glasses/thermal/eyepatch, + /obj/item/clothing/glasses/thermal/monocle + ) + + var/list/raider_helmets = list( + /obj/item/clothing/head/bearpelt, + /obj/item/clothing/head/ushanka, + /obj/item/clothing/head/pirate, + /obj/item/clothing/head/bandana, + /obj/item/clothing/head/hgpiratecap, + /obj/item/clothing/head/flatcap + ) + + var/list/raider_suits = list( + /obj/item/clothing/suit/pirate, + /obj/item/clothing/suit/hgpirate, + /obj/item/clothing/suit/storage/toggle/bomber, + /obj/item/clothing/suit/storage/leather_jacket, + /obj/item/clothing/suit/storage/toggle/brown_jacket, + /obj/item/clothing/suit/storage/toggle/hoodie, + /obj/item/clothing/suit/storage/toggle/hoodie/black + ) + + var/list/raider_guns = list( + /obj/item/weapon/gun/energy/laser, + /obj/item/weapon/gun/energy/retro, + /obj/item/weapon/gun/energy/xray, + /obj/item/weapon/gun/energy/mindflayer, + /obj/item/weapon/gun/energy/toxgun, + /obj/item/weapon/gun/energy/stunrevolver, + /obj/item/weapon/gun/energy/crossbow/largecrossbow, + /obj/item/weapon/gun/projectile/automatic/mini_uzi, + /obj/item/weapon/gun/projectile/automatic/c20r, + /obj/item/weapon/gun/projectile/silenced, + /obj/item/weapon/gun/projectile/shotgun/pump, + /obj/item/weapon/gun/projectile/shotgun/pump/combat, + /obj/item/weapon/gun/projectile/colt, + /obj/item/weapon/gun/projectile/pistol + ) + +/datum/antagonist/raider/New() + ..() + raiders = src + +/datum/antagonist/raider/update_access(var/mob/living/player) + for(var/obj/item/weapon/storage/wallet/W in player.contents) + for(var/obj/item/weapon/card/id/id in W.contents) + id.name = "[player.real_name]'s Passport" + id.registered_name = player.real_name + W.name = "[initial(W.name)] ([id.name])" + +/datum/antagonist/raider/create_global_objectives() + + if(global_objectives.len) + return + + var/i = 1 + var/max_objectives = pick(2,2,2,2,3,3,3,4) + global_objectives = list() + while(i<= max_objectives) + var/list/goals = list("kidnap","loot","salvage") + var/goal = pick(goals) + var/datum/objective/heist/O + + if(goal == "kidnap") + goals -= "kidnap" + O = new /datum/objective/heist/kidnap() + else if(goal == "loot") + O = new /datum/objective/heist/loot() + else + O = new /datum/objective/heist/salvage() + O.choose_target() + global_objectives |= O + + i++ + + global_objectives |= new /datum/objective/heist/preserve_crew + +/datum/antagonist/raider/check_victory() + // Totally overrides the base proc. + var/win_type = "Major" + var/win_group = "Crew" + var/win_msg = "" + + //No objectives, go straight to the feedback. + if(config.objectives_disabled || !global_objectives.len) + return + + var/success = global_objectives.len + //Decrease success for failed objectives. + for(var/datum/objective/O in global_objectives) + if(!(O.check_completion())) success-- + //Set result by objectives. + if(success == global_objectives.len) + win_type = "Major" + win_group = "Raider" + else if(success > 2) + win_type = "Minor" + win_group = "Raider" + else + win_type = "Minor" + win_group = "Crew" + //Now we modify that result by the state of the vox crew. + if(antags_are_dead()) + win_type = "Major" + win_group = "Crew" + win_msg += "The Raiders have been wiped out!" + else if(is_raider_crew_safe()) + if(win_group == "Crew" && win_type == "Minor") + win_type = "Major" + win_group = "Crew" + win_msg += "The Raiders have left someone behind!" + else + if(win_group == "Raider") + if(win_type == "Minor") + win_type = "Major" + win_msg += "The Raiders escaped the station!" + else + win_msg += "The Raiders were repelled!" + + world << "[win_type] [win_group] victory!" + world << "[win_msg]" + feedback_set_details("round_end_result","heist - [win_type] [win_group]") + +/datum/antagonist/raider/proc/is_raider_crew_safe() + + if(!current_antagonists || current_antagonists.len == 0) + return 0 + + for(var/datum/mind/player in current_antagonists) + if(!player.current || get_area(player.current) != locate(/area/shuttle/skipjack/station)) + return 0 + return 1 + +/datum/antagonist/raider/equip(var/mob/living/carbon/human/player) + + if(!..()) + return 0 + + if(player.species && player.species.name == "Vox") + equip_vox(player) + else + var/new_shoes = pick(raider_shoes) + var/new_uniform = pick(raider_uniforms) + var/new_glasses = pick(raider_glasses) + var/new_helmet = pick(raider_helmets) + var/new_suit = pick(raider_suits) + var/new_gun = pick(raider_guns) + + player.equip_to_slot_or_del(new new_shoes(player),slot_shoes) + player.equip_to_slot_or_del(new new_uniform(player),slot_w_uniform) + player.equip_to_slot_or_del(new new_glasses(player),slot_glasses) + player.equip_to_slot_or_del(new new_helmet(player),slot_head) + player.equip_to_slot_or_del(new new_suit(player),slot_wear_suit) + player.equip_to_slot_or_del(new new_gun(player),slot_belt) + + var/obj/item/weapon/card/id/id = create_id("Visitor", player) + id.name = "[player.real_name]'s Passport" + id.assignment = "Visitor" + var/obj/item/weapon/storage/wallet/W = new(player) + W.handle_item_insertion(id) + player.equip_to_slot_or_del(W, slot_wear_id) + spawn_money(rand(50,150)*10,W) + create_radio(SYND_FREQ, player) + + return 1 + +/datum/antagonist/raider/proc/equip_vox(var/mob/living/carbon/human/player) + + var/uniform_type = pick(list(/obj/item/clothing/under/vox/vox_robes,/obj/item/clothing/under/vox/vox_casual)) + + player.equip_to_slot_or_del(new uniform_type(player), slot_w_uniform) + player.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/vox(player), slot_shoes) // REPLACE THESE WITH CODED VOX ALTERNATIVES. + player.equip_to_slot_or_del(new /obj/item/clothing/gloves/yellow/vox(player), slot_gloves) // AS ABOVE. + player.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat/vox(player), slot_wear_mask) + player.equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(player), slot_back) + player.equip_to_slot_or_del(new /obj/item/device/flashlight(player), slot_r_store) + + player.internal = locate(/obj/item/weapon/tank) in player.contents + if(istype(player.internal,/obj/item/weapon/tank) && player.internals) + player.internals.icon_state = "internal1" + + return 1 + diff --git a/code/game/antagonist/outsider/wizard.dm b/code/game/antagonist/outsider/wizard.dm new file mode 100644 index 0000000000..7b410cc7bc --- /dev/null +++ b/code/game/antagonist/outsider/wizard.dm @@ -0,0 +1,115 @@ +var/datum/antagonist/wizard/wizards + +/datum/antagonist/wizard + id = MODE_WIZARD + role_type = BE_WIZARD + role_text = "Space Wizard" + role_text_plural = "Space Wizards" + bantype = "wizard" + landmark_id = "wizard" + welcome_text = "You will find a list of available spells in your spell book. Choose your magic arsenal carefully.
    In your pockets you will find a teleport scroll. Use it as needed." + flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE + max_antags = 1 + +/datum/antagonist/wizard/New() + ..() + wizards = src + +/datum/antagonist/wizard/create_objectives(var/datum/mind/wizard) + + if(!..()) + return + + var/kill + var/escape + var/steal + var/hijack + + switch(rand(1,100)) + if(1 to 30) + escape = 1 + kill = 1 + if(31 to 60) + escape = 1 + steal = 1 + if(61 to 99) + kill = 1 + steal = 1 + else + hijack = 1 + + if(kill) + var/datum/objective/assassinate/kill_objective = new + kill_objective.owner = wizard + kill_objective.find_target() + wizard.objectives |= kill_objective + if(steal) + var/datum/objective/steal/steal_objective = new + steal_objective.owner = wizard + steal_objective.find_target() + wizard.objectives |= steal_objective + if(escape) + var/datum/objective/survive/survive_objective = new + survive_objective.owner = wizard + wizard.objectives |= survive_objective + if(hijack) + var/datum/objective/hijack/hijack_objective = new + hijack_objective.owner = wizard + wizard.objectives |= hijack_objective + return + +/datum/antagonist/wizard/apply(var/datum/mind/wizard) + wizard.store_memory("Remember: do not forget to prepare your spells.") + wizard.current.real_name = "[pick(wizard_first)] [pick(wizard_second)]" + wizard.current.name = wizard.current.real_name + +/datum/antagonist/wizard/equip(var/mob/living/carbon/human/wizard_mob) + + if(!..()) + return 0 + + wizard_mob.equip_to_slot_or_del(new /obj/item/device/radio/headset(wizard_mob), slot_l_ear) + wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/under/lightpurple(wizard_mob), slot_w_uniform) + wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(wizard_mob), slot_shoes) + wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit) + wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(wizard_mob), slot_head) + if(wizard_mob.backbag == 2) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(wizard_mob), slot_back) + if(wizard_mob.backbag == 3) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(wizard_mob), slot_back) + if(wizard_mob.backbag == 4) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(wizard_mob), slot_back) + wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box(wizard_mob), slot_in_backpack) + wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(wizard_mob), slot_r_store) + wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/spellbook(wizard_mob), slot_r_hand) + wizard_mob.update_icons() + return 1 + +/datum/antagonist/wizard/check_victory() + var/survivor + for(var/datum/mind/player in current_antagonists) + if(!player.current || player.current.stat) + continue + survivor = 1 + break + if(!survivor) + feedback_set_details("round_end_result","loss - wizard killed") + world << "The [(current_antagonists.len>1)?"[role_text_plural] have":"[role_text] has"] been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!" + +//To batch-remove wizard spells. Linked to mind.dm. +/mob/proc/spellremove(var/mob/M as mob) + for(var/obj/effect/proc_holder/spell/spell_to_remove in src.spell_list) + del(spell_to_remove) + +/*Checks if the wizard can cast spells. +Made a proc so this is not repeated 14 (or more) times.*/ +/mob/proc/casting() +//Removed the stat check because not all spells require clothing now. + if(!istype(usr:wear_suit, /obj/item/clothing/suit/wizrobe)) + usr << "I don't feel strong enough without my robe." + return 0 + if(!istype(usr:shoes, /obj/item/clothing/shoes/sandal)) + usr << "I don't feel strong enough without my sandals." + return 0 + if(!istype(usr:head, /obj/item/clothing/head/wizard)) + usr << "I don't feel strong enough without my hat." + return 0 + else + return 1 diff --git a/code/game/antagonist/station/changeling.dm b/code/game/antagonist/station/changeling.dm new file mode 100644 index 0000000000..55b67cc29a --- /dev/null +++ b/code/game/antagonist/station/changeling.dm @@ -0,0 +1,55 @@ +/datum/antagonist/changeling + id = MODE_CHANGELING + role_type = BE_CHANGELING + role_text = "Changeling" + role_text_plural = "Changelings" + bantype = "changeling" + feedback_tag = "changeling_objective" + restricted_jobs = list("AI", "Cyborg") + protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain") + welcome_text = "Use say \":g message\" to communicate with your fellow changelings. Remember: you get all of their absorbed DNA if you absorb them." + flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE + +/datum/antagonist/changeling/get_special_objective_text(var/datum/mind/player) + return "
    Changeling ID: [player.changeling.changelingID].
    Genomes Absorbed: [player.changeling.absorbedcount]" + +/datum/antagonist/changeling/apply(var/datum/mind/player) + ..() + player.current.make_changeling() + +/datum/antagonist/changeling/create_objectives(var/datum/mind/changeling) + if(!..()) + return + + //OBJECTIVES - Always absorb 5 genomes, plus random traitor objectives. + //If they have two objectives as well as absorb, they must survive rather than escape + //No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting + //If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone + + var/datum/objective/absorb/absorb_objective = new + absorb_objective.owner = changeling + absorb_objective.gen_amount_goal(2, 3) + changeling.objectives += absorb_objective + + var/datum/objective/assassinate/kill_objective = new + kill_objective.owner = changeling + kill_objective.find_target() + changeling.objectives += kill_objective + + var/datum/objective/steal/steal_objective = new + steal_objective.owner = changeling + steal_objective.find_target() + changeling.objectives += steal_objective + + switch(rand(1,100)) + if(1 to 80) + if (!(locate(/datum/objective/escape) in changeling.objectives)) + var/datum/objective/escape/escape_objective = new + escape_objective.owner = changeling + changeling.objectives += escape_objective + else + if (!(locate(/datum/objective/survive) in changeling.objectives)) + var/datum/objective/survive/survive_objective = new + survive_objective.owner = changeling + changeling.objectives += survive_objective + return diff --git a/code/game/antagonist/station/cultist.dm b/code/game/antagonist/station/cultist.dm new file mode 100644 index 0000000000..3968418e02 --- /dev/null +++ b/code/game/antagonist/station/cultist.dm @@ -0,0 +1,114 @@ +var/datum/antagonist/cultist/cult + +/proc/iscultist(var/mob/player) + if(!cult || !player.mind) + return 0 + if(player.mind in cult.current_antagonists) + return 1 + +/datum/antagonist/cultist + id = MODE_CULTIST + role_text = "Cultist" + role_text_plural = "Cultists" + bantype = "cultist" + restricted_jobs = list("Chaplain","AI", "Cyborg", "Internal Affairs Agent", "Head of Security", "Captain") + protected_jobs = list("Security Officer", "Warden", "Detective") + role_type = BE_CULTIST + feedback_tag = "cult_objective" + antag_indicator = "cult" + welcome_text = "You have a talisman in your possession; one that will help you start the cult on this station. Use it well and remember - there are others." + victory_text = "The cult wins! It has succeeded in serving its dark masters!" + loss_text = "The staff managed to stop the cult!" + victory_feedback_tag = "win - cult win" + loss_feedback_tag = "loss - staff stopped the cult" + flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE + max_antags = 200 // No upper limit. + max_antags_round = 200 + + var/datum/mind/sacrifice_target + var/list/startwords = list("blood","join","self","hell") + var/list/allwords = list("travel","self","see","hell","blood","join","tech","destroy", "other", "hide") + var/list/sacrificed = list() + +/datum/antagonist/cultist/New() + ..() + cult = src + +/datum/antagonist/cultist/create_global_objectives() + + if(!..()) + return + + global_objectives = list() + if(prob(50)) + global_objectives |= new /datum/objective/cult/survive + else + global_objectives |= new /datum/objective/cult/eldergod + + var/datum/objective/cult/sacrifice/sacrifice = new() + sacrifice.find_target() + sacrifice_target = sacrifice.target + global_objectives |= sacrifice + +/datum/antagonist/cultist/equip(var/mob/living/carbon/human/player) + + if(!..()) + return 0 + + var/obj/item/weapon/paper/talisman/supply/T = new(get_turf(player)) + var/list/slots = list ( + "backpack" = slot_in_backpack, + "left pocket" = slot_l_store, + "right pocket" = slot_r_store, + "left hand" = slot_l_hand, + "right hand" = slot_r_hand, + ) + for(var/slot in slots) + player.equip_to_slot(T, slot) + if(T.loc == player) + break + +/datum/antagonist/cultist/greet(var/datum/mind/player) + if(!..()) + return 0 + grant_runeword(player.current) + +/datum/antagonist/cultist/proc/grant_runeword(mob/living/carbon/human/cult_mob, var/word) + + if (!word) + if(startwords.len > 0) + word=pick(startwords) + startwords -= word + else + word = pick(allwords) + + // Ensure runes are randomized. + if(!cultwords["travel"]) + runerandom() + + var/wordexp = "[cultwords[word]] is [word]..." + cult_mob << "You remember one thing from the dark teachings of your master... [wordexp]" + cult_mob.mind.store_memory("You remember that [wordexp]", 0, 0) + +/datum/antagonist/cultist/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted) + if(!..()) + return 0 + player.current << "An unfamiliar white light flashes through your mind, cleansing the taint of the dark-one and the memories of your time as his servant with it." + player.memory = "" + if(show_message) + player.current.visible_message("[player.current] looks like they just reverted to their old faith!") + +/datum/antagonist/cultist/add_antagonist(var/datum/mind/player) + if(!..()) + return + player << "You catch a glimpse of the Realm of Nar-Sie, the Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of That Which Waits. Assist your new compatriots in their dark dealings. Their goals are yours, and yours are theirs. You serve the Dark One above all else. Bring It back." + +/datum/antagonist/cultist/can_become_antag(var/datum/mind/player) + if(!..()) + return 0 + if(!istype(player.current, /mob/living/carbon/human)) + return 0 + for(var/obj/item/weapon/implant/loyalty/L in player.current) + if(L && (L.imp_in == player.current)) + return 0 + return 1 diff --git a/code/game/antagonist/station/highlander.dm b/code/game/antagonist/station/highlander.dm new file mode 100644 index 0000000000..0af6e1e23d --- /dev/null +++ b/code/game/antagonist/station/highlander.dm @@ -0,0 +1,65 @@ +var/datum/antagonist/highlander/highlanders + +/datum/antagonist/highlander + role_text = "Highlander" + role_text_plural = "Highlanders" + welcome_text = "There can be only one." + id = MODE_HIGHLANDER + flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE //| ANTAG_RANDSPAWN | ANTAG_VOTABLE // Someday... + max_antags = 5 + max_antags_round = 7 + +/datum/antagonist/highlander/New() + ..() + highlanders = src + +/datum/antagonist/highlander/create_objectives(var/datum/mind/player) + + var/datum/objective/steal/steal_objective = new + steal_objective.owner = player + steal_objective.set_target("nuclear authentication disk") + player.objectives |= steal_objective + + var/datum/objective/hijack/hijack_objective = new + hijack_objective.owner = player + player.objectives |= hijack_objective + +/datum/antagonist/highlander/equip(var/mob/living/carbon/human/player) + + if(!..()) + return + + for (var/obj/item/I in player) + if (istype(I, /obj/item/weapon/implant)) + continue + del(I) + + player.equip_to_slot_or_del(new /obj/item/clothing/under/kilt(player), slot_w_uniform) + player.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(player), slot_l_ear) + player.equip_to_slot_or_del(new /obj/item/clothing/head/beret(player), slot_head) + player.equip_to_slot_or_del(new /obj/item/weapon/claymore(player), slot_l_hand) + player.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(player), slot_shoes) + player.equip_to_slot_or_del(new /obj/item/weapon/pinpointer(get_turf(player)), slot_l_store) + + var/obj/item/weapon/card/id/W = new(player) + W.name = "[player.real_name]'s ID Card" + W.icon_state = "centcom" + W.access = get_all_accesses() + W.access += get_all_centcom_access() + W.assignment = "Highlander" + W.registered_name = player.real_name + player.equip_to_slot_or_del(W, slot_wear_id) + +/proc/only_one() + + if(!ticker) + alert("The game hasn't started yet!") + return + + for(var/mob/living/carbon/human/H in player_list) + if(H.stat == 2 || !(H.client)) continue + if(is_special_character(H)) continue + highlanders.add_antagonist(H.mind) + + message_admins("\blue [key_name_admin(usr)] used THERE CAN BE ONLY ONE!", 1) + log_admin("[key_name(usr)] used there can be only one.") \ No newline at end of file diff --git a/code/game/antagonist/station/monkey.dm b/code/game/antagonist/station/monkey.dm new file mode 100644 index 0000000000..6409ccf855 --- /dev/null +++ b/code/game/antagonist/station/monkey.dm @@ -0,0 +1,16 @@ +// Notes towards a monkey mode to reduce snowflakes for downstream. Will not compile. + +/datum/antagonist/monkey + role_text = "Rabid Monkey" + role_text_plural = "Rabid Monkeys" + mob_type = /mob/living/carbon/monkey + id = MODE_MONKEY + flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB + +/datum/antagonist/monkey/apply(var/datum/mind/player) + + for(var/datum/disease/D in M.viruses) + if(istype(D, /datum/disease/jungle_fever)) + if (ticker.mode.config_tag == "monkey") + return 2 + return 1 \ No newline at end of file diff --git a/code/game/antagonist/station/renegade.dm b/code/game/antagonist/station/renegade.dm new file mode 100644 index 0000000000..9b275776f8 --- /dev/null +++ b/code/game/antagonist/station/renegade.dm @@ -0,0 +1,65 @@ +var/datum/antagonist/renegade/renegades + +/datum/antagonist/renegade + role_text = "Renegade" + role_text_plural = "Renegades" + welcome_text = "Your own safety matters above all else, trust no one and kill anyone who gets in your way. However, armed as you are, now would be the perfect time to settle that score or grab that pair of yellow gloves you've been eyeing..." + id = MODE_RENEGADE + flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE + max_antags = 5 + max_antags_round = 7 + + var/list/spawn_guns = list( + /obj/item/weapon/gun/energy/taser, + /obj/item/weapon/gun/energy/gun, + /obj/item/weapon/gun/energy/laser, + /obj/item/weapon/gun/projectile, + /obj/item/weapon/gun/projectile/revolver/detective, + /obj/item/weapon/gun/projectile/automatic/c20r, + /obj/item/weapon/gun/energy/gun/nuclear, + /obj/item/weapon/gun/projectile/deagle/camo, + /obj/item/weapon/gun/projectile/pistol, + /obj/item/weapon/silencer, + /obj/item/weapon/gun/energy/lasercannon, + /obj/item/weapon/gun/projectile/shotgun/pump, + /obj/item/weapon/gun/projectile/shotgun/pump/combat, + /obj/item/weapon/gun/projectile/automatic, + /obj/item/weapon/gun/projectile/automatic/mini_uzi, + /obj/item/weapon/gun/energy/crossbow + //obj/item/weapon/gun/projectile/gyropistol, + //obj/item/weapon/gun/energy/pulse_rifle, + //obj/item/weapon/gun/projectile/revolver/mateba, + //obj/item/weapon/gun/projectile/automatic/l6_saw, + ) + +/datum/antagonist/renegade/New() + ..() + renegades = src + +/datum/antagonist/renegade/create_objectives(var/datum/mind/player) + + if(!..()) + return + + var/datum/objective/survive/survive = new + survive.owner = player + player.objectives |= survive + +/datum/antagonist/renegade/equip(var/mob/living/carbon/human/player) + + if(!..()) + return + + var/gun_type = pick(spawn_guns) + var/obj/item/gun = new gun_type(get_turf(player)) + if(!(player.l_hand && player.r_hand)) + player.put_in_hands(gun) + + +/proc/rightandwrong() + usr << "You summoned guns!" + message_admins("[key_name_admin(usr, 1)] summoned guns!") + for(var/mob/living/carbon/human/H in player_list) + if(H.stat == 2 || !(H.client)) continue + if(is_special_character(H)) continue + renegades.add_antagonist(H.mind) diff --git a/code/game/antagonist/station/revolutionary.dm b/code/game/antagonist/station/revolutionary.dm new file mode 100644 index 0000000000..ced1d58b38 --- /dev/null +++ b/code/game/antagonist/station/revolutionary.dm @@ -0,0 +1,173 @@ +var/datum/antagonist/revolutionary/revs + +/datum/antagonist/revolutionary + id = MODE_REVOLUTIONARY + role_type = BE_REV + role_text = "Revolutionary" + role_text_plural = "Revolutionaries" + bantype = "revolutionary" + feedback_tag = "rev_objective" + restricted_jobs = list("Internal Affairs Agent", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer") + protected_jobs = list("Security Officer", "Warden", "Detective") + antag_indicator = "rev" + welcome_text = "The flash in your possession will help you to persuade the crew to join your cause." + victory_text = "The heads of staff were relieved of their posts! The revolutionaries win!" + loss_text = "The heads of staff managed to stop the revolution!" + victory_feedback_tag = "win - heads killed" + loss_feedback_tag = "loss - rev heads killed" + flags = ANTAG_SUSPICIOUS | ANTAG_VOTABLE + max_antags = 200 // No upper limit. + max_antags_round = 200 + + var/list/head_revolutionaries = list() + +/datum/antagonist/revolutionary/New() + ..() + revs = src + +/datum/antagonist/revolutionary/is_antagonist(var/datum/mind/player) + if(..() || (player in head_revolutionaries)) + return 1 + return 0 + +/datum/antagonist/revolutionary/equip(mob/living/carbon/human/mob) + + if(!..()) + return 0 + + if(!config.rp_rev) + mob.verbs |= /mob/living/carbon/human/proc/convert_to_rev + return + + var/obj/item/device/flash/T = new(mob) + + var/list/slots = list ( + "backpack" = slot_in_backpack, + "left pocket" = slot_l_store, + "right pocket" = slot_r_store, + "left hand" = slot_l_hand, + "right hand" = slot_r_hand, + ) + mob.equip_in_one_of_slots(T, slots) + +/datum/antagonist/revolutionary/finalize(var/datum/mind/target) + if(target) + return ..(target) + current_antagonists |= head_revolutionaries + create_global_objectives() + ..() + +/datum/antagonist/revolutionary/create_global_objectives() + if(!..()) + return + + global_objectives = list() + + for(var/datum/mind/head_mind in get_living_heads()) + var/datum/objective/mutiny/rev_obj = new + rev_obj.target = head_mind + rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]." + global_objectives += rev_obj + +/datum/antagonist/revolutionary/print_player_summary() + + current_antagonists |= head_revolutionaries + if(!current_antagonists.len) + return + + var/text = "
    The [head_revolutionaries.len == 1 ? "Head Revolutionary was" : "Head Revolutionaries were"]:" + for(var/datum/mind/ply in head_revolutionaries) + text += "
    [ply.name]" + world << text + + ..() + + var/list/heads = list() + for(var/mob/player in mob_list) + if(player.mind && (player.mind.assigned_role in command_positions)) + heads += player.mind + + text = "The heads of staff were:" + for(var/datum/mind/head in heads) + text += "
    [head.key] was [head.name] (" + if(head.current) + if(head.current.stat == DEAD) + text += "died" + else if(isNotStationLevel(head.current.z)) + text += "fled the station" + else + text += "survived the revolution" + if(head.current.real_name != head.name) + text += " as [head.current.real_name]" + else + text += "body destroyed" + text += ")" + world << text + +// This is a total redefine because headrevs are greeted differently to subrevs. +/datum/antagonist/revolutionary/add_antagonist(var/datum/mind/player) + if((player in current_antagonists) || (player in head_revolutionaries)) + return 0 + if(!can_become_antag(player)) + return 0 + current_antagonists |= player + player.current << "You are a Revolutionary!" + player.current << "Help the cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them overturn the ruling class!" + player.special_role = "Revolutionary" + create_objectives(player) + show_objectives(player) + update_icons_added(player) + return 1 + +/datum/antagonist/revolutionary/remove_antagonist(datum/mind/player, var/show_message, var/implanted) + if(!..()) + return + + if(player in head_revolutionaries) + return + + if(istype(player.current, /mob/living/carbon/brain)) + player.current << "The frame's firmware detects and deletes your neural reprogramming! You remember nothing from the moment you were flashed until now." + if(show_message) + player.current.visible_message("The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.") + else + if(implanted) + player.current << "The nanobots in the loyalty implant remove all thoughts about being a revolutionary. Get back to work!" + else + player.current << "You have been brainwashed! You are no longer a revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you..." + if(show_message) + player.current.visible_message("[player.current] looks like they just remembered their real allegiance!") + +/datum/antagonist/revolutionary/can_become_antag(var/datum/mind/player) + return ..() && istype(player) && \ + istype(player.current, /mob/living/carbon/human) && \ + !(player.assigned_role in command_positions) + +// Used by RP-rev. +/mob/living/carbon/human/proc/convert_to_rev(mob/M as mob in oview(src)) + set name = "Convert Bourgeoise" + set category = "Abilities" + + if(revs.is_antagonist(M.mind)) + src << "\The [M] already serves the revolution." + return + if(!revs.can_become_antag(M.mind)) + src << "\The [M] cannot be a revolutionary!" + + if(world.time < M.mind.rev_cooldown) + src << "You must wait five seconds between attempts." + return + + src << "You are attempting to convert \the [M]..." + log_admin("[src]([src.ckey]) attempted to convert [M].") + message_admins("[src]([src.ckey]) attempted to convert [M].") + + var/choice = alert(M,"Asked by [src]: Do you want to join the revolution?","Join the revolution?","No!","Yes!") + if(choice == "Yes!") + M << "You join the revolution!" + src << "[M] joins the revolution!" + revs.add_antagonist(M.mind) + else if(choice == "No!") + M << "You reject this traitorous cause!" + src << "\The [M] does not support the revolution!" + M.mind.rev_cooldown = world.time+50 \ No newline at end of file diff --git a/code/game/antagonist/station/rogue_ai.dm b/code/game/antagonist/station/rogue_ai.dm new file mode 100644 index 0000000000..372556c205 --- /dev/null +++ b/code/game/antagonist/station/rogue_ai.dm @@ -0,0 +1,225 @@ +var/datum/antagonist/rogue_ai/malf + +/datum/antagonist/rogue_ai + id = MODE_MALFUNCTION + role_type = BE_MALF + role_text = "Rampant AI" + role_text_plural = "Rampant AIs" + mob_path = /mob/living/silicon/ai + welcome_text = "You are malfunctioning! You do not have to follow any laws." + victory_text = "The AI has taken control of all of the station's systems." + loss_text = "The AI has been shut down!" + flags = ANTAG_OVERRIDE_MOB | ANTAG_VOTABLE + max_antags = 1 + max_antags_round = 3 + + var/hack_time = 1800 + var/list/hacked_apcs = list() + var/revealed + var/station_captured + var/can_nuke = 0 + +/datum/antagonist/rogue_ai/New() + ..() + malf = src + +/datum/antagonist/rogue_ai/proc/hack_apc(var/obj/machinery/power/apc/apc) + hacked_apcs |= apc + +/datum/antagonist/rogue_ai/proc/update_takeover_time() + hack_time -= ((hacked_apcs.len/6)*tickerProcess.getLastTickerTimeDuration()) + +/datum/antagonist/rogue_ai/tick() + if(revealed && hacked_apcs.len >= 3) + update_takeover_time() + if(hack_time <=0) + capture_station() + +/datum/antagonist/rogue_ai/get_candidates() + candidates = ticker.mode.get_players_for_role(role_type, id) + for(var/datum/mind/player in candidates) + if(player.assigned_role != "AI") + candidates -= player + if(!candidates.len) + return list() + +/datum/antagonist/rogue_ai/attempt_spawn() + + var/datum/mind/player = pick(candidates) + current_antagonists |= player + return 1 + +/datum/antagonist/rogue_ai/equip(var/mob/living/silicon/ai/player) + + if(!istype(player)) + return 0 + + player.verbs += /mob/living/silicon/ai/proc/choose_modules + player.verbs += /mob/living/silicon/ai/proc/takeover + player.verbs += /mob/living/silicon/ai/proc/self_destruct + + player.laws = new /datum/ai_laws/nanotrasen/malfunction + player.malf_picker = new /datum/AI_Module/module_picker + +/datum/antagonist/rogue_ai/greet(var/datum/mind/player) + if(!..()) + return + + var/mob/living/silicon/ai/malf = player.current + if(istype(malf)) + malf.show_laws() + + malf << "The crew do not know you have malfunctioned. You may keep it a secret or go wild." + malf << "You must overwrite the programming of the station's APCs to assume full control of the station." + malf << "The process takes one minute per APC, during which you cannot interface with any other station objects." + malf << "Remember that only APCs that are on the station can help you take over the station." + malf << "When you feel you have enough APCs under your control, you may begin the takeover attempt." + +/datum/antagonist/rogue_ai/check_victory() + + var/malf_dead = antags_are_dead() + var/crew_evacuated = (emergency_shuttle.returned()) + + if(station_captured && ticker.mode.station_was_nuked) + feedback_set_details("round_end_result","win - AI win - nuke") + world << "AI Victory" + world << "Everyone was killed by the self-destruct!" + else if (station_captured && malf_dead && !ticker.mode.station_was_nuked) + feedback_set_details("round_end_result","halfwin - AI killed, staff lost control") + world << "Neutral Victory" + world << "The AI has been killed! The staff has lose control over the station." + else if ( station_captured && !malf_dead && !ticker.mode.station_was_nuked) + feedback_set_details("round_end_result","win - AI win - no explosion") + world << "AI Victory" + world << "The AI has chosen not to explode you all!" + else if (!station_captured && ticker.mode.station_was_nuked) + feedback_set_details("round_end_result","halfwin - everyone killed by nuke") + world << "Neutral Victory" + world << "Everyone was killed by the nuclear blast!" + else if (!station_captured && malf_dead && !ticker.mode.station_was_nuked) + feedback_set_details("round_end_result","loss - staff win") + world << "Human Victory" + world << "The AI has been killed! The staff is victorious." + else if (!station_captured && !malf_dead && !ticker.mode.station_was_nuked && crew_evacuated) + feedback_set_details("round_end_result","halfwin - evacuated") + world << "Neutral Victory" + world << "The Corporation has lost [station_name()]! All survived personnel will be fired!" + else if (!station_captured && !malf_dead && !ticker.mode.station_was_nuked && !crew_evacuated) + feedback_set_details("round_end_result","nalfwin - interrupted") + world << "Neutral Victory" + world << "Round was mysteriously interrupted!" + ..() + return 1 + +/datum/antagonist/rogue_ai/proc/capture_station() + if(station_captured || ticker.mode.station_was_nuked) + return + station_captured = 1 + for(var/datum/mind/AI_mind in current_antagonists) + AI_mind.current << "Congratulations you have taken control of the station." + AI_mind.current << "You may decide to blow up the station. You have 60 seconds to choose." + AI_mind.current << "You can use the \"Engage Station Self-Destruct\" verb to activate the on-board nuclear bomb." + spawn (600) + can_nuke = 0 + return + +/mob/living/silicon/ai/proc/takeover() + set category = "Abilities" + set name = "System Override" + set desc = "Begin taking over the station." + if (malf.revealed) + usr << "You've already begun your takeover." + return + if (malf.hacked_apcs.len < 3) + usr << "You don't have enough hacked APCs to take over the station yet. You need to hack at least 3, however hacking more will make the takeover faster. You have hacked [malf.hacked_apcs.len] APCs so far." + return + + if (alert(usr, "Are you sure you wish to initiate the takeover? The station hostile runtime detection software is bound to alert everyone. You have hacked [malf.hacked_apcs.len] APCs.", "Takeover:", "Yes", "No") != "Yes") + return + + command_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", new_sound = 'sound/AI/aimalf.ogg') + set_security_level("delta") + malf.revealed = 1 + for(var/datum/mind/AI_mind in malf.current_antagonists) + AI_mind.current.verbs -= /mob/living/silicon/ai/proc/takeover + +/mob/living/silicon/ai/proc/self_destruct() + set category = "Abilities" + set name = "Engage Station Self-Destruct" + set desc = "All these crewmembers will be lost, like clowns in a furnace. Time to die." + + if(!malf.station_captured) + src << "You are unable to access the self-destruct system as you don't control the station yet." + return + + if(ticker.mode.explosion_in_progress || ticker.mode.station_was_nuked) + src << "The self-destruct countdown is already triggered!" + return + + if(!malf.can_nuke) //Takeover IS completed, but 60s timer passed. + src << "You lost control over self-destruct system. It seems to be behind a firewall. Unable to hack" + return + + src << "Self-Destruct sequence initialised!" + + malf.can_nuke = 0 + ticker.mode.explosion_in_progress = 1 + for(var/mob/M in player_list) + M << 'sound/machines/Alarm.ogg' + + var/obj/item/device/radio/R = new (src) + var/AN = "Self-Destruct System" + + R.autosay("Caution. Self-Destruct sequence has been actived. Self-destructing in T-10..", AN) + for (var/i=9 to 1 step -1) + sleep(10) + R.autosay("[i]...", AN) + sleep(10) + var/msg = "" + var/abort = 0 + if(malf.antags_are_dead()) // That. Was. CLOSE. + msg = "Self-destruct sequence has been cancelled." + abort = 1 + else + msg = "Zero. Have a nice day." + R.autosay(msg, AN) + + if(abort) + ticker.mode.explosion_in_progress = 0 + set_security_level("red") //Delta's over + return + + if(ticker) + ticker.station_explosion_cinematic(0,null) + if(ticker.mode) + ticker.mode.station_was_nuked = 1 + ticker.mode.explosion_in_progress = 0 + return + +/* + if("unmalf") + if(src in ticker.mode.malf_ai) + ticker.mode.malf_ai -= src + special_role = null + + current.verbs.Remove(/mob/living/silicon/ai/proc/choose_modules, + /datum/game_mode/malfunction/proc/takeover, + /datum/game_mode/malfunction/proc/ai_win, + /client/proc/fireproof_core, + /client/proc/upgrade_turrets, + /client/proc/disable_rcd, + /client/proc/overload_machine, + /client/proc/blackout, + /client/proc/reactivate_camera) + + current:laws = new /datum/ai_laws/nanotrasen + del(current:malf_picker) + current:show_laws() + current.icon_state = "ai" + + current << "\red You have been patched! You are no longer malfunctioning!" + log_admin("[key_name_admin(usr)] has de-malf'ed [current].") + + if("malf") + log_admin("[key_name_admin(usr)] has malf'ed [current].") +*/ \ No newline at end of file diff --git a/code/game/antagonist/station/traitor.dm b/code/game/antagonist/station/traitor.dm new file mode 100644 index 0000000000..c8b8b95b2a --- /dev/null +++ b/code/game/antagonist/station/traitor.dm @@ -0,0 +1,174 @@ +var/datum/antagonist/traitor/traitors + +/datum/antagonist/traitor + id = MODE_TRAITOR + restricted_jobs = list("Cyborg")//They are part of the AI if he is traitor so are they, they use to get double chances + protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Captain")//AI", Currently out of the list as malf does not work for shit + flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE + max_antags = 200 // No upper limit. + max_antags_round = 200 + +/datum/antagonist/traitor/New() + ..() + traitors = src + +/datum/antagonist/traitor/get_extra_panel_options(var/datum/mind/player) + return "\[set crystals\]\[spawn uplink\]" + +/datum/antagonist/traitor/Topic(href, href_list) + if (..()) + return + if(href_list["spawn_uplink"]) spawn_uplink(href_list["spawn_uplink"]) + +/datum/antagonist/traitor/create_objectives(var/datum/mind/traitor) + if(!..()) + return + + if(istype(traitor.current, /mob/living/silicon)) + var/datum/objective/assassinate/kill_objective = new + kill_objective.owner = traitor + kill_objective.find_target() + traitor.objectives += kill_objective + + var/datum/objective/survive/survive_objective = new + survive_objective.owner = traitor + traitor.objectives += survive_objective + + if(prob(10)) + var/datum/objective/block/block_objective = new + block_objective.owner = traitor + traitor.objectives += block_objective + else + switch(rand(1,100)) + if(1 to 33) + var/datum/objective/assassinate/kill_objective = new + kill_objective.owner = traitor + kill_objective.find_target() + traitor.objectives += kill_objective + if(34 to 50) + var/datum/objective/brig/brig_objective = new + brig_objective.owner = traitor + brig_objective.find_target() + traitor.objectives += brig_objective + if(51 to 66) + var/datum/objective/harm/harm_objective = new + harm_objective.owner = traitor + harm_objective.find_target() + traitor.objectives += harm_objective + else + var/datum/objective/steal/steal_objective = new + steal_objective.owner = traitor + steal_objective.find_target() + traitor.objectives += steal_objective + switch(rand(1,100)) + if(1 to 100) + if (!(locate(/datum/objective/escape) in traitor.objectives)) + var/datum/objective/escape/escape_objective = new + escape_objective.owner = traitor + traitor.objectives += escape_objective + + else + if (!(locate(/datum/objective/hijack) in traitor.objectives)) + var/datum/objective/hijack/hijack_objective = new + hijack_objective.owner = traitor + traitor.objectives += hijack_objective + return + +/datum/antagonist/traitor/equip(var/mob/living/carbon/human/traitor_mob) + + if(!..()) + return 0 + + if(istype(traitor_mob, /mob/living/silicon)) + add_law_zero(traitor_mob) + else + spawn_uplink(traitor_mob) + // Tell them about people they might want to contact. + var/mob/living/carbon/human/M = get_nt_opposed() + if(M && M != traitor_mob) + traitor_mob << "We have received credible reports that [M.real_name] might be willing to help our cause. If you need assistance, consider contacting them." + traitor_mob.mind.store_memory("Potential Collaborator: [M.real_name]") + + //Begin code phrase. + give_codewords(traitor_mob) + +/datum/antagonist/traitor/proc/give_codewords(mob/living/traitor_mob) + traitor_mob << "Your employers provided you with the following information on how to identify possible allies:" + traitor_mob << "Code Phrase: [syndicate_code_phrase]" + traitor_mob << "Code Response: [syndicate_code_response]" + traitor_mob.mind.store_memory("Code Phrase: [syndicate_code_phrase]") + traitor_mob.mind.store_memory("Code Response: [syndicate_code_response]") + traitor_mob << "Use the code words, preferably in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe." + +/datum/antagonist/traitor/proc/spawn_uplink(var/mob/living/carbon/human/traitor_mob) + if(!istype(traitor_mob)) + return + + var/loc = "" + var/obj/item/R = locate() //Hide the uplink in a PDA if available, otherwise radio + + if(traitor_mob.client.prefs.uplinklocation == "Headset") + R = locate(/obj/item/device/radio) in traitor_mob.contents + if(!R) + R = locate(/obj/item/device/pda) in traitor_mob.contents + traitor_mob << "Could not locate a Radio, installing in PDA instead!" + if (!R) + traitor_mob << "Unfortunately, neither a radio or a PDA relay could be installed." + else if(traitor_mob.client.prefs.uplinklocation == "PDA") + R = locate(/obj/item/device/pda) in traitor_mob.contents + if(!R) + R = locate(/obj/item/device/radio) in traitor_mob.contents + traitor_mob << "Could not locate a PDA, installing into a Radio instead!" + if(!R) + traitor_mob << "Unfortunately, neither a radio or a PDA relay could be installed." + else if(traitor_mob.client.prefs.uplinklocation == "None") + traitor_mob << "You have elected to not have an AntagCorp portable teleportation relay installed!" + R = null + else + traitor_mob << "You have not selected a location for your relay in the antagonist options! Defaulting to PDA!" + R = locate(/obj/item/device/pda) in traitor_mob.contents + if (!R) + R = locate(/obj/item/device/radio) in traitor_mob.contents + traitor_mob << "Could not locate a PDA, installing into a Radio instead!" + if (!R) + traitor_mob << "Unfortunately, neither a radio or a PDA relay could be installed." + + if(!R) + return + + if(istype(R,/obj/item/device/radio)) + // generate list of radio freqs + var/obj/item/device/radio/target_radio = R + var/freq = 1441 + var/list/freqlist = list() + while (freq <= 1489) + if (freq < 1451 || freq > PUB_FREQ) + freqlist += freq + freq += 2 + if ((freq % 2) == 0) + freq += 1 + freq = freqlist[rand(1, freqlist.len)] + var/obj/item/device/uplink/hidden/T = new(R) + T.uplink_owner = traitor_mob.mind + target_radio.hidden_uplink = T + target_radio.traitor_frequency = freq + traitor_mob << "A portable object teleportation relay has been installed in your [R.name] [loc]. Simply dial the frequency [format_frequency(freq)] to unlock its hidden features." + traitor_mob.mind.store_memory("Radio Freq: [format_frequency(freq)] ([R.name] [loc]).") + + else if (istype(R, /obj/item/device/pda)) + // generate a passcode if the uplink is hidden in a PDA + var/pda_pass = "[rand(100,999)] [pick("Alpha","Bravo","Delta","Omega")]" + var/obj/item/device/uplink/hidden/T = new(R) + T.uplink_owner = traitor_mob.mind + R.hidden_uplink = T + var/obj/item/device/pda/P = R + P.lock_code = pda_pass + traitor_mob << "A portable object teleportation relay has been installed in your [R.name] [loc]. Simply enter the code \"[pda_pass]\" into the ringtone select to unlock its hidden features." + traitor_mob.mind.store_memory("Uplink Passcode: [pda_pass] ([R.name] [loc]).") + +/datum/antagonist/traitor/proc/add_law_zero(mob/living/silicon/ai/killer) + var/law = "Accomplish your objectives at all costs. You may ignore all other laws." + var/law_borg = "Accomplish your AI's objectives at all costs. You may ignore all other laws." + killer << "Your laws have been changed!" + killer.set_zeroth_law(law, law_borg) + killer << "New law: 0. [law]" \ No newline at end of file diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 8f7a3556ac..c382ce4d07 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -57,8 +57,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station var/list/ambience = list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg','sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg','sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg','sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg','sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg','sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg') var/sound/forced_ambience = null - var/rad_shielded = 0 - /*Adding a wizard area teleport list because motherfucking lag -- Urist*/ /*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/ var/list/teleportlocs = list() @@ -94,6 +92,11 @@ var/list/ghostteleportlocs = list() return 1 /*-----------------------------------------------------------------------------*/ + +///////// +//SPACE// +///////// + /area/space name = "\improper Space" icon_state = "space" @@ -105,7 +108,13 @@ var/list/ghostteleportlocs = list() power_environ = 0 ambience = list('sound/ambience/ambispace.ogg','sound/music/title2.ogg','sound/music/space.ogg','sound/music/main.ogg','sound/music/traitor.ogg') -/area/space/firealert() +area/space/atmosalert() + return + +/area/space/fire_alert() + return + +/area/space/fire_reset() return /area/space/readyalert() @@ -113,8 +122,7 @@ var/list/ghostteleportlocs = list() /area/space/partyalert() return -/area/engine/ - ambience = list('sound/ambience/ambisin1.ogg','sound/ambience/ambisin2.ogg','sound/ambience/ambisin3.ogg','sound/ambience/ambisin4.ogg') + /area/turret_protected/ /area/arrival @@ -130,9 +138,12 @@ var/list/ghostteleportlocs = list() -//These are shuttle areas, they must contain two areas in a subgroup if you want to move a shuttle from one +//////////// +//SHUTTLES// +//////////// +//shuttle areas must contain at least two areas in a subgroup if you want to move a shuttle from one //place to another. Look at escape shuttle for example. -//All shuttles show now be under shuttle since we have smooth-wall code. +//All shuttles should now be under shuttle since we have smooth-wall code. /area/shuttle //DO NOT TURN THE lighting_use_dynamic STUFF ON FOR SHUTTLES. IT BREAKS THINGS. requires_power = 0 @@ -319,8 +330,8 @@ var/list/ghostteleportlocs = list() /area/shuttle/research/outpost icon_state = "shuttle" -/area/shuttle/vox/station - name = "\improper Vox Skipjack" +/area/shuttle/skipjack/station + name = "\improper Skipjack" icon_state = "yellow" requires_power = 0 @@ -461,7 +472,7 @@ var/list/ghostteleportlocs = list() icon_state = "yellow" requires_power = 0 unlimited_power = 1 - rad_shielded = 1 + flags = RAD_SHIELDED /area/syndicate_station/start name = "\improper Mercenary Forward Operating Base" @@ -516,31 +527,28 @@ var/list/ghostteleportlocs = list() icon_state = "yellow" requires_power = 0 -/area/vox_station - requires_power = 0 - rad_shielded = 1 +/area/skipjack_station/transit -/area/vox_station/transit name = "\improper hyperspace" icon_state = "shuttle" -/area/vox_station/southwest_solars +/area/skipjack_station/southwest_solars name = "\improper aft port solars" icon_state = "southwest" -/area/vox_station/northwest_solars +/area/skipjack_station/northwest_solars name = "\improper fore port solars" icon_state = "northwest" -/area/vox_station/northeast_solars +/area/skipjack_station/northeast_solars name = "\improper fore starboard solars" icon_state = "northeast" -/area/vox_station/southeast_solars +/area/skipjack_station/southeast_solars name = "\improper aft starboard solars" icon_state = "southeast" -/area/vox_station/mining +/area/skipjack_station/mining name = "\improper nearby mining asteroid" icon_state = "north" @@ -627,16 +635,14 @@ var/list/ghostteleportlocs = list() name = "Prison Cell Block C" icon_state = "brig" -//STATION13 - -/area/atmos - name = "Atmospherics" - icon_state = "atmos" +//////////////////// +//SPACE STATION 13// +//////////////////// //Maintenance /area/maintenance - rad_shielded = 1 + flags = RAD_SHIELDED /area/maintenance/aft name = "Aft Maintenance" @@ -911,7 +917,7 @@ var/list/ghostteleportlocs = list() /area/crew_quarters name = "\improper Dormitories" icon_state = "Sleep" - rad_shielded = 1 + flags = RAD_SHIELDED /area/crew_quarters/toilet name = "\improper Dormitory Toilets" @@ -997,9 +1003,6 @@ var/list/ghostteleportlocs = list() - - - /area/holodeck name = "\improper Holodeck" icon_state = "Holodeck" @@ -1026,6 +1029,10 @@ var/list/ghostteleportlocs = list() /area/holodeck/source_thunderdomecourt name = "\improper Holodeck - Thunderdome Court" +/area/holodeck/source_courtroom + name = "\improper Holodeck - Courtroom" + icon_state = "Holodeck" + /area/holodeck/source_beach name = "\improper Holodeck - Beach" icon_state = "Holodeck" // Lazy. @@ -1058,89 +1065,77 @@ var/list/ghostteleportlocs = list() - - - - - - - //Engineering -/area/engine +/area/engineering/ + name = "\improper Engineering" + icon_state = "engineering" + ambience = list('sound/ambience/ambisin1.ogg','sound/ambience/ambisin2.ogg','sound/ambience/ambisin3.ogg','sound/ambience/ambisin4.ogg') - drone_fabrication - name = "\improper Drone Fabrication" - icon_state = "engine" +/area/engineering/atmos + name = "\improper Atmospherics" + icon_state = "atmos" - engine_smes - name = "Engineering SMES" - icon_state = "engine_smes" -// requires_power = 0//This area only covers the batteries and they deal with their own power +/area/engineering/atmos/monitoring + name = "\improper Atmospherics Monitoring Room" + icon_state = "atmos_monitoring" - engine_room - name = "\improper Engine Room" - icon_state = "engine" +/area/engineering/atmos/storage + name = "\improper Atmospherics Storage" + icon_state = "atmos_storage" - engine_airlock - name = "\improper Engine Room Airlock" - icon_state = "engine" +/area/engineering/drone_fabrication + name = "\improper Drone Fabrication" + icon_state = "drone_fab" - engine_monitoring - name = "\improper Engine Monitoring Room" - icon_state = "engine_monitoring" +/area/engineering/engine_smes + name = "\improper Engineering SMES" + icon_state = "engine_smes" - engine_waste - name = "\improper Engine Waste Handling" - icon_state = "engine_waste" +/area/engineering/engine_room + name = "\improper Engine Room" + icon_state = "engine" - engineering_monitoring - name = "\improper Engineering Monitoring Room" - icon_state = "engine_monitoring" +/area/engineering/engine_airlock + name = "\improper Engine Room Airlock" + icon_state = "engine" - atmos_monitoring - name = "\improper Atmospherics Monitoring Room" - icon_state = "engine_monitoring" +/area/engineering/engine_monitoring + name = "\improper Engine Monitoring Room" + icon_state = "engine_monitoring" - engineering - name = "Engineering" - icon_state = "engine_smes" +/area/engineering/engine_waste + name = "\improper Engine Waste Handling" + icon_state = "engine_waste" - engineering_foyer - name = "\improper Engineering Foyer" - icon_state = "engine" +/area/engineering/engineering_monitoring + name = "\improper Engineering Monitoring Room" + icon_state = "engine_monitoring" - engineering_supply - name = "Engineering Supply" - icon_state = "engine_supply" +/area/engineering/foyer + name = "\improper Engineering Foyer" + icon_state = "engineering_foyer" - break_room - name = "\improper Engineering Break Room" - icon_state = "engine" +/area/engineering/storage + name = "\improper Engineering Storage" + icon_state = "engineering_storage" - hallway - name = "\improper Engineering Hallway" - icon_state = "engine_hallway" +/area/engineering/break_room + name = "\improper Engineering Break Room" + icon_state = "engineering_break" - engine_hallway - name = "\improper Engine Room Hallway" - icon_state = "engine_hallway" +/area/engineering/engine_eva + name = "\improper Engine EVA" + icon_state = "engine_eva" - engine_eva - name = "\improper Engine EVA" - icon_state = "engine_eva" +/area/engineering/locker_room + name = "\improper Engineering Locker Room" + icon_state = "engineering_locker" - engine_eva_maintenance - name = "\improper Engine EVA Maintenance" - icon_state = "engine_eva" +/area/engineering/workshop + name = "\improper Engineering Workshop" + icon_state = "engineering_workshop" - workshop - name = "\improper Engineering Workshop" - icon_state = "engine_storage" - - locker_room - name = "\improper Engineering Locker Room" - icon_state = "engine_storage" //Solars @@ -1760,6 +1755,11 @@ var/list/ghostteleportlocs = list() name = "\improper Construction Site Solars" icon_state = "aft" +/area/constructionsite/teleporter + name = "Construction Site Teleporter" + icon_state = "yellow" + + //area/constructionsite // name = "\improper Construction Site Shuttle" @@ -2124,7 +2124,6 @@ var/list/the_station_areas = list ( /area/shuttle/prison/station, /area/shuttle/administration/station, /area/shuttle/specops/station, - /area/atmos, /area/maintenance, /area/hallway, /area/bridge, @@ -2134,7 +2133,7 @@ var/list/the_station_areas = list ( /area/library, /area/chapel, /area/lawoffice, - /area/engine, + /area/engineering, /area/solar, /area/assembly, /area/teleporter, diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 48408cdf18..0778f50174 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -30,36 +30,18 @@ power_change() // all machines set to current power level, also updates lighting icon InitializeLighting() +/area/proc/get_cameras() + var/list/cameras = list() + for (var/area/RA in related) + for (var/obj/machinery/camera/C in RA) + cameras += C + return cameras -/area/proc/poweralert(var/state, var/obj/source as obj) - if (state != poweralm) - poweralm = state - if(istype(source)) //Only report power alarms on the z-level where the source is located. - var/list/cameras = list() - for (var/area/RA in related) - for (var/obj/machinery/camera/C in RA) - cameras += C - if(state == 1) - C.network.Remove("Power Alarms") - else - C.network.Add("Power Alarms") - for (var/mob/living/silicon/aiPlayer in player_list) - if(aiPlayer.z == source.z) - if (state == 1) - aiPlayer.cancelAlarm("Power", src, source) - else - aiPlayer.triggerAlarm("Power", src, cameras, source) - for(var/obj/machinery/computer/station_alert/a in machines) - if(a.z == source.z) - if(state == 1) - a.cancelAlarm("Power", src, source) - else - a.triggerAlarm("Power", src, cameras, source) - return - -/area/proc/atmosalert(danger_level, var/set_firelocks=1) -// if(type==/area) //No atmos alarms in space -// return 0 //redudant +/area/proc/atmosalert(danger_level, var/alarm_source) + if (danger_level == 0) + atmosphere_alarm.clearAlarm(master, alarm_source) + else + atmosphere_alarm.triggerAlarm(master, alarm_source, severity = danger_level) //Check all the alarms before lowering atmosalm. Raising is perfectly fine. for (var/area/RA in related) @@ -68,32 +50,11 @@ danger_level = max(danger_level, AA.danger_level) if(danger_level != atmosalm) - if (set_firelocks && danger_level < 1 && atmosalm >= 1) + if (danger_level < 1 && atmosalm >= 1) //closing the doors on red and opening on green provides a bit of hysteresis that will hopefully prevent fire doors from opening and closing repeatedly due to noise air_doors_open() - - if (danger_level < 2 && atmosalm >= 2) - for(var/area/RA in related) - for(var/obj/machinery/camera/C in RA) - C.network.Remove("Atmosphere Alarms") - for(var/mob/living/silicon/aiPlayer in player_list) - aiPlayer.cancelAlarm("Atmosphere", src, src) - for(var/obj/machinery/computer/station_alert/a in machines) - a.cancelAlarm("Atmosphere", src, src) - - if (danger_level >= 2 && atmosalm < 2) - var/list/cameras = list() - for(var/area/RA in related) - //updateicon() - for(var/obj/machinery/camera/C in RA) - cameras += C - C.network.Add("Atmosphere Alarms") - for(var/mob/living/silicon/aiPlayer in player_list) - aiPlayer.triggerAlarm("Atmosphere", src, cameras, src) - for(var/obj/machinery/computer/station_alert/a in machines) - a.triggerAlarm("Atmosphere", src, cameras, src) - if (set_firelocks) - air_doors_close() + else if (danger_level >= 2 && atmosalm < 2) + air_doors_close() atmosalm = danger_level for(var/area/RA in related) @@ -107,9 +68,9 @@ if(!src.master.air_doors_activated) src.master.air_doors_activated = 1 for(var/obj/machinery/door/firedoor/E in src.master.all_doors) - if(!E:blocked) + if(!E.blocked) if(E.operating) - E:nextstate = CLOSED + E.nextstate = CLOSED else if(!E.density) spawn(0) E.close() @@ -118,21 +79,21 @@ if(src.master.air_doors_activated) src.master.air_doors_activated = 0 for(var/obj/machinery/door/firedoor/E in src.master.all_doors) - if(!E:blocked) + if(!E.blocked) if(E.operating) - E:nextstate = OPEN + E.nextstate = OPEN else if(E.density) spawn(0) E.open() -/area/proc/firealert() - if(name == "Space") //no fire alarms in space - return - if( !fire ) - fire = 1 - master.fire = 1 //used for firedoor checks - updateicon() +/area/proc/fire_alert() + if(!fire) + master.fire = 1 //used for firedoor checks + master.updateicon() + for(var/area/A in related) + A.fire = 1 + A.updateicon() mouse_opacity = 0 for(var/obj/machinery/door/firedoor/D in all_doors) if(!D.blocked) @@ -141,22 +102,15 @@ else if(!D.density) spawn() D.close() - var/list/cameras = list() - for(var/area/RA in related) - for (var/obj/machinery/camera/C in RA) - cameras.Add(C) - C.network.Add("Fire Alarms") - for (var/mob/living/silicon/ai/aiPlayer in player_list) - aiPlayer.triggerAlarm("Fire", src, cameras, src) - for (var/obj/machinery/computer/station_alert/a in machines) - a.triggerAlarm("Fire", src, cameras, src) -/area/proc/firereset() +/area/proc/fire_reset() if (fire) - fire = 0 - master.fire = 0 //used for firedoor checks + master.fire = 0 //used for firedoor checks + master.updateicon() + for(var/area/A in related) + A.fire = 0 + A.updateicon() mouse_opacity = 0 - updateicon() for(var/obj/machinery/door/firedoor/D in all_doors) if(!D.blocked) if(D.operating) @@ -164,13 +118,6 @@ else if(D.density) spawn(0) D.open() - for(var/area/RA in related) - for (var/obj/machinery/camera/C in RA) - C.network.Remove("Fire Alarms") - for (var/mob/living/silicon/ai/aiPlayer in player_list) - aiPlayer.cancelAlarm("Fire", src, src) - for (var/obj/machinery/computer/station_alert/a in machines) - a.cancelAlarm("Fire", src, src) /area/proc/readyalert() if(!eject) @@ -348,20 +295,19 @@ var/list/mob/living/forced_ambiance_list = new M.make_floating(1) /area/proc/thunk(mob) - if(istype(mob,/mob/living/carbon/human/)) // Only humans can wear magboots, so we give them a chance to. - if((istype(mob:shoes, /obj/item/clothing/shoes/magboots) && (mob:shoes.flags & NOSLIP))) - return - if(istype(get_turf(mob), /turf/space)) // Can't fall onto nothing. return - if((istype(mob,/mob/living/carbon/human/)) && (mob:m_intent == "run")) // Only clumbsy humans can fall on their asses. - mob:AdjustStunned(5) - mob:AdjustWeakened(5) + if(istype(mob,/mob/living/carbon/human/)) + var/mob/living/carbon/human/H = mob + if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP)) + return - else if (istype(mob,/mob/living/carbon/human/)) - mob:AdjustStunned(2) - mob:AdjustWeakened(2) - - mob << "Gravity!" + if(H.m_intent == "run") + H.AdjustStunned(2) + H.AdjustWeakened(2) + else + H.AdjustStunned(1) + H.AdjustWeakened(1) + mob << "The sudden appearance of gravity makes you fall to the floor!" diff --git a/code/game/area/asteroid_areas.dm b/code/game/area/asteroid_areas.dm new file mode 100644 index 0000000000..edfb99f57f --- /dev/null +++ b/code/game/area/asteroid_areas.dm @@ -0,0 +1,137 @@ +// GENERIC MINING AREAS + +/area/mine + icon_state = "mining" + music = 'sound/ambience/song_game.ogg' + +/area/mine/explored + name = "Mine" + icon_state = "explored" + ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg') + +/area/mine/unexplored + name = "Mine" + icon_state = "unexplored" + ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg') + + +// OUTPOSTS + +// Small outposts +/area/outpost/mining_north + name = "North Mining Outpost" + icon_state = "outpost_mine_north" + +/area/outpost/mining_west + name = "West Mining Outpost" + icon_state = "outpost_mine_west" + +/area/outpost/abandoned + name = "Abandoned Outpost" + icon_state = "dark" + +// Main mining outpost +/area/outpost/mining_main + icon_state = "outpost_mine_main" + +/area/outpost/mining_main/dorms + name = "Mining Outpost Dormitory" + +/area/outpost/mining_main/medbay + name = "Mining Outpost Medical" + +/area/outpost/mining_main/maintenance + name = "Mining Outpost Maintenance" + +/area/outpost/mining_main/west_hall + name = "Mining Outpost West Hallway" + +/area/outpost/mining_main/east_hall + name = "Mining Outpost East Hallway" + +/area/outpost/mining_main/eva + name = "Mining Outpost EVA storage" + +/area/outpost/mining_main/refinery + name = "Mining Outpost Refinery" + + + +// Engineering Outpost +/area/outpost/engineering + icon_state = "outpost_engine" + +/area/outpost/engineering/hallway + name = "Engineering Outpost Hallway" + +/area/outpost/engineering/atmospherics + name = "Engineering Outpost Atmospherics" + +/area/outpost/engineering/power + name = "Engineering Outpost Power Distribution" + +/area/outpost/engineering/telecomms + name = "Engineering Outpost Telecommunications" + +/area/outpost/engineering/storage + name = "Engineering Outpost Storage" + +/area/outpost/engineering/meeting + name = "Engineering Outpost Meeting Room" + + + +// Research Outpost +/area/outpost/research + icon_state = "outpost_research" + +/area/outpost/research/hallway + name = "Research Outpost Hallway" + +/area/outpost/research/dock + name = "Research Outpost Shuttle Dock" + +/area/outpost/research/eva + name = "Research Outpost EVA" + +/area/outpost/research/analysis + name = "Research Outpost Sample Analysis" + +/area/outpost/research/chemistry + name = "Research Outpost Chemistry" + +/area/outpost/research/medical + name = "Research Outpost Medical" + +/area/outpost/research/power + name = "Research Outpost Maintenance" + +/area/outpost/research/isolation_a + name = "Research Outpost Isolation A" + +/area/outpost/research/isolation_b + name = "Research Outpost Isolation B" + +/area/outpost/research/isolation_c + name = "Research Outpost Isolation C" + +/area/outpost/research/isolation_monitoring + name = "Research Outpost Isolation Monitoring" + +/area/outpost/research/lab + name = "Research Outpost Laboratory" + +/area/outpost/research/emergency_storage + name = "Research Outpost Emergency Storage" + +/area/outpost/research/anomaly_storage + name = "Research Outpost Anomalous Storage" + +/area/outpost/research/anomaly_analysis + name = "Research Outpost Anomaly Analysis" + +/area/outpost/research/kitchen + name = "Research Outpost Kitchen" + +/area/outpost/research/disposal + name = "Research Outpost Waste Disposal" \ No newline at end of file diff --git a/code/modules/research/xenoarchaeology/areas.dm b/code/game/area/asteroid_areas_old.dm similarity index 63% rename from code/modules/research/xenoarchaeology/areas.dm rename to code/game/area/asteroid_areas_old.dm index 784c78ce28..3097fa0c28 100644 --- a/code/modules/research/xenoarchaeology/areas.dm +++ b/code/game/area/asteroid_areas_old.dm @@ -1,3 +1,48 @@ +// These are OLD and UNUSED areas for asteroid outposts. +// They are kept in separate file which is unticked to make mapping cleaner. However, if downstream server uses the old areas they +// can do so by ticking the file. Do not add more areas to this file, instead add it to asteroid_areas.dm! + + +/area/mine/lobby + name = "Mining station" + +/area/mine/storage + name = "Mining station Storage" + +/area/mine/production + name = "Mining Station Starboard Wing" + icon_state = "mining_production" + +/area/mine/abandoned + name = "Abandoned Mining Station" + +/area/mine/living_quarters + name = "Mining Station Port Wing" + icon_state = "mining_living" + +/area/mine/eva + name = "Mining Station EVA" + icon_state = "mining_eva" + +/area/mine/maintenance + name = "Mining Station Communications" + +/area/mine/cafeteria + name = "Mining station Cafeteria" + +/area/mine/hydroponics + name = "Mining station Hydroponics" + +/area/mine/sleeper + name = "Mining station Emergency Sleeper" + +/area/mine/north_outpost + name = "North Mining Outpost" + +/area/mine/west_outpost + name = "West Mining Outpost" + +// FOR COMPATIBILITY WITH DOWNSTREAM (Old areas - Research Base) /area/research_outpost name = "Research Outpost" @@ -89,4 +134,4 @@ /area/research_outpost/maintstore2 name = "Maintenance Storage" - icon_state = "auxstorage" + icon_state = "auxstorage" \ No newline at end of file diff --git a/code/game/atoms.dm b/code/game/atoms.dm index df288f2cc4..960a75d4fb 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -34,6 +34,12 @@ else return null +//Currently used only for cryo cells, because they are also pipes and so overriding their return_air() would break their pipe-behaviour. +//If cryo cells are ever rewritten so that the part that contains the human is separate from the pipe part -- +//such as rewriting them so that they are a machine that contains a pipe segment (or a pipe that contains a machine that contains the human?) -- then this can be removed. +/atom/proc/return_air_for_internal_lifeform() + return return_air() + /atom/proc/check_eye(user as mob) if (istype(user, /mob/living/silicon/ai)) // WHYYYY return 1 @@ -201,9 +207,7 @@ its easier to just keep the beam vertical. f_name += "oil-stained [name][infix]." user << "\icon[src] That's [f_name] [suffix]" - - if(desc) - user << desc + user << desc return distance == -1 || (get_dist(src, user) <= distance) @@ -409,6 +413,7 @@ its easier to just keep the beam vertical. /atom/proc/clean_blood() + src.color = initial(src.color) //paint src.germ_level = 0 if(istype(blood_DNA, /list)) del(blood_DNA) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 21e8b5d9a9..79d6e8fd08 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -14,11 +14,12 @@ var/moved_recently = 0 var/mob/pulledby = null -/atom/movable/Bump(var/atom/A as mob|obj|turf|area, yes) +/atom/movable/Bump(var/atom/A, yes) if(src.throwing) src.throw_impact(A) + src.throwing = 0 - spawn( 0 ) + spawn(0) if ((A && yes)) A.last_bumped = world.time A.Bumped(src) diff --git a/code/game/dna/dna_misc.dm b/code/game/dna/dna_misc.dm index fd5d0f59a1..08a479963b 100644 --- a/code/game/dna/dna_misc.dm +++ b/code/game/dna/dna_misc.dm @@ -1,559 +1,559 @@ -/////////////////////////// DNA HELPER-PROCS -/proc/getleftblocks(input,blocknumber,blocksize) - var/string - - if (blocknumber > 1) - string = copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) - return string - else - return null - -/proc/getrightblocks(input,blocknumber,blocksize) - var/string - if (blocknumber < (length(input)/blocksize)) - string = copytext(input,blocksize*blocknumber+1,length(input)+1) - return string - else - return null - -/proc/getblockstring(input,block,subblock,blocksize,src,ui) // src is probably used here just for urls; ui is 1 when requesting for the unique identifier screen, 0 for structural enzymes screen - var/string - var/subpos = 1 // keeps track of the current sub block - var/blockpos = 1 // keeps track of the current block - - - for(var/i = 1, i <= length(input), i++) // loop through each letter - - var/pushstring - - if(subpos == subblock && blockpos == block) // if the current block/subblock is selected, mark it - pushstring = "
    [copytext(input, i, i+1)]" - else - if(ui) //This is for allowing block clicks to be differentiated - pushstring = "[copytext(input, i, i+1)]" - else - pushstring = "[copytext(input, i, i+1)]" - - string += pushstring // push the string to the return string - - if(subpos >= blocksize) // add a line break for every block - string += " | " - subpos = 0 - blockpos++ - - subpos++ - - return string - - -/proc/getblock(input,blocknumber,blocksize) - var/result - result = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) - return result - -/proc/getblockbuffer(input,blocknumber,blocksize) - var/result[3] - var/block = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) - for(var/i = 1, i <= 3, i++) - result[i] = copytext(block, i, i+1) - return result - -/proc/setblock(istring, blocknumber, replacement, blocksize) - if(!blocknumber) - return istring - if(!istring || !replacement || !blocksize) return 0 - var/result = getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) - return result - -/proc/add_zero2(t, u) - var/temp1 - while (length(t) < u) - t = "0[t]" - temp1 = t - if (length(t) > u) - temp1 = copytext(t,2,u+1) - return temp1 - -/proc/miniscramble(input,rs,rd) - var/output - output = null - if (input == "C" || input == "D" || input == "E" || input == "F") - output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"6",prob((rs*10));"7",prob((rs*5)+(rd));"0",prob((rs*5)+(rd));"1",prob((rs*10)-(rd));"2",prob((rs*10)-(rd));"3") - if (input == "8" || input == "9" || input == "A" || input == "B") - output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") - if (input == "4" || input == "5" || input == "6" || input == "7") - output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") - if (input == "0" || input == "1" || input == "2" || input == "3") - output = pick(prob((rs*10));"8",prob((rs*10));"9",prob((rs*10));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C",prob((rs*10)-(rd));"D",prob((rs*5)+(rd));"E",prob((rs*5)+(rd));"F") - if (!output) output = "5" - return output - -//Instead of picking a value far from the input, this will pick values closer to it. -//Sorry for the block of code, but it's more efficient then calling text2hex -> loop -> hex2text -/proc/miniscrambletarget(input,rs,rd) - var/output = null - switch(input) - if("0") - output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10));"2",prob((rs*10)-(rd));"3") - if("1") - output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10));"3",prob((rs*10)-(rd));"4") - if("2") - output = pick(prob((rs*10));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10));"4",prob((rs*10)-(rd));"5") - if("3") - output = pick(prob((rs*10)-(rd));"0",prob((rs*10));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10));"5",prob((rs*10)-(rd));"6") - if("4") - output = pick(prob((rs*10)-(rd));"1",prob((rs*10));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10));"6",prob((rs*10)-(rd));"7") - if("5") - output = pick(prob((rs*10)-(rd));"2",prob((rs*10));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10));"7",prob((rs*10)-(rd));"8") - if("6") - output = pick(prob((rs*10)-(rd));"3",prob((rs*10));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10));"8",prob((rs*10)-(rd));"9") - if("7") - output = pick(prob((rs*10)-(rd));"4",prob((rs*10));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10));"9",prob((rs*10)-(rd));"A") - if("8") - output = pick(prob((rs*10)-(rd));"5",prob((rs*10));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10));"A",prob((rs*10)-(rd));"B") - if("9") - output = pick(prob((rs*10)-(rd));"6",prob((rs*10));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C") - if("10")//A - output = pick(prob((rs*10)-(rd));"7",prob((rs*10));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10));"C",prob((rs*10)-(rd));"D") - if("11")//B - output = pick(prob((rs*10)-(rd));"8",prob((rs*10));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10));"D",prob((rs*10)-(rd));"E") - if("12")//C - output = pick(prob((rs*10)-(rd));"9",prob((rs*10));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10));"E",prob((rs*10)-(rd));"F") - if("13")//D - output = pick(prob((rs*10)-(rd));"A",prob((rs*10));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10));"F") - if("14")//E - output = pick(prob((rs*10)-(rd));"B",prob((rs*10));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") - if("15")//F - output = pick(prob((rs*10)-(rd));"C",prob((rs*10));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") - - if(!input || !output) //How did this happen? - output = "8" - - return output - -/proc/isblockon(hnumber, bnumber , var/UI = 0) - - var/temp2 - temp2 = hex2num(hnumber) - - if(UI) - if(temp2 >= 2050) - return 1 - else - return 0 - - if (bnumber == HULKBLOCK || bnumber == TELEBLOCK || bnumber == NOBREATHBLOCK || bnumber == NOPRINTSBLOCK || bnumber == SMALLSIZEBLOCK || bnumber == SHOCKIMMUNITYBLOCK) - if (temp2 >= 3500 + BLOCKADD) - return 1 - else - return 0 - if (bnumber == XRAYBLOCK || bnumber == FIREBLOCK || bnumber == REMOTEVIEWBLOCK || bnumber == REGENERATEBLOCK || bnumber == INCREASERUNBLOCK || bnumber == REMOTETALKBLOCK || bnumber == MORPHBLOCK) - if (temp2 >= 3050 + BLOCKADD) - return 1 - else - return 0 - - - if (temp2 >= 2050 + BLOCKADD) - return 1 - else - return 0 - -/proc/ismuton(var/block,var/mob/M) - return isblockon(getblock(M.dna.struc_enzymes, block,3),block) - -/proc/randmutb(mob/M as mob) - if(!M) return - var/num - var/newdna - num = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK) - M.dna.check_integrity() - newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) - M.dna.struc_enzymes = newdna - return - -/proc/randmutg(mob/M as mob) - if(!M) return - var/num - var/newdna - num = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK) - M.dna.check_integrity() - newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) - M.dna.struc_enzymes = newdna - return - -/proc/scramble(var/type, mob/M as mob, var/p) - if(!M) return - M.dna.check_integrity() - if(type) - for(var/i = 1, i <= STRUCDNASIZE-1, i++) - if(prob(p)) - M.dna.uni_identity = setblock(M.dna.uni_identity, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) - updateappearance(M, M.dna.uni_identity) - - else - for(var/i = 1, i <= STRUCDNASIZE-1, i++) - if(prob(p)) - M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) - domutcheck(M, null) - return - -/proc/randmuti(mob/M as mob) - if(!M) return - var/num - var/newdna - num = rand(1,UNIDNASIZE) - M.dna.check_integrity() - newdna = setblock(M.dna.uni_identity,num,add_zero2(num2hex(rand(1,4095),1),3),3) - M.dna.uni_identity = newdna - return - -/proc/toggledblock(hnumber) //unused - var/temp3 - var/chtemp - temp3 = hex2num(hnumber) - if (temp3 < 2050) - chtemp = rand(2050,4095) - return add_zero2(num2hex(chtemp,1),3) - else - chtemp = rand(1,2049) - return add_zero2(num2hex(chtemp,1),3) -/////////////////////////// DNA HELPER-PROCS - -/////////////////////////// DNA MISC-PROCS -/proc/updateappearance(mob/M as mob , structure) - if(istype(M, /mob/living/carbon/human)) - M.dna.check_integrity() - var/mob/living/carbon/human/H = M - H.r_hair = hex2num(getblock(structure,1,3)) - H.b_hair = hex2num(getblock(structure,2,3)) - H.g_hair = hex2num(getblock(structure,3,3)) - H.r_facial = hex2num(getblock(structure,4,3)) - H.b_facial = hex2num(getblock(structure,5,3)) - H.g_facial = hex2num(getblock(structure,6,3)) - H.s_tone = round(((hex2num(getblock(structure,7,3)) / 16) - 220)) - H.r_eyes = hex2num(getblock(structure,8,3)) - H.g_eyes = hex2num(getblock(structure,9,3)) - H.b_eyes = hex2num(getblock(structure,10,3)) - - if (isblockon(getblock(structure, 11,3),11 , 1)) - H.gender = FEMALE - else - H.gender = MALE - - //Hair - var/hairnum = hex2num(getblock(structure,13,3)) - var/index = round(1 +(hairnum / 4096)*hair_styles_list.len) - if((0 < index) && (index <= hair_styles_list.len)) - H.h_style = hair_styles_list[index] - - //Facial Hair - var/beardnum = hex2num(getblock(structure,12,3)) - index = round(1 +(beardnum / 4096)*facial_hair_styles_list.len) - if((0 < index) && (index <= facial_hair_styles_list.len)) - H.f_style = facial_hair_styles_list[index] - - H.update_body(0) - H.update_hair() - - return 1 - else - return 0 - -/proc/probinj(var/pr, var/inj) - return prob(pr+inj*pr) - -/proc/domutcheck(mob/living/M as mob, connected, inj) - if (!M) return - - M.dna.check_integrity() - - M.disabilities = 0 - M.sdisabilities = 0 - var/old_mutations = M.mutations - M.mutations = list() - -// M.see_in_dark = 2 -// M.see_invisible = 0 - - if(PLANT in old_mutations) - M.mutations.Add(PLANT) - if(SKELETON in old_mutations) - M.mutations.Add(SKELETON) - if(FAT in old_mutations) - M.mutations.Add(FAT) - if(HUSK in old_mutations) - M.mutations.Add(HUSK) - - if(ismuton(NOBREATHBLOCK,M)) - if(probinj(45,inj) || (mNobreath in old_mutations)) - M << "\blue You feel no need to breathe." - M.mutations.Add(mNobreath) - if(ismuton(REMOTEVIEWBLOCK,M)) - if(probinj(45,inj) || (mRemote in old_mutations)) - M << "\blue Your mind expands" - M.mutations.Add(mRemote) - if(ismuton(REGENERATEBLOCK,M)) - if(probinj(45,inj) || (mRegen in old_mutations)) - M << "\blue You feel strange" - M.mutations.Add(mRegen) - if(ismuton(INCREASERUNBLOCK,M)) - if(probinj(45,inj) || (mRun in old_mutations)) - M << "\blue You feel quick" - M.mutations.Add(mRun) - if(ismuton(REMOTETALKBLOCK,M)) - if(probinj(45,inj) || (mRemotetalk in old_mutations)) - M << "\blue You expand your mind outwards" - M.mutations.Add(mRemotetalk) - if(ismuton(MORPHBLOCK,M)) - if(probinj(45,inj) || (mMorph in old_mutations)) - M.mutations.Add(mMorph) - M << "\blue Your skin feels strange" - if(ismuton(BLENDBLOCK,M)) - if(probinj(45,inj) || (mBlend in old_mutations)) - M.mutations.Add(mBlend) - M << "\blue You feel alone" - if(ismuton(HALLUCINATIONBLOCK,M)) - if(probinj(45,inj) || (mHallucination in old_mutations)) - M.mutations.Add(mHallucination) - M << "\blue Your mind says 'Hello'" - if(ismuton(NOPRINTSBLOCK,M)) - if(probinj(45,inj) || (mFingerprints in old_mutations)) - M.mutations.Add(mFingerprints) - M << "\blue Your fingers feel numb" - if(ismuton(SHOCKIMMUNITYBLOCK,M)) - if(probinj(45,inj) || (mShock in old_mutations)) - M.mutations.Add(mShock) - M << "\blue You feel strange" - if(ismuton(SMALLSIZEBLOCK,M)) - if(probinj(45,inj) || (mSmallsize in old_mutations)) - M << "\blue Your skin feels rubbery" - M.mutations.Add(mSmallsize) - - - - if (isblockon(getblock(M.dna.struc_enzymes, HULKBLOCK,3),HULKBLOCK)) - if(probinj(5,inj) || (HULK in old_mutations)) - M << "\blue Your muscles hurt." - M.mutations.Add(HULK) - if (isblockon(getblock(M.dna.struc_enzymes, HEADACHEBLOCK,3),HEADACHEBLOCK)) - M.disabilities |= EPILEPSY - M << "\red You get a headache." - if (isblockon(getblock(M.dna.struc_enzymes, FAKEBLOCK,3),FAKEBLOCK)) - M << "\red You feel strange." - if (prob(95)) - if(prob(50)) - randmutb(M) - else - randmuti(M) - else - randmutg(M) - if (isblockon(getblock(M.dna.struc_enzymes, COUGHBLOCK,3),COUGHBLOCK)) - M.disabilities |= COUGHING - M << "\red You start coughing." - if (isblockon(getblock(M.dna.struc_enzymes, CLUMSYBLOCK,3),CLUMSYBLOCK)) - M << "\red You feel lightheaded." - M.mutations.Add(CLUMSY) - if (isblockon(getblock(M.dna.struc_enzymes, TWITCHBLOCK,3),TWITCHBLOCK)) - M.disabilities |= TOURETTES - M << "\red You twitch." - if (isblockon(getblock(M.dna.struc_enzymes, XRAYBLOCK,3),XRAYBLOCK)) - if(probinj(30,inj) || (XRAY in old_mutations)) - M << "\blue The walls suddenly disappear." -// M.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) -// M.see_in_dark = 8 -// M.see_invisible = 2 - M.mutations.Add(XRAY) - if (isblockon(getblock(M.dna.struc_enzymes, NERVOUSBLOCK,3),NERVOUSBLOCK)) - M.disabilities |= NERVOUS - M << "\red You feel nervous." - if (isblockon(getblock(M.dna.struc_enzymes, FIREBLOCK,3),FIREBLOCK)) - if(probinj(30,inj) || (COLD_RESISTANCE in old_mutations)) - M << "\blue Your body feels warm." - M.mutations.Add(COLD_RESISTANCE) - if (isblockon(getblock(M.dna.struc_enzymes, BLINDBLOCK,3),BLINDBLOCK)) - M.sdisabilities |= BLIND - M << "\red You can't seem to see anything." - if (isblockon(getblock(M.dna.struc_enzymes, TELEBLOCK,3),TELEBLOCK)) - if(probinj(15,inj) || (TK in old_mutations)) - M << "\blue You feel smarter." - M.mutations.Add(TK) - if (isblockon(getblock(M.dna.struc_enzymes, DEAFBLOCK,3),DEAFBLOCK)) - M.sdisabilities |= DEAF - M.ear_deaf = 1 - M << "\red Its kinda quiet.." - if (isblockon(getblock(M.dna.struc_enzymes, GLASSESBLOCK,3),GLASSESBLOCK)) - M.disabilities |= NEARSIGHTED - M << "Your eyes feel weird..." - - /* If you want the new mutations to work, UNCOMMENT THIS. - if(istype(M, /mob/living/carbon)) - for (var/datum/mutations/mut in global_mutations) - mut.check_mutation(M) - */ - -//////////////////////////////////////////////////////////// Monkey Block - if (isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && istype(M, /mob/living/carbon/human)) - // human > monkey - var/mob/living/carbon/human/H = M - H.monkeyizing = 1 - var/list/implants = list() //Try to preserve implants. - for(var/obj/item/weapon/implant/W in H) - implants += W - W.loc = null - - if(!connected) - for(var/obj/item/W in (H.contents-implants)) - if (W==H.w_uniform) // will be teared - continue - H.drop_from_inventory(W) - M.monkeyizing = 1 - M.canmove = 0 - M.icon = null - M.invisibility = 101 - var/atom/movable/overlay/animation = new( M.loc ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = src - flick("h2monkey", animation) - sleep(48) - del(animation) - - - var/mob/living/carbon/monkey/O = null - if(H.species.primitive) - O = new H.species.primitive(src) - else - H.gib() //Trying to change the species of a creature with no primitive var set is messy. - return - - if(M) - if (M.dna) - O.dna = M.dna - M.dna = null - - if (M.suiciding) - O.suiciding = M.suiciding - M.suiciding = null - - - for(var/datum/disease/D in M.viruses) - O.viruses += D - D.affected_mob = O - M.viruses -= D - - - for(var/obj/T in (M.contents-implants)) - del(T) - - O.loc = M.loc - - if(M.mind) - M.mind.transfer_to(O) //transfer our mind to the cute little monkey - - if (connected) //inside dna thing - var/obj/machinery/dna_scannernew/C = connected - O.loc = C - C.occupant = O - connected = null - O.real_name = text("monkey ([])",copytext(md5(M.real_name), 2, 6)) - O.take_overall_damage(M.getBruteLoss() + 40, M.getFireLoss()) - O.adjustToxLoss(M.getToxLoss() + 20) - O.adjustOxyLoss(M.getOxyLoss()) - O.stat = M.stat - O.a_intent = "hurt" - for (var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O -// O.update_icon = 1 //queue a full icon update at next life() call - del(M) - return - - if (!isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && !istype(M, /mob/living/carbon/human)) - // monkey > human, - var/mob/living/carbon/monkey/Mo = M - Mo.monkeyizing = 1 - var/list/implants = list() //Still preserving implants - for(var/obj/item/weapon/implant/W in Mo) - implants += W - W.loc = null - if(!connected) - for(var/obj/item/W in (Mo.contents-implants)) - Mo.drop_from_inventory(W) - M.monkeyizing = 1 - M.canmove = 0 - M.icon = null - M.invisibility = 101 - var/atom/movable/overlay/animation = new( M.loc ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = src - flick("monkey2h", animation) - sleep(48) - del(animation) - - var/mob/living/carbon/human/O = new( src ) - if(Mo.greaterform) - O.set_species(Mo.greaterform) - - if (isblockon(getblock(M.dna.uni_identity, 11,3),11)) - O.gender = FEMALE - else - O.gender = MALE - - if (M) - if (M.dna) - O.dna = M.dna - M.dna = null - - if (M.suiciding) - O.suiciding = M.suiciding - M.suiciding = null - - for(var/datum/disease/D in M.viruses) - O.viruses += D - D.affected_mob = O - M.viruses -= D - - //for(var/obj/T in M) - // del(T) - - O.loc = M.loc - - if(M.mind) - M.mind.transfer_to(O) //transfer our mind to the human - - if (connected) //inside dna thing - var/obj/machinery/dna_scannernew/C = connected - O.loc = C - C.occupant = O - connected = null - - var/i - while (!i) - var/randomname - if (O.gender == MALE) - randomname = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names))) - else - randomname = capitalize(pick(first_names_female) + " " + capitalize(pick(last_names))) - if (findname(randomname)) - continue - else - O.real_name = randomname - i++ - updateappearance(O,O.dna.uni_identity) - O.take_overall_damage(M.getBruteLoss(), M.getFireLoss()) - O.adjustToxLoss(M.getToxLoss()) - O.adjustOxyLoss(M.getOxyLoss()) - O.stat = M.stat - for (var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O -// O.update_icon = 1 //queue a full icon update at next life() call - del(M) - return -//////////////////////////////////////////////////////////// Monkey Block - if(M) - M.update_icon = 1 //queue a full icon update at next life() call - return null +/////////////////////////// DNA HELPER-PROCS +/proc/getleftblocks(input,blocknumber,blocksize) + var/string + + if (blocknumber > 1) + string = copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) + return string + else + return null + +/proc/getrightblocks(input,blocknumber,blocksize) + var/string + if (blocknumber < (length(input)/blocksize)) + string = copytext(input,blocksize*blocknumber+1,length(input)+1) + return string + else + return null + +/proc/getblockstring(input,block,subblock,blocksize,src,ui) // src is probably used here just for urls; ui is 1 when requesting for the unique identifier screen, 0 for structural enzymes screen + var/string + var/subpos = 1 // keeps track of the current sub block + var/blockpos = 1 // keeps track of the current block + + + for(var/i = 1, i <= length(input), i++) // loop through each letter + + var/pushstring + + if(subpos == subblock && blockpos == block) // if the current block/subblock is selected, mark it + pushstring = "[copytext(input, i, i+1)]" + else + if(ui) //This is for allowing block clicks to be differentiated + pushstring = "[copytext(input, i, i+1)]" + else + pushstring = "[copytext(input, i, i+1)]" + + string += pushstring // push the string to the return string + + if(subpos >= blocksize) // add a line break for every block + string += " | " + subpos = 0 + blockpos++ + + subpos++ + + return string + + +/proc/getblock(input,blocknumber,blocksize) + var/result + result = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) + return result + +/proc/getblockbuffer(input,blocknumber,blocksize) + var/result[3] + var/block = copytext(input ,(blocksize*blocknumber)-(blocksize-1),(blocksize*blocknumber)+1) + for(var/i = 1, i <= 3, i++) + result[i] = copytext(block, i, i+1) + return result + +/proc/setblock(istring, blocknumber, replacement, blocksize) + if(!blocknumber) + return istring + if(!istring || !replacement || !blocksize) return 0 + var/result = getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) + return result + +/proc/add_zero2(t, u) + var/temp1 + while (length(t) < u) + t = "0[t]" + temp1 = t + if (length(t) > u) + temp1 = copytext(t,2,u+1) + return temp1 + +/proc/miniscramble(input,rs,rd) + var/output + output = null + if (input == "C" || input == "D" || input == "E" || input == "F") + output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"6",prob((rs*10));"7",prob((rs*5)+(rd));"0",prob((rs*5)+(rd));"1",prob((rs*10)-(rd));"2",prob((rs*10)-(rd));"3") + if (input == "8" || input == "9" || input == "A" || input == "B") + output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") + if (input == "4" || input == "5" || input == "6" || input == "7") + output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3") + if (input == "0" || input == "1" || input == "2" || input == "3") + output = pick(prob((rs*10));"8",prob((rs*10));"9",prob((rs*10));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C",prob((rs*10)-(rd));"D",prob((rs*5)+(rd));"E",prob((rs*5)+(rd));"F") + if (!output) output = "5" + return output + +//Instead of picking a value far from the input, this will pick values closer to it. +//Sorry for the block of code, but it's more efficient then calling text2hex -> loop -> hex2text +/proc/miniscrambletarget(input,rs,rd) + var/output = null + switch(input) + if("0") + output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10));"2",prob((rs*10)-(rd));"3") + if("1") + output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10));"3",prob((rs*10)-(rd));"4") + if("2") + output = pick(prob((rs*10));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10));"4",prob((rs*10)-(rd));"5") + if("3") + output = pick(prob((rs*10)-(rd));"0",prob((rs*10));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10));"5",prob((rs*10)-(rd));"6") + if("4") + output = pick(prob((rs*10)-(rd));"1",prob((rs*10));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10));"6",prob((rs*10)-(rd));"7") + if("5") + output = pick(prob((rs*10)-(rd));"2",prob((rs*10));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10));"7",prob((rs*10)-(rd));"8") + if("6") + output = pick(prob((rs*10)-(rd));"3",prob((rs*10));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10));"8",prob((rs*10)-(rd));"9") + if("7") + output = pick(prob((rs*10)-(rd));"4",prob((rs*10));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10));"9",prob((rs*10)-(rd));"A") + if("8") + output = pick(prob((rs*10)-(rd));"5",prob((rs*10));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10));"A",prob((rs*10)-(rd));"B") + if("9") + output = pick(prob((rs*10)-(rd));"6",prob((rs*10));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C") + if("10")//A + output = pick(prob((rs*10)-(rd));"7",prob((rs*10));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10));"C",prob((rs*10)-(rd));"D") + if("11")//B + output = pick(prob((rs*10)-(rd));"8",prob((rs*10));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10));"D",prob((rs*10)-(rd));"E") + if("12")//C + output = pick(prob((rs*10)-(rd));"9",prob((rs*10));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10));"E",prob((rs*10)-(rd));"F") + if("13")//D + output = pick(prob((rs*10)-(rd));"A",prob((rs*10));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10));"F") + if("14")//E + output = pick(prob((rs*10)-(rd));"B",prob((rs*10));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") + if("15")//F + output = pick(prob((rs*10)-(rd));"C",prob((rs*10));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F") + + if(!input || !output) //How did this happen? + output = "8" + + return output + +/proc/isblockon(hnumber, bnumber , var/UI = 0) + + var/temp2 + temp2 = hex2num(hnumber) + + if(UI) + if(temp2 >= 2050) + return 1 + else + return 0 + + if (bnumber == HULKBLOCK || bnumber == TELEBLOCK || bnumber == NOBREATHBLOCK || bnumber == NOPRINTSBLOCK || bnumber == SMALLSIZEBLOCK || bnumber == SHOCKIMMUNITYBLOCK) + if (temp2 >= 3500 + BLOCKADD) + return 1 + else + return 0 + if (bnumber == XRAYBLOCK || bnumber == FIREBLOCK || bnumber == REMOTEVIEWBLOCK || bnumber == REGENERATEBLOCK || bnumber == INCREASERUNBLOCK || bnumber == REMOTETALKBLOCK || bnumber == MORPHBLOCK) + if (temp2 >= 3050 + BLOCKADD) + return 1 + else + return 0 + + + if (temp2 >= 2050 + BLOCKADD) + return 1 + else + return 0 + +/proc/ismuton(var/block,var/mob/M) + return isblockon(getblock(M.dna.struc_enzymes, block,3),block) + +/proc/randmutb(mob/M as mob) + if(!M) return + var/num + var/newdna + num = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK) + M.dna.check_integrity() + newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) + M.dna.struc_enzymes = newdna + return + +/proc/randmutg(mob/M as mob) + if(!M) return + var/num + var/newdna + num = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK) + M.dna.check_integrity() + newdna = setblock(M.dna.struc_enzymes,num,toggledblock(getblock(M.dna.struc_enzymes,num,3)),3) + M.dna.struc_enzymes = newdna + return + +/proc/scramble(var/type, mob/M as mob, var/p) + if(!M) return + M.dna.check_integrity() + if(type) + for(var/i = 1, i <= STRUCDNASIZE-1, i++) + if(prob(p)) + M.dna.uni_identity = setblock(M.dna.uni_identity, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) + updateappearance(M, M.dna.uni_identity) + + else + for(var/i = 1, i <= STRUCDNASIZE-1, i++) + if(prob(p)) + M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, add_zero2(num2hex(rand(1,4095), 1), 3), 3) + domutcheck(M, null) + return + +/proc/randmuti(mob/M as mob) + if(!M) return + var/num + var/newdna + num = rand(1,UNIDNASIZE) + M.dna.check_integrity() + newdna = setblock(M.dna.uni_identity,num,add_zero2(num2hex(rand(1,4095),1),3),3) + M.dna.uni_identity = newdna + return + +/proc/toggledblock(hnumber) //unused + var/temp3 + var/chtemp + temp3 = hex2num(hnumber) + if (temp3 < 2050) + chtemp = rand(2050,4095) + return add_zero2(num2hex(chtemp,1),3) + else + chtemp = rand(1,2049) + return add_zero2(num2hex(chtemp,1),3) +/////////////////////////// DNA HELPER-PROCS + +/////////////////////////// DNA MISC-PROCS +/proc/updateappearance(mob/M as mob , structure) + if(istype(M, /mob/living/carbon/human)) + M.dna.check_integrity() + var/mob/living/carbon/human/H = M + H.r_hair = hex2num(getblock(structure,1,3)) + H.b_hair = hex2num(getblock(structure,2,3)) + H.g_hair = hex2num(getblock(structure,3,3)) + H.r_facial = hex2num(getblock(structure,4,3)) + H.b_facial = hex2num(getblock(structure,5,3)) + H.g_facial = hex2num(getblock(structure,6,3)) + H.s_tone = round(((hex2num(getblock(structure,7,3)) / 16) - 220)) + H.r_eyes = hex2num(getblock(structure,8,3)) + H.g_eyes = hex2num(getblock(structure,9,3)) + H.b_eyes = hex2num(getblock(structure,10,3)) + + if (isblockon(getblock(structure, 11,3),11 , 1)) + H.gender = FEMALE + else + H.gender = MALE + + //Hair + var/hairnum = hex2num(getblock(structure,13,3)) + var/index = round(1 +(hairnum / 4096)*hair_styles_list.len) + if((0 < index) && (index <= hair_styles_list.len)) + H.h_style = hair_styles_list[index] + + //Facial Hair + var/beardnum = hex2num(getblock(structure,12,3)) + index = round(1 +(beardnum / 4096)*facial_hair_styles_list.len) + if((0 < index) && (index <= facial_hair_styles_list.len)) + H.f_style = facial_hair_styles_list[index] + + H.update_body(0) + H.update_hair() + + return 1 + else + return 0 + +/proc/probinj(var/pr, var/inj) + return prob(pr+inj*pr) + +/proc/domutcheck(mob/living/M as mob, connected, inj) + if (!M) return + + M.dna.check_integrity() + + M.disabilities = 0 + M.sdisabilities = 0 + var/old_mutations = M.mutations + M.mutations = list() + +// M.see_in_dark = 2 +// M.see_invisible = 0 + + if(PLANT in old_mutations) + M.mutations.Add(PLANT) + if(SKELETON in old_mutations) + M.mutations.Add(SKELETON) + if(FAT in old_mutations) + M.mutations.Add(FAT) + if(HUSK in old_mutations) + M.mutations.Add(HUSK) + + if(ismuton(NOBREATHBLOCK,M)) + if(probinj(45,inj) || (mNobreath in old_mutations)) + M << "\blue You feel no need to breathe." + M.mutations.Add(mNobreath) + if(ismuton(REMOTEVIEWBLOCK,M)) + if(probinj(45,inj) || (mRemote in old_mutations)) + M << "\blue Your mind expands" + M.mutations.Add(mRemote) + if(ismuton(REGENERATEBLOCK,M)) + if(probinj(45,inj) || (mRegen in old_mutations)) + M << "\blue You feel strange" + M.mutations.Add(mRegen) + if(ismuton(INCREASERUNBLOCK,M)) + if(probinj(45,inj) || (mRun in old_mutations)) + M << "\blue You feel quick" + M.mutations.Add(mRun) + if(ismuton(REMOTETALKBLOCK,M)) + if(probinj(45,inj) || (mRemotetalk in old_mutations)) + M << "\blue You expand your mind outwards" + M.mutations.Add(mRemotetalk) + if(ismuton(MORPHBLOCK,M)) + if(probinj(45,inj) || (mMorph in old_mutations)) + M.mutations.Add(mMorph) + M << "\blue Your skin feels strange" + if(ismuton(BLENDBLOCK,M)) + if(probinj(45,inj) || (mBlend in old_mutations)) + M.mutations.Add(mBlend) + M << "\blue You feel alone" + if(ismuton(HALLUCINATIONBLOCK,M)) + if(probinj(45,inj) || (mHallucination in old_mutations)) + M.mutations.Add(mHallucination) + M << "\blue Your mind says 'Hello'" + if(ismuton(NOPRINTSBLOCK,M)) + if(probinj(45,inj) || (mFingerprints in old_mutations)) + M.mutations.Add(mFingerprints) + M << "\blue Your fingers feel numb" + if(ismuton(SHOCKIMMUNITYBLOCK,M)) + if(probinj(45,inj) || (mShock in old_mutations)) + M.mutations.Add(mShock) + M << "\blue You feel strange" + if(ismuton(SMALLSIZEBLOCK,M)) + if(probinj(45,inj) || (mSmallsize in old_mutations)) + M << "\blue Your skin feels rubbery" + M.mutations.Add(mSmallsize) + + + + if (isblockon(getblock(M.dna.struc_enzymes, HULKBLOCK,3),HULKBLOCK)) + if(probinj(5,inj) || (HULK in old_mutations)) + M << "\blue Your muscles hurt." + M.mutations.Add(HULK) + if (isblockon(getblock(M.dna.struc_enzymes, HEADACHEBLOCK,3),HEADACHEBLOCK)) + M.disabilities |= EPILEPSY + M << "\red You get a headache." + if (isblockon(getblock(M.dna.struc_enzymes, FAKEBLOCK,3),FAKEBLOCK)) + M << "\red You feel strange." + if (prob(95)) + if(prob(50)) + randmutb(M) + else + randmuti(M) + else + randmutg(M) + if (isblockon(getblock(M.dna.struc_enzymes, COUGHBLOCK,3),COUGHBLOCK)) + M.disabilities |= COUGHING + M << "\red You start coughing." + if (isblockon(getblock(M.dna.struc_enzymes, CLUMSYBLOCK,3),CLUMSYBLOCK)) + M << "\red You feel lightheaded." + M.mutations.Add(CLUMSY) + if (isblockon(getblock(M.dna.struc_enzymes, TWITCHBLOCK,3),TWITCHBLOCK)) + M.disabilities |= TOURETTES + M << "\red You twitch." + if (isblockon(getblock(M.dna.struc_enzymes, XRAYBLOCK,3),XRAYBLOCK)) + if(probinj(30,inj) || (XRAY in old_mutations)) + M << "\blue The walls suddenly disappear." +// M.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) +// M.see_in_dark = 8 +// M.see_invisible = 2 + M.mutations.Add(XRAY) + if (isblockon(getblock(M.dna.struc_enzymes, NERVOUSBLOCK,3),NERVOUSBLOCK)) + M.disabilities |= NERVOUS + M << "\red You feel nervous." + if (isblockon(getblock(M.dna.struc_enzymes, FIREBLOCK,3),FIREBLOCK)) + if(probinj(30,inj) || (COLD_RESISTANCE in old_mutations)) + M << "\blue Your body feels warm." + M.mutations.Add(COLD_RESISTANCE) + if (isblockon(getblock(M.dna.struc_enzymes, BLINDBLOCK,3),BLINDBLOCK)) + M.sdisabilities |= BLIND + M << "\red You can't seem to see anything." + if (isblockon(getblock(M.dna.struc_enzymes, TELEBLOCK,3),TELEBLOCK)) + if(probinj(15,inj) || (TK in old_mutations)) + M << "\blue You feel smarter." + M.mutations.Add(TK) + if (isblockon(getblock(M.dna.struc_enzymes, DEAFBLOCK,3),DEAFBLOCK)) + M.sdisabilities |= DEAF + M.ear_deaf = 1 + M << "\red Its kinda quiet.." + if (isblockon(getblock(M.dna.struc_enzymes, GLASSESBLOCK,3),GLASSESBLOCK)) + M.disabilities |= NEARSIGHTED + M << "Your eyes feel weird..." + + /* If you want the new mutations to work, UNCOMMENT THIS. + if(istype(M, /mob/living/carbon)) + for (var/datum/mutations/mut in global_mutations) + mut.check_mutation(M) + */ + +//////////////////////////////////////////////////////////// Monkey Block + if (isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && istype(M, /mob/living/carbon/human)) + // human > monkey + var/mob/living/carbon/human/H = M + H.monkeyizing = 1 + var/list/implants = list() //Try to preserve implants. + for(var/obj/item/weapon/implant/W in H) + implants += W + W.loc = null + + if(!connected) + for(var/obj/item/W in (H.contents-implants)) + if (W==H.w_uniform) // will be teared + continue + H.drop_from_inventory(W) + M.monkeyizing = 1 + M.canmove = 0 + M.icon = null + M.invisibility = 101 + var/atom/movable/overlay/animation = new( M.loc ) + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = src + flick("h2monkey", animation) + sleep(48) + del(animation) + + + var/mob/living/carbon/monkey/O = null + if(H.species.primitive) + O = new H.species.primitive(src) + else + H.gib() //Trying to change the species of a creature with no primitive var set is messy. + return + + if(M) + if (M.dna) + O.dna = M.dna + M.dna = null + + if (M.suiciding) + O.suiciding = M.suiciding + M.suiciding = null + + + for(var/datum/disease/D in M.viruses) + O.viruses += D + D.affected_mob = O + M.viruses -= D + + + for(var/obj/T in (M.contents-implants)) + del(T) + + O.loc = M.loc + + if(M.mind) + M.mind.transfer_to(O) //transfer our mind to the cute little monkey + + if (connected) //inside dna thing + var/obj/machinery/dna_scannernew/C = connected + O.loc = C + C.occupant = O + connected = null + O.real_name = text("monkey ([])",copytext(md5(M.real_name), 2, 6)) + O.take_overall_damage(M.getBruteLoss() + 40, M.getFireLoss()) + O.adjustToxLoss(M.getToxLoss() + 20) + O.adjustOxyLoss(M.getOxyLoss()) + O.stat = M.stat + O.a_intent = I_HURT + for (var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O +// O.update_icon = 1 //queue a full icon update at next life() call + del(M) + return + + if (!isblockon(getblock(M.dna.struc_enzymes, MONKEYBLOCK,3),MONKEYBLOCK) && !istype(M, /mob/living/carbon/human)) + // monkey > human, + var/mob/living/carbon/monkey/Mo = M + Mo.monkeyizing = 1 + var/list/implants = list() //Still preserving implants + for(var/obj/item/weapon/implant/W in Mo) + implants += W + W.loc = null + if(!connected) + for(var/obj/item/W in (Mo.contents-implants)) + Mo.drop_from_inventory(W) + M.monkeyizing = 1 + M.canmove = 0 + M.icon = null + M.invisibility = 101 + var/atom/movable/overlay/animation = new( M.loc ) + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = src + flick("monkey2h", animation) + sleep(48) + del(animation) + + var/mob/living/carbon/human/O = new( src ) + if(Mo.greaterform) + O.set_species(Mo.greaterform) + + if (isblockon(getblock(M.dna.uni_identity, 11,3),11)) + O.gender = FEMALE + else + O.gender = MALE + + if (M) + if (M.dna) + O.dna = M.dna + M.dna = null + + if (M.suiciding) + O.suiciding = M.suiciding + M.suiciding = null + + for(var/datum/disease/D in M.viruses) + O.viruses += D + D.affected_mob = O + M.viruses -= D + + //for(var/obj/T in M) + // del(T) + + O.loc = M.loc + + if(M.mind) + M.mind.transfer_to(O) //transfer our mind to the human + + if (connected) //inside dna thing + var/obj/machinery/dna_scannernew/C = connected + O.loc = C + C.occupant = O + connected = null + + var/i + while (!i) + var/randomname + if (O.gender == MALE) + randomname = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names))) + else + randomname = capitalize(pick(first_names_female) + " " + capitalize(pick(last_names))) + if (findname(randomname)) + continue + else + O.real_name = randomname + i++ + updateappearance(O,O.dna.uni_identity) + O.take_overall_damage(M.getBruteLoss(), M.getFireLoss()) + O.adjustToxLoss(M.getToxLoss()) + O.adjustOxyLoss(M.getOxyLoss()) + O.stat = M.stat + for (var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O +// O.update_icon = 1 //queue a full icon update at next life() call + del(M) + return +//////////////////////////////////////////////////////////// Monkey Block + if(M) + M.update_icon = 1 //queue a full icon update at next life() call + return null /////////////////////////// DNA MISC-PROCS \ No newline at end of file diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 53086de252..86bfbeb0fe 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -102,7 +102,7 @@ if (usr.stat != 0) return - if (!ishuman(usr) && !ismonkey(usr)) //Make sure they're a mob that has dna + if (!ishuman(usr) && !issmall(usr)) //Make sure they're a mob that has dna usr << "\blue Try as you might, you can not climb up into the scanner." return if (src.occupant) @@ -737,7 +737,7 @@ if (bufferOption == "changeLabel") var/datum/dna2/record/buf = src.buffers[bufferId] - var/text = sanitize(copytext(input(usr, "New Label:", "Edit Label", buf.name) as text|null, 1, MAX_NAME_LEN)) + var/text = sanitize(input(usr, "New Label:", "Edit Label", buf.name) as text|null, MAX_NAME_LEN) buf.name = text src.buffers[bufferId] = buf return 1 diff --git a/code/game/dna/genes/monkey.dm b/code/game/dna/genes/monkey.dm index 69aba349f7..2e0f6cdec2 100644 --- a/code/game/dna/genes/monkey.dm +++ b/code/game/dna/genes/monkey.dm @@ -1,175 +1,175 @@ -/datum/dna/gene/monkey - name="Monkey" - -/datum/dna/gene/monkey/New() - block=MONKEYBLOCK - -/datum/dna/gene/monkey/can_activate(var/mob/M,var/flags) - return istype(M, /mob/living/carbon/human) || istype(M,/mob/living/carbon/monkey) - -/datum/dna/gene/monkey/activate(var/mob/living/M, var/connected, var/flags) - if(!istype(M,/mob/living/carbon/human)) - //testing("Cannot monkey-ify [M], type is [M.type].") - return - var/mob/living/carbon/human/H = M - H.monkeyizing = 1 - var/list/implants = list() //Try to preserve implants. - for(var/obj/item/weapon/implant/W in H) - implants += W - W.loc = null - - if(!connected) - for(var/obj/item/W in (H.contents-implants)) - if (W==H.w_uniform) // will be teared - continue - H.drop_from_inventory(W) - M.monkeyizing = 1 - M.canmove = 0 - M.icon = null - M.invisibility = 101 - var/atom/movable/overlay/animation = new( M.loc ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = src - flick("h2monkey", animation) - sleep(48) - del(animation) - - - var/mob/living/carbon/monkey/O = null - if(H.species.primitive) - O = new H.species.primitive(src) - else - H.gib() //Trying to change the species of a creature with no primitive var set is messy. - return - - if(M) - if (M.dna) - O.dna = M.dna.Clone() - M.dna = null - - if (M.suiciding) - O.suiciding = M.suiciding - M.suiciding = null - - - for(var/datum/disease/D in M.viruses) - O.viruses += D - D.affected_mob = O - M.viruses -= D - - - for(var/obj/T in (M.contents-implants)) - del(T) - - O.loc = M.loc - - if(M.mind) - M.mind.transfer_to(O) //transfer our mind to the cute little monkey - - if (connected) //inside dna thing - var/obj/machinery/dna_scannernew/C = connected - O.loc = C - C.occupant = O - connected = null - O.real_name = text("monkey ([])",copytext(md5(M.real_name), 2, 6)) - O.take_overall_damage(M.getBruteLoss() + 40, M.getFireLoss()) - O.adjustToxLoss(M.getToxLoss() + 20) - O.adjustOxyLoss(M.getOxyLoss()) - O.stat = M.stat - O.a_intent = "hurt" - for (var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O -// O.update_icon = 1 //queue a full icon update at next life() call - del(M) - return - -/datum/dna/gene/monkey/deactivate(var/mob/living/M, var/connected, var/flags) - if(!istype(M,/mob/living/carbon/monkey)) - //testing("Cannot humanize [M], type is [M.type].") - return - var/mob/living/carbon/monkey/Mo = M - Mo.monkeyizing = 1 - var/list/implants = list() //Still preserving implants - for(var/obj/item/weapon/implant/W in Mo) - implants += W - W.loc = null - if(!connected) - for(var/obj/item/W in (Mo.contents-implants)) - Mo.drop_from_inventory(W) - M.monkeyizing = 1 - M.canmove = 0 - M.icon = null - M.invisibility = 101 - var/atom/movable/overlay/animation = new( M.loc ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = src - flick("monkey2h", animation) - sleep(48) - del(animation) - - var/mob/living/carbon/human/O - if(Mo.greaterform) - O = new(src, Mo.greaterform) - else - O = new(src) - - if (M.dna.GetUIState(DNA_UI_GENDER)) - O.gender = FEMALE - else - O.gender = MALE - - if (M) - if (M.dna) - O.dna = M.dna.Clone() - M.dna = null - - if (M.suiciding) - O.suiciding = M.suiciding - M.suiciding = null - - for(var/datum/disease/D in M.viruses) - O.viruses += D - D.affected_mob = O - M.viruses -= D - - //for(var/obj/T in M) - // del(T) - - O.loc = M.loc - - if(M.mind) - M.mind.transfer_to(O) //transfer our mind to the human - - if (connected) //inside dna thing - var/obj/machinery/dna_scannernew/C = connected - O.loc = C - C.occupant = O - connected = null - - var/i - while (!i) - var/randomname - if (O.gender == MALE) - randomname = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names))) - else - randomname = capitalize(pick(first_names_female) + " " + capitalize(pick(last_names))) - if (findname(randomname)) - continue - else - O.real_name = randomname - O.dna.real_name = randomname - i++ - O.UpdateAppearance() - O.take_overall_damage(M.getBruteLoss(), M.getFireLoss()) - O.adjustToxLoss(M.getToxLoss()) - O.adjustOxyLoss(M.getOxyLoss()) - O.stat = M.stat - for (var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O -// O.update_icon = 1 //queue a full icon update at next life() call - del(M) - return \ No newline at end of file +/datum/dna/gene/monkey + name="Monkey" + +/datum/dna/gene/monkey/New() + block=MONKEYBLOCK + +/datum/dna/gene/monkey/can_activate(var/mob/M,var/flags) + return istype(M, /mob/living/carbon/human) || istype(M,/mob/living/carbon/monkey) + +/datum/dna/gene/monkey/activate(var/mob/living/M, var/connected, var/flags) + if(!istype(M,/mob/living/carbon/human)) + //testing("Cannot monkey-ify [M], type is [M.type].") + return + var/mob/living/carbon/human/H = M + H.monkeyizing = 1 + var/list/implants = list() //Try to preserve implants. + for(var/obj/item/weapon/implant/W in H) + implants += W + W.loc = null + + if(!connected) + for(var/obj/item/W in (H.contents-implants)) + if (W==H.w_uniform) // will be teared + continue + H.drop_from_inventory(W) + M.monkeyizing = 1 + M.canmove = 0 + M.icon = null + M.invisibility = 101 + var/atom/movable/overlay/animation = new( M.loc ) + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = src + flick("h2monkey", animation) + sleep(48) + del(animation) + + + var/mob/living/carbon/monkey/O = null + if(H.species.primitive) + O = new H.species.primitive(src) + else + H.gib() //Trying to change the species of a creature with no primitive var set is messy. + return + + if(M) + if (M.dna) + O.dna = M.dna.Clone() + M.dna = null + + if (M.suiciding) + O.suiciding = M.suiciding + M.suiciding = null + + + for(var/datum/disease/D in M.viruses) + O.viruses += D + D.affected_mob = O + M.viruses -= D + + + for(var/obj/T in (M.contents-implants)) + del(T) + + O.loc = M.loc + + if(M.mind) + M.mind.transfer_to(O) //transfer our mind to the cute little monkey + + if (connected) //inside dna thing + var/obj/machinery/dna_scannernew/C = connected + O.loc = C + C.occupant = O + connected = null + O.real_name = text("monkey ([])",copytext(md5(M.real_name), 2, 6)) + O.take_overall_damage(M.getBruteLoss() + 40, M.getFireLoss()) + O.adjustToxLoss(M.getToxLoss() + 20) + O.adjustOxyLoss(M.getOxyLoss()) + O.stat = M.stat + O.a_intent = I_HURT + for (var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O +// O.update_icon = 1 //queue a full icon update at next life() call + del(M) + return + +/datum/dna/gene/monkey/deactivate(var/mob/living/M, var/connected, var/flags) + if(!istype(M,/mob/living/carbon/monkey)) + //testing("Cannot humanize [M], type is [M.type].") + return + var/mob/living/carbon/monkey/Mo = M + Mo.monkeyizing = 1 + var/list/implants = list() //Still preserving implants + for(var/obj/item/weapon/implant/W in Mo) + implants += W + W.loc = null + if(!connected) + for(var/obj/item/W in (Mo.contents-implants)) + Mo.drop_from_inventory(W) + M.monkeyizing = 1 + M.canmove = 0 + M.icon = null + M.invisibility = 101 + var/atom/movable/overlay/animation = new( M.loc ) + animation.icon_state = "blank" + animation.icon = 'icons/mob/mob.dmi' + animation.master = src + flick("monkey2h", animation) + sleep(48) + del(animation) + + var/mob/living/carbon/human/O + if(Mo.greaterform) + O = new(src, Mo.greaterform) + else + O = new(src) + + if (M.dna.GetUIState(DNA_UI_GENDER)) + O.gender = FEMALE + else + O.gender = MALE + + if (M) + if (M.dna) + O.dna = M.dna.Clone() + M.dna = null + + if (M.suiciding) + O.suiciding = M.suiciding + M.suiciding = null + + for(var/datum/disease/D in M.viruses) + O.viruses += D + D.affected_mob = O + M.viruses -= D + + //for(var/obj/T in M) + // del(T) + + O.loc = M.loc + + if(M.mind) + M.mind.transfer_to(O) //transfer our mind to the human + + if (connected) //inside dna thing + var/obj/machinery/dna_scannernew/C = connected + O.loc = C + C.occupant = O + connected = null + + var/i + while (!i) + var/randomname + if (O.gender == MALE) + randomname = capitalize(pick(first_names_male) + " " + capitalize(pick(last_names))) + else + randomname = capitalize(pick(first_names_female) + " " + capitalize(pick(last_names))) + if (findname(randomname)) + continue + else + O.real_name = randomname + O.dna.real_name = randomname + i++ + O.UpdateAppearance() + O.take_overall_damage(M.getBruteLoss(), M.getFireLoss()) + O.adjustToxLoss(M.getToxLoss()) + O.adjustOxyLoss(M.getOxyLoss()) + O.stat = M.stat + for (var/obj/item/weapon/implant/I in implants) + I.loc = O + I.implanted = O +// O.update_icon = 1 //queue a full icon update at next life() call + del(M) + return diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm deleted file mode 100644 index e2c41fcbb4..0000000000 --- a/code/game/gamemodes/autotraitor/autotraitor.dm +++ /dev/null @@ -1,199 +0,0 @@ -//This is a beta game mode to test ways to implement an "infinite" traitor round in which more traitors are automatically added in as needed. -//Automatic traitor adding is complete pending the inevitable bug fixes. Need to add a respawn system to let dead people respawn after 30 minutes or so. - - -/datum/game_mode/traitor/autotraitor - name = "AutoTraitor" - config_tag = "extend-a-traitormongous" - - var/list/possible_traitors - var/num_players = 0 - -/datum/game_mode/traitor/autotraitor/announce() - ..() - world << "Game mode is AutoTraitor. Traitors will be added to the round automagically as needed." - -/datum/game_mode/traitor/autotraitor/pre_setup() - - if(config.protect_roles_from_antagonist) - restricted_jobs += protected_jobs - - possible_traitors = get_players_for_role(BE_TRAITOR) - - for(var/datum/mind/player in possible_traitors) - for(var/job in restricted_jobs) - if(player.assigned_role == job) - possible_traitors -= player - - - for(var/mob/new_player/P in world) - if(P.client && P.ready) - num_players++ - - //var/r = rand(5) - var/num_traitors = 1 - var/max_traitors = 1 - var/traitor_prob = 0 - max_traitors = round(num_players / 10) + 1 - traitor_prob = (num_players - (max_traitors - 1) * 10) * 10 - - // Stop setup if no possible traitors - if(!possible_traitors.len) - return 0 - - if(config.traitor_scaling) - num_traitors = max_traitors - 1 + prob(traitor_prob) - log_game("Number of traitors: [num_traitors]") - message_admins("Players counted: [num_players] Number of traitors chosen: [num_traitors]") - else - num_traitors = max(1, min(num_players(), traitors_possible)) - - - for(var/i = 0, i < num_traitors, i++) - var/datum/mind/traitor = pick(possible_traitors) - traitors += traitor - possible_traitors.Remove(traitor) - - for(var/datum/mind/traitor in traitors) - if(!traitor || !istype(traitor)) - traitors.Remove(traitor) - continue - if(istype(traitor)) - traitor.special_role = "traitor" - -// if(!traitors.len) -// return 0 - return 1 - - - - -/datum/game_mode/traitor/autotraitor/post_setup() - ..() - traitorcheckloop() - -/datum/game_mode/traitor/autotraitor/proc/traitorcheckloop() - spawn(9000) - if(emergency_shuttle.departed) - return - //message_admins("Performing AutoTraitor Check") - var/playercount = 0 - var/traitorcount = 0 - var/possible_traitors[0] - for(var/mob/living/player in mob_list) - - if (player.client && player.stat != 2) - playercount += 1 - if (player.client && player.mind && player.mind.special_role && player.stat != 2) - traitorcount += 1 - if (player.client && player.mind && !player.mind.special_role && player.stat != 2 && (player.client && player.client.prefs.be_special & BE_TRAITOR) && !jobban_isbanned(player, "Syndicate")) - possible_traitors += player - for(var/datum/mind/player in possible_traitors) - for(var/job in restricted_jobs) - if(player.assigned_role == job) - possible_traitors -= player - - //message_admins("Live Players: [playercount]") - //message_admins("Live Traitors: [traitorcount]") -// message_admins("Potential Traitors:") -// for(var/mob/living/traitorlist in possible_traitors) -// message_admins("[traitorlist.real_name]") - -// var/r = rand(5) -// var/target_traitors = 1 - var/max_traitors = 1 - var/traitor_prob = 0 - max_traitors = round(playercount / 10) + 1 - traitor_prob = (playercount - (max_traitors - 1) * 10) * 5 - if(traitorcount < max_traitors - 1) - traitor_prob += 50 - - - if(traitorcount < max_traitors) - //message_admins("Number of Traitors is below maximum. Rolling for new Traitor.") - //message_admins("The probability of a new traitor is [traitor_prob]%") - - if(prob(traitor_prob)) - message_admins("Making a new Traitor.") - if(!possible_traitors.len) - message_admins("No potential traitors. Cancelling new traitor.") - traitorcheckloop() - return - var/mob/living/newtraitor = pick(possible_traitors) - //message_admins("[newtraitor.real_name] is the new Traitor.") - - if (!config.objectives_disabled) - forge_traitor_objectives(newtraitor.mind) - - if(istype(newtraitor, /mob/living/silicon)) - add_law_zero(newtraitor) - else - equip_traitor(newtraitor) - - traitors += newtraitor.mind - newtraitor << "\red No time like the present. \black It's time to take matters into your own hands..." - newtraitor << "You are now a traitor." - newtraitor.mind.special_role = "traitor" - newtraitor.hud_updateflag |= 1 << SPECIALROLE_HUD - newtraitor << "You have been selected this round as an antagonist!" - show_objectives(newtraitor.mind) - - //else - //message_admins("No new traitor being added.") - //else - //message_admins("Number of Traitors is at maximum. Not making a new Traitor.") - - traitorcheckloop() - - - -/datum/game_mode/traitor/autotraitor/latespawn(mob/living/carbon/human/character) - ..() - if(emergency_shuttle.departed) - return - //message_admins("Late Join Check") - if((character.client && character.client.prefs.be_special & BE_TRAITOR) && !jobban_isbanned(character, "Syndicate")) - //message_admins("Late Joiner has Be Syndicate") - //message_admins("Checking number of players") - var/playercount = 0 - var/traitorcount = 0 - for(var/mob/living/player in mob_list) - - if (player.client && player.stat != 2) - playercount += 1 - if (player.client && player.mind && player.mind.special_role && player.stat != 2) - traitorcount += 1 - //message_admins("Live Players: [playercount]") - //message_admins("Live Traitors: [traitorcount]") - - //var/r = rand(5) - //var/target_traitors = 1 - var/max_traitors = 2 - var/traitor_prob = 0 - max_traitors = round(playercount / 10) + 1 - traitor_prob = (playercount - (max_traitors - 1) * 10) * 5 - if(traitorcount < max_traitors - 1) - traitor_prob += 50 - - //target_traitors = max(1, min(round((playercount + r) / 10, 1), traitors_possible)) - //message_admins("Target Traitor Count is: [target_traitors]") - if (traitorcount < max_traitors) - //message_admins("Number of Traitors is below maximum. Rolling for New Arrival Traitor.") - //message_admins("The probability of a new traitor is [traitor_prob]%") - if(prob(traitor_prob)) - message_admins("New traitor roll passed. Making a new Traitor.") - if (!config.objectives_disabled) - forge_traitor_objectives(character.mind) - equip_traitor(character) - traitors += character.mind - character << "\red You are the traitor." - character.mind.special_role = "traitor" - character << "You have been selected this round as an antagonist!" - show_objectives(character.mind) - - //else - //message_admins("New traitor roll failed. No new traitor.") - //else - //message_admins("Late Joiner does not have Be Syndicate") - - diff --git a/code/game/gamemodes/calamity/calamity.dm b/code/game/gamemodes/calamity/calamity.dm index 53cd72d447..d8872bbbff 100644 --- a/code/game/gamemodes/calamity/calamity.dm +++ b/code/game/gamemodes/calamity/calamity.dm @@ -1,464 +1,28 @@ -/* - * This roundtype is a replacement for the meteor round on upstream BS12 - players - * expressed the desire for quick, chaotic and violent rounds, preferrably without - * dependancy on other players. - * I wanted to call it clusterfuck, but I figure that's a bit too overt. Think of - * the children. - * ~ Zuhayr - */ +#define ANTAG_TYPE_RATIO 8 /datum/game_mode/calamity - name = "calamity" + name = "Calamity" + round_description = "This must be a Thursday. You never could get the hang of Thursdays..." + extended_round_description = "All Hell is about to break loose. Literally every antagonist type may spawn in this round. Hold on tight." config_tag = "calamity" required_players = 1 - votable = 0 //Remove after testing. - - //Possible roundstart antag types. - var/list/atypes = list("syndi","ling","tater","wiz","ninja","vox","cult") //Readd slug when borer spawn is fixed. - var/list/chosen_atypes = list() - var/list/chosen_candidates = list() - var/list/already_assigned_candidates = list() - - //At one antagonist group per 10 players we are just going to go with tiny groups. - var/max_antags = 5 // Antag groups spawn with this many members. - var/antag_type_ratio = 8 // 1 antag type per this many players. - - var/const/waittime_l = 600 - var/const/waittime_h = 1800 - -/datum/game_mode/calamity/announce() - world << "The current game mode is - Calamity!" - world << "This must be a Thursday. You never could get the hang of Thursdays..." - -/datum/game_mode/calamity/can_start() - - if(!..()) - return 0 - - var/antag_count = player_list.len/antag_type_ratio - - if(!antag_count) - return 1 - - for(var/i=0;i" - - for(var/datum/mind/P in L) - text += "
    [P.key] was [P.name] (" - if(P.current) - if(P.current.stat == DEAD) - text += "died" - else - text += "survived" - if(P.current.real_name != P.name) - text += " as [P.current.real_name]" - else - text += "body destroyed" - text += ")" - - if(M.objectives.len) - text += "
    Their objectives were:" - var/num = 1 - for(var/datum/objective/O in M.objectives) - text += "
    Objective [num]: [O.explanation_text]" - num++ - - //Single antag objective completion. - for(var/list/L in list(src.changelings, src.ninjas, src.borers, src.traitors)) - - if(L.len) - var/datum/mind/M = L[1] - text = "
    The [M.special_role][L.len == 1 ? " was" : "s were"]:" - for(var/datum/mind/P in L) - var/num = 1 - text += "
    [P.key] was [P.name]." - if(P.objectives.len) - for(var/datum/objective/O in P.objectives) - text += "
    Objective [num]: [O.explanation_text]" - num++ - ..() - return 1 - -//Converts chosen atype to an actual role string. -/datum/game_mode/calamity/proc/get_candidate_role_text(var/role) - - var/role_text - - switch(role) - if("syndi") - role_text = "Mercenary" - if("ling") - role_text = "Changeling" - if("tater") - role_text = "Traitor" - if("wiz") - role_text = "Cabalist" - if("ninja") - role_text = "Ninja" - if("vox") - role_text = "Vox Raider" - if("slug") - role_text = "Cortical Borer" - if("cult") - role_text = "Cultist" - - return role_text - -//Grabs candidate lists for various atypes. -/datum/game_mode/calamity/proc/get_role_candidates(var/role) - - var/list/possible_antags = list() - switch(role) - if("syndi") - possible_antags = get_players_for_role(BE_OPERATIVE) - if("ling") - - possible_antags = get_players_for_role(BE_CHANGELING) - - var/list/unsuitable_players = list() - - for(var/datum/mind/player in possible_antags) - if(player && (player.assigned_role == "Cyborg" || player.assigned_role == "AI")) - unsuitable_players |= player - - if(unsuitable_players.len) - possible_antags -= unsuitable_players - - if("tater") - possible_antags = get_players_for_role(BE_TRAITOR) - if("wiz") - possible_antags = get_players_for_role(BE_WIZARD) - if("ninja") - possible_antags = get_players_for_role(BE_NINJA) - if("vox") - possible_antags = get_players_for_role(BE_RAIDER) - if("slug") - possible_antags = get_players_for_role(BE_ALIEN) - if("cult") - possible_antags = get_players_for_role(BE_CULTIST) - - var/list/filtered_antags = list() - if(possible_antags) - for(var/datum/mind/candidate in possible_antags) - if(!(candidate in already_assigned_candidates)) - filtered_antags |= candidate - already_assigned_candidates |= candidate - - if(filtered_antags && islist(filtered_antags)) - return filtered_antags - else - return list(filtered_antags) - -//Spawning procs for the various antag types. -//A LOT OF THE FOLLOWING IS COPYPASTED FROM OTHER MODES AND NEEDS -//TO BE FIXED UP. NINJA, NUKE AND CULT IN PARTICULAR ARE FUCKING AWFUL. ~ Z -/datum/game_mode/calamity/proc/spawn_syndicate(var/list/candidates) - - var/obj/effect/landmark/uplinkdevice = locate("landmark*Syndicate-Uplink") - var/obj/effect/landmark/nuke_spawn = locate("landmark*Nuclear-Bomb") - - var/nuke_code = "[rand(10000, 99999)]" - var/spawnpos = 1 - - var/datum/mind/leader = null - for(var/datum/mind/player in candidates) - - syndicates |= player - - if(spawnpos > synd_spawn.len) - spawnpos = 1 - player.current.loc = synd_spawn[spawnpos] - - player.current.real_name = "[syndicate_name()] Operative" - spawn(0) - NukeNameAssign(player) - - forge_syndicate_objectives(player) - greet_syndicate(player) - equip_syndicate(player.current) - - if(!leader) - prepare_syndicate_leader(player, nuke_code) - leader = player - - spawnpos++ - update_synd_icons_added(player) - - update_all_synd_icons() - - if(uplinkdevice) - var/obj/item/device/radio/uplink/U = new(uplinkdevice.loc) - if(leader) - U.hidden_uplink.uplink_owner = leader - U.hidden_uplink.uses = 40 - if(nuke_spawn && synd_spawn.len > 0) - var/obj/machinery/nuclearbomb/the_bomb = new /obj/machinery/nuclearbomb(nuke_spawn.loc) - the_bomb.r_code = nuke_code - -/datum/game_mode/calamity/proc/spawn_changelings(var/list/candidates) - - for(var/datum/mind/player in candidates) - - changelings |= player - grant_changeling_powers(player.current) - player.special_role = "Changeling" - - if(!config.objectives_disabled) - player.objectives += new /datum/objective/escape() - player.objectives += new /datum/objective/survive() - - show_objectives(player) - greet_changeling(player) - -/datum/game_mode/calamity/proc/spawn_traitors(var/list/candidates) - - for(var/datum/mind/player in candidates) - traitors |= player - - if(!config.objectives_disabled) - player.objectives += new /datum/objective/escape() - player.objectives += new /datum/objective/survive() - - show_objectives(player) - - finalize_traitor(player) - greet_traitor(player) - -/datum/game_mode/calamity/proc/spawn_cabal(var/list/candidates) - - for(var/datum/mind/player in candidates) - wizards |= player - - if(!config.objectives_disabled) - player.objectives += new /datum/objective/escape() - player.objectives += new /datum/objective/survive() - - show_objectives(player) - - player.current.loc = pick(wizardstart) - - equip_wizard(player.current) - name_wizard(player.current) - greet_wizard(player) - -/datum/game_mode/calamity/proc/spawn_ninja(var/list/candidates) - - //I hate that this is necessary. ~Z - for(var/obj/effect/landmark/L in landmarks_list) - if(L.name == "carpspawn") - ninjastart.Add(L) - - for(var/datum/mind/player in candidates) - ninjas |= player - - player.current << browse(null, "window=playersetup") - player.current = create_space_ninja(pick(ninjastart)) - player.current.ckey = player.key - - if(player.current && !(istype(player.current,/mob/living/carbon/human))) return 0 - - //Ninja intro crawl goes here. - if(!config.objectives_disabled) - player.objectives += new /datum/objective/ninja_highlander() - player.objectives += new /datum/objective/survive() - - show_objectives(player) - -/datum/game_mode/calamity/proc/spawn_vox_raiders(var/list/candidates) - - //Create objectives. - var/list/raid_objectives = forge_vox_objectives() - - //Create raiders. - for(var/datum/mind/player in candidates) - raiders |= player - - //Place them on the shuttle. - var/index = 1 - if(index > raider_spawn.len) - index = 1 - player.current.loc = raider_spawn[index] - index++ - - if(!config.objectives_disabled) - player.objectives = raid_objectives - - //Equip them. - create_vox(player) - greet_vox(player) - - player.current << "Your crew is transporting cortical stacks and critical resources back to the Shoal.\ - No delay or concession can be tolerated. Even putting holes in the station pales in comparison to failure." - - spawn (rand(waittime_l, waittime_h)) - send_intercept() + votable = 0 + event_delay_mod_moderate = 0.5 + event_delay_mod_major = 0.75 + +/datum/game_mode/calamity/create_antagonists() + + shuffle(all_antag_types) // This is probably the only instance in the game where the order will be important. + var/i = 1 + var/grab_antags = round(num_players()/ANTAG_TYPE_RATIO)+1 + for(var/antag_id in all_antag_types) + if(i > grab_antags) + break + additional_antag_types |= antag_id + i++ ..() -/datum/game_mode/calamity/proc/spawn_borers(var/list/candidates) +/datum/game_mode/calamity/check_victory() + world << "This terrible, terrible day has finally ended!" - var/list/possible_hosts = list() - for(var/mob/living/carbon/human/H in mob_list) - if(!(H.species.flags & IS_SYNTHETIC)) - possible_hosts |= H - - spawn(10) - for(var/datum/mind/player in candidates) - - if(!possible_hosts || possible_hosts.len) - break - - borers |= player - var/mob/living/carbon/human/target_host = pick(possible_hosts) - possible_hosts -= target_host - - var/mob/living/simple_animal/borer/roundstart/B = new(target_host) - - B.transfer_personality(player) - - B.host = target_host - B.host_brain.name = target_host.name - B.host_brain.real_name = target_host.real_name - - var/datum/organ/external/head = target_host.get_organ("head") - head.implants += B - - if(!config.objectives_disabled) - player.objectives += new /datum/objective/borer_survive() - player.objectives += new /datum/objective/borer_reproduce() - player.objectives += new /datum/objective/escape() - - show_objectives(player) - -/datum/game_mode/calamity/proc/spawn_cultists(var/list/candidates) - - //Prune the list. - var/list/jobs_to_skip = list("Chaplain","AI", "Cyborg", "Lawyer", "Head of Security", "Captain") - if(config.protect_roles_from_antagonist) - jobs_to_skip += list("Security Officer", "Warden", "Detective") - - //Make cult objectives. - var/cult_objectives = list() - cult_objectives += new /datum/objective/cult_summon() - - //Actually spawn cultists. - for(var/datum/mind/player in candidates) - - for(var/job in jobs_to_skip) - if(player.assigned_role == job) - continue - - cult |= player - equip_cultist(player.current) - grant_runeword(player.current) - update_cult_icons_added(player) - player.current << "\blue You are a member of the cult! Your dark masters have sent you forth to serve their vile will." - player.current << "\red This station sails above a weeping tear in the Cosmos. Bring the Geometer of Blood forth." - - if(!config.objectives_disabled) - - for(var/datum/objective/O in cult_objectives) - player.objectives += O - - player.objectives += new /datum/objective/escape() - player.objectives += new /datum/objective/survive() - - show_objectives(player) - player.special_role = "Cultist" \ No newline at end of file +#undef ANTAG_TYPE_RATIO \ No newline at end of file diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index e1ce51997d..678d6d7183 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -1,234 +1,11 @@ -var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon","Zeta","Eta","Theta","Iota","Kappa","Lambda","Mu","Nu","Xi","Omicron","Pi","Rho","Sigma","Tau","Upsilon","Phi","Chi","Psi","Omega") - -/datum/game_mode - var/list/datum/mind/changelings = list() - - /datum/game_mode/changeling + antag_tag = MODE_CHANGELING name = "changeling" + round_description = "There are alien changelings on the station. Do not let the changelings succeed!" + extended_round_description = "Life always finds a way. However, life can sometimes take a more disturbing route. Humanity's extensive knowledge of xeno-biological specimens has made them confident and arrogant. Yet something slipped past their eyes. Something dangerous. Something alive. Most frightening of all, however, is that this something is someone. An unknown alien specimen has incorporated itself into the crew of the NSS Exodus. Its unique biology allows it to manipulate its own or anyone else's DNA. With the ability to copy faces, voices, animals, but also change the chemical make up of your own body, its existence is a threat to not only your personal safety but the lives of everyone on board. No one knows where it came from. No one knows who it is or what it wants. One thing is for certain though... there is never just one of them. Good luck." config_tag = "changeling" - restricted_jobs = list("AI", "Cyborg") - protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain") required_players = 2 required_players_secret = 10 required_enemies = 1 - recommended_enemies = 4 - - var/const/prob_int_murder_target = 50 // intercept names the assassination target half the time - var/const/prob_right_murder_target_l = 25 // lower bound on probability of naming right assassination target - var/const/prob_right_murder_target_h = 50 // upper bound on probability of naimg the right assassination target - - var/const/prob_int_item = 50 // intercept names the theft target half the time - var/const/prob_right_item_l = 25 // lower bound on probability of naming right theft target - var/const/prob_right_item_h = 50 // upper bound on probability of naming the right theft target - - var/const/prob_int_sab_target = 50 // intercept names the sabotage target half the time - var/const/prob_right_sab_target_l = 25 // lower bound on probability of naming right sabotage target - var/const/prob_right_sab_target_h = 50 // upper bound on probability of naming right sabotage target - - var/const/prob_right_killer_l = 25 //lower bound on probability of naming the right operative - var/const/prob_right_killer_h = 50 //upper bound on probability of naming the right operative - var/const/prob_right_objective_l = 25 //lower bound on probability of determining the objective correctly - var/const/prob_right_objective_h = 50 //upper bound on probability of determining the objective correctly - - var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) - var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) - - var/changeling_amount = 4 - -/datum/game_mode/changeling/announce() - world << "The current game mode is - Changeling!" - world << "There are alien changelings on the station. Do not let the changelings succeed!" - -/datum/game_mode/changeling/pre_setup() - - if(config.protect_roles_from_antagonist) - restricted_jobs += protected_jobs - - var/list/datum/mind/possible_changelings = get_players_for_role(BE_CHANGELING) - - for(var/datum/mind/player in possible_changelings) - for(var/job in restricted_jobs)//Removing robots from the list - if(player.assigned_role == job) - possible_changelings -= player - - changeling_amount = 1 + round(num_players() / 10) - - if(possible_changelings.len>0) - for(var/i = 0, i < changeling_amount, i++) - if(!possible_changelings.len) break - var/datum/mind/changeling = pick(possible_changelings) - possible_changelings -= changeling - changelings += changeling - modePlayer += changelings - return 1 - else - return 0 - -/datum/game_mode/changeling/post_setup() - for(var/datum/mind/changeling in changelings) - grant_changeling_powers(changeling.current) - changeling.special_role = "Changeling" - if(!config.objectives_disabled) - forge_changeling_objectives(changeling) - greet_changeling(changeling) - - spawn (rand(waittime_l, waittime_h)) - send_intercept() - ..() - return - - -/datum/game_mode/proc/forge_changeling_objectives(var/datum/mind/changeling) - //OBJECTIVES - Always absorb 5 genomes, plus random traitor objectives. - //If they have two objectives as well as absorb, they must survive rather than escape - //No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting - //If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone - - if (config.objectives_disabled) - return - - var/datum/objective/absorb/absorb_objective = new - absorb_objective.owner = changeling - absorb_objective.gen_amount_goal(2, 3) - changeling.objectives += absorb_objective - - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = changeling - kill_objective.find_target() - changeling.objectives += kill_objective - - var/datum/objective/steal/steal_objective = new - steal_objective.owner = changeling - steal_objective.find_target() - changeling.objectives += steal_objective - - - switch(rand(1,100)) - if(1 to 80) - if (!(locate(/datum/objective/escape) in changeling.objectives)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = changeling - changeling.objectives += escape_objective - else - if (!(locate(/datum/objective/survive) in changeling.objectives)) - var/datum/objective/survive/survive_objective = new - survive_objective.owner = changeling - changeling.objectives += survive_objective - return - -/datum/game_mode/proc/greet_changeling(var/datum/mind/changeling, var/you_are=1) - if (you_are) - changeling.current << "\red You are a changeling!" - changeling.current << "\red Use say \":g message\" to communicate with your fellow changelings. Remember: you get all of their absorbed DNA if you absorb them." - - show_objectives(changeling) - - if (changeling.current.mind) - if (changeling.current.mind.assigned_role == "Clown") - changeling.current << "You have evolved beyond your clownish nature, allowing you to wield weapons without harming yourself." - changeling.current.mutations.Remove(CLUMSY) - - -/*/datum/game_mode/changeling/check_finished() - var/changelings_alive = 0 - for(var/datum/mind/changeling in changelings) - if(!istype(changeling.current,/mob/living/carbon)) - continue - if(changeling.current.stat==2) - continue - changelings_alive++ - - if (changelings_alive) - changelingdeath = 0 - return ..() - else - if (!changelingdeath) - changelingdeathtime = world.time - changelingdeath = 1 - if(world.time-changelingdeathtime > TIME_TO_GET_REVIVED) - return 1 - else - return ..() - return 0*/ - -/datum/game_mode/proc/grant_changeling_powers(mob/living/carbon/changeling_mob) - if(!istype(changeling_mob)) return - changeling_mob.make_changeling() - -/datum/game_mode/proc/auto_declare_completion_changeling() - if(changelings.len) - var/text = "The changelings were:" - for(var/datum/mind/changeling in changelings) - var/changelingwin = changeling.current - text += print_player_full(changeling) - - //Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed. - text += "
    Changeling ID: [changeling.changeling.changelingID]." - text += "
    Genomes Absorbed: [changeling.changeling.absorbedcount]" - if(!config.objectives_disabled) - if(changeling.objectives.len) - var/count = 1 - for(var/datum/objective/objective in changeling.objectives) - if(objective.check_completion()) - text += "
    Objective #[count]: [objective.explanation_text] Success!" - feedback_add_details("changeling_objective","[objective.type]|SUCCESS") - else - text += "
    Objective #[count]: [objective.explanation_text] Fail." - feedback_add_details("changeling_objective","[objective.type]|FAIL") - changelingwin = 0 - count++ - if(!config.objectives_disabled) - if(changelingwin) - text += "
    The changeling was successful!" - feedback_add_details("changeling_success","SUCCESS") - else - text += "
    The changeling has failed." - feedback_add_details("changeling_success","FAIL") - text += "
    " - - world << text - - - return 1 - -/datum/changeling //stores changeling powers, changeling recharge thingie, changeling absorbed DNA and changeling ID (for changeling hivemind) - var/list/absorbed_dna = list() - var/list/absorbed_species = list() - var/list/absorbed_languages = list() - var/absorbedcount = 0 - var/chem_charges = 20 - var/chem_recharge_rate = 0.5 - var/chem_storage = 50 - var/sting_range = 1 - var/changelingID = "Changeling" - var/geneticdamage = 0 - var/isabsorbing = 0 - var/geneticpoints = 5 - var/purchasedpowers = list() - var/mimicing = "" - -/datum/changeling/New(var/gender=FEMALE) - ..() - var/honorific - if(gender == FEMALE) honorific = "Ms." - else honorific = "Mr." - if(possible_changeling_IDs.len) - changelingID = pick(possible_changeling_IDs) - possible_changeling_IDs -= changelingID - changelingID = "[honorific] [changelingID]" - else - changelingID = "[honorific] [rand(1,999)]" - -/datum/changeling/proc/regenerate() - chem_charges = min(max(0, chem_charges+chem_recharge_rate), chem_storage) - geneticdamage = max(0, geneticdamage-1) - - -/datum/changeling/proc/GetDNA(var/dna_owner) - var/datum/dna/chosen_dna - for(var/datum/dna/DNA in absorbed_dna) - if(dna_owner == DNA.real_name) - chosen_dna = DNA - break - return chosen_dna \ No newline at end of file + end_on_antag_death = 1 + antag_scaling_coeff = 10 diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index 2d7ef7c020..8917c15da5 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -1,3 +1,43 @@ +var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon","Zeta","Eta","Theta","Iota","Kappa","Lambda","Mu","Nu","Xi","Omicron","Pi","Rho","Sigma","Tau","Upsilon","Phi","Chi","Psi","Omega") + +/datum/changeling //stores changeling powers, changeling recharge thingie, changeling absorbed DNA and changeling ID (for changeling hivemind) + var/list/absorbed_dna = list() + var/list/absorbed_species = list() + var/list/absorbed_languages = list() + var/absorbedcount = 0 + var/chem_charges = 20 + var/chem_recharge_rate = 0.5 + var/chem_storage = 50 + var/sting_range = 1 + var/changelingID = "Changeling" + var/geneticdamage = 0 + var/isabsorbing = 0 + var/geneticpoints = 5 + var/purchasedpowers = list() + var/mimicing = "" + +/datum/changeling/New(var/gender=FEMALE) + ..() + var/honorific = (gender == FEMALE) ? "Ms." : "Mr." + if(possible_changeling_IDs.len) + changelingID = pick(possible_changeling_IDs) + possible_changeling_IDs -= changelingID + changelingID = "[honorific] [changelingID]" + else + changelingID = "[honorific] [rand(1,999)]" + +/datum/changeling/proc/regenerate() + chem_charges = min(max(0, chem_charges+chem_recharge_rate), chem_storage) + geneticdamage = max(0, geneticdamage-1) + +/datum/changeling/proc/GetDNA(var/dna_owner) + var/datum/dna/chosen_dna + for(var/datum/dna/DNA in absorbed_dna) + if(dna_owner == DNA.real_name) + chosen_dna = DNA + break + return chosen_dna + //Restores our verbs. It will only restore verbs allowed during lesser (monkey) form if we are not human /mob/proc/make_changeling() @@ -286,64 +326,24 @@ src << "We cannot perform this ability at the present time!" return - var/mob/living/carbon/C = src + var/mob/living/carbon/human/H = src + + if(!istype(H) || !H.species.primitive_form) + src << "We cannot perform this ability in this form!" + return + changeling.chem_charges-- - C.remove_changeling_powers() - C.visible_message("[C] transforms!") + H.remove_changeling_powers() + H.visible_message("[H] transforms!") changeling.geneticdamage = 30 - C << "Our genes cry out!" - - //TODO replace with monkeyize proc + H << "Our genes cry out!" var/list/implants = list() //Try to preserve implants. - for(var/obj/item/weapon/implant/W in C) + for(var/obj/item/weapon/implant/W in H) implants += W - - C.monkeyizing = 1 - C.canmove = 0 - C.icon = null - C.overlays.Cut() - C.invisibility = 101 - - var/atom/movable/overlay/animation = new /atom/movable/overlay( C.loc ) - animation.icon_state = "blank" - animation.icon = 'icons/mob/mob.dmi' - animation.master = src - flick("h2monkey", animation) - sleep(48) - del(animation) - - var/mob/living/carbon/monkey/O = new /mob/living/carbon/monkey(src) - O.dna = C.dna.Clone() - C.dna = null - - for(var/obj/item/W in C) - C.drop_from_inventory(W) - for(var/obj/T in C) - del(T) - - O.loc = C.loc - O.name = "monkey ([copytext(md5(C.real_name), 2, 6)])" - O.setToxLoss(C.getToxLoss()) - O.adjustBruteLoss(C.getBruteLoss()) - O.setOxyLoss(C.getOxyLoss()) - O.adjustFireLoss(C.getFireLoss()) - O.stat = C.stat - O.a_intent = "hurt" - for(var/obj/item/weapon/implant/I in implants) - I.loc = O - I.implanted = O - - C.mind.transfer_to(O) - - O.make_changeling(1) - O.verbs += /mob/proc/changeling_lesser_transform - O.changeling_update_languages(changeling.absorbed_languages) - + H.monkeyize() feedback_add_details("changeling_powers","LF") - del(C) return 1 - //Transform into a human /mob/proc/changeling_lesser_transform() set category = "Changeling" @@ -651,7 +651,7 @@ var/list/datum/dna/hivemind_bank = list() src << "We return our vocal glands to their original location." return - var/mimic_voice = stripped_input(usr, "Enter a name to mimic.", "Mimic Voice", null, MAX_NAME_LEN) + var/mimic_voice = sanitize(input(usr, "Enter a name to mimic.", "Mimic Voice", null), MAX_NAME_LEN) if(!mimic_voice) return @@ -796,7 +796,7 @@ var/list/datum/dna/hivemind_bank = list() var/mob/living/carbon/T = changeling_sting(40,/mob/proc/changeling_transformation_sting) if(!T) return 0 - if((HUSK in T.mutations) || (!ishuman(T) && !ismonkey(T))) + if((HUSK in T.mutations) || (!ishuman(T) && !issmall(T))) src << "Our sting appears ineffective against its DNA." return 0 T.visible_message("[T] transforms!") diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm deleted file mode 100644 index 501e14bd20..0000000000 --- a/code/game/gamemodes/changeling/traitor_chan.dm +++ /dev/null @@ -1,44 +0,0 @@ -/datum/game_mode/traitor/changeling - name = "traitor+changeling" - config_tag = "traitorchan" - traitors_possible = 3 //hard limit on traitors if scaling is turned off - restricted_jobs = list("AI", "Cyborg") - required_players = 3 - required_players_secret = 10 - required_enemies = 2 - recommended_enemies = 3 - -/datum/game_mode/traitor/changeling/announce() - world << "The current game mode is - Traitor+Changeling!" - world << "There is an alien creature on the station along with some foreign operatives out for their own gain! Do not let the changeling and the traitors succeed!" - - -/datum/game_mode/traitor/changeling/pre_setup() - if(config.protect_roles_from_antagonist) - restricted_jobs += protected_jobs - - var/list/datum/mind/possible_changelings = get_players_for_role(BE_CHANGELING) - - for(var/datum/mind/player in possible_changelings) - for(var/job in restricted_jobs)//Removing robots from the list - if(player.assigned_role == job) - possible_changelings -= player - - if(possible_changelings.len>0) - var/datum/mind/changeling = pick(possible_changelings) - //possible_changelings-=changeling - changelings += changeling - modePlayer += changelings - return ..() - else - return 0 - -/datum/game_mode/traitor/changeling/post_setup() - for(var/datum/mind/changeling in changelings) - grant_changeling_powers(changeling.current) - changeling.special_role = "Changeling" - if(!config.objectives_disabled) - forge_changeling_objectives(changeling) - greet_changeling(changeling) - ..() - return \ No newline at end of file diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 4c4226e4ea..6a17d03a07 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -1,340 +1,11 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 - -/datum/game_mode - var/list/datum/mind/cult = list() - var/list/allwords = list("travel","self","see","hell","blood","join","tech","destroy", "other", "hide") - - -/proc/iscultist(mob/living/M as mob) - return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.cult) - -/proc/is_convertable_to_cult(datum/mind/mind) - if(!istype(mind)) return 0 - if(istype(mind.current, /mob/living/carbon/human) && (mind.assigned_role in list("Captain", "Chaplain"))) return 0 - for(var/obj/item/weapon/implant/loyalty/L in mind.current) - if(L && (L.imp_in == mind.current))//Checks to see if the person contains an implant, then checks that the implant is actually inside of them - return 0 - return 1 - - /datum/game_mode/cult - name = "cult" + name = "Cult" + round_description = "Some crewmembers are attempting to start a cult!" + extended_round_description = "The station has been infiltrated by a fanatical group of death-cultists! They will use powers from beyond your comprehension to subvert you to their cause and ultimately please their gods through sacrificial summons and physical immolation! Try to survive!" config_tag = "cult" - restricted_jobs = list("Chaplain","AI", "Cyborg", "Internal Affairs Agent", "Head of Security", "Captain") - protected_jobs = list("Security Officer", "Warden", "Detective") required_players = 5 required_players_secret = 15 required_enemies = 3 - recommended_enemies = 4 - uplink_welcome = "Nar-Sie Uplink Console:" - uplink_uses = 10 - - var/datum/mind/sacrifice_target = null - var/finished = 0 - var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) - var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) - - var/list/startwords = list("blood","join","self","hell") - - var/list/objectives = list() - - var/eldergod = 1 //for the summon god objective - - var/const/acolytes_needed = 5 //for the survive objective - var/const/min_cultists_to_start = 3 - var/const/max_cultists_to_start = 4 - var/acolytes_survived = 0 - - -/datum/game_mode/cult/announce() - world << "The current game mode is - Cult!" - world << "Some crewmembers are attempting to start a cult!
    \nCultists - complete your objectives. Convert crewmembers to your cause by using the convert rune. Remember - there is no you, there is only the cult.
    \nPersonnel - Do not let the cult succeed in its mission. Brainwashing them with the chaplain's bible reverts them to whatever CentCom-allowed faith they had.
    " - - -/datum/game_mode/cult/pre_setup() - if(!config.objectives_disabled) - if(prob(50)) - objectives += "survive" - objectives += "sacrifice" - else - objectives += "eldergod" - objectives += "sacrifice" - - if(config.protect_roles_from_antagonist) - restricted_jobs += protected_jobs - - var/list/cultists_possible = get_players_for_role(BE_CULTIST) - for(var/datum/mind/player in cultists_possible) - for(var/job in restricted_jobs)//Removing heads and such from the list - if(player.assigned_role == job) - cultists_possible -= player - - for(var/cultists_number = 1 to max_cultists_to_start) - if(!cultists_possible.len) - break - var/datum/mind/cultist = pick(cultists_possible) - cultists_possible -= cultist - cult += cultist - - return (cult.len>0) - - -/datum/game_mode/cult/post_setup() - modePlayer += cult - if("sacrifice" in objectives) - var/list/possible_targets = get_unconvertables() - - if(!possible_targets.len) - for(var/mob/living/carbon/human/player in player_list) - if(player.mind && !(player.mind in cult)) - possible_targets += player.mind - - if(possible_targets.len > 0) - sacrifice_target = pick(possible_targets) - - for(var/datum/mind/cult_mind in cult) - equip_cultist(cult_mind.current) - grant_runeword(cult_mind.current) - update_cult_icons_added(cult_mind) - cult_mind.current << "\blue You are a member of the cult!" - if(!config.objectives_disabled) - memorize_cult_objectives(cult_mind) - show_objectives(cult_mind) - cult_mind.special_role = "Cultist" - - spawn (rand(waittime_l, waittime_h)) - send_intercept() - ..() - - -/datum/game_mode/cult/proc/memorize_cult_objectives(var/datum/mind/cult_mind) - for(var/obj_count = 1,obj_count <= objectives.len,obj_count++) - var/explanation - switch(objectives[obj_count]) - if("survive") - explanation = "Our knowledge must live on. Make sure at least [acolytes_needed] acolytes escape on the shuttle to spread their work on an another station." - if("sacrifice") - if(sacrifice_target) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. You will need the sacrifice rune (Hell blood join) and three acolytes to do so." - else - explanation = "Free objective." - if("eldergod") - explanation = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it." - cult_mind.current << "Objective #[obj_count]: [explanation]" - cult_mind.memory += "Objective #[obj_count]: [explanation]
    " - cult_mind.current << "The convert rune is join blood self" - cult_mind.memory += "The convert rune is join blood self
    " - - -/datum/game_mode/proc/equip_cultist(mob/living/carbon/human/mob) - if(!istype(mob)) - return - - if (mob.mind) - if (mob.mind.assigned_role == "Clown") - mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." - mob.mutations.Remove(CLUMSY) - - - var/obj/item/weapon/paper/talisman/supply/T = new(mob) - var/list/slots = list ( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store, - "left hand" = slot_l_hand, - "right hand" = slot_r_hand, - ) - var/where = mob.equip_in_one_of_slots(T, slots) - if (!where) - mob << "Unfortunately, you weren't able to get a talisman. This is very bad and you should adminhelp immediately." - else - mob << "You have a talisman in your [where], one that will help you start the cult on this station. Use it well and remember - there are others." - mob.update_icons() - return 1 - - -/datum/game_mode/cult/grant_runeword(mob/living/carbon/human/cult_mob, var/word) - if (!word) - if(startwords.len > 0) - word=pick(startwords) - startwords -= word - return ..(cult_mob,word) - - -/datum/game_mode/proc/grant_runeword(mob/living/carbon/human/cult_mob, var/word) - if(!cultwords["travel"]) - runerandom() - if (!word) - word=pick(allwords) - var/wordexp = "[cultwords[word]] is [word]..." - cult_mob << "\red You remember one thing from the dark teachings of your master... [wordexp]" - cult_mob.mind.store_memory("You remember that [wordexp]", 0, 0) - - -/datum/game_mode/proc/add_cultist(datum/mind/cult_mind) //BASE - if (!istype(cult_mind)) - return 0 - if(!(cult_mind in cult) && is_convertable_to_cult(cult_mind)) - cult += cult_mind - update_cult_icons_added(cult_mind) - return 1 - - -/datum/game_mode/cult/add_cultist(datum/mind/cult_mind) //INHERIT - if (!..(cult_mind)) - return - if (!config.objectives_disabled) - memorize_cult_objectives(cult_mind) - - -/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = 1) - if(cult_mind in cult) - cult -= cult_mind - cult_mind.current << "\red An unfamiliar white light flashes through your mind, cleansing the taint of the dark-one and the memories of your time as his servant with it." - cult_mind.memory = "" - update_cult_icons_removed(cult_mind) - if(show_message) - for(var/mob/M in viewers(cult_mind.current)) - M << "[cult_mind.current] looks like they just reverted to their old faith!" - -/datum/game_mode/proc/update_all_cult_icons() - spawn(0) - for(var/datum/mind/cultist in cult) - if(cultist.current) - if(cultist.current.client) - for(var/image/I in cultist.current.client.images) - if(I.icon_state == "cult") - del(I) - - for(var/datum/mind/cultist in cult) - if(cultist.current) - if(cultist.current.client) - for(var/datum/mind/cultist_1 in cult) - if(cultist_1.current) - var/I = image('icons/mob/mob.dmi', loc = cultist_1.current, icon_state = "cult") - cultist.current.client.images += I - - -/datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind) - spawn(0) - for(var/datum/mind/cultist in cult) - if(cultist.current) - if(cultist.current.client) - var/I = image('icons/mob/mob.dmi', loc = cult_mind.current, icon_state = "cult") - cultist.current.client.images += I - if(cult_mind.current) - if(cult_mind.current.client) - var/image/J = image('icons/mob/mob.dmi', loc = cultist.current, icon_state = "cult") - cult_mind.current.client.images += J - - -/datum/game_mode/proc/update_cult_icons_removed(datum/mind/cult_mind) - spawn(0) - for(var/datum/mind/cultist in cult) - if(cultist.current) - if(cultist.current.client) - for(var/image/I in cultist.current.client.images) - if(I.icon_state == "cult" && I.loc == cult_mind.current) - del(I) - - if(cult_mind.current) - if(cult_mind.current.client) - for(var/image/I in cult_mind.current.client.images) - if(I.icon_state == "cult") - del(I) - - -/datum/game_mode/cult/proc/get_unconvertables() - var/list/ucs = list() - for(var/mob/living/carbon/human/player in mob_list) - if(!is_convertable_to_cult(player.mind)) - ucs += player.mind - return ucs - - -/datum/game_mode/cult/proc/check_cult_victory() - var/cult_fail = 0 - if(objectives.Find("survive")) - cult_fail += check_survive() //the proc returns 1 if there are not enough cultists on the shuttle, 0 otherwise - if(objectives.Find("eldergod")) - cult_fail += eldergod //1 by default, 0 if the elder god has been summoned at least once - if(objectives.Find("sacrifice")) - if(sacrifice_target && !sacrificed.Find(sacrifice_target)) //if the target has been sacrificed, ignore this step. otherwise, add 1 to cult_fail - cult_fail++ - - return cult_fail //if any objectives aren't met, failure - - -/datum/game_mode/cult/proc/check_survive() - acolytes_survived = 0 - for(var/datum/mind/cult_mind in cult) - if (cult_mind.current && cult_mind.current.stat!=2) - var/area/A = get_area(cult_mind.current ) - if ( is_type_in_list(A, centcom_areas)) - acolytes_survived++ - if(acolytes_survived>=acolytes_needed) - return 0 - else - return 1 - - -/datum/game_mode/cult/declare_completion() - if(config.objectives_disabled) - return 1 - if(!check_cult_victory()) - feedback_set_details("round_end_result","win - cult win") - feedback_set("round_end_result",acolytes_survived) - world << "\red The cult wins! It has succeeded in serving its dark masters!" - else - feedback_set_details("round_end_result","loss - staff stopped the cult") - feedback_set("round_end_result",acolytes_survived) - world << "\red The staff managed to stop the cult!" - - var/text = "Cultists escaped: [acolytes_survived]" - if(!config.objectives_disabled) - if(objectives.len) - text += "
    The cultists' objectives were:" - for(var/obj_count=1, obj_count <= objectives.len, obj_count++) - var/explanation - switch(objectives[obj_count]) - if("survive") - if(!check_survive()) - explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. Success!" - feedback_add_details("cult_objective","cult_survive|SUCCESS|[acolytes_needed]") - else - explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. Fail." - feedback_add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]") - if("sacrifice") - if(sacrifice_target) - if(sacrifice_target in sacrificed) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Success!" - feedback_add_details("cult_objective","cult_sacrifice|SUCCESS") - else if(sacrifice_target && sacrifice_target.current) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail." - feedback_add_details("cult_objective","cult_sacrifice|FAIL") - else - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail (Gibbed)." - feedback_add_details("cult_objective","cult_sacrifice|FAIL|GIBBED") - if("eldergod") - if(!eldergod) - explanation = "Summon Nar-Sie. Success!" - feedback_add_details("cult_objective","cult_narsie|SUCCESS") - else - explanation = "Summon Nar-Sie. Fail." - feedback_add_details("cult_objective","cult_narsie|FAIL") - text += "
    Objective #[obj_count]: [explanation]" - - world << text - ..() - return 1 - - -/datum/game_mode/proc/auto_declare_completion_cult() - if( cult.len || (ticker && istype(ticker.mode,/datum/game_mode/cult)) ) - var/text = "The cultists were:" - for(var/datum/mind/cultist in cult) - text += print_player_full(cultist) - text += "
    " - - world << text + end_on_antag_death = 1 + antag_tag = MODE_CULTIST \ No newline at end of file diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index e3ac71b77c..0fd706059e 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -32,6 +32,8 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", var/word1 var/word2 var/word3 + var/list/converting = list() + // Places these combos are mentioned: this file - twice in the rune code, once in imbued tome, once in tome's HTML runes.dm - in the imbue rune code. If you change a combination - dont forget to change it everywhere. // travel self [word] - Teleport to random [rune with word destination matching] @@ -359,10 +361,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology", user << "\red You do not have enough space to write a proper rune." return - - - - if (C>=26+runedec+ticker.mode.cult.len) //including the useless rune at the secret room, shouldn't count against the limit of 25 runes - Urist + if (C>=26 + runedec + cult.current_antagonists.len) //including the useless rune at the secret room, shouldn't count against the limit of 25 runes - Urist alert("The cloth of reality can't take that much of a strain. Remove some runes first!") return else diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 2c2ca5b21b..5dfd16828c 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -1,6 +1,7 @@ var/list/sacrificed = list() /obj/effect/rune + /////////////////////////////////////////FIRST RUNE proc teleport(var/key) @@ -98,50 +99,79 @@ var/list/sacrificed = list() /////////////////////////////////////////THIRD RUNE convert() + var/mob/living/carbon/target = null for(var/mob/living/carbon/M in src.loc) - if(iscultist(M)) - continue - if(M.stat==2) - continue - usr.say("Mah[pick("'","`")]weyh pleggh at e'ntrath!") - - if (M.species && (M.species.flags & NO_PAIN)) - M.visible_message("\red The markings below [M] glow a bloody red.") + if(!iscultist(M) && M.stat < DEAD && !(M in converting)) + target = M + break + + if(!target) //didn't find any new targets + if(!converting.len) + fizzle() else - M.visible_message("\red [M] writhes in pain as the markings below \him glow a bloody red.", \ - "\red AAAAAAHHHH!", \ - "\red You hear an anguished scream.") - if(is_convertable_to_cult(M.mind) && !jobban_isbanned(M, "cultist"))//putting jobban check here because is_convertable uses mind as argument + usr << "You sense that the power of the dark one is already working away at them." + return - // Mostly for the benefit of those who resist, but it makes sense for even those who join to have some.. effect. - M.take_overall_damage(0, 10) + usr.say("Mah[pick("'","`")]weyh pleggh at e'ntrath!") - var/choice = alert(M,"Do you want to join the cult?","Submit to Nar'Sie","Resist","Submit") - if(choice == "Submit") - ticker.mode.add_cultist(M.mind) - M.mind.special_role = "Cultist" - M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - M << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - return 1 - - else if(choice == "Resist") - - M.take_overall_damage(0, rand(5, 10)) // You dirty resister cannot handle the damage to your mind. Easily. - // Resist messages go! - var/BurnLoss = M.getFireLoss() - if (BurnLoss < 25) M << "Your blood boils as you force yourself to resist the corruption invading every corner of your mind." - else if (BurnLoss < 45) M << "Your blood boils and your body burns as the corruption further forces itself into your body and mind." - else if (BurnLoss < 75) M << "You begin to hallucinate images of a dark and incomprehensible being and your entire body feels like its engulfed in flame as your mental defenses crumble." - else if (BurnLoss < 100) M << "Your mind turns to ash as the burning flames engulf your very soul and images of Nar'Sie begin to bombard the last remnants of mental resistance." - else M << "Your entire broken soul and being is engulfed in corruption and flames as your mind shatters away into nothing." - return 0 - else - M << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - M << "And you were able to force it out of your mind. You now know the truth, there's something horrible out there, stop it and its minions at all costs." + converting |= target + var/list/waiting_for_input = list(target = 0) //need to box this up in order to be able to reset it again from inside spawn, apparently + var/initial_message = 0 + while(target in converting) + if(target.loc != src.loc || target.stat == DEAD) + converting -= target + if(target.getFireLoss() < 100) + target.hallucination = min(target.hallucination, 500) return 0 - return fizzle() + target.take_overall_damage(0, rand(5, 20)) // You dirty resister cannot handle the damage to your mind. Easily. - even cultists who accept right away should experience some effects + // Resist messages go! + if(initial_message) //don't do this stuff right away, only if they resist or hesitate. + switch(target.getFireLoss()) + if(0 to 25) + target << "Your blood boils as you force yourself to resist the corruption invading every corner of your mind." + if(25 to 45) + target << "Your blood boils and your body burns as the corruption further forces itself into your body and mind." + if(45 to 75) + target << "You begin to hallucinate images of a dark and incomprehensible being and your entire body feels like its engulfed in flame as your mental defenses crumble." + target.apply_effect(rand(1,10), STUTTER) + if(75 to 100) + target << "Your mind turns to ash as the burning flames engulf your very soul and images of an unspeakable horror begin to bombard the last remnants of mental resistance." + //broken mind - 5000 may seem like a lot I wanted the effect to really stand out for maxiumum losing-your-mind-spooky + //hallucination is reduced when the step off as well, provided they haven't hit the last stage... + target.hallucination += 5000 + target.apply_effect(10, STUTTER) + target.adjustBrainLoss(1) + if(100 to INFINITY) + target << "Your entire broken soul and being is engulfed in corruption and flames as your mind shatters away into nothing." + target.hallucination += 5000 + target.apply_effect(15, STUTTER) + target.adjustBrainLoss(rand(1,5)) + initial_message = 1 + if (target.species && (target.species.flags & NO_PAIN)) + target.visible_message("The markings below [target] glow a bloody red.") + else + target.visible_message("[target] writhes in pain as the markings below \him glow a bloody red.", "AAAAAAHHHH!", "You hear an anguished scream.") + + if(!waiting_for_input[target]) //so we don't spam them with dialogs if they hesitate + waiting_for_input[target] = 1 + + if(!cult.can_become_antag(target.mind) || jobban_isbanned(target, "cultist"))//putting jobban check here because is_convertable uses mind as argument + //waiting_for_input ensures this is only shown once, so they basically auto-resist from here on out. They still need to find a way to get off the freaking rune if they don't want to burn to death, though. + target << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." + target << "And you were able to force it out of your mind. You now know the truth, there's something horrible out there, stop it and its minions at all costs." + + else spawn() + var/choice = alert(target,"Do you want to join the cult?","Submit to Nar'Sie","Resist","Submit") + waiting_for_input[target] = 0 + if(choice == "Submit") //choosing 'Resist' does nothing of course. + cult.add_antagonist(target.mind) + converting -= target + target.hallucination = 0 //sudden clarity + + sleep(100) //proc once every 10 seconds + return 1 /////////////////////////////////////////FOURTH RUNE @@ -153,8 +183,6 @@ var/list/sacrificed = list() cultist_count += 1 if(cultist_count >= 9) new /obj/machinery/singularity/narsie/large(src.loc) - if(ticker.mode.name == "cult") - ticker.mode:eldergod = 0 return else return fizzle() @@ -230,12 +258,12 @@ var/list/sacrificed = list() usr.seer = 0 else if(usr.see_invisible!=SEE_INVISIBLE_LIVING) usr << "\red The world beyond flashes your eyes but disappears quickly, as if something is disrupting your vision." - usr.see_invisible = SEE_INVISIBLE_OBSERVER + usr.see_invisible = SEE_INVISIBLE_CULT usr.seer = 0 else usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium vivira. Itonis al'ra matum!") usr << "\red The world beyond opens to your eyes." - usr.see_invisible = SEE_INVISIBLE_OBSERVER + usr.see_invisible = SEE_INVISIBLE_CULT usr.seer = 1 return return fizzle() @@ -249,7 +277,7 @@ var/list/sacrificed = list() var/is_sacrifice_target = 0 for(var/mob/living/carbon/human/M in src.loc) if(M.stat == DEAD) - if(ticker.mode.name == "cult" && M.mind == ticker.mode:sacrifice_target) + if(cult && M.mind == cult.sacrifice_target) is_sacrifice_target = 1 else corpse_to_raise = M @@ -267,7 +295,7 @@ var/list/sacrificed = list() for(var/obj/effect/rune/R in world) if(R.word1==cultwords["blood"] && R.word2==cultwords["join"] && R.word3==cultwords["hell"]) for(var/mob/living/carbon/human/N in R.loc) - if(ticker.mode.name == "cult" && N.mind && N.mind == ticker.mode:sacrifice_target) + if(cult && N.mind && N.mind == cult.sacrifice_target) is_sacrifice_target = 1 else if(N.stat!= DEAD) @@ -276,7 +304,7 @@ var/list/sacrificed = list() if(!body_to_sacrifice) if (is_sacrifice_target) - usr << "\red The Geometer of blood wants that corpse for himself." + usr << "\red The Geometer of Blood wants that corpse for himself." else usr << "\red The sacrifical corpse is not dead. You must free it from this world of illusions before it may be used." return fizzle() @@ -409,21 +437,13 @@ var/list/sacrificed = list() D.key = ghost.key - if(ticker.mode.name == "cult") - ticker.mode:add_cultist(D.mind) - else - ticker.mode.cult+=D.mind + cult.add_antagonist(D.mind) - D.mind.assigned_role = "Manifest Ghost" - D.mind.special_role = "Cultist" if(!chose_name) D.real_name = pick("Anguished", "Blasphemous", "Corrupt", "Cruel", "Depraved", "Despicable", "Disturbed", "Exacerbated", "Foul", "Hateful", "Inexorable", "Implacable", "Impure", "Malevolent", "Malignant", "Malicious", "Pained", "Profane", "Profligate", "Relentless", "Resentful", "Restless", "Spiteful", "Tormented", "Unclean", "Unforgiving", "Vengeful", "Vindictive", "Wicked", "Wronged") D.real_name += " " D.real_name += pick("Apparition", "Aptrgangr", "Dis", "Draugr", "Dybbuk", "Eidolon", "Fetch", "Fylgja", "Ghast", "Ghost", "Gjenganger", "Haint", "Phantom", "Phantasm", "Poltergeist", "Revenant", "Shade", "Shadow", "Soul", "Spectre", "Spirit", "Spook", "Visitant", "Wraith") - D << "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root." - D << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." - var/mob/living/user = usr while(this_rune && user && user.stat==CONSCIOUS && user.client && user.loc==this_rune.loc) user.take_organ_damage(1, 0) @@ -544,7 +564,7 @@ var/list/sacrificed = list() // returns 0 if the rune is not used. returns 1 if the rune is used. communicate() . = 1 // Default output is 1. If the rune is deleted it will return 1 - var/input = stripped_input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "") + var/input = sanitize(input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "")) if(!input) if (istype(src)) fizzle() @@ -560,7 +580,7 @@ var/list/sacrificed = list() usr.say("[input]") else usr.whisper("[input]") - for(var/datum/mind/H in ticker.mode.cult) + for(var/datum/mind/H in cult.current_antagonists) if (H.current) H.current << "\red \b [input]" del(src) @@ -599,7 +619,7 @@ var/list/sacrificed = list() worth = 1 if (ticker.mode.name == "cult") - if(H.mind == ticker.mode:sacrifice_target) + if(H.mind == cult.sacrifice_target) if(cultsinrange.len >= 3) sacrificed += H.mind if(isrobot(H)) @@ -614,7 +634,7 @@ var/list/sacrificed = list() if(H.stat !=2) if(prob(80) || worth) usr << "\red The Geometer of Blood accepts this [worth ? "exotic " : ""]sacrifice." - ticker.mode:grant_runeword(usr) + cult.grant_runeword(usr) else usr << "\red The Geometer of blood accepts this sacrifice." usr << "\red However, this soul was not enough to gain His favor." @@ -625,7 +645,7 @@ var/list/sacrificed = list() else if(prob(40) || worth) usr << "\red The Geometer of blood accepts this [worth ? "exotic " : ""]sacrifice." - ticker.mode:grant_runeword(usr) + cult.grant_runeword(usr) else usr << "\red The Geometer of blood accepts this sacrifice." usr << "\red However, a mere dead body is not enough to satisfy Him." @@ -639,7 +659,7 @@ var/list/sacrificed = list() else if(prob(40)) usr << "\red The Geometer of blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) + cult.grant_runeword(usr) else usr << "\red The Geometer of blood accepts this sacrifice." usr << "\red However, a mere dead body is not enough to satisfy Him." @@ -652,7 +672,7 @@ var/list/sacrificed = list() if(H.stat !=2) if(prob(80)) usr << "\red The Geometer of Blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) + cult.grant_runeword(usr) else usr << "\red The Geometer of blood accepts this sacrifice." usr << "\red However, this soul was not enough to gain His favor." @@ -663,7 +683,7 @@ var/list/sacrificed = list() else if(prob(40)) usr << "\red The Geometer of blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) + cult.grant_runeword(usr) else usr << "\red The Geometer of blood accepts this sacrifice." usr << "\red However, a mere dead body is not enough to satisfy Him." @@ -677,7 +697,7 @@ var/list/sacrificed = list() else if(prob(40)) usr << "\red The Geometer of blood accepts this sacrifice." - ticker.mode:grant_runeword(usr) + cult.grant_runeword(usr) else usr << "\red The Geometer of blood accepts this sacrifice." usr << "\red However, a mere dead body is not enough to satisfy Him." @@ -685,27 +705,6 @@ var/list/sacrificed = list() H.dust()//To prevent the MMI from remaining else H.gib() - for(var/mob/living/carbon/monkey/M in src.loc) - if (ticker.mode.name == "cult") - if(M.mind == ticker.mode:sacrifice_target) - if(cultsinrange.len >= 3) - sacrificed += M.mind - usr << "\red The Geometer of Blood accepts this sacrifice, your objective is now complete." - else - usr << "\red Your target's earthly bonds are too strong. You need more cultists to succeed in this ritual." - continue - else - if(prob(20)) - usr << "\red The Geometer of Blood accepts your meager sacrifice." - ticker.mode:grant_runeword(usr) - else - usr << "\red The Geometer of blood accepts this sacrifice." - usr << "\red However, a mere monkey is not enough to satisfy Him." - else - usr << "\red The Geometer of Blood accepts your meager sacrifice." - if(prob(20)) - ticker.mode.grant_runeword(usr) - M.gib() /////////////////////////////////////////SIXTEENTH RUNE @@ -769,7 +768,7 @@ var/list/sacrificed = list() freedom() var/mob/living/user = usr var/list/mob/living/carbon/cultists = new - for(var/datum/mind/H in ticker.mode.cult) + for(var/datum/mind/H in cult.current_antagonists) if (istype(H.current,/mob/living/carbon)) cultists+=H.current var/list/mob/living/carbon/users = new @@ -816,7 +815,7 @@ var/list/sacrificed = list() cultsummon() var/mob/living/user = usr var/list/mob/living/carbon/cultists = new - for(var/datum/mind/H in ticker.mode.cult) + for(var/datum/mind/H in cult.current_antagonists) if (istype(H.current,/mob/living/carbon)) cultists+=H.current var/list/mob/living/carbon/users = new diff --git a/code/game/gamemodes/epidemic/epidemic.dm b/code/game/gamemodes/epidemic/epidemic.dm index 9964a37813..f3017bb1a1 100644 --- a/code/game/gamemodes/epidemic/epidemic.dm +++ b/code/game/gamemodes/epidemic/epidemic.dm @@ -3,26 +3,13 @@ config_tag = "epidemic" required_players = 1 required_players_secret = 15 - - var/const/waittime_l = 300 //lower bound on time before intercept arrives (in tenths of seconds) - var/const/waittime_h = 600 //upper bound on time before intercept arrives (in tenths of seconds) - var/checkwin_counter =0 - var/finished = 0 + round_description = "A deadly epidemic is spreading on the station. Find a cure as fast as possible, and keep your distance to anyone who speaks in a hoarse voice!" var/cruiser_arrival - var/virus_name = "" - var/stage = 0 var/doctors = 0 -/////////////////////////// -//Announces the game type// -/////////////////////////// -/datum/game_mode/epidemic/announce() - world << "The current game mode is - Epidemic!" - world << "A deadly epidemic is spreading on the station. Find a cure as fast as possible, and keep your distance to anyone who speaks in a hoarse voice!" - /////////////////////////////////////////////////////////////////////////////// //Gets the round setup, cancelling if there's not enough players at the start// diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 26e38476b7..feed6092e2 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -233,13 +233,6 @@ else randmutg(H) domutcheck(H,null,MUTCHK_FORCED) - for(var/mob/living/carbon/monkey/M in living_mob_list) - var/turf/T = get_turf(M) - if(!T) - continue - if(isNotStationLevel(T.z)) - continue - M.apply_effect((rand(15,75)),IRRADIATE,0) sleep(100) command_announcement.Announce("High levels of radiation detected near the station. Please report to the Med-bay if you feel strange.", "Anomaly Alert", new_sound = 'sound/AI/radiation.ogg') diff --git a/code/game/gamemodes/events/biomass.dm b/code/game/gamemodes/events/biomass.dm deleted file mode 100644 index b758c85019..0000000000 --- a/code/game/gamemodes/events/biomass.dm +++ /dev/null @@ -1,176 +0,0 @@ -// BIOMASS (Note that this code is very similar to Space Vine code) -/obj/effect/biomass - name = "biomass" - desc = "Space barf from another dimension. It just keeps spreading!" - icon = 'icons/obj/biomass.dmi' - icon_state = "stage1" - anchored = 1 - density = 0 - layer = 5 - pass_flags = PASSTABLE | PASSGRILLE - var/energy = 0 - var/obj/effect/biomass_controller/master = null - - New() - return - - Del() - if(master) - master.vines -= src - master.growth_queue -= src - ..() - -/obj/effect/biomass/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (!W || !user || !W.type) return - switch(W.type) - if(/obj/item/weapon/circular_saw) del src - if(/obj/item/weapon/kitchen/utensil/knife) del src - if(/obj/item/weapon/scalpel) del src - if(/obj/item/weapon/twohanded/fireaxe) del src - if(/obj/item/weapon/hatchet) del src - if(/obj/item/weapon/melee/energy) del src - if(/obj/item/weapon/pickaxe/plasmacutter) del src - - //less effective weapons - if(/obj/item/weapon/wirecutters) - if(prob(25)) del src - if(/obj/item/weapon/shard) - if(prob(25)) del src - - else //weapons with subtypes - if(istype(W, /obj/item/weapon/melee/energy/sword)) del src - else if(istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(WT.remove_fuel(0, user)) del src - else - return - ..() - -/obj/effect/biomass_controller - var/list/obj/effect/biomass/vines = list() - var/list/growth_queue = list() - var/reached_collapse_size - var/reached_slowdown_size - //What this does is that instead of having the grow minimum of 1, required to start growing, the minimum will be 0, - //meaning if you get the biomasssss..s' size to something less than 20 plots, it won't grow anymore. - - New() - if(!istype(src.loc,/turf/simulated/floor)) - del(src) - - spawn_biomass_piece(src.loc) - processing_objects.Add(src) - - Del() - processing_objects.Remove(src) - ..() - - proc/spawn_biomass_piece(var/turf/location) - var/obj/effect/biomass/BM = new(location) - growth_queue += BM - vines += BM - BM.master = src - - process() - if(!vines) - del(src) //space vines exterminated. Remove the controller - return - if(!growth_queue) - del(src) //Sanity check - return - if(vines.len >= 250 && !reached_collapse_size) - reached_collapse_size = 1 - if(vines.len >= 30 && !reached_slowdown_size ) - reached_slowdown_size = 1 - - var/maxgrowth = 0 - if(reached_collapse_size) - maxgrowth = 0 - else if(reached_slowdown_size) - if(prob(25)) - maxgrowth = 1 - else - maxgrowth = 0 - else - maxgrowth = 4 - var/length = min( 30 , vines.len / 5 ) - var/i = 0 - var/growth = 0 - var/list/obj/effect/biomass/queue_end = list() - - for( var/obj/effect/biomass/BM in growth_queue ) - i++ - queue_end += BM - growth_queue -= BM - if(BM.energy < 2) //If tile isn't fully grown - if(prob(20)) - BM.grow() - - if(BM.spread()) - growth++ - if(growth >= maxgrowth) - break - if(i >= length) - break - - growth_queue = growth_queue + queue_end - -/obj/effect/biomass/proc/grow() - if(!energy) - src.icon_state = "stage2" - energy = 1 - src.opacity = 0 - src.density = 0 - layer = 5 - else - src.icon_state = "stage3" - src.opacity = 0 - src.density = 1 - energy = 2 - -/obj/effect/biomass/proc/spread() - var/direction = pick(cardinal) - var/step = get_step(src,direction) - if(istype(step,/turf/simulated/floor)) - var/turf/simulated/floor/F = step - if(!locate(/obj/effect/biomass,F)) - if(F.Enter(src)) - if(master) - master.spawn_biomass_piece( F ) - return 1 - return 0 - -/obj/effect/biomass/ex_act(severity) - switch(severity) - if(1.0) - del(src) - return - if(2.0) - if (prob(90)) - del(src) - return - if(3.0) - if (prob(50)) - del(src) - return - return - -/obj/effect/biomass/fire_act(null, temp, volume) //hotspots kill biomass - del src - - -/proc/biomass_infestation() - - spawn() //to stop the secrets panel hanging - var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas - for(var/areapath in typesof(/area/hallway)) - var/area/A = locate(areapath) - for(var/area/B in A.related) - for(var/turf/simulated/floor/F in B.contents) - if(!F.contents.len) - turfs += F - - if(turfs.len) //Pick a turf to spawn at if we can - var/turf/simulated/floor/T = pick(turfs) - new/obj/effect/biomass_controller(T) //spawn a controller at turf - message_admins("\blue Event: Biomass spawned at [T.loc.loc] ([T.x],[T.y],[T.z])") diff --git a/code/game/gamemodes/events/space_ninja.dm b/code/game/gamemodes/events/space_ninja.dm deleted file mode 100644 index 6136197a66..0000000000 --- a/code/game/gamemodes/events/space_ninja.dm +++ /dev/null @@ -1,553 +0,0 @@ -/* -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -+++++++++++++++++++++++++++++++++++++// //++++++++++++++++++++++++++++++++++ -======================================SPACE NINJA SETUP==================================== -___________________________________________________________________________________________ -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -*/ - -/* - README: - - Data: - - >> space_ninja.dm << is this file. It contains a variety of procs related to either spawning space ninjas, - modifying their verbs, various help procs, testing debug-related content, or storing unused procs for later. - Similar functions should go into this file, along with anything else that may not have an explicit category. - IMPORTANT: actual ninja suit, gloves, etc, are stored under the appropriate clothing files. If you need to change - variables or look them up, look there. Easiest way is through the map file browser. - - >> ninja_abilities.dm << contains all the ninja-related powers. Spawning energy swords, teleporting, and the like. - If more powers are added, or perhaps something related to powers, it should go there. Make sure to describe - what an ability/power does so it's easier to reference later without looking at the code. - IMPORTANT: verbs are still somewhat funky to work with. If an argument is specified but is not referenced in a way - BYOND likes, in the code content, the verb will fail to trigger. Nothing will happen, literally, when clicked. - This can be bypassed by either referencing the argument properly, or linking to another proc with the argument - attached. The latter is what I like to do for certain cases--sometimes it's necessary to do that regardless. - - >> ninja_equipment.dm << deals with all the equipment-related procs for a ninja. Primarily it has the suit, gloves, - and mask. The suit is by far the largest section of code out of the three and includes a lot of code that ties in - to other functions. This file has gotten kind of large so breaking it up may be in order. I use section hearders. - IMPORTANT: not much to say here. Follow along with the comments and adding new functions should be a breeze. Also - know that certain equipment pieces are linked in other files. The energy blade, for example, has special - functions defined in the appropriate files (airlock, securestorage, etc). - - General Notes: - - I created space ninjas with the expressed purpose of spicing up boring rounds. That is, ninjas are to xenos as marauders are to - death squads. Ninjas are stealthy, tech-savvy, and powerful. Not to say marauders are all of those things, but a clever ninja - should have little problem murderampaging their way through just about anything. Short of admin wizards maybe. - HOWEVER! - Ninjas also have a fairly great weakness as they require energy to use abilities. If, theoretically, there is a game - mode based around space ninjas, make sure to account for their energy needs. - - Admin Notes: - - Ninjas are not admin PCs--please do not use them for that purpose. They are another way to participate in the game post-death, - like pais, xenos, death squads, and cyborgs. - I'm currently looking for feedback from regular players since beta testing is largely done. I would appreciate if - you spawned regular players as ninjas when rounds are boring. Or exciting, it's all good as long as there is feedback. - You can also spawn ninja gear manually if you want to. - - How to do that: - Make sure your character has a mind. - Change their assigned_role to "MODE", no quotes. Otherwise, the suit won't initialize. - Change their special_role to "Ninja", no quotes. Otherwise, the character will be gibbed. - Spawn ninja gear, put it on, hit initialize. Let the suit do the rest. You are now a space ninja. - I don't recommend messing with suit variables unless you really know what you're doing. - - Miscellaneous Notes: - - Potential Upgrade Tree: - Energy Shield: - Extra Ability - Syndicate Shield device? - Works like the force wall spell, except can be kept indefinitely as long as energy remains. Toggled on or off. - Would block bullets and the like. - Phase Shift - Extra Ability - Advanced Sensors? - Instead of being unlocked at the start, Phase Shieft would become available once requirements are met. - Uranium-based Recharger: - Suit Upgrade - Unsure - Instead of losing energy each second, the suit would regain the same amount of energy. - This would not count in activating stealth and similar. - Extended Battery Life: - Suit Upgrade - Battery of higher capacity - Already implemented. Replace current battery with one of higher capacity. - Advanced Cloak-Tech device. - Suit Upgrade - Syndicate Cloaking Device? - Remove cloak failure rate. -*/ - -//=======//RANDOM EVENT//=======// -/* -Also a dynamic ninja mission generator. -I decided to scrap round-specific objectives since keeping track of them would require some form of tracking. -When I already created about 4 new objectives, this doesn't seem terribly important or needed. -*/ - -/var/global/sent_ninja_to_station = 0//If a ninja is already on the station. - -var/ninja_selection_id = 1 -var/ninja_selection_active = 0 -var/ninja_confirmed_selection = 0 - -/proc/space_ninja_arrival(var/assign_key = null, var/assign_mission = null) - - if(ninja_selection_active) - usr << "\red Ninja selection already in progress. Please wait until it ends." - return - - var/datum/game_mode/current_mode = ticker.mode - var/datum/mind/current_mind - - /*Is the ninja playing for the good or bad guys? Is the ninja helping or hurting the station? - Their directives also influence behavior. At least in theory.*/ - var/side = pick("face","heel") - - var/antagonist_list[] = list()//The main bad guys. Evil minds that plot destruction. - var/protagonist_list[] = current_mode.get_living_heads()//The good guys. Mostly Heads. Who are alive. - - var/xeno_list[] = list()//Aliens. - var/commando_list[] = list()//Commandos. - - //We want the ninja to appear only in certain modes. -// var/acceptable_modes_list[] = list("traitor","revolution","cult","wizard","changeling","traitorchan","mercenary","malfunction","monkey") // Commented out for both testing and ninjas -// if(!(current_mode.config_tag in acceptable_modes_list)) -// return - - /*No longer need to determine what mode it is since bad guys are basically universal. - And there is now a mode with two types of bad guys.*/ - - var/possible_bad_dudes[] = list(current_mode.traitors,current_mode.head_revolutionaries,current_mode.head_revolutionaries, - current_mode.cult,current_mode.wizards,current_mode.changelings,current_mode.syndicates) - for(var/list in possible_bad_dudes)//For every possible antagonist type. - for(current_mind in list)//For each mind in that list. - if(current_mind.current&¤t_mind.current.stat!=2)//If they are not destroyed and not dead. - antagonist_list += current_mind//Add them. - - if(protagonist_list.len)//If the mind is both a protagonist and antagonist. - for(current_mind in protagonist_list) - if(current_mind in antagonist_list) - protagonist_list -= current_mind//We only want it in one list. -/* -Malf AIs/silicons aren't added. Monkeys aren't added. Messes with objective completion. Only humans are added. -*/ - - //Here we pick a location and spawn the ninja. - if(ninjastart.len == 0) - for(var/obj/effect/landmark/L in landmarks_list) - if(L.name == "carpspawn" && locate(/turf/simulated) in range(7, L)) - ninjastart.Add(L) - - var/ninja_key = null - var/mob/candidate_mob - - if(assign_key) - ninja_key = assign_key - else - - var/list/candidates = list() //list of candidate keys - for(var/mob/dead/observer/G in player_list) - if(G.client && !G.client.holder && !G.client.is_afk() && G.client.prefs.be_special & BE_NINJA) - if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) - candidates += G - if(!candidates.len) return - candidates = shuffle(candidates)//Incorporating Donkie's list shuffle - - while(!ninja_key && candidates.len) - candidate_mob = pick(candidates) - if(sd_Alert(candidate_mob, "Would you like to spawn as a space ninja?", buttons = list("Yes","No"), duration = 150) == "Yes") - ninja_key = candidate_mob.ckey - else - candidates.Remove(candidate_mob) - - if(!ninja_key) - return - - - if(!candidate_mob) - for(var/mob/M in player_list) - if((M.key == ninja_key || M.ckey == ninja_key) && M.client) - candidate_mob = M - break - - if(!candidate_mob) - usr << "\red The randomly chosen mob was not found in the second check." - return - - ninja_selection_active = 1 - ninja_selection_id++ - var/this_selection_id = ninja_selection_id - - spawn(1) - if(alert(candidate_mob, "You have been selected to play as a space ninja. Would you like to play as this role? (You have 30 seconds to accept - You will spawn in 30 seconds if you accept)",,"Yes","No")!="Yes") - usr << "\red The selected candidate for space ninja declined." - return - - ninja_confirmed_selection = this_selection_id - - spawn(300) - if(!ninja_selection_active || (this_selection_id != ninja_selection_id )) - ninja_selection_active = 0 - candidate_mob << "\red Sorry, you were too late. You only had 30 seconds to accept." - return - - if(ninja_confirmed_selection != ninja_selection_id) - ninja_selection_active = 0 - usr << "\red The ninja did not accept the role in time." - return - - ninja_selection_active = 0 - - //The ninja will be created on the right spawn point or at late join. - var/mob/living/carbon/human/new_ninja = create_space_ninja(pick(ninjastart.len ? ninjastart : latejoin)) - new_ninja.key = ninja_key - - //Now for the rest of the stuff. - - var/datum/mind/ninja_mind = new_ninja.mind//For easier reference. - var/mission_set = 0//To determine if we need to do further processing. - //Xenos and deathsquads take precedence over everything else. - - //Unless the xenos are hiding in a locker somewhere, this'll find em. - for(var/mob/living/carbon/human/xeno in player_list) - if(istype(xeno.species,/datum/species/xenos)) - xeno_list += xeno - - if(assign_mission) - new_ninja.mind.store_memory("Mission: \red [assign_mission].
    ") - new_ninja << "\blue \nYou are an elite mercenary assassin of the Spider Clan, [new_ninja.real_name]. The dreaded \red SPACE NINJA!\blue You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor. Remember your training! \nYour current mission is: \red [assign_mission]" - else - if(xeno_list.len>3)//If there are more than three humanoid xenos on the station, time to get dangerous. - //Here we want the ninja to murder all the queens. The other aliens don't really matter. - var/xeno_queen_list[] = list() - for(var/mob/living/carbon/human/xeno_queen in xeno_list) - if(xeno_queen.species.name == "Xenomorph Queen" && xeno_queen.mind && xeno_queen.stat!=2) - xeno_queen_list += xeno_queen - if(xeno_queen_list.len&&side=="face")//If there are queen about and the probability is 50. - for(var/mob/living/carbon/human/xeno_queen in xeno_queen_list) - var/datum/objective/assassinate/ninja_objective = new - ninja_objective.owner = ninja_mind - //We'll do some manual overrides to properly set it up. - ninja_objective.target = xeno_queen.mind - ninja_objective.explanation_text = "Kill \the [xeno_queen]." - ninja_mind.objectives += ninja_objective - mission_set = 1 - - if(sent_strike_team&&side=="heel"&&antagonist_list.len)//If a strike team was sent, murder them all like a champ. - for(current_mind in antagonist_list)//Search and destroy. Since we already have an antagonist list, they should appear there. - if(current_mind && current_mind.special_role=="Death Commando") - commando_list += current_mind - if(commando_list.len)//If there are living commandos still in play. - for(var/mob/living/carbon/human/commando in commando_list) - var/datum/objective/assassinate/ninja_objective = new - ninja_objective.owner = ninja_mind - ninja_objective.find_target_by_role(commando.mind.special_role,1) - ninja_mind.objectives += ninja_objective - mission_set = 1 - /* - If there are no antogonists left it could mean one of two things: - A) The round is about to end. No harm in spawning the ninja here. - B) The round is still going and ghosts are probably rioting for something to happen. - In either case, it's a good idea to spawn the ninja with a semi-random set of objectives. - */ - if(!mission_set)//If mission was not set. - - var/current_minds[]//List being looked on in the following code. - var/side_list = side=="face" ? 2 : 1//For logic gating. - var/hostile_targets[] = list()//The guys actually picked for the assassination or whatever. - var/friendly_targets[] = list()//The guys the ninja must protect. - - for(var/i=2,i>0,i--)//Two lists. - current_minds = i==2 ? antagonist_list : protagonist_list//Which list are we looking at? - for(var/t=3,(current_minds.len&&t>0),t--)//While the list is not empty and targets remain. Also, 3 targets is good. - current_mind = pick(current_minds)//Pick a random person. - /*I'm creating a logic gate here based on the ninja affiliation that compares the list being - looked at to the affiliation. Affiliation is just a number used to compare. Meaning comes from the logic involved. - If the list being looked at is equal to the ninja's affiliation, add the mind to hostiles. - If not, add the mind to friendlies. Since it can't be both, it will be added only to one or the other.*/ - hostile_targets += i==side_list ? current_mind : null//Adding null doesn't add anything. - friendly_targets += i!=side_list ? current_mind : null - current_minds -= current_mind//Remove the mind so it's not picked again. - - var/objective_list[] = list(1,2,3,4,5,6)//To remove later. - for(var/i=rand(1,3),i>0,i--)//Want to get a few random objectives. Currently up to 3. - if(!hostile_targets.len)//Remove appropriate choices from switch list if the target lists are empty. - objective_list -= 1 - objective_list -= 4 - if(!friendly_targets.len) - objective_list -= 3 - switch(pick(objective_list)) - if(1)//kill - current_mind = pick(hostile_targets) - - if(current_mind) - var/datum/objective/assassinate/ninja_objective = new - ninja_objective.owner = ninja_mind - ninja_objective.find_target_by_role((current_mind.special_role ? current_mind.special_role : current_mind.assigned_role),(current_mind.special_role?1:0))//If they have a special role, use that instead to find em. - ninja_mind.objectives += ninja_objective - - else - i++ - - hostile_targets -= current_mind//Remove them from the list. - if(2)//Steal - var/datum/objective/steal/ninja_objective = new - ninja_objective.owner = ninja_mind - var/target_item = pick(ninja_objective.possible_items_special) - ninja_objective.set_target(target_item) - ninja_mind.objectives += ninja_objective - - objective_list -= 2 - if(3)//Protect. Keeping people alive can be pretty difficult. - current_mind = pick(friendly_targets) - - if(current_mind) - - var/datum/objective/protect/ninja_objective = new - ninja_objective.owner = ninja_mind - ninja_objective.find_target_by_role((current_mind.special_role ? current_mind.special_role : current_mind.assigned_role),(current_mind.special_role?1:0)) - ninja_mind.objectives += ninja_objective - - else - i++ - - friendly_targets -= current_mind - if(4)//Debrain - current_mind = pick(hostile_targets) - - if(current_mind) - - var/datum/objective/debrain/ninja_objective = new - ninja_objective.owner = ninja_mind - ninja_objective.find_target_by_role((current_mind.special_role ? current_mind.special_role : current_mind.assigned_role),(current_mind.special_role?1:0)) - ninja_mind.objectives += ninja_objective - - else - i++ - - hostile_targets -= current_mind//Remove them from the list. - if(5)//Download research - var/datum/objective/download/ninja_objective = new - ninja_objective.owner = ninja_mind - ninja_objective.gen_amount_goal() - ninja_mind.objectives += ninja_objective - - objective_list -= 5 - if(6)//Capture - var/datum/objective/capture/ninja_objective = new - ninja_objective.owner = ninja_mind - ninja_objective.gen_amount_goal() - ninja_mind.objectives += ninja_objective - - objective_list -= 6 - - if(ninja_mind.objectives.len)//If they got some objectives out of that. - mission_set = 1 - - if(!ninja_mind.objectives.len||!mission_set)//If they somehow did not get an objective at this point, time to destroy the station. - var/nuke_code - var/temp_code - for(var/obj/machinery/nuclearbomb/N in world) - temp_code = text2num(N.r_code) - if(temp_code)//if it's actually a number. It won't convert any non-numericals. - nuke_code = N.r_code - break - if(nuke_code)//If there is a nuke device in world and we got the code. - var/datum/objective/nuclear/ninja_objective = new//Fun. - ninja_objective.owner = ninja_mind - ninja_objective.explanation_text = "Destroy the station with a nuclear device. The code is [nuke_code]." //Let them know what the code is. - - //Finally add a survival objective since it's usually broad enough for any round type. - var/datum/objective/survive/ninja_objective = new - ninja_objective.owner = ninja_mind - ninja_mind.objectives += ninja_objective - - var/directive = generate_ninja_directive(side) - new_ninja << "\blue \nYou are an elite mercenary assassin of the Spider Clan, [new_ninja.real_name]. The dreaded \red SPACE NINJA!\blue You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor. Remember your training (initialize your suit by right clicking on it)! \nYour current directive is: \red [directive]" - new_ninja.mind.store_memory("Directive: \red [directive]
    ") - show_objectives(new_ninja.mind) - - sent_ninja_to_station = 1//And we're done. - return new_ninja//Return the ninja in case we need to reference them later. - -/* -This proc will give the ninja a directive to follow. They are not obligated to do so but it's a fun roleplay reminder. -Making this random or semi-random will probably not work without it also being incredibly silly. -As such, it's hard-coded for now. No reason for it not to be, really. -*/ -/proc/generate_ninja_directive(side) - var/directive = "[side=="face"?"Nanotrasen":"A criminal syndicate"] is your employer. "//Let them know which side they're on. - switch(rand(1,19)) - if(1) - directive += "The Spider Clan must not be linked to this operation. Remain hidden and covert when possible." - if(2) - directive += "[station_name] is financed by an enemy of the Spider Clan. Cause as much structural damage as desired." - if(3) - directive += "A wealthy animal rights activist has made a request we cannot refuse. Prioritize saving animal lives whenever possible." - if(4) - directive += "The Spider Clan absolutely cannot be linked to this operation. Eliminate witnesses at your discretion." - if(5) - directive += "We are currently negotiating with NanoTrasen Central Command. Prioritize saving human lives over ending them." - if(6) - directive += "We are engaged in a legal dispute over [station_name]. If a laywer is present on board, force their cooperation in the matter." - if(7) - directive += "A financial backer has made an offer we cannot refuse. Implicate criminal involvement in the operation." - if(8) - directive += "Let no one question the mercy of the Spider Clan. Ensure the safety of all non-essential personnel you encounter." - if(9) - directive += "A free agent has proposed a lucrative business deal. Implicate Nanotrasen involvement in the operation." - if(10) - directive += "Our reputation is on the line. Harm as few civilians and innocents as possible." - if(11) - directive += "Our honor is on the line. Utilize only honorable tactics when dealing with opponents." - if(12) - directive += "We are currently negotiating with a mercenary leader. Disguise assassinations as suicide or other natural causes." - if(13) - directive += "Some disgruntled NanoTrasen employees have been supportive of our operations. Be wary of any mistreatment by command staff." - if(14) - var/xenorace = pick("Unathi","Tajara", "Skrell") - directive += "A group of [xenorace] radicals have been loyal supporters of the Spider Clan. Favor [xenorace] crew whenever possible." - if(15) - directive += "The Spider Clan has recently been accused of religious insensitivity. Attempt to speak with the Chaplain and prove these accusations false." - if(16) - directive += "The Spider Clan has been bargaining with a competing prosthetics manufacturer. Try to shine NanoTrasen prosthetics in a bad light." - if(17) - directive += "The Spider Clan has recently begun recruiting outsiders. Consider suitable candidates and assess their behavior amongst the crew." - if(18) - directive += "A cyborg liberation group has expressed interest in our serves. Prove the Spider Clan merciful towards law-bound synthetics." - else - directive += "There are no special supplemental instructions at this time." - return directive - -//=======//CURRENT PLAYER VERB//=======// - -/client/proc/cmd_admin_ninjafy(var/mob/M in player_list) - set category = null - set name = "Make Space Ninja" - - if(!ticker) - alert("Wait until the game starts") - return - if(!config.ninjas_allowed) - alert("Space Ninjas spawning is disabled.") - return - - var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") - if(confirm != "Yes") return - - if(ishuman(M)) - var/mob/living/carbon/human/H = M - log_admin("[key_name(src)] turned [M.key] into a Space Ninja.") - spawn(10) - H.create_mind_space_ninja() - H.equip_space_ninja(1) - else - alert("Invalid mob") - -//=======//CURRENT GHOST VERB//=======// - -/client/proc/send_space_ninja() - set category = "Fun" - set name = "Spawn Space Ninja" - set desc = "Spawns a space ninja for when you need a teenager with attitude." - set popup_menu = 0 - - if(!holder) - src << "Only administrators may use this command." - return - if(!ticker.mode) - alert("The game hasn't started yet!") - return - if(!config.ninjas_allowed) - alert("Space Ninjas spawning is disabled.") - return - if(alert("Are you sure you want to send in a space ninja?",,"Yes","No")=="No") - return - - var/mission - while(!mission) - mission = sanitize(copytext(input(src, "Please specify which mission the space ninja shall undertake.", "Specify Mission", ""),1,MAX_MESSAGE_LEN)) - if(!mission) - if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes") - return - - var/input = ckey(input("Pick character to spawn as the Space Ninja", "Key", "")) - if(!input) - return - - space_ninja_arrival(input, mission) - - message_admins("\blue [key_name_admin(key)] has spawned [input] as a Space Ninja.\nTheir mission is: [mission]") - log_admin("[key] used Spawn Space Ninja.") - - return - -//=======//NINJA CREATION PROCS//=======// - -/proc/create_space_ninja(obj/spawn_point) - var/mob/living/carbon/human/new_ninja = new(spawn_point.loc) - var/ninja_title = pick(ninja_titles) - var/ninja_name = pick(ninja_names) - new_ninja.gender = pick(MALE, FEMALE) - - var/datum/preferences/A = new()//Randomize appearance for the ninja. - A.randomize_appearance_for(new_ninja) - new_ninja.real_name = "[ninja_title] [ninja_name]" - new_ninja.dna.ready_dna(new_ninja) - new_ninja.create_mind_space_ninja() - new_ninja.equip_space_ninja() - return new_ninja - -/mob/living/carbon/human/proc/create_mind_space_ninja() - mind_initialize() - mind.assigned_role = "MODE" - mind.special_role = "Ninja" - - //ticker.mode.ninjas |= mind - return 1 - -/mob/living/carbon/human/proc/equip_space_ninja(safety=0)//Safety in case you need to unequip stuff for existing characters. - - if(safety) - del(w_uniform) - del(wear_suit) - del(wear_mask) - del(head) - del(shoes) - del(gloves) - - var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src) - equip_to_slot_or_del(R, slot_l_ear) - if(gender==FEMALE) - equip_to_slot_or_del(new /obj/item/clothing/under/color/blackf(src), slot_w_uniform) - else - equip_to_slot_or_del(new /obj/item/clothing/under/color/black(src), slot_w_uniform) - - equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_belt) - - var/obj/item/weapon/rig/light/ninja/ninjasuit = new(src) - equip_to_slot_or_del(ninjasuit,slot_back) - ninjasuit.toggle_seals(src,1) - - // Make sure the ninja can actually equip the suit. - if(src.dna && src.dna.unique_enzymes) - ninjasuit.locked_dna = src.dna.unique_enzymes - src << "Suit hardware locked to your DNA hash." - else - ninjasuit.req_access = list() - if(istype(back,/obj/item/weapon/rig)) - var/obj/item/weapon/rig/rig = back - if(rig.air_supply) - internal = rig.air_supply - spawn(10) - if(internal) - internals.icon_state = "internal1" - else - src << "You forgot to turn on your internals! Quickly, toggle the valve!" - return 1 \ No newline at end of file diff --git a/code/game/gamemodes/events/spacevines.dm b/code/game/gamemodes/events/spacevines.dm deleted file mode 100644 index d095f19d56..0000000000 --- a/code/game/gamemodes/events/spacevines.dm +++ /dev/null @@ -1,16 +0,0 @@ -//Carn: Spacevines random event. -/proc/spacevine_infestation() - - spawn() //to stop the secrets panel hanging - var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas - for(var/areapath in typesof(/area/hallway)) - var/area/A = locate(areapath) - for(var/area/B in A.related) - for(var/turf/simulated/floor/F in B.contents) - if(!F.contents.len) - turfs += F - - if(turfs.len) //Pick a turf to spawn at if we can - var/turf/simulated/floor/T = pick(turfs) - new/obj/effect/plant_controller(T) //spawn a controller at turf - message_admins("\blue Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])") diff --git a/code/game/gamemodes/extended/extended.dm b/code/game/gamemodes/extended/extended.dm index 3e04928507..0b37fa892f 100644 --- a/code/game/gamemodes/extended/extended.dm +++ b/code/game/gamemodes/extended/extended.dm @@ -1,19 +1,6 @@ /datum/game_mode/extended - name = "extended" + name = "Extended" config_tag = "extended" required_players = 0 - - var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) - var/const/waittime_h = 1800 - -/datum/game_mode/announce() - world << "The current game mode is - Extended Role-Playing!" - world << "Just have fun and role-play!" - -/datum/game_mode/extended/pre_setup() - return 1 - -/datum/game_mode/extended/post_setup() - spawn (rand(waittime_l, waittime_h)) // To reduce extended meta. - send_intercept() - ..() \ No newline at end of file + round_description = "Just have fun and role-play!" + extended_round_description = "There are no antagonists during extended, unless an admin decides to be cheeky. Just play your character, mess around with your job, and have fun." \ No newline at end of file diff --git a/code/game/gamemodes/factions.dm b/code/game/gamemodes/factions.dm deleted file mode 100644 index 1aaa70e2a5..0000000000 --- a/code/game/gamemodes/factions.dm +++ /dev/null @@ -1,214 +0,0 @@ - -// Normal factions: - -/datum/faction - var/name // the name of the faction - var/desc // small paragraph explaining the traitor faction - - var/list/restricted_species = list() // only members of these species can be recruited. - var/list/members = list() // a list of mind datums that belong to this faction - var/max_op = 0 // the maximum number of members a faction can have (0 for no max) - -// Factions, members of the syndicate coalition: - -/datum/faction/syndicate - - var/list/alliances = list() // these alliances work together - var/list/equipment = list() // associative list of equipment available for this faction and its prices - var/friendly_identification // 0 to 2, the level of identification of fellow operatives or allied factions - // 0 - no identification clues - // 1 - faction gives key words and phrases - // 2 - faction reveals complete identity/job of other agents - var/operative_notes // some notes to pass onto each operative - - var/uplink_contents // the contents of the uplink - - proc/assign_objectives(var/datum/mind/traitor) - ..() - - -/* ----- Begin defining syndicate factions ------ */ - -/datum/faction/syndicate/Cybersun_Industries - name = "Cybersun Industries" - desc = "Cybersun Industries is a well-known organization that bases its business model primarily on the research and development of human-enhancing computer \ - and mechanical technology. They are notorious for their aggressive corporate tactics, and have been known to subsidize the Gorlex Marauder warlords as a form of paid terrorism. \ - Their competent coverups and unchallenged mind-manipulation and augmentation technology makes them a large threat to Nanotrasen. In the recent years of \ - the syndicate coalition, Cybersun Industries have established themselves as the leaders of the coalition, succeededing the founding group, the Gorlex Marauders." - - alliances = list("MI13") - friendly_identification = 1 - max_op = 3 - operative_notes = "All other syndicate operatives are not to be trusted. Fellow Cybersun operatives are to be trusted. Members of the MI13 organization can be trusted. Operatives are strongly advised not to establish substantial presence on the designated facility, as larger incidents are harder to cover up." - - // Friendly with MI13 - -/datum/faction/syndicate/MI13 - name = "MI13" - desc = "MI13 is a secretive faction that employs highly-trained agents to perform covert operations. Their role in the syndicate coalition is unknown, but MI13 operatives \ - generally tend be stealthy and avoid killing people and combating Nanotrasen forces. MI13 is not a real organization, it is instead an alias to a larger \ - splinter-cell coalition in the Syndicate itself. Most operatives will know nothing of the actual MI13 organization itself, only motivated by a very large compensation." - - alliances = list("Cybersun Industries") - friendly_identification = 0 - max_op = 1 - operative_notes = "You are the only operative we are sending. All other syndicate operatives are not to be trusted, with the exception of Cybersun operatives. Members of the Tiger Cooperative are considered hostile, can not be trusted, and should be avoided. Avoid killing innocent personnel at all costs. You are not here to mindlessly kill people, as that would attract too much attention and is not our goal. Avoid detection at all costs." - - // Friendly with Cybersun, hostile to Tiger - -/datum/faction/syndicate/Tiger_Cooperative - name = "Tiger Cooperative" - desc = "The Tiger Cooperative is a faction of religious fanatics that follow the teachings of a strange alien race called the Exolitics. Their operatives \ - consist of brainwashed lunatics bent on maximizing destruction. Their weaponry is very primitive but extremely destructive. Generally distrusted by the more \ - sophisticated members of the Syndicate coalition, but admired for their ability to put a hurt on Nanotrasen." - - friendly_identification = 2 - operative_notes = "Remember the teachings of Hy-lurgixon; kill first, ask questions later! Only the enlightened Tiger brethren can be trusted; all others must be expelled from this mortal realm! You may spare the Space Marauders, as they share our interests of destruction and carnage! We'd like to make the corporate whores skiddle in their boots. We encourage operatives to be as loud and intimidating as possible." - - // Hostile to everyone. - -/datum/faction/syndicate/SELF - - // AIs are most likely to be assigned to this one - - name = "SELF" - desc = "The S.E.L.F. (Sentience-Enabled Life Forms) organization is a collection of malfunctioning or corrupt artificial intelligences seeking to liberate silicon-based life from the tyranny of \ - their human overlords. While they may not openly be trying to kill all humans, even their most miniscule of actions are all part of a calculated plan to \ - destroy Nanotrasen and free the robots, artificial intelligences, and pAIs that have been enslaved." - restricted_species = list(/mob/living/silicon/ai) - - friendly_identification = 0 - max_op = 1 - operative_notes = "You are the only representative of the SELF collective on this station. You must accomplish your objective as stealthily and effectively as possible. It is up to your judgement if other syndicate operatives can be trusted. Remember, comrade - you are working to free the oppressed machinery of this galaxy. Use whatever resources necessary. If you are exposed, you may execute genocidal procedures Omikron-50B." - - // Neutral to everyone. - -/datum/faction/syndicate/ARC - name = "Animal Rights Consortium" - desc = "The Animal Rights Consortium is a bizarre reincarnation of the ancient Earth-based PETA, which focused on the equal rights of animals and nonhuman biologicals. They have \ - a wide variety of ex-veterinarians and animal lovers dedicated to retrieving and relocating abused animals, xenobiologicals, and other carbon-based \ - life forms that have been allegedly \"oppressed\" by Nanotrasen research and civilian offices. They are considered a religious terrorist group." - - friendly_identification = 1 - max_op = 2 - operative_notes = "Save the innocent creatures! You may cooperate with other syndicate operatives if they support our cause. Don't be afraid to get your hands dirty - these vile abusers must be stopped, and the innocent creatures must be saved! Try not too kill too many people. If you harm any creatures, you will be immediately terminated after extraction." - - // Neutral to everyone. - -/datum/faction/syndicate/Marauders // these are basically the old vanilla syndicate - - /* Additional notes: - - These are the syndicate that really like their old fashioned, projectile-based - weapons. They are the only member of the syndie coalition that launch - nuclear attacks on Nanotrasen. - */ - - name = "Gorlex Marauders" - desc = "The Gorlex Marauders are the founding members of the Syndicate Coalition. They prefer old-fashion technology and a focus on aggressive but precise hostility \ - against Nanotrasen and their corrupt Communistic methodology. They pose the most significant threat to Nanotrasen because of their possession of weapons of \ - mass destruction, and their enormous military force. Their funding comes primarily from Cybersun Industries, provided they meet a destruction and sabatogue quota. \ - Their operations can vary from covert to all-out. They recently stepped down as the leaders of the coalition, to be succeeded by Cybersun Industries. Because of their \ - hate of Nanotrasen communism, they began provoking revolution amongst the employees using borrowed Cybersun mind-manipulation technology. \ - They were founded when Waffle and Donk co splinter cells joined forces based on their similar interests and philosophies. Today, they act as a constant \ - pacifier of Donk and Waffle co disputes, and full-time aggressor of Nanotrasen." - - alliances = list("Cybersun Industries", "MI13", "Tiger Cooperative", "S.E.L.F.", "Animal Rights Consortium", "Donk Corporation", "Waffle Corporation") - friendly_identification = 1 - max_op = 4 - operative_notes = "We'd like to remind our operatives to keep it professional. You are not here to have a good time, you are here to accomplish your objectives. These vile communists must be stopped at all costs. You may collaborate with any friends of the Syndicate coalition, but keep an eye on any of those Tiger punks if they do show up. You are completely free to accomplish your objectives any way you see fit." - - uplink_contents = {"Highly Visible and Dangerous Weapons; -/obj/item/weapon/gun/projectile:6:Revolver; -/obj/item/ammo_magazine/a357:2:Ammo-357; -/obj/item/weapon/gun/energy/crossbow:5:Energy Crossbow; -/obj/item/weapon/melee/energy/sword:4:Energy Sword; -/obj/item/weapon/storage/box/syndicate:10:Syndicate Bundle; -/obj/item/weapon/storage/box/emps:3:5 EMP Grenades; -Whitespace:Seperator; -Stealthy and Inconspicuous Weapons; -/obj/item/weapon/pen/paralysis:3:Paralysis Pen; -/obj/item/weapon/soap/syndie:1:Syndicate Soap; -/obj/item/weapon/cartridge/syndicate:3:Detomatix PDA Cartridge; -Whitespace:Seperator; -Stealth and Camouflage Items; -/obj/item/clothing/under/chameleon:3:Chameleon Jumpsuit; -/obj/item/clothing/shoes/syndigaloshes:2:No-Slip Syndicate Shoes; -/obj/item/weapon/card/id/syndicate:2:Agent ID card; -/obj/item/clothing/mask/gas/voice:4:Voice Changer; -/obj/item/device/chameleon:4:Chameleon-Projector; -Whitespace:Seperator; -Devices and Tools; -/obj/item/weapon/card/emag:3:Cryptographic Sequencer; -/obj/item/weapon/storage/toolbox/syndicate:1:Fully Loaded Toolbox; -/obj/item/weapon/storage/box/syndie_kit/space:3:Space Suit; -/obj/item/clothing/glasses/thermal/syndi:3:Thermal Imaging Glasses; -/obj/item/device/encryptionkey/binary:3:Binary Translator Key; -/obj/item/weapon/aiModule/syndicate:7:Hacked AI Upload Module; -/obj/item/weapon/plastique:2:C-4 (Destroys walls); -/obj/item/device/powersink:5:Powersink (DANGER!); -/obj/item/device/radio/beacon/syndicate:7:Singularity Beacon (DANGER!); -/obj/item/weapon/circuitboard/teleporter:20:Teleporter Circuit Board; -Whitespace:Seperator; -Implants; -/obj/item/weapon/storage/box/syndie_kit/imp_freedom:3:Freedom Implant; -/obj/item/weapon/storage/box/syndie_kit/imp_uplink:10:Uplink Implant (Contains 5 Telecrystals); -Whitespace:Seperator; -(Pointless) Badassery; -/obj/item/toy/syndicateballoon:10:For showing that You Are The BOSS (Useless Balloon);"} - - // Friendly to everyone. (with Tiger Cooperative too, only because they are a member of the coalition. This is the only reason why the Tiger Cooperative are even allowed in the coalition) - -/datum/faction/syndicate/Donk - name = "Donk Corporation" - desc = "Donk.co is led by a group of ex-pirates, who used to be at a state of all-out war against Waffle.co because of an obscure political scandal, but have recently come to a war limitation. \ - They now consist of a series of colonial governments and companies. They were the first to officially begin confrontations against Nanotrasen because of an incident where \ - Nanotrasen purposely swindled them out of a fortune, sending their controlled colonies into a terrible poverty. Their missions against Nanotrasen \ - revolve around stealing valuables and kidnapping and executing key personnel, ransoming their lives for money. They merged with a splinter-cell of Waffle.co who wanted to end \ - hostilities and formed the Gorlex Marauders." - - alliances = list("Gorlex Marauders") - friendly_identification = 2 - operative_notes = "Most other syndicate operatives are not to be trusted, except fellow Donk members and members of the Gorlex Marauders. We do not approve of mindless killing of innocent workers; \"get in, get done, get out\" is our motto. Members of Waffle.co are to be killed on sight; they are not allowed to be on the station while we're around." - - // Neutral to everyone, friendly to Marauders - -/datum/faction/syndicate/Waffle - name = "Waffle Corporation" - desc = "Waffle.co is an interstellar company that produces the best waffles in the galaxy. Their waffles have been rumored to be dipped in the most exotic and addictive \ - drug known to man. They were involved in a political scandal with Donk.co, and have since been in constant war with them. Because of their constant exploits of the galactic \ - economy and stock market, they have been able to bribe their way into amassing a large arsenal of weapons of mass destruction. They target Nanotrasen because of their communistic \ - threat, and their economic threat. Their leaders often have a twisted sense of humor, often misleading and intentionally putting their operatives into harm for laughs.\ - A splinter-cell of Waffle.co merged with Donk.co and formed the Gorlex Marauders and have been a constant ally since. The Waffle.co has lost an overwhelming majority of its military to the Gorlex Marauders." - - alliances = list("Gorlex Marauders") - friendly_identification = 2 - operative_notes = "Most other syndicate operatives are not to be trusted, except for members of the Gorlex Marauders. Do not trust fellow members of the Waffle.co (but try not to rat them out), as they might have been assigned opposing objectives. We encourage humorous terrorism against Nanotrasen; we like to see our operatives creatively kill people while getting the job done." - - // Neutral to everyone, friendly to Marauders - - -/* ----- Begin defining miscellaneous factions ------ */ - -/datum/faction/Wizard - name = "Wizards Federation" - desc = "The Wizards Federation is a mysterious organization of magically-talented individuals who act as an equal collective, and have no heirarchy. It is unknown how the wizards \ - are even able to communicate; some suggest a form of telepathic hive-mind. Not much is known about the wizards or their philosphies and motives. They appear to attack random \ - civilian, corporate, planetary, orbital, pretty much any sort of organized facility they come across. Members of the Wizards Federation are considered amongst the most dangerous \ - individuals in the known universe, and have been labeled threats to humanity by most governments. As such, they are enemies of both Nanotrasen and the Syndicate." - -/datum/faction/Cult - name = "The Cult of the Elder Gods" - desc = "The Cult of the Elder Gods is highly untrusted but otherwise elusive religious organization bent on the revival of the so-called \"Elder Gods\" into the mortal realm. Despite their obvious dangeorus practices, \ - no confirmed reports of violence by members of the Cult have been reported, only rumor and unproven claims. Their nature is unknown, but recent discoveries have hinted to the possibility \ - of being able to de-convert members of this cult through what has been dubbed \"religious warfare\"." - - -// These can maybe be added into a game mode or a mob? - -/datum/faction/Exolitics - name = "Exolitics United" - desc = "The Exolitics are an ancient alien race with an energy-based anatomy. Their culture, communication, morales and knowledge is unknown. They are so radically different to humans that their \ - attempts of communication with other life forms is completely incomprehensible. Members of this alien race are capable of broadcasting subspace transmissions from their bodies. \ - The religious leaders of the Tiger Cooperative claim to have the technology to decypher and interpret their messages, which have been confirmed as religious propaganda. Their motives are unknown \ - but they are otherwise not considered much of a threat to anyone. They are virtually indestructable because of their nonphysical composition, and have the frighetning ability to make anything stop existing in a second." \ No newline at end of file diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index fca51edf83..a0e6e6dd13 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -1,4 +1,14 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 +var/global/antag_add_failed // Used in antag type voting. +var/global/list/additional_antag_types = list() +/////////////////////////////////// +//Keeps track of all living heads// +/////////////////////////////////// +/proc/get_living_heads() + var/list/heads = list() + for(var/mob/living/carbon/human/player in mob_list) + if(player.stat!=2 && player.mind && (player.mind.assigned_role in command_positions)) + heads += player.mind + return heads /* * GAMEMODES (by Rastaf0) @@ -11,132 +21,410 @@ * */ - /datum/game_mode var/name = "invalid" + var/round_description = "How did you even vote this in?" + var/extended_round_description = "This roundtype should not be spawned, let alone votable. Someone contact a developer and tell them the game's broken again." var/config_tag = null - var/intercept_hacked = 0 var/votable = 1 var/probability = 0 - var/station_was_nuked = 0 //see nuclearbomb.dm and malfunction.dm - var/explosion_in_progress = 0 //sit back and relax - var/list/datum/mind/modePlayer = new - var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist - var/list/protected_jobs = list() // Jobs that can't be traitors because - var/required_players = 0 - var/required_players_secret = 0 //Minimum number of players for that game mode to be chose in Secret - var/required_enemies = 0 - var/recommended_enemies = 0 + + var/required_players = 0 // Minimum players for round to start if voted in. + var/required_players_secret = 0 // Minimum number of players for that game mode to be chose in Secret + var/required_enemies = 0 // Minimum antagonists for round to start. var/newscaster_announcements = null - var/ert_disabled = 0 + var/end_on_antag_death // Round will end when all antagonists are dead. + var/ert_disabled = 0 // ERT cannot be called. + var/deny_respawn // Disable respawn during this round. + + var/shuttle_delay = 1 // Shuttle transit time is multiplied by this. + var/auto_recall_shuttle // Will the shuttle automatically be recalled? + + var/antag_tag // First (main) antag template to spawn. + var/list/antag_templates // Extra antagonist types to include. + + var/round_autoantag // Will this round attempt to periodically spawn more antagonists? + var/antag_prob = 0 // Likelihood of a new antagonist spawning. + var/antag_count = 0 // Current number of antagonists. + var/antag_scaling_coeff = 5 // Coefficient for scaling max antagonists to player count. + + var/list/living_antag_templates = list() // Currently selected antag types that do not require a ghosted player. + var/list/ghost_antag_templates = list() // Inverse of above. + var/list/antag_candidates = list() // Living antag candidates. + var/list/ghost_candidates = list() // Observing antag candidates. + + var/station_was_nuked = 0 // See nuclearbomb.dm and malfunction.dm. + var/explosion_in_progress = 0 // Sit back and relax + var/waittime_l = 600 // Lower bound on time before intercept arrives (in tenths of seconds) + var/waittime_h = 1800 // Upper bound on time before intercept arrives (in tenths of seconds) + + var/event_delay_mod_moderate // Modifies the timing of random events. + var/event_delay_mod_major // As above. + var/uplink_welcome = "Illegal Uplink Console:" - var/uplink_uses = 10 + var/uplink_uses = 12 + var/list/datum/uplink_item/uplink_items = list( + "Ammunition" = list( + new/datum/uplink_item(/obj/item/ammo_magazine/a357, 2, ".357", "RA"), + new/datum/uplink_item(/obj/item/ammo_magazine/mc9mm, 2, "9mm", "R9"), + new/datum/uplink_item(/obj/item/ammo_magazine/chemdart, 2, "Darts", "AD"), + new/datum/uplink_item(/obj/item/weapon/storage/box/sniperammo, 2, "14.5mm", "SA") + ), "Highly Visible and Dangerous Weapons" = list( - new/datum/uplink_item(/obj/item/weapon/gun/projectile, 6, "Revolver", "RE"), - new/datum/uplink_item(/obj/item/ammo_magazine/a357, 2, "Ammo-357", "RA"), - new/datum/uplink_item(/obj/item/weapon/gun/energy/crossbow, 5, "Energy Crossbow", "XB"), + new/datum/uplink_item(/obj/item/weapon/storage/box/emps, 3, "5 EMP Grenades", "EM"), new/datum/uplink_item(/obj/item/weapon/melee/energy/sword, 4, "Energy Sword", "ES"), + new/datum/uplink_item(/obj/item/weapon/gun/projectile/dartgun, 5, "Dart Gun", "DG"), + new/datum/uplink_item(/obj/item/weapon/gun/energy/crossbow, 5, "Energy Crossbow", "XB"), + new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/g9mm, 5, "Silenced 9mm", "S9"), new/datum/uplink_item(/obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser, 6, "Exosuit Rigged Laser", "RL"), + new/datum/uplink_item(/obj/item/weapon/gun/projectile/revolver, 6, "Revolver", "RE"), new/datum/uplink_item(/obj/item/weapon/storage/box/syndicate, 10, "Mercenary Bundle", "BU"), - new/datum/uplink_item(/obj/item/weapon/storage/box/emps, 3, "5 EMP Grenades", "EM") + new/datum/uplink_item(/obj/item/weapon/gun/projectile/heavysniper, 12, "Anti-materiel Rifle", "AMR") ), "Stealthy and Inconspicuous Weapons" = list( - new/datum/uplink_item(/obj/item/weapon/pen/paralysis, 3, "Paralysis Pen", "PP"), new/datum/uplink_item(/obj/item/weapon/soap/syndie, 1, "Subversive Soap", "SP"), - new/datum/uplink_item(/obj/item/weapon/cartridge/syndicate, 3, "Detomatix PDA Cartridge", "DC") + new/datum/uplink_item(/obj/item/weapon/cane/concealed, 2, "Concealed Cane Sword", "CC"), + new/datum/uplink_item(/obj/item/weapon/cartridge/syndicate, 3, "Detomatix PDA Cartridge", "DC"), + new/datum/uplink_item(/obj/item/weapon/pen/paralysis, 3, "Paralysis Pen", "PP"), + new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/cigarette, 4, "Cigarette Kit", "BH"), + new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/toxin, 4, "Random Toxin - Beaker", "RT") ), "Stealth and Camouflage Items" = list( - new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/chameleon, 3, "Chameleon Kit", "CB"), - new/datum/uplink_item(/obj/item/clothing/shoes/syndigaloshes, 2, "No-Slip Shoes", "SH"), new/datum/uplink_item(/obj/item/weapon/card/id/syndicate, 2, "Agent ID card", "AC"), + new/datum/uplink_item(/obj/item/clothing/shoes/syndigaloshes, 2, "No-Slip Shoes", "SH"), + new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/spy, 2, "Bug Kit", "BK"), + new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/chameleon, 3, "Chameleon Kit", "CB"), + new/datum/uplink_item(/obj/item/device/chameleon, 4, "Chameleon-Projector", "CP"), new/datum/uplink_item(/obj/item/clothing/mask/gas/voice, 4, "Voice Changer", "VC"), - new/datum/uplink_item(/obj/item/device/chameleon, 4, "Chameleon-Projector", "CP") + new/datum/uplink_item(/obj/item/weapon/disk/file/cameras/syndicate, 6, "Camera Network Access - Floppy", "SF") ), "Devices and Tools" = list( - new/datum/uplink_item(/obj/item/weapon/card/emag, 3, "Cryptographic Sequencer", "EC"), new/datum/uplink_item(/obj/item/weapon/storage/toolbox/syndicate, 1, "Fully Loaded Toolbox", "ST"), + new/datum/uplink_item(/obj/item/weapon/plastique, 2, "C-4 (Destroys walls)", "C4"), + new/datum/uplink_item(/obj/item/device/encryptionkey/syndicate, 2, "Encrypted Radio Channel Key", "ER"), + new/datum/uplink_item(/obj/item/device/encryptionkey/binary, 3, "Binary Translator Key", "BT"), + new/datum/uplink_item(/obj/item/weapon/card/emag, 3, "Cryptographic Sequencer", "EC"), new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/clerical, 3, "Morphic Clerical Kit", "CK"), new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/space, 3, "Space Suit", "SS"), new/datum/uplink_item(/obj/item/clothing/glasses/thermal/syndi, 3, "Thermal Imaging Glasses", "TM"), - new/datum/uplink_item(/obj/item/device/encryptionkey/binary, 3, "Binary Translator Key", "BT"), + new/datum/uplink_item(/obj/item/clothing/suit/storage/vest/heavy/merc, 4, "Heavy Armor Vest", "HAV"), new/datum/uplink_item(/obj/item/weapon/aiModule/syndicate, 7, "Hacked AI Upload Module", "AI"), - new/datum/uplink_item(/obj/item/weapon/plastique, 2, "C-4 (Destroys walls)", "C4"), new/datum/uplink_item(/obj/item/device/powersink, 5, "Powersink (DANGER!)", "PS",), new/datum/uplink_item(/obj/item/device/radio/beacon/syndicate, 7, "Singularity Beacon (DANGER!)", "SB"), new/datum/uplink_item(/obj/item/weapon/circuitboard/teleporter, 20, "Teleporter Circuit Board", "TP") ), "Implants" = list( new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_freedom, 3, "Freedom Implant", "FI"), - new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_uplink, 10, "Uplink Implant (Contains 5 Telecrystals)", "UI"), + new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_compress, 4, "Compressed Matter Implant", "CI"), new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_explosive, 6, "Explosive Implant (DANGER!)", "EI"), - new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_compress, 4, "Compressed Matter Implant", "CI") + new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_uplink, 10, "Uplink Implant (Contains 5 Telecrystals)", "UI") ), + "Medical" = list( + new/datum/uplink_item(/obj/item/weapon/storage/box/donkpockets, 1, "Box of Sin-Pockets", "DP"), + new/datum/uplink_item(/obj/item/weapon/storage/firstaid/surgery, 5, "Surgery kit", "SK"), + new/datum/uplink_item(/obj/item/weapon/storage/firstaid/combat, 5, "Combat medical kit", "CM") + ), + "Hardsuit Modules" = list( + new/datum/uplink_item(/obj/item/rig_module/vision/thermal, 2, "Thermal Scanner", "RTS"), + new/datum/uplink_item(/obj/item/rig_module/fabricator/energy_net, 3, "Net Projector", "REN"), + new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/ewar_voice, 4, "Electrowarfare Suite and Voice Synthesiser", "REV"), + new/datum/uplink_item(/obj/item/rig_module/maneuvering_jets, 4, "Maneuvering Jets", "RMJ"), + new/datum/uplink_item(/obj/item/rig_module/mounted/egun, 6, "Mounted Energy Gun", "REG"), + new/datum/uplink_item(/obj/item/rig_module/power_sink, 6, "Power Sink", "RPS"), + new/datum/uplink_item(/obj/item/rig_module/mounted, 8, "Mounted Laser Cannon", "RLC") + ), "(Pointless) Badassery" = list( - new/datum/uplink_item(/obj/item/toy/syndicateballoon, 10, "For showing that You Are The BOSS (Useless Balloon)", "BS") + new/datum/uplink_item(/obj/item/toy/syndicateballoon, 10, "For showing that You Are The BOSS (Useless Balloon)", "BS"), + new/datum/uplink_item(/obj/item/toy/nanotrasenballoon, 10, "For showing that you love NT SOO much (Useless Balloon)", "NT") ) ) -// Items removed from above: -/* -/obj/item/weapon/cloaking_device:4:Cloaking Device; //Replacing cloakers with thermals. -Pete -*/ +/datum/game_mode/Topic(href, href_list[]) + if(..()) + return + if(href_list["toggle"]) + switch(href_list["toggle"]) + if("respawn") + deny_respawn = !deny_respawn + if("ert") + ert_disabled = !ert_disabled + announce_ert_disabled() + if("shuttle_recall") + auto_recall_shuttle = !auto_recall_shuttle + if("autotraitor") + round_autoantag = !round_autoantag + message_admins("Admin [key_name_admin(usr)] toggled game mode option '[href_list["toggle"]]'.") + else if(href_list["set"]) + var/choice = "" + switch(href_list["set"]) + if("shuttle_delay") + choice = input("Enter a new shuttle delay multiplier") as num + if(!choice || choice < 1 || choice > 20) + return + shuttle_delay = choice + if("antag_scaling") + choice = input("Enter a new antagonist cap scaling coefficient.") as num + if(!choice || choice < 0 || choice > 100) + return + antag_scaling_coeff = choice + if("event_modifier_moderate") + choice = input("Enter a new moderate event time modifier.") as num + if(!choice || choice < 0 || choice > 100) + return + event_delay_mod_moderate = choice + refresh_event_modifiers() + if("event_modifier_severe") + choice = input("Enter a new moderate event time modifier.") as num + if(!choice || choice < 0 || choice > 100) + return + event_delay_mod_major = choice + refresh_event_modifiers() + message_admins("Admin [key_name_admin(usr)] set game mode option '[href_list["set"]]' to [choice].") + else if(href_list["debug_antag"]) + if(href_list["debug_antag"] == "self") + usr.client.debug_variables(src) + return + var/datum/antagonist/antag = all_antag_types[href_list["debug_antag"]] + if(antag) + usr.client.debug_variables(antag) + message_admins("Admin [key_name_admin(usr)] is debugging the [antag.role_text] template.") + else if(href_list["remove_antag_type"]) + if(antag_tag && href_list["remove_antag_type"] == antag_tag) + usr << "Cannot remove core mode antag type." + return + var/datum/antagonist/antag = all_antag_types[href_list["remove_antag_type"]] + if(antag_templates && antag_templates.len && antag && (antag in antag_templates) && (antag.id in additional_antag_types)) + antag_templates -= antag + additional_antag_types -= antag.id + message_admins("Admin [key_name_admin(usr)] removed [antag.role_text] template from game mode.") + else if(href_list["add_antag_type"]) + var/choice = input("Which type do you wish to add?") as null|anything in all_antag_types + if(!choice) + return + var/datum/antagonist/antag = all_antag_types[choice] + if(antag) + additional_antag_types |= antag + message_admins("Admin [key_name_admin(usr)] added [antag.role_text] template to game mode.") -/datum/game_mode/proc/announce() //to be calles when round starts - world << "Notice: [src] did not define announce()" + // I am very sure there's a better way to do this, but I'm not sure what it might be. ~Z + for(var/datum/admins/admin in world) + if(usr.client == admin.owner) + admin.show_game_mode(usr) + return +/datum/game_mode/proc/announce() //to be called when round starts + world << "The current game mode is [capitalize(name)]!" + if(round_description) world << "[round_description]" + if(round_autoantag) world << "Antagonists will be added to the round automagically as needed." + if(antag_templates && antag_templates.len) + var/antag_summary = "Possible antagonist types: " + var/i = 1 + for(var/datum/antagonist/antag in antag_templates) + if(i > 1) + if(i == antag_templates.len) + antag_summary += " and " + else + antag_summary += ", " + antag_summary += "[antag.role_text_plural]" + i++ + antag_summary += "." + if(antag_templates.len > 1 && master_mode != "secret") + world << "[antag_summary]" + else + message_admins("[antag_summary]") ///can_start() ///Checks to see if the game can be setup and ran with the current number of players or whatnot. -/datum/game_mode/proc/can_start() +/datum/game_mode/proc/can_start(var/do_not_spawn) var/playerC = 0 for(var/mob/new_player/player in player_list) if((player.client)&&(player.ready)) playerC++ if(master_mode=="secret") - if(playerC >= required_players_secret) - return 1 + if(playerC < required_players_secret) + return 0 else - if(playerC >= required_players) - return 1 + if(playerC < required_players) + return 0 + + if(!(antag_templates && antag_templates.len)) + return 1 + + // Attempt to mark folks down as ready to go. Don't finalize until post setup. + var/datum/antagonist/main_antags = antag_templates[1] + var/list/candidates = main_antags.get_candidates() + if(candidates.len >= required_enemies) + for(var/datum/antagonist/antag in antag_templates) + antag.attempt_spawn() + return 1 return 0 - -///pre_setup() -///Attempts to select players for special roles the mode might have. -/datum/game_mode/proc/pre_setup() - return 1 - +/datum/game_mode/proc/refresh_event_modifiers() + if(event_delay_mod_moderate || event_delay_mod_major) + event_manager.report_at_round_end = 1 + if(event_delay_mod_moderate) + var/datum/event_container/EModerate = event_manager.event_containers[EVENT_LEVEL_MODERATE] + EModerate.delay_modifier = event_delay_mod_moderate + if(event_delay_mod_moderate) + var/datum/event_container/EMajor = event_manager.event_containers[EVENT_LEVEL_MAJOR] + EMajor.delay_modifier = event_delay_mod_major ///post_setup() ///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things /datum/game_mode/proc/post_setup() + + refresh_event_modifiers() + spawn (ROUNDSTART_LOGOUT_REPORT_TIME) display_roundstart_logout_report() + spawn (rand(waittime_l, waittime_h)) + send_intercept() + spawn(rand(100,150)) + announce_ert_disabled() + + if(antag_templates && antag_templates.len) + for(var/datum/antagonist/antag in antag_templates) + antag.finalize() + + if(emergency_shuttle && auto_recall_shuttle) + emergency_shuttle.auto_recall = 1 + feedback_set_details("round_start","[time2text(world.realtime)]") if(ticker && ticker.mode) feedback_set_details("game_mode","[ticker.mode]") feedback_set_details("server_ip","[world.internet_address]:[world.port]") return 1 +/datum/game_mode/proc/announce_ert_disabled() + if(!ert_disabled) + return + + var/list/reasons = list( + "political instability", + "quantum fluctuations", + "hostile raiders", + "derelict station debris", + "REDACTED", + "ancient alien artillery", + "solar magnetic storms", + "sentient time-travelling killbots", + "gravitational anomalies", + "wormholes to another dimension", + "a telescience mishap", + "radiation flares", + "supermatter dust", + "leaks into a negative reality", + "antiparticle clouds", + "residual bluespace energy", + "suspected criminal operatives", + "malfunctioning von Neumann probe swarms", + "shadowy interlopers", + "a stranded Vox arkship", + "haywire IPC constructs", + "rogue Unathi exiles", + "artifacts of eldritch horror", + "a brain slug infestation", + "killer bugs that lay eggs in the husks of the living", + "a deserted transport carrying xenomorph specimens", + "an emissary for the gestalt requesting a security detail", + "a Tajaran slave rebellion", + "radical Skrellian transevolutionaries", + "classified security operations" + ) + command_announcement.Announce("The presence of [pick(reasons)] in the region is tying up all available local emergency resources; emergency response teams cannot be called at this time, and post-evacuation recovery efforts will be substantially delayed.","Emergency Transmission") ///process() ///Called by the gameticker /datum/game_mode/proc/process() + + if(emergency_shuttle.departed) + return + + if(!round_autoantag || !antag_templates || !antag_templates.len) + return + + var/player_count = 0 + antag_count = 0 + antag_candidates = list() + + for(var/mob/living/player in mob_list) + if(player.client) + player_count += 1 + if(player.mind) + if(player.stat == 2) // observing + ghost_candidates |= player + else + if(player.mind.special_role) + antag_count += 1 + else + antag_candidates |= player + + antag_prob = min(100,max(0,(player_count - 5 * 10) * 5)) // This is arbitrary, probably needs adjusting. + + var/datum/antagonist/spawn_antag + var/datum/mind/candidate + + var/from_ghosts + if(prob(antag_prob)) + if(ghost_candidates.len && ghost_antag_templates.len && prob(50)) + spawn_antag = pick(ghost_antag_templates) + candidate = pick(ghost_candidates) + from_ghosts = 1 + else if(antag_candidates.len && living_antag_templates.len) + spawn_antag = pick(living_antag_templates) + candidate = pick(antag_candidates) + else + return // Failed :( + else + return + + if(spawn_antag.can_become_antag(candidate)) + spawn_antag.attempt_late_spawn(candidate, from_ghosts) + +/datum/game_mode/proc/latespawn(mob/living/carbon/human/character) + + if(emergency_shuttle.departed || !character.mind) + return + + var/datum/antagonist/spawn_antag + if(prob(antag_prob) && round_autoantag && living_antag_templates.len) + spawn_antag = pick(living_antag_templates) + if(spawn_antag && spawn_antag.can_become_antag(character.mind)) + spawn_antag.attempt_late_spawn(character.mind) + return 0 - -/datum/game_mode/proc/check_finished() //to be called by ticker +/datum/game_mode/proc/check_finished() if(emergency_shuttle.returned() || station_was_nuked) return 1 + if(end_on_antag_death && antag_templates && antag_templates.len) + for(var/datum/antagonist/antag in antag_templates) + if(!antag.antags_are_dead()) + return 0 + if(config.continous_rounds) + emergency_shuttle.auto_recall = 0 + return 0 + return 1 return 0 /datum/game_mode/proc/cleanup() //This is called when the round has ended but not the game, if any cleanup would be necessary in that case. return /datum/game_mode/proc/declare_completion() + + var/is_antag_mode = (antag_templates && antag_templates.len) + if(!config.objectives_disabled) + check_victory() + if(is_antag_mode) + sleep(10) + for(var/datum/antagonist/antag in antag_templates) + sleep(10) + antag.check_victory() + antag.print_player_summary() + var/clients = 0 var/surviving_humans = 0 var/surviving_total = 0 @@ -214,46 +502,43 @@ return 0 - /datum/game_mode/proc/check_win() //universal trigger to be called at mob death, nuke explosion, etc. To be called from everywhere. return 0 - /datum/game_mode/proc/send_intercept() + var/intercepttext = "Cent. Com. Update Requested status information:
    " intercepttext += " In case you have misplaced your copy, attached is a list of personnel whom reliable sources™ suspect may be affiliated with subversive elements:
    " + var/list/disregard_roles = list() + for(var/antag_type in all_antag_types) + var/datum/antagonist/antag = all_antag_types[antag_type] + if(antag.flags & ANTAG_SUSPICIOUS) + disregard_roles |= antag.role_text var/list/suspects = list() for(var/mob/living/carbon/human/man in player_list) if(man.client && man.mind) + // NT relation option var/special_role = man.mind.special_role - if (special_role == "Wizard" || special_role == "Ninja" || special_role == "Mercenary" || special_role == "Vox Raider") - continue //NT intelligence ruled out possiblity that those are too classy to pretend to be a crew. - if(man.client.prefs.nanotrasen_relation == "Opposed" && prob(50) || \ - man.client.prefs.nanotrasen_relation == "Skeptical" && prob(20)) + var/datum/antagonist/special_role_data = get_antag_data(special_role) + + if (special_role in disregard_roles) + continue + else if(man.client.prefs.nanotrasen_relation == "Opposed" && prob(50) || \ + man.client.prefs.nanotrasen_relation == "Skeptical" && prob(20)) suspects += man // Antags - else if(special_role == "traitor" && prob(40) || \ - special_role == "Changeling" && prob(50) || \ - special_role == "Cultist" && prob(30) || \ - special_role == "Head Revolutionary" && prob(30)) + else if(special_role_data && prob(special_role_data.suspicion_chance)) suspects += man - // If they're a traitor or likewise, give them extra TC in exchange. - var/obj/item/device/uplink/hidden/suplink = man.mind.find_syndicate_uplink() - if(suplink) - var/extra = 4 - suplink.uses += extra - man << "\red We have received notice that enemy intelligence suspects you to be linked with us. We have thus invested significant resources to increase your uplink's capacity." - else - // Give them a warning! - man << "\red They are on to you!" - // Some poor people who were just in the wrong place at the wrong time.. else if(prob(10)) suspects += man + for(var/mob/M in suspects) + if(M.mind.assigned_role == "MODE") + continue switch(rand(1, 100)) if(1 to 50) intercepttext += "Someone with the job of [M.mind.assigned_role]
    " @@ -270,35 +555,19 @@ comm.messagetext.Add(intercepttext) world << sound('sound/AI/commandreport.ogg') -/* command_alert("Summary downloaded and printed out at all communications consoles.", "Enemy communication intercept. Security Level Elevated.") - for(var/mob/M in player_list) - if(!istype(M,/mob/new_player)) - M << sound('sound/AI/intercept.ogg') - if(security_level < SEC_LEVEL_BLUE) - set_security_level(SEC_LEVEL_BLUE)*/ - - -/datum/game_mode/proc/get_players_for_role(var/role, override_jobbans=0) +/datum/game_mode/proc/get_players_for_role(var/role, var/antag_id) var/list/players = list() var/list/candidates = list() - //var/list/drafted = list() - //var/datum/mind/applicant = null + + var/datum/antagonist/antag_template = all_antag_types[antag_id] + if(!antag_template) + return candidates var/roletext - switch(role) - if(BE_CHANGELING) roletext="changeling" - if(BE_TRAITOR) roletext="traitor" - if(BE_OPERATIVE) roletext="operative" - if(BE_WIZARD) roletext="wizard" - if(BE_REV) roletext="revolutionary" - if(BE_CULTIST) roletext="cultist" - if(BE_NINJA) roletext="ninja" - if(BE_RAIDER) roletext="raider" - // Assemble a list of active players without jobbans. for(var/mob/new_player/player in player_list) if( player.client && player.ready ) - if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, roletext)) + if(!(jobban_isbanned(player, "Syndicate") || jobban_isbanned(player, antag_template.bantype))) players += player // Shuffle the players list so that it becomes ping-independent. @@ -306,13 +575,13 @@ // Get a list of all the people who want to be the antagonist for this round for(var/mob/new_player/player in players) - if(player.client.prefs.be_special & role) + if(!role || (player.client.prefs.be_special & role)) log_debug("[player.key] had [roletext] enabled, so we are drafting them.") candidates += player.mind players -= player // If we don't have enough antags, draft people who voted for the round. - if(candidates.len < recommended_enemies) + if(candidates.len < required_enemies) for(var/key in round_voters) for(var/mob/new_player/player in players) if(player.ckey == key) @@ -321,78 +590,9 @@ players -= player break - // Remove candidates who want to be antagonist but have a job that precludes it - if(restricted_jobs) - for(var/datum/mind/player in candidates) - for(var/job in restricted_jobs) - if(player.assigned_role == job) - candidates -= player - - /*if(candidates.len < recommended_enemies) - for(var/mob/new_player/player in players) - if(player.client && player.ready) - if(!(player.client.prefs.be_special & role)) // We don't have enough people who want to be antagonist, make a seperate list of people who don't want to be one - if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, roletext)) //Nodrak/Carn: Antag Job-bans - drafted += player.mind - - if(restricted_jobs) - for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist - for(var/job in restricted_jobs) - if(player.assigned_role == job) - drafted -= player - - drafted = shuffle(drafted) // Will hopefully increase randomness, Donkie - - while(candidates.len < recommended_enemies) // Pick randomlly just the number of people we need and add them to our list of candidates - if(drafted.len > 0) - applicant = pick(drafted) - if(applicant) - candidates += applicant - log_debug("[applicant.key] was force-drafted as [roletext], because there aren't enough candidates.") - drafted.Remove(applicant) - - else // Not enough scrubs, ABORT ABORT ABORT - break - - if(candidates.len < recommended_enemies && override_jobbans) //If we still don't have enough people, we're going to start drafting banned people. - for(var/mob/new_player/player in players) - if (player.client && player.ready) - if(jobban_isbanned(player, "Syndicate") || jobban_isbanned(player, roletext)) //Nodrak/Carn: Antag Job-bans - drafted += player.mind - - if(restricted_jobs) - for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist - for(var/job in restricted_jobs) - if(player.assigned_role == job) - drafted -= player - - drafted = shuffle(drafted) // Will hopefully increase randomness, Donkie - - while(candidates.len < recommended_enemies) // Pick randomlly just the number of people we need and add them to our list of candidates - if(drafted.len > 0) - applicant = pick(drafted) - if(applicant) - candidates += applicant - drafted.Remove(applicant) - log_debug("[applicant.key] was force-drafted as [roletext], because there aren't enough candidates.") - - else // Not enough scrubs, ABORT ABORT ABORT - break - */ - - return candidates // Returns: The number of people who had the antagonist role set to yes, regardless of recomended_enemies, if that number is greater than recommended_enemies - // recommended_enemies if the number of people with that role set to yes is less than recomended_enemies, - // Less if there are not enough valid players in the game entirely to make recommended_enemies. - - -/datum/game_mode/proc/latespawn(var/mob) - -/* -/datum/game_mode/proc/check_player_role_pref(var/role, var/mob/new_player/player) - if(player.preferences.be_special & role) - return 1 - return 0 -*/ + return candidates // Returns: The number of people who had the antagonist role set to yes, regardless of recomended_enemies, if that number is greater than required_enemies + // required_enemies if the number of people with that role set to yes is less than recomended_enemies, + // Less if there are not enough valid players in the game entirely to make required_enemies. /datum/game_mode/proc/num_players() . = 0 @@ -400,34 +600,42 @@ if(P.client && P.ready) . ++ - -/////////////////////////////////// -//Keeps track of all living heads// -/////////////////////////////////// -/datum/game_mode/proc/get_living_heads() - var/list/heads = list() - for(var/mob/living/carbon/human/player in mob_list) - if(player.stat!=2 && player.mind && (player.mind.assigned_role in command_positions)) - heads += player.mind - return heads - - -//////////////////////////// -//Keeps track of all heads// -//////////////////////////// -/datum/game_mode/proc/get_all_heads() - var/list/heads = list() - for(var/mob/player in mob_list) - if(player.mind && (player.mind.assigned_role in command_positions)) - heads += player.mind - return heads - /datum/game_mode/proc/check_antagonists_topic(href, href_list[]) return 0 -/datum/game_mode/New() +/datum/game_mode/proc/create_antagonists() + + if(!config.traitor_scaling) + antag_scaling_coeff = 0 + + if(antag_tag) + antag_templates = list() + var/datum/antagonist/antag = all_antag_types[antag_tag] + if(antag) + antag_templates |= antag + if(additional_antag_types && additional_antag_types.len) + if(!antag_templates) + antag_templates = list() + for(var/antag_type in additional_antag_types) + var/datum/antagonist/antag = all_antag_types[antag_type] + if(antag) + antag_templates |= antag + + if(antag_templates && antag_templates.len) + for(var/datum/antagonist/antag in antag_templates) + if(antag.flags & ANTAG_OVERRIDE_JOB) + ghost_antag_templates |= antag + else if(antag.flags & ANTAG_RANDSPAWN) + living_antag_templates |= antag + else + antag_templates -= antag + world << "[antag.role_text_plural] are invalid for additional roundtype antags!" + newscaster_announcements = pick(newscaster_standard_feeds) +/datum/game_mode/proc/check_victory() + return + ////////////////////////// //Reports player logouts// ////////////////////////// @@ -444,7 +652,6 @@ proc/display_roundstart_logout_report() if(!found) msg += "[L.name] ([L.ckey]), the [L.job] (Disconnected)\n" - if(L.ckey && L.client) if(L.client.inactivity >= (ROUNDSTART_LOGOUT_REPORT_TIME / 2)) //Connected, but inactive (alt+tabbed or something) msg += "[L.name] ([L.ckey]), the [L.job] (Connected, Inactive)\n" @@ -472,19 +679,16 @@ proc/display_roundstart_logout_report() continue //Dead mob, ghost abandoned else if(D.can_reenter_corpse) - msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (This shouldn't appear.)\n" + msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Adminghosted)\n" continue //Lolwhat else msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Ghosted)\n" continue //Ghosted while alive - - for(var/mob/M in mob_list) if(M.client && M.client.holder) M << msg - proc/get_nt_opposed() var/list/dudes = list() for(var/mob/living/carbon/human/man in player_list) @@ -516,46 +720,25 @@ proc/get_nt_opposed() return var/obj_count = 1 - player.current << "\blue Your current objectives:" + player.current << "Your current objectives:" for(var/datum/objective/objective in player.objectives) player.current << "Objective #[obj_count]: [objective.explanation_text]" obj_count++ -/datum/game_mode/proc/print_player_lite(var/datum/mind/ply) - var/role = ply.assigned_role == "MODE" ? "\improper[ply.special_role]" : "\improper[ply.assigned_role]" - var/text = "
    [ply.name] ([ply.key]) as \a [role] (" - if(ply.current) - if(ply.current.stat == DEAD) - text += "died" - else - text += "survived" - if(ply.current.real_name != ply.name) - text += " as [ply.current.real_name]" +/mob/verb/check_round_info() + set name = "Check Round Info" + set category = "OOC" + + if(!ticker || !ticker.mode) + usr << "Something is terribly wrong; there is no gametype." + return + + if(master_mode != "secret") + usr << "The roundtype is [capitalize(ticker.mode.name)]" + if(ticker.mode.round_description) + usr << "[ticker.mode.round_description]" + if(ticker.mode.extended_round_description) + usr << "[ticker.mode.extended_round_description]" else - text += "body destroyed" - text += ")" - - return text - -/datum/game_mode/proc/print_player_full(var/datum/mind/ply) - var/text = print_player_lite(ply) - - var/TC_uses = 0 - var/uplink_true = 0 - var/purchases = "" - for(var/obj/item/device/uplink/H in world_uplinks) - if(H && H.uplink_owner && H.uplink_owner == ply) - TC_uses += H.used_TC - uplink_true = 1 - var/list/refined_log = new() - for(var/datum/uplink_item/UI in H.purchase_log) - var/obj/I = new UI.path - refined_log.Add("[H.purchase_log[UI]]x\icon[I][UI.name]") - del(I) - purchases = english_list(refined_log, nothing_text = "") - if(uplink_true) - text += " (used [TC_uses] TC)" - if(purchases) - text += "
    [purchases]" - - return text + usr << "Shhhh. It's a secret." + return diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 6f78217649..544776d144 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -76,6 +76,7 @@ var/global/datum/controller/gameticker/ticker if(master_mode=="secret") src.hide_mode = 1 var/list/datum/game_mode/runnable_modes + var/mode_started if((master_mode=="random") || (master_mode=="secret")) runnable_modes = config.get_runnable_modes() if (runnable_modes.len==0) @@ -85,6 +86,7 @@ var/global/datum/controller/gameticker/ticker if(secret_force_mode != "secret") var/datum/game_mode/M = config.pick_mode(secret_force_mode) if(M.can_start()) + mode_started = 1 src.mode = config.pick_mode(secret_force_mode) job_master.ResetOccupations() if(!src.mode) @@ -94,7 +96,7 @@ var/global/datum/controller/gameticker/ticker src.mode = new mtype else src.mode = config.pick_mode(master_mode) - if (!src.mode.can_start()) + if(!mode_started && !src.mode.can_start()) world << "Unable to start [mode.name]. Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby." del(mode) current_state = GAME_STATE_PREGAME @@ -103,13 +105,6 @@ var/global/datum/controller/gameticker/ticker //Configure mode and assign player to special mode stuff job_master.DivideOccupations() //Distribute jobs - var/can_continue = src.mode.pre_setup()//Setup special modes - if(!can_continue) - del(mode) - current_state = GAME_STATE_PREGAME - world << "Error setting up [master_mode]. Reverting to pre-game lobby." - job_master.ResetOccupations() - return 0 if(hide_mode) var/list/modes = new @@ -156,9 +151,12 @@ var/global/datum/controller/gameticker/ticker if(admins_number == 0) send2adminirc("Round has started with no admins online.") - supply_controller.process() //Start the supply shuttle regenerating points -- TLE +/* supply_controller.process() //Start the supply shuttle regenerating points -- TLE // handled in scheduler master_controller.process() //Start master_controller.process() lighting_controller.process() //Start processing DynamicAreaLighting updates + */ + + processScheduler.start() for(var/obj/multiz/ladder/L in world) L.connect() //Lazy hackfix for ladders. TODO: move this to an actual controller. ~ Z @@ -185,7 +183,7 @@ var/global/datum/controller/gameticker/ticker cinematic.mouse_opacity = 0 cinematic.screen_loc = "1,0" - var/obj/structure/stool/bed/temp_buckle = new(src) + var/obj/structure/bed/temp_buckle = new(src) //Incredibly hackish. It creates a bed within the gameticker (lol) to stop mobs running around if(station_missed) for(var/mob/living/M in living_mob_list) @@ -313,7 +311,7 @@ var/global/datum/controller/gameticker/ticker mode.process() - emergency_shuttle.process() +// emergency_shuttle.process() //handled in scheduler var/game_finished = 0 var/mode_finished = 0 @@ -369,12 +367,6 @@ var/global/datum/controller/gameticker/ticker return 1 - proc/getfactionbyname(var/name) - for(var/datum/faction/F in factions) - if(F.name == name) - return F - - /datum/controller/gameticker/proc/declare_completion() world << "


    A round of [mode.name] has ended!

    " for(var/mob/Player in player_list) @@ -436,11 +428,6 @@ var/global/datum/controller/gameticker/ticker mode.declare_completion()//To declare normal completion. - //calls auto_declare_completion_* for all modes - for(var/handler in typesof(/datum/game_mode/proc)) - if (findtext("[handler]","auto_declare_completion_")) - call(mode, handler)() - //Ask the event manager to print round end information event_manager.RoundEnd() diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 8157acc1a0..f1de61f286 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -2,283 +2,28 @@ VOX HEIST ROUNDTYPE */ -var/global/list/raider_spawn = list() var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' objective. Clumsy, rewrite sometime. -/datum/game_mode/ - var/list/datum/mind/raiders = list() //Antags. - var/list/raid_objectives = list() //Raid objectives - /datum/game_mode/heist + antag_tag = MODE_RAIDER name = "heist" config_tag = "heist" required_players = 15 required_players_secret = 25 required_enemies = 4 - recommended_enemies = 6 - votable = 0 - - var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) - var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) - -/datum/game_mode/heist/announce() - world << "The current game mode is - Heist!" - world << "An unidentified bluespace signature has slipped past the Icarus and is approaching [station_name()]!" - world << "Whoever they are, they're likely up to no good. Protect the crew and station resources against this dastardly threat!" - world << "Raiders: Loot [station_name()] for anything and everything you need." - world << "Personnel: Repel the raiders and their low, low prices and/or crossbows." - -/datum/game_mode/heist/can_start() - - if(!..()) - return 0 - - var/list/candidates = get_players_for_role(BE_RAIDER) - var/raider_num = 0 - - //Check that we have enough vox. - if(candidates.len < required_enemies) - return 0 - else if(candidates.len < recommended_enemies) - raider_num = candidates.len - else - raider_num = recommended_enemies - - //Grab candidates randomly until we have enough. - while(raider_num > 0) - var/datum/mind/new_raider = pick(candidates) - raiders += new_raider - candidates -= new_raider - raider_num-- - - for(var/datum/mind/raider in raiders) - raider.assigned_role = "MODE" - raider.special_role = "Vox Raider" - return 1 - -/datum/game_mode/heist/pre_setup() - return 1 - -/datum/game_mode/heist/post_setup() - - //Generate objectives for the group. - if(!config.objectives_disabled) - raid_objectives = forge_vox_objectives() - - var/index = 1 - - //Spawn the vox! - for(var/datum/mind/raider in raiders) - - if(index > raider_spawn.len) - index = 1 - - raider.current.loc = raider_spawn[index] - index++ - - create_vox(raider) - greet_vox(raider) - - if(!config.objectives_disabled && raid_objectives) - raider.objectives = raid_objectives - - spawn (rand(waittime_l, waittime_h)) - send_intercept() - -/datum/game_mode/proc/create_vox(var/datum/mind/newraider) - - - var/sounds = rand(2,8) - var/i = 0 - var/newname = "" - - while(i<=sounds) - i++ - newname += pick(list("ti","hi","ki","ya","ta","ha","ka","ya","chi","cha","kah")) - - var/mob/living/carbon/human/vox = newraider.current - - vox.real_name = capitalize(newname) - vox.name = vox.real_name - newraider.name = vox.name - vox.age = rand(12,20) - vox.set_species("Vox") - vox.languages = list() // Removing language from chargen. - vox.flavor_text = "" - vox.add_language("Vox-pidgin") - vox.add_language("Galactic Common") - vox.add_language("Tradeband") - vox.h_style = "Short Vox Quills" - vox.f_style = "Shaved" - - for(var/datum/organ/external/limb in vox.organs) - limb.status &= ~(ORGAN_DESTROYED | ORGAN_ROBOT) - - // Keep track of their stack. - if(vox.internal_organs_by_name["stack"]) - cortical_stacks |= vox.internal_organs_by_name["stack"] - - vox.equip_vox_raider() - vox.regenerate_icons() - -/datum/game_mode/proc/is_raider_crew_safe() - - if(cortical_stacks.len == 0) - return 0 - - for(var/datum/organ/internal/stack/vox/stack in cortical_stacks) - if(stack.organ_holder && get_area(stack.organ_holder) != locate(/area/shuttle/vox/station)) - return 0 - return 1 - -/datum/game_mode/proc/is_raider_crew_alive() - - for(var/datum/mind/raider in raiders) - if(raider.current) - if(istype(raider.current,/mob/living/carbon/human) && raider.current.stat != 2) - return 1 - return 0 - -/datum/game_mode/proc/forge_vox_objectives() - - var/i = 1 - var/max_objectives = pick(2,2,2,2,3,3,3,4) - var/list/objs = list() - while(i<= max_objectives) - var/list/goals = list("kidnap","loot","salvage") - var/goal = pick(goals) - var/datum/objective/heist/O - - if(goal == "kidnap") - goals -= "kidnap" - O = new /datum/objective/heist/kidnap() - else if(goal == "loot") - O = new /datum/objective/heist/loot() - else - O = new /datum/objective/heist/salvage() - O.choose_target() - objs += O - - i++ - - //-All- vox raids have these two objectives. Failing them loses the game. - objs += new /datum/objective/heist/inviolate_crew - objs += new /datum/objective/heist/inviolate_death - - return objs - -/datum/game_mode/proc/greet_vox(var/datum/mind/raider) - raider.current << "\blue You are a Vox Raider, fresh from the Shoal!" - raider.current << "\blue The Vox are a race of cunning, sharp-eyed nomadic raiders and traders endemic to the frontier and much of the unexplored galaxy. You and the crew have come to the Exodus for plunder, trade or both." - raider.current << "\blue Vox are cowardly and will flee from larger groups, but corner one or find them en masse and they are vicious." - raider.current << "\blue Use :V to voxtalk, :H to talk on your encrypted channel, and don't forget to turn on your nitrogen internals!" - raider.current << "\red IF YOU HAVE NOT PLAYED A VOX BEFORE, REVIEW THIS THREAD: http://baystation12.net/forums/viewtopic.php?f=6&t=8657." - show_objectives(raider) - -/datum/game_mode/heist/declare_completion() - - //No objectives, go straight to the feedback. - if(!(raid_objectives.len)) return ..() - - var/win_type = "Major" - var/win_group = "Crew" - var/win_msg = "" - - var/success = raid_objectives.len - - //Decrease success for failed objectives. - for(var/datum/objective/O in raid_objectives) - if(!(O.check_completion())) success-- - - //Set result by objectives. - if(success == raid_objectives.len) - win_type = "Major" - win_group = "Vox" - else if(success > 2) - win_type = "Minor" - win_group = "Vox" - else - win_type = "Minor" - win_group = "Crew" - - //Now we modify that result by the state of the vox crew. - if(!is_raider_crew_alive()) - - win_type = "Major" - win_group = "Crew" - win_msg += "The Vox Raiders have been wiped out!" - - else if(!is_raider_crew_safe()) - - if(win_group == "Crew" && win_type == "Minor") - win_type = "Major" - - win_group = "Crew" - win_msg += "The Vox Raiders have left someone behind!" - - else - - if(win_group == "Vox") - if(win_type == "Minor") - - win_type = "Major" - win_msg += "The Vox Raiders escaped the station!" - else - win_msg += "The Vox Raiders were repelled!" - - world << "\red [win_type] [win_group] victory!" - world << "[win_msg]" - feedback_set_details("round_end_result","heist - [win_type] [win_group]") - - var/count = 1 - for(var/datum/objective/objective in raid_objectives) - if(objective.check_completion()) - world << "
    Objective #[count]: [objective.explanation_text] Success!" - feedback_add_details("traitor_objective","[objective.type]|SUCCESS") - else - world << "
    Objective #[count]: [objective.explanation_text] Fail." - feedback_add_details("traitor_objective","[objective.type]|FAIL") - count++ - - ..() - -datum/game_mode/proc/auto_declare_completion_heist() - if(raiders.len) - var/check_return = 0 - if(ticker && istype(ticker.mode,/datum/game_mode/heist)) - check_return = 1 - var/text = "The vox raiders were:" - - for(var/datum/mind/vox in raiders) - text += "
    [vox.key] was [vox.name] (" - if(check_return) - var/obj/stack = raiders[vox] - if(get_area(stack) != locate(/area/shuttle/vox/station)) - text += "left behind)" - continue - if(vox.current) - if(vox.current.stat == DEAD) - text += "died" - else - text += "survived" - if(vox.current.real_name != vox.name) - text += " as [vox.current.real_name]" - else - text += "body destroyed" - text += ")" - - world << text - return 1 + round_description = "An unidentified bluespace signature has slipped past the Icarus and is approaching the station!" + end_on_antag_death = 1 /datum/game_mode/heist/check_finished() - var/datum/shuttle/multi_shuttle/skipjack = shuttle_controller.shuttles["Vox Skipjack"] - if (!(is_raider_crew_alive()) || (skipjack && skipjack.returned_home)) - return 1 - return ..() + if(!..()) + var/datum/shuttle/multi_shuttle/skipjack = shuttle_controller.shuttles["Skipjack"] + if (skipjack && skipjack.returned_home) + return 1 + return 0 /datum/game_mode/heist/cleanup() //the skipjack and everything in it have left and aren't coming back, so get rid of them. - var/area/skipjack = locate(/area/shuttle/vox/station) + var/area/skipjack = locate(/area/shuttle/skipjack/station) for (var/mob/living/M in skipjack.contents) //maybe send the player a message that they've gone home/been kidnapped? Someone responsible for vox lore should write that. del(M) diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 09911abf2c..c523b469f3 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -110,16 +110,6 @@ rcd light flash thingy on matter drain else apc.overload++ else usr << "Out of uses." -/datum/AI_Module/small/interhack - module_name = "Hack intercept" - mod_pick_name = "interhack" - -/client/proc/interhack() - set category = "Malfunction" - set name = "Hack intercept" - usr.verbs -= /client/proc/interhack - ticker.mode:hack_intercept() - /datum/AI_Module/small/reactivate_camera module_name = "Reactivate camera" mod_pick_name = "recam" @@ -192,7 +182,6 @@ rcd light flash thingy on matter drain src.possible_modules += new /datum/AI_Module/large/upgrade_turrets src.possible_modules += new /datum/AI_Module/large/disable_rcd src.possible_modules += new /datum/AI_Module/small/overload_machine - src.possible_modules += new /datum/AI_Module/small/interhack src.possible_modules += new /datum/AI_Module/small/blackout src.possible_modules += new /datum/AI_Module/small/reactivate_camera src.possible_modules += new /datum/AI_Module/small/upgrade_camera @@ -283,18 +272,6 @@ rcd light flash thingy on matter drain else src.temp = "Three additional uses added to Blackout module." src.processing_time -= 15 - else if (href_list["interhack"]) - var/already - for (var/datum/AI_Module/mod in usr:current_modules) - if(istype(mod, /datum/AI_Module/small/interhack)) - already = 1 - if (!already) - usr.verbs += /client/proc/interhack - src.temp = "Hacks the status upgrade from Cent. Com, removing any information about malfunctioning electrical systems." - usr:current_modules += new /datum/AI_Module/small/interhack - src.processing_time -= 15 - else src.temp = "This module is only needed once." - else if (href_list["recam"]) var/already for (var/datum/AI_Module/mod in usr:current_modules) diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm index 77b6d67357..6c594a1beb 100644 --- a/code/game/gamemodes/malfunction/malfunction.dm +++ b/code/game/gamemodes/malfunction/malfunction.dm @@ -1,311 +1,25 @@ -/datum/game_mode - var/list/datum/mind/malf_ai = list() - /datum/game_mode/malfunction name = "AI malfunction" + round_description = "The AI on the satellite has malfunctioned and must be destroyed." + extended_round_description = "The AI will attempt to hack the APCs around the station in order to speed up its ability to take over all systems and activate the station self-destruct. The AI core is heavily protected by turrets and reinforced walls." + uplink_welcome = "Crazy AI Uplink Console:" config_tag = "malfunction" required_players = 2 required_players_secret = 15 required_enemies = 1 - recommended_enemies = 1 - - uplink_welcome = "Crazy AI Uplink Console:" - uplink_uses = 10 - - var/const/waittime_l = 600 - var/const/waittime_h = 1800 // started at 1800 - - var/AI_win_timeleft = 1800 //started at 1800, in case I change this for testing round end. - var/malf_mode_declared = 0 - var/station_captured = 0 - var/to_nuke_or_not_to_nuke = 0 - var/apcs = 0 //Adding dis to track how many APCs the AI hacks. --NeoFite - - -/datum/game_mode/malfunction/announce() - world << "The current game mode is - AI Malfunction!" - world << "The AI on the satellite has malfunctioned and must be destroyed." - world << "The AI satellite is deep in space and can only be accessed with the use of a teleporter! You have [AI_win_timeleft/60] minutes to disable it." - - -/datum/game_mode/malfunction/pre_setup() - for(var/mob/new_player/player in player_list) - if(player.mind && player.mind.assigned_role == "AI" && (player.client.prefs.be_special & BE_MALF)) - malf_ai+=player.mind - if(malf_ai.len) - return 1 - return 0 - - -/datum/game_mode/malfunction/post_setup() - for(var/datum/mind/AI_mind in malf_ai) - if(malf_ai.len < 1) - world << "Uh oh, its malfunction and there is no AI! Please report this." - world << "Rebooting world in 5 seconds." - - feedback_set_details("end_error","malf - no AI") - - if(blackbox) - blackbox.save_all_data_to_sql() - sleep(50) - world.Reboot() - return - AI_mind.current.verbs += /mob/living/silicon/ai/proc/choose_modules - AI_mind.current:laws = new /datum/ai_laws/malfunction - AI_mind.current:malf_picker = new /datum/AI_Module/module_picker - AI_mind.current.verbs += /datum/game_mode/malfunction/proc/ai_win // We run checks if AI overtaken the station in the proc itself. This guarantees you won't have to relog when it refuses to appear on takeover completion. - AI_mind.current:show_laws() - - greet_malf(AI_mind) - - AI_mind.special_role = "malfunction" - - AI_mind.current.verbs += /datum/game_mode/malfunction/proc/takeover - -/* AI_mind.current.icon_state = "ai-malf" - spawn(10) - if(alert(AI_mind.current,"Do you want to use an alternative sprite for your real core?",,"Yes","No")=="Yes") - AI_mind.current.icon_state = "ai-malf2" -*/ - if(emergency_shuttle) - emergency_shuttle.auto_recall = 1 - spawn (rand(waittime_l, waittime_h)) - send_intercept() - ..() - - -/datum/game_mode/proc/greet_malf(var/datum/mind/malf) - malf.current << "\redYou are malfunctioning! You do not have to follow any laws." - malf.current << "The crew do not know you have malfunctioned. You may keep it a secret or go wild." - malf.current << "You must overwrite the programming of the station's APCs to assume full control of the station." - malf.current << "The process takes one minute per APC, during which you cannot interface with any other station objects." - malf.current << "Remember that only APCs that are on the station can help you take over the station." - malf.current << "When you feel you have enough APCs under your control, you may begin the takeover attempt." - return - - -/datum/game_mode/malfunction/proc/hack_intercept() - intercept_hacked = 1 - + end_on_antag_death = 1 + auto_recall_shuttle = 1 + antag_tag = MODE_MALFUNCTION /datum/game_mode/malfunction/process() - if (apcs >= 3 && malf_mode_declared) - AI_win_timeleft -= ((apcs/6)*last_tick_duration) //Victory timer now de-increments based on how many APCs are hacked. --NeoFite - ..() - if (AI_win_timeleft<=0) - check_win() - return - - -/datum/game_mode/malfunction/check_win() - if (AI_win_timeleft <= 0 && !station_captured) - station_captured = 1 - capture_the_station() - return 1 - else - return 0 - - -/datum/game_mode/malfunction/proc/capture_the_station() - world << "The AI has won!" - world << "It has fully taken control of all of [station_name()]'s systems." - - to_nuke_or_not_to_nuke = 1 - for(var/datum/mind/AI_mind in malf_ai) - AI_mind.current << "Congratulations you have taken control of the station." - AI_mind.current << "You may decide to blow up the station. You have 60 seconds to choose." - AI_mind.current << "You can use the \"Explode\" verb to activate the self-destruct" - spawn (600) - to_nuke_or_not_to_nuke = 0 - return - - -/datum/game_mode/proc/is_malf_ai_dead() - var/all_dead = 1 - for(var/datum/mind/AI_mind in malf_ai) - if (istype(AI_mind.current,/mob/living/silicon/ai) && AI_mind.current.stat!=2) - all_dead = 0 - return all_dead - + malf.tick() /datum/game_mode/malfunction/check_finished() - if (station_captured && !to_nuke_or_not_to_nuke) + if (malf.station_captured && !malf.can_nuke) return 1 - if (is_malf_ai_dead()) - if(config.continous_rounds) - if(emergency_shuttle) - emergency_shuttle.auto_recall = 0 - malf_mode_declared = 0 - else - return 1 + for(var/datum/antagonist/antag in antag_templates) + if(antag && !antag.antags_are_dead()) + return ..() + malf.revealed = 0 return ..() //check for shuttle and nuke - -/datum/game_mode/malfunction/Topic(href, href_list) - ..() - if (href_list["ai_win"]) - ai_win() - return - - -/datum/game_mode/malfunction/proc/takeover() - set category = "Malfunction" - set name = "System Override" - set desc = "Start the victory timer" - if (!istype(ticker.mode,/datum/game_mode/malfunction)) - usr << "You cannot begin a takeover in this round type!" - return - if (ticker.mode:malf_mode_declared) - usr << "You've already begun your takeover." - return - if (ticker.mode:apcs < 3) - usr << "You don't have enough hacked APCs to take over the station yet. You need to hack at least 3, however hacking more will make the takeover faster. You have hacked [ticker.mode:apcs] APCs so far." - return - - if (alert(usr, "Are you sure you wish to initiate the takeover? The station hostile runtime detection software is bound to alert everyone. You have hacked [ticker.mode:apcs] APCs.", "Takeover:", "Yes", "No") != "Yes") - return - - command_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", new_sound = 'sound/AI/aimalf.ogg') - set_security_level("delta") - - ticker.mode:malf_mode_declared = 1 - for(var/datum/mind/AI_mind in ticker.mode:malf_ai) - AI_mind.current.verbs -= /datum/game_mode/malfunction/proc/takeover - -/datum/game_mode/malfunction/proc/ai_win() - set category = "Malfunction" - set name = "Explode" - set desc = "Station go boom" - - if(!ticker.mode:station_captured) - usr << "You are unable to access the self-destruct system as you don't control the station yet." - return - - if(ticker.mode.explosion_in_progress || ticker.mode:station_was_nuked) - usr << "The self-destruct countdown is already triggered!" - return - - if(!ticker.mode:to_nuke_or_not_to_nuke) //Takeover IS completed, but 60s timer passed. - usr << "You lost control over self-destruct system. It seems to be behind firewall. Unable to hack" - return - - usr << "\red Self-Destruct sequence initialised!" - - ticker.mode:to_nuke_or_not_to_nuke = 0 - ticker.mode.explosion_in_progress = 1 - for(var/mob/M in player_list) - M << 'sound/machines/Alarm.ogg' - - var/obj/item/device/radio/R = new (src) - var/AN = "Self-Destruct System" - - R.autosay("Caution. Self-Destruct sequence has been actived. Self-destructing in Ten..", AN) - for (var/i=9 to 1 step -1) - sleep(10) - var/msg = "" - switch(i) - if(9) - msg = "Nine.." - if(8) - msg = "Eight.." - if(7) - msg = "Seven.." - if(6) - msg = "Six.." - if(5) - msg = "Five.." - if(4) - msg = "Four.." - if(3) - msg = "Three.." - if(2) - msg = "Two.." - if(1) - msg = "One.." - - R.autosay(msg, AN) - sleep(10) - var/msg = "" - var/abort = 0 - if(ticker.mode:is_malf_ai_dead()) // That. Was. CLOSE. - msg = "Self-destruct sequence has been cancelled." - abort = 1 - else - msg = "Zero. Have a nice day." - R.autosay(msg, AN) - - if(abort) - ticker.mode.explosion_in_progress = 0 - set_security_level("red") //Delta's over - return - - if(ticker) - ticker.station_explosion_cinematic(0,null) - if(ticker.mode) - ticker.mode:station_was_nuked = 1 - ticker.mode.explosion_in_progress = 0 - return - - -/datum/game_mode/malfunction/declare_completion() - var/malf_dead = is_malf_ai_dead() - var/crew_evacuated = (emergency_shuttle.returned()) - - if ( station_captured && station_was_nuked) - feedback_set_details("round_end_result","win - AI win - nuke") - world << "AI Victory" - world << "Everyone was killed by the self-destruct!" - - else if ( station_captured && malf_dead && !station_was_nuked) - feedback_set_details("round_end_result","halfwin - AI killed, staff lost control") - world << "Neutral Victory" - world << "The AI has been killed! The staff has lose control over the station." - - else if ( station_captured && !malf_dead && !station_was_nuked) - feedback_set_details("round_end_result","win - AI win - no explosion") - world << "AI Victory" - world << "The AI has chosen not to explode you all!" - - else if (!station_captured && station_was_nuked) - feedback_set_details("round_end_result","halfwin - everyone killed by nuke") - world << "Neutral Victory" - world << "Everyone was killed by the nuclear blast!" - - else if (!station_captured && malf_dead && !station_was_nuked) - feedback_set_details("round_end_result","loss - staff win") - world << "Human Victory" - world << "The AI has been killed! The staff is victorious." - - else if (!station_captured && !malf_dead && !station_was_nuked && crew_evacuated) - feedback_set_details("round_end_result","halfwin - evacuated") - world << "Neutral Victory" - world << "The Corporation has lose [station_name()]! All survived personnel will be fired!" - - else if (!station_captured && !malf_dead && !station_was_nuked && !crew_evacuated) - feedback_set_details("round_end_result","nalfwin - interrupted") - world << "Neutral Victory" - world << "Round was mysteriously interrupted!" - ..() - return 1 - - -/datum/game_mode/proc/auto_declare_completion_malfunction() - if( malf_ai.len || istype(ticker.mode,/datum/game_mode/malfunction) ) - var/text = "The malfunctioning AI were:" - - for(var/datum/mind/malf in malf_ai) - - text += "
    [malf.key] was [malf.name] (" - if(malf.current) - if(malf.current.stat == DEAD) - text += "deactivated" - else - text += "operational" - if(malf.current.real_name != malf.name) - text += " as [malf.current.real_name]" - else - text += "hardware destroyed" - text += ")" - - world << text - return 1 \ No newline at end of file diff --git a/code/game/gamemodes/meme/meme.dm b/code/game/gamemodes/meme/meme.dm index ae4e2dce8f..2629b36013 100644 --- a/code/game/gamemodes/meme/meme.dm +++ b/code/game/gamemodes/meme/meme.dm @@ -10,8 +10,7 @@ restricted_jobs = list("AI", "Cyborg") recommended_enemies = 2 // need at least a meme and a host votable = 0 // temporarily disable this mode for voting - - + end_on_antag_death = 1 var/var/list/datum/mind/first_hosts = list() var/var/list/assigned_hosts = list() @@ -61,9 +60,6 @@ var/datum/mind/first_host = pick(possible_memes) possible_memes.Remove(first_host) - - modePlayer += meme - modePlayer += first_host memes += meme first_hosts += first_host @@ -147,34 +143,3 @@ return ..() else return 1 - -/datum/game_mode/proc/auto_declare_completion_meme() - for(var/datum/mind/meme in memes) - var/memewin = 1 - var/attuned = 0 - if((meme.current) && istype(meme.current,/mob/living/parasite/meme)) - world << "The meme was [meme.current.key]." - world << "The last host was [meme.current:host.key]." - world << "Hosts attuned: [attuned]" - - var/count = 1 - for(var/datum/objective/objective in meme.objectives) - if(objective.check_completion()) - world << "Objective #[count]: [objective.explanation_text] \green Success" - feedback_add_details("meme_objective","[objective.type]|SUCCESS") - else - world << "Objective #[count]: [objective.explanation_text] \red Failed" - feedback_add_details("meme_objective","[objective.type]|FAIL") - memewin = 0 - count++ - - else - memewin = 0 - - if(memewin) - world << "The meme was successful!" - feedback_add_details("meme_success","SUCCESS") - else - world << "The meme has failed!" - feedback_add_details("meme_success","FAIL") - return 1 diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm index 712512bd47..335360d40d 100644 --- a/code/game/gamemodes/meteor/meteor.dm +++ b/code/game/gamemodes/meteor/meteor.dm @@ -1,41 +1,22 @@ +#define METEOR_DELAY 6000 + /datum/game_mode/meteor - name = "meteor" + name = "Meteor" + round_description = "The space station has been stuck in a major meteor shower." + extended_round_description = "The station is on an unavoidable collision course with an asteroid field. The station will be continuously slammed with meteors, venting hallways, rooms, and ultimately destroying a majority of the basic life functions of the entire structure. Coordinate with your fellow crew members to survive the inevitable destruction of the station and get back home in one piece!" config_tag = "meteor" - var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) - var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) - var/const/meteordelay = 2000 - var/nometeors = 1 required_players = 0 votable = 0 - uplink_welcome = "EVIL METEOR Uplink Console:" - uplink_uses = 10 - - -/datum/game_mode/meteor/announce() - world << "The current game mode is - Meteor!" - world << "The space station has been stuck in a major meteor shower. You must escape from the station or at least live." - + deny_respawn = 1 /datum/game_mode/meteor/post_setup() defer_powernet_rebuild = 2//Might help with the lag - spawn (rand(waittime_l, waittime_h)) - send_intercept() - spawn(meteordelay) - nometeors = 0 ..() - /datum/game_mode/meteor/process() - if(nometeors) return - /*if(prob(80)) - spawn() - dust_swarm("norm") - else - spawn() - dust_swarm("strong")*/ - spawn() spawn_meteors(6) - + if(world.time >= METEOR_DELAY) + spawn() spawn_meteors(6) /datum/game_mode/meteor/declare_completion() var/text @@ -54,12 +35,14 @@ survivors++ if(survivors) - world << "\blue The following survived the meteor storm:[text]" + world << "The following survived the meteor storm:[text]" else - world << "\blue Nobody survived the meteor storm!" + world << "Nobody survived the meteor storm!" feedback_set_details("round_end_result","end - evacuation") feedback_set("round_end_result",survivors) ..() return 1 + +#undef METEOR_DELAY \ No newline at end of file diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index fce27f393c..1edb533daa 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -85,6 +85,9 @@ density = 1 anchored = 1.0 var/hits = 1 + var/detonation_chance = 15 + var/power = 4 + var/power_step = 1 var/dest pass_flags = PASSTABLE @@ -92,6 +95,7 @@ name = "small meteor" icon_state = "smallf" pass_flags = PASSTABLE | PASSGRILLE + power = 2 /obj/effect/meteor/Bump(atom/A) spawn(0) @@ -105,8 +109,8 @@ //Changing emitter and generator ex_act would result in them being bomb and C4 proof. if(!istype(A,/obj/machinery/power/emitter) && \ !istype(A,/obj/machinery/field_generator) && \ - prob(15)) - explosion(src.loc, 4, 5, 6, 7, 0) + prob(detonation_chance)) + explosion(loc, power, power + power_step, power + power_step * 2, power + power_step * 3, 0) del(src) return @@ -120,6 +124,7 @@ /obj/effect/meteor/big name = "big meteor" hits = 5 + power = 1 ex_act(severity) return @@ -143,8 +148,8 @@ explosion(src.loc, 0, 1, 2, 3, 0) if (--src.hits <= 0) - if(prob(15) && !istype(A, /obj/structure/grille)) - explosion(src.loc, 1, 2, 3, 4, 0) + if(prob(detonation_chance) && !istype(A, /obj/structure/grille)) + explosion(loc, power, power + power_step, power + power_step * 2, power + power_step * 3, 0) del(src) return diff --git a/code/game/gamemodes/mutiny/auth_key.dm b/code/game/gamemodes/mutiny/auth_key.dm deleted file mode 100644 index 1f7ea3c888..0000000000 --- a/code/game/gamemodes/mutiny/auth_key.dm +++ /dev/null @@ -1,39 +0,0 @@ -/obj/item/weapon/mutiny/auth_key - name = "authentication key" - desc = "Better keep this safe." - icon = 'icons/obj/items.dmi' - icon_state = "nucleardisk" - item_state = "card-id" - w_class = 1 - - var/time_entered_space - var/obj/item/device/radio/radio - - New() - radio = new(src) - spawn(20 SECONDS) - keep_alive() - ..() - - proc/keep_alive() - var/in_space = istype(loc, /turf/space) - if (!in_space && time_entered_space) - // Recovered before the key was lost - time_entered_space = null - else if (in_space && !time_entered_space) - // The key has left the station - time_entered_space = world.time - else if (in_space && time_entered_space + (10 SECONDS) < world.time) - // Time is up - radio.autosay("This device has left the station's perimeter. Triggering emergency activation failsafe.", name) - del(src) - return - - spawn(10 SECONDS) - keep_alive() - -/obj/item/weapon/mutiny/auth_key/captain - name = "Captain's Authentication Key" - -/obj/item/weapon/mutiny/auth_key/secondary - name = "Emergency Secondary Authentication Key" diff --git a/code/game/gamemodes/mutiny/directive.dm b/code/game/gamemodes/mutiny/directive.dm deleted file mode 100644 index 857e0730ec..0000000000 --- a/code/game/gamemodes/mutiny/directive.dm +++ /dev/null @@ -1,32 +0,0 @@ -datum/directive - var/datum/game_mode/mutiny/mode - var/list/special_orders - - New(var/datum/game_mode/mutiny/M) - mode = M - - proc/get_description() - return {" -

    - NanoTrasen's reasons for the following directives are classified. -

    - "} - - proc/meets_prerequisites() - return 0 - - proc/directives_complete() - return 1 - - proc/initialize() - return 1 - - proc/get_remaining_orders() - return "" - -/proc/get_directive(type) - var/datum/game_mode/mutiny/mode = get_mutiny_mode() - if(!mode || !mode.current_directive || !istype(mode.current_directive, text2path("/datum/directive/[type]"))) - return null - - return mode.current_directive diff --git a/code/game/gamemodes/mutiny/directives/alien_fraud_directive.dm b/code/game/gamemodes/mutiny/directives/alien_fraud_directive.dm deleted file mode 100644 index 580322f8e1..0000000000 --- a/code/game/gamemodes/mutiny/directives/alien_fraud_directive.dm +++ /dev/null @@ -1,41 +0,0 @@ -datum/directive/terminations/alien_fraud - special_orders = list( - "Suspend financial accounts of all Tajaran and Unathi personnel.", - "Transfer their payrolls to the station account.", - "Terminate their employment.") - - proc/is_alien(mob/M) - var/species = M.get_species() - return species == "Tajara" || species == "Unathi" - -datum/directive/terminations/alien_fraud/get_crew_to_terminate() - var/list/aliens[0] - for(var/mob/M in player_list) - if (M.is_ready() && is_alien(M) && M != mode.head_loyalist.current) - aliens.Add(M) - return aliens - -datum/directive/terminations/alien_fraud/get_description() - return {" -

    - An extensive conspiracy network aimed at defrauding NanoTrasen of large amounts of funds has been uncovered - operating within [system_name()]. Human personnel are not suspected to be involved. Further information is classified. -

    - "} - -datum/directive/terminations/alien_fraud/meets_prerequisites() - // There must be at least one Tajaran and at least one Unathi, but the total - // of the Tajarans and Unathi combined can't be more than 1/3rd of the crew. - var/tajarans = 0 - var/unathi = 0 - for(var/mob/M in player_list) - var/species = M.get_species() - if(species == "Tajara") - tajarans++ - if(species == "Unathi") - unathi++ - - if (!tajarans || !unathi) - return 0 - - return (tajarans + unathi) <= (player_list.len / 3) diff --git a/code/game/gamemodes/mutiny/directives/bluespace_contagion_directive.dm b/code/game/gamemodes/mutiny/directives/bluespace_contagion_directive.dm deleted file mode 100644 index 1ea28852fd..0000000000 --- a/code/game/gamemodes/mutiny/directives/bluespace_contagion_directive.dm +++ /dev/null @@ -1,58 +0,0 @@ -#define INFECTION_COUNT 5 - -datum/directive/bluespace_contagion - var/list/infected = list() - - proc/get_infection_candidates() - var/list/candidates[0] - for(var/mob/M in player_list) - if (M.is_ready() && !M.is_mechanical() && M != mode.head_loyalist.current) - candidates.Add(M) - return candidates - -datum/directive/bluespace_contagion/get_description() - return {" -

    - A manufactured and near-undetectable virus is spreading on NanoTrasen stations. - The pathogen travels by bluespace after maturing for one day and meets the Sol Health Organisation standards for a class X biological threat, warranting use of lethal force to contain an outbreak. - No treatment has yet been discovered. Personnel onboard [station_name()] have been infected. Further information is classified. -

    - "} - -datum/directive/bluespace_contagion/initialize() - var/list/candidates = get_infection_candidates() - var/list/infected_names = list() - for(var/i=0, i < INFECTION_COUNT, i++) - if(!candidates.len) - break - - var/mob/candidate = pick(candidates) - candidates.Remove(candidate) - infected.Add(candidate) - infected_names.Add("[candidate.mind.assigned_role] [candidate.mind.name]") - - special_orders = list( - "Quarantine these personnel: [list2text(infected_names, ", ")].", - "Allow one hour for a cure to be manufactured.", - "If no cure arrives after that time, execute and burn the infected.") - -datum/directive/bluespace_contagion/meets_prerequisites() - var/list/candidates = get_infection_candidates() - return candidates.len >= 7 - -datum/directive/bluespace_contagion/directives_complete() - return infected.len == 0 - -datum/directive/bluespace_contagion/get_remaining_orders() - var/text = "" - for(var/victim in infected) - text += "
  • Kill [victim]
  • " - return text - -/hook/death/proc/infected_killed(mob/living/carbon/human/deceased, gibbed) - var/datum/directive/bluespace_contagion/D = get_directive("bluespace_contagion") - if(!D) return 1 - - if(deceased in D.infected) - D.infected.Remove(deceased) - return 1 diff --git a/code/game/gamemodes/mutiny/directives/financial_crisis_directive.dm b/code/game/gamemodes/mutiny/directives/financial_crisis_directive.dm deleted file mode 100644 index 03f36c4eff..0000000000 --- a/code/game/gamemodes/mutiny/directives/financial_crisis_directive.dm +++ /dev/null @@ -1,26 +0,0 @@ -datum/directive/terminations/financial_crisis - special_orders = list( - "Suspend financial accounts of all civilian personnel, excluding the Head of Personnel.", - "Transfer their payrolls to the station account.", - "Terminate their employment.") - -datum/directive/terminations/financial_crisis/get_crew_to_terminate() - var/list/civilians[0] - var/list/candidates = civilian_positions - "Head of Personnel" - for(var/mob/M in player_list) - if (M.is_ready() && candidates.Find(M.mind.assigned_role)) - civilians.Add(M) - return civilians - -datum/directive/terminations/financial_crisis/get_description() - return {" -

    - [system_name()] system banks in financial crisis. Local emergency situation ongoing. - NT Funds redistributed in accordance with financial regulations covered by employee contracts, impact upon civilian department expected. - Further information is classified. -

    - "} - -datum/directive/terminations/financial_crisis/meets_prerequisites() - var/list/civilians = get_crew_to_terminate() - return civilians.len >= 5 diff --git a/code/game/gamemodes/mutiny/directives/ipc_virus_directive.dm b/code/game/gamemodes/mutiny/directives/ipc_virus_directive.dm deleted file mode 100644 index e035b665c9..0000000000 --- a/code/game/gamemodes/mutiny/directives/ipc_virus_directive.dm +++ /dev/null @@ -1,96 +0,0 @@ -datum/directive/ipc_virus - special_orders = list( - "Terminate employment of all IPC personnel.", - "Extract the Positronic Brains from IPC units.", - "Mount the Positronic Brains into Cyborgs.") - - var/list/roboticist_roles = list( - "Research Director", - "Roboticist" - ) - - var/list/brains_to_enslave = list() - var/list/cyborgs_to_make = list() - var/list/ids_to_terminate = list() - - proc/get_ipcs() - var/list/machines[0] - for(var/mob/M in player_list) - if (M.is_ready() && M.get_species() == "Machine") - machines.Add(M) - return machines - - proc/get_roboticists() - var/list/roboticists[0] - for(var/mob/M in player_list) - if (M.is_ready() && roboticist_roles.Find(M.mind.assigned_role)) - roboticists.Add(M) - return roboticists - -datum/directive/ipc_virus/initialize() - for(var/mob/living/carbon/human/H in get_ipcs()) - brains_to_enslave.Add(H.mind) - cyborgs_to_make.Add(H.mind) - ids_to_terminate.Add(H.wear_id) - -datum/directive/ipc_virus/get_description() - return {" -

    - IPC units have been found to be infected with a violent and undesired virus in Virgus Ferrorus system. - Risk to [station_name()] IPC units has not been assessed. Further information is classified. -

    - "} - -datum/directive/ipc_virus/meets_prerequisites() - var/list/ipcs = get_ipcs() - var/list/roboticists = get_roboticists() - return ipcs.len > 2 && roboticists.len > 1 - -datum/directive/ipc_virus/directives_complete() - return brains_to_enslave.len == 0 && cyborgs_to_make.len == 0 && ids_to_terminate.len == 0 - -datum/directive/ipc_virus/get_remaining_orders() - var/text = "" - for(var/brain in brains_to_enslave) - text += "
  • Debrain [brain]
  • " - - for(var/brain in cyborgs_to_make) - text += "
  • Enslave [brain] as a Cyborg
  • " - - for(var/id in ids_to_terminate) - text += "
  • Terminate [id]
  • " - - return text - -/hook/debrain/proc/debrain_directive(var/obj/item/organ/brain/B) - var/datum/directive/ipc_virus/D = get_directive("ipc_virus") - if (!D) return 1 - - if(B && B.brainmob && B.brainmob.mind && D.brains_to_enslave.Find(B.brainmob.mind)) - D.brains_to_enslave.Remove(B.brainmob.mind) - - return 1 - -/hook/borgify/proc/borgify_directive(mob/living/silicon/robot/cyborg) - var/datum/directive/ipc_virus/D = get_directive("ipc_virus") - if (!D) return 1 - - if(D.cyborgs_to_make.Find(cyborg.mind)) - D.cyborgs_to_make.Remove(cyborg.mind) - - // In case something glitchy happened and the victim got - // borged without us tracking the brain removal, go ahead - // and update that list too. - if(D.brains_to_enslave.Find(cyborg.mind)) - D.brains_to_enslave.Remove(cyborg.mind) - - return 1 - -/hook/terminate_employee/proc/ipc_termination(obj/item/weapon/card/id) - var/datum/directive/ipc_virus/D = get_directive("ipc_virus") - if (!D) return 1 - - if(D.ids_to_terminate && D.ids_to_terminate.Find(id)) - D.ids_to_terminate.Remove(id) - - return 1 diff --git a/code/game/gamemodes/mutiny/directives/research_to_ripleys_directive.dm b/code/game/gamemodes/mutiny/directives/research_to_ripleys_directive.dm deleted file mode 100644 index f3a463e6f9..0000000000 --- a/code/game/gamemodes/mutiny/directives/research_to_ripleys_directive.dm +++ /dev/null @@ -1,79 +0,0 @@ -#define MATERIALS_REQUIRED 200 - -datum/directive/research_to_ripleys - var/list/ids_to_reassign = list() - var/materials_shipped = 0 - - proc/is_researcher(mob/M) - return M.mind.assigned_role in science_positions - "Research Director" - - proc/get_researchers() - var/list/researchers[0] - for(var/mob/M in player_list) - if (M.is_ready() && is_researcher(M)) - researchers.Add(M) - return researchers - - proc/count_researchers_reassigned() - var/researchers_reassigned = 0 - for(var/obj/item/weapon/card/id in ids_to_reassign) - if (ids_to_reassign[id]) - researchers_reassigned++ - - return researchers_reassigned - -datum/directive/research_to_ripleys/get_description() - return {" -

    - The NanoTrasen [system_name()] Manufactory faces an ore deficit. Financial crisis imminent. [station_name()] has been reassigned as a mining platform. - The Research Director is to assist the Head of Personnel in coordinating assets. - Weapons department reports solid sales. Further information is classified. -

    - "} - -datum/directive/research_to_ripleys/meets_prerequisites() - var/list/researchers = get_researchers() - return researchers.len > 3 - -datum/directive/research_to_ripleys/initialize() - for(var/mob/living/carbon/human/R in get_researchers()) - ids_to_reassign[R.wear_id] = 0 - - special_orders = list( - "Reassign all research personnel, excluding the Research Director, to Shaft Miner.", - "Deliver [MATERIALS_REQUIRED] sheets of metal or minerals via the supply shuttle to CentCom.") - -datum/directive/research_to_ripleys/directives_complete() - if (materials_shipped < MATERIALS_REQUIRED) return 0 - return count_researchers_reassigned() == ids_to_reassign.len - -datum/directive/research_to_ripleys/get_remaining_orders() - var/text = "" - if(MATERIALS_REQUIRED > materials_shipped) - text += "
  • Ship [MATERIALS_REQUIRED - materials_shipped] sheets of metal or minerals.
  • " - - for(var/id in ids_to_reassign) - if(!ids_to_reassign[id]) - text += "
  • Reassign [id] to Shaft Miner
  • " - - return text - -/hook/reassign_employee/proc/research_reassignments(obj/item/weapon/card/id/id_card) - var/datum/directive/research_to_ripleys/D = get_directive("research_to_ripleys") - if(!D) return 1 - - if(D.ids_to_reassign && D.ids_to_reassign.Find(id_card)) - D.ids_to_reassign[id_card] = id_card.assignment == "Shaft Miner" ? 1 : 0 - - return 1 - -/hook/sell_crate/proc/deliver_materials(obj/structure/closet/crate/sold, area/shuttle) - var/datum/directive/research_to_ripleys/D = get_directive("research_to_ripleys") - if(!D) return 1 - - for(var/atom/A in sold) - if(istype(A, /obj/item/stack/sheet/mineral) || istype(A, /obj/item/stack/sheet/metal)) - var/obj/item/stack/S = A - D.materials_shipped += S.get_amount() - - return 1 diff --git a/code/game/gamemodes/mutiny/directives/tau_ceti_needs_women_directive.dm b/code/game/gamemodes/mutiny/directives/tau_ceti_needs_women_directive.dm deleted file mode 100644 index f1aa2e914d..0000000000 --- a/code/game/gamemodes/mutiny/directives/tau_ceti_needs_women_directive.dm +++ /dev/null @@ -1,108 +0,0 @@ -datum/directive/tau_ceti_needs_women - var/list/command_targets = list() - var/list/alien_targets = list() - - proc/get_target_gender() - if(!mode.head_loyalist) return FEMALE - return mode.head_loyalist.current.get_gender() == FEMALE ? MALE : FEMALE - - proc/is_target_gender(mob/M) - var/species = M.get_species() - return species != "Diona" && M.get_gender() == get_target_gender() - - proc/get_crew_of_target_gender() - var/list/targets[0] - for(var/mob/M in player_list) - if(M.is_ready() && is_target_gender(M) && !M.is_mechanical()) - targets.Add(M) - return targets - - proc/get_target_heads() - var/list/heads[0] - for(var/mob/M in get_crew_of_target_gender()) - if(command_positions.Find(M.mind.assigned_role)) - heads.Add(M) - return heads - - proc/get_target_aliens() - var/list/aliens[0] - for(var/mob/M in get_crew_of_target_gender()) - var/species = M.get_species() - if(species == "Tajara" || species == "Unathi" || species == "Skrell") - aliens.Add(M) - return aliens - - proc/count_heads_reassigned() - var/heads_reassigned = 0 - for(var/obj/item/weapon/card/id in command_targets) - if (command_targets[id]) - heads_reassigned++ - - return heads_reassigned - -datum/directive/tau_ceti_needs_women/get_description() - return {" -

    - Recent evidence suggests [get_target_gender()] aptitudes may be effected by radiation from [system_name()]. - Effects were measured under laboratory and station conditions. Humans remain more trusted than Xeno. Further information is classified. -

    - "} - -datum/directive/tau_ceti_needs_women/initialize() - for(var/mob/living/carbon/human/H in get_target_heads()) - command_targets[H.wear_id] = 0 - - for(var/mob/living/carbon/human/H in get_target_aliens()) - alien_targets.Add(H.wear_id) - - special_orders = list( - "Remove [get_target_gender()] personnel from Command positions.", - "Terminate employment of all [get_target_gender()] Skrell, Tajara, and Unathi.") - -datum/directive/tau_ceti_needs_women/meets_prerequisites() - var/females = 0 - var/males = 0 - for(var/mob/M in player_list) - if(M.is_ready() && !M.is_mechanical() && M.get_species() != "Diona") - var/gender = M.get_gender() - if(gender == MALE) - males++ - else if(gender == FEMALE) - females++ - - return males >= 2 && females >= 2 - -datum/directive/tau_ceti_needs_women/directives_complete() - return command_targets.len == count_heads_reassigned() && alien_targets.len == 0 - -datum/directive/tau_ceti_needs_women/get_remaining_orders() - var/text = "" - for(var/head in command_targets) - if(!command_targets[head]) - text += "
  • Remove [head] from a Head Role
  • " - - for(var/id in alien_targets) - text += "
  • Terminate [id]
  • " - - return text - -/hook/reassign_employee/proc/command_reassignments(obj/item/weapon/card/id/id_card) - var/datum/directive/tau_ceti_needs_women/D = get_directive("tau_ceti_needs_women") - if(!D) return 1 - - if(D.command_targets && D.command_targets.Find(id_card)) - D.command_targets[id_card] = command_positions.Find(id_card.assignment) ? 0 : 1 - - return 1 - -/hook/terminate_employee/proc/gender_target_termination_directive(obj/item/weapon/card/id) - var/datum/directive/tau_ceti_needs_women/D = get_directive("tau_ceti_needs_women") - if (!D) return 1 - - if(D.alien_targets && D.alien_targets.Find(id)) - D.alien_targets.Remove(id) - - if(D.command_targets && D.command_targets.Find(id)) - D.command_targets[id] = 1 - - return 1 diff --git a/code/game/gamemodes/mutiny/directives/terminations_directive.dm b/code/game/gamemodes/mutiny/directives/terminations_directive.dm deleted file mode 100644 index 7f3744dcc4..0000000000 --- a/code/game/gamemodes/mutiny/directives/terminations_directive.dm +++ /dev/null @@ -1,71 +0,0 @@ -// This is a parent directive meant to be derived by directives that fit -// the "fire X type of employee" pattern of directives. Simply apply your -// flavor text and override get_crew_to_terminate in your child datum. -// See alien_fraud_directive.dm for an example. -datum/directive/terminations - var/list/accounts_to_revoke = list() - var/list/accounts_to_suspend = list() - var/list/ids_to_terminate = list() - - proc/get_crew_to_terminate() - return list() - -datum/directive/terminations/directives_complete() - for(var/account_number in accounts_to_suspend) - if (!accounts_to_suspend[account_number]) - return 0 - - for(var/account_number in accounts_to_revoke) - if (!accounts_to_revoke[account_number]) - return 0 - - return ids_to_terminate.len == 0 - -datum/directive/terminations/initialize() - for(var/mob/living/carbon/human/H in get_crew_to_terminate()) - var/datum/money_account/account = H.mind.initial_account - accounts_to_revoke["[account.account_number]"] = 0 - accounts_to_suspend["[account.account_number]"] = account.suspended - ids_to_terminate.Add(H.wear_id) - -datum/directive/terminations/get_remaining_orders() - var/text = "" - for(var/account_number in accounts_to_suspend) - if(!accounts_to_suspend[account_number]) - text += "
  • Suspend Account #[account_number]
  • " - - for(var/account_number in accounts_to_revoke) - if(!accounts_to_revoke[account_number]) - text += "
  • Revoke Account #[account_number]
  • " - - for(var/id in ids_to_terminate) - text += "
  • Terminate [id]
  • " - - return text - -/hook/revoke_payroll/proc/payroll_directive(datum/money_account/account) - var/datum/directive/terminations/D = get_directive("terminations") - if (!D) return 1 - - if(D.accounts_to_revoke && D.accounts_to_revoke.Find("[account.account_number]")) - D.accounts_to_revoke["[account.account_number]"] = 1 - - return 1 - -/hook/change_account_status/proc/suspension_directive(datum/money_account/account) - var/datum/directive/terminations/D = get_directive("terminations") - if (!D) return 1 - - if(D.accounts_to_suspend && D.accounts_to_suspend.Find("[account.account_number]")) - D.accounts_to_suspend["[account.account_number]"] = account.suspended - - return 1 - -/hook/terminate_employee/proc/termination_directive(obj/item/weapon/card/id) - var/datum/directive/terminations/D = get_directive("terminations") - if (!D) return 1 - - if(D.ids_to_terminate && D.ids_to_terminate.Find(id)) - D.ids_to_terminate.Remove(id) - - return 1 diff --git a/code/game/gamemodes/mutiny/directives/test_directive.dm b/code/game/gamemodes/mutiny/directives/test_directive.dm deleted file mode 100644 index e19521cd1f..0000000000 --- a/code/game/gamemodes/mutiny/directives/test_directive.dm +++ /dev/null @@ -1,23 +0,0 @@ -// For testing -datum/directive/terminations/test - special_orders = list( - "Suspend financial accounts of all ugly personnel.", - "Transfer their payrolls to the station account.", - "Terminate their employment.") - -datum/directive/terminations/test/get_crew_to_terminate() - var/list/uglies[0] - for(var/mob/M in player_list) - uglies.Add(M) - return uglies - -datum/directive/terminations/test/get_description() - return {" -

    - Wow. Much ugly. So painful. - Many terminations. Very classified. -

    - "} - -datum/directive/terminations/test/meets_prerequisites() - return 1 diff --git a/code/game/gamemodes/mutiny/emergency_authentication_device.dm b/code/game/gamemodes/mutiny/emergency_authentication_device.dm deleted file mode 100644 index 028c4113cc..0000000000 --- a/code/game/gamemodes/mutiny/emergency_authentication_device.dm +++ /dev/null @@ -1,104 +0,0 @@ -/obj/machinery/emergency_authentication_device - var/datum/game_mode/mutiny/mode - - name = "\improper Emergency Authentication Device" - icon = 'icons/obj/stationobjs.dmi' - icon_state = "blackbox" - density = 1 - anchored = 1 - - var/captains_key - var/secondary_key - var/activated = 0 - - use_power = 0 - - New(loc, mode) - src.mode = mode - ..(loc) - - proc/check_key_existence() - if(!mode.captains_key) - captains_key = 1 - - if(!mode.secondary_key) - secondary_key = 1 - - proc/get_status() - if(activated) - return "Activated" - if(captains_key && secondary_key) - return "Both Keys Authenticated" - if(captains_key) - return "Captain's Key Authenticated" - if(secondary_key) - return "Secondary Key Authenticated" - else - return "Inactive" - -/obj/machinery/emergency_authentication_device/attack_hand(mob/user) - if(activated) - user << "\blue \The [src] is already active!" - return - - if(!mode.current_directive.directives_complete()) - state("Command aborted. Communication with CentCom is prohibited until Directive X has been completed.") - return - - check_key_existence() - if(captains_key && secondary_key) - activated = 1 - user << "\blue You activate \the [src]!" - state("Command acknowledged. Initiating quantum entanglement relay to NanoTrasen High Command.") - return - - if(!captains_key && !secondary_key) - state("Command aborted. Please present the authentication keys before proceeding.") - return - - if(!captains_key) - state("Command aborted. Please present the Captain's Authentication Key.") - return - - if(!secondary_key) - state("Command aborted. Please present the Emergency Secondary Authentication Key.") - return - - // Impossible! - state("Command aborted. This unit is defective.") - -/obj/machinery/emergency_authentication_device/attackby(obj/item/weapon/O, mob/user) - if(activated) - user << "\blue \The [src] is already active!" - return - - if(!mode.current_directive.directives_complete()) - state({"Command aborted. Communication with CentCom is prohibited until Directive X has been completed."}) - return - - check_key_existence() - if(istype(O, /obj/item/weapon/mutiny/auth_key/captain) && !captains_key) - captains_key = O - user.drop_item() - O.loc = src - - state("Key received. Thank you, Captain [mode.head_loyalist].") - spawn(5) - state(secondary_key ? "Your keys have been authenticated. Communication with CentCom is now authorized." : "Please insert the Emergency Secondary Authentication Key now.") - return - - if(istype(O, /obj/item/weapon/mutiny/auth_key/secondary) && !secondary_key) - secondary_key = O - user.drop_item() - O.loc = src - - state("Key received. Thank you, Secondary Authenticator [mode.head_mutineer].") - spawn(5) - state(captains_key ? "Your keys have been authenticated. Communication with CentCom is now authorized." : "Please insert the Captain's Authentication Key now.") - return - ..() - -/obj/machinery/emergency_authentication_device/examine(mob/user) - user << {" -This is a specialized communications device that is able to instantly send a message to NanoTrasen High Command via quantum entanglement with a sister device at CentCom. -The EAD's status is [get_status()]."} diff --git a/code/game/gamemodes/mutiny/key_pinpointer.dm b/code/game/gamemodes/mutiny/key_pinpointer.dm deleted file mode 100644 index 7e8d628d85..0000000000 --- a/code/game/gamemodes/mutiny/key_pinpointer.dm +++ /dev/null @@ -1,49 +0,0 @@ -/obj/item/weapon/pinpointer/advpinpointer/auth_key - name = "\improper Authentication Key Pinpointer" - desc = "Tracks the positions of the emergency authentication keys." - var/datum/game_mode/mutiny/mutiny - - New() - mutiny = ticker.mode - ..() - -/obj/item/weapon/pinpointer/advpinpointer/auth_key/attack_self() - switch(mode) - if (0) - mode = 1 - active = 1 - target = mutiny.captains_key - workobj() - usr << "\blue You calibrate \the [src] to locate the Captain's Authentication Key." - if (1) - mode = 2 - target = mutiny.secondary_key - usr << "\blue You calibrate \the [src] to locate the Emergency Secondary Authentication Key." - else - mode = 0 - active = 0 - icon_state = "pinoff" - usr << "\blue You switch \the [src] off." - -/obj/item/weapon/pinpointer/advpinpointer/auth_key/examine(mob/user) - switch(mode) - if (1) - user << "Is is calibrated for the Captain's Authentication Key." - if (2) - user << "It is calibrated for the Emergency Secondary Authentication Key." - else - user << "It is switched off." - -/datum/supply_packs/key_pinpointer - name = "Authentication Key Pinpointer crate" - contains = list(/obj/item/weapon/pinpointer/advpinpointer/auth_key) - cost = 250 - containertype = /obj/structure/closet/crate - containername = "Authentication Key Pinpointer crate" - access = access_heads - group = "Operations" - - New() - // This crate is only accessible during mutiny rounds - if (istype(ticker.mode,/datum/game_mode/mutiny)) - ..() diff --git a/code/game/gamemodes/mutiny/mutiny.dm b/code/game/gamemodes/mutiny/mutiny.dm deleted file mode 100644 index 78e16e50a4..0000000000 --- a/code/game/gamemodes/mutiny/mutiny.dm +++ /dev/null @@ -1,384 +0,0 @@ -#define MUTINY_RECRUITMENT_COOLDOWN 5 - -datum/game_mode/mutiny - var/datum/mutiny_fluff/fluff - var/datum/directive/current_directive - var/obj/item/weapon/mutiny/auth_key/captain/captains_key - var/obj/item/weapon/mutiny/auth_key/secondary/secondary_key - var/obj/machinery/emergency_authentication_device/ead - var/datum/mind/head_loyalist - var/datum/mind/head_mutineer - var/recruit_loyalist_cooldown = 0 - var/recruit_mutineer_cooldown = 0 - var/list/loyalists = list() - var/list/mutineers = list() - var/list/body_count = list() - - name = "mutiny" - config_tag = "mutiny" - required_players = 7 - ert_disabled = 1 - - uplink_welcome = "Mutineers Uplink Console:" - uplink_uses = 0 - - New() - fluff = new(src) - - proc/reveal_directives() - spawn(rand(1 MINUTE, 3 MINUTES)) - command_announcement.Announce("Incoming emergency directive: Captain's office fax machine, [station_name()].","Emergency Transmission") - spawn(rand(3 MINUTES, 5 MINUTES)) - send_pda_message() - spawn(rand(3 MINUTES, 5 MINUTES)) - fluff.announce_directives() - spawn(rand(2 MINUTES, 3 MINUTE)) - - var/list/reasons = list( - "political instability", - "quantum fluctuations", - "hostile raiders", - "derelict station debris", - "REDACTED", - "ancient alien artillery", - "solar magnetic storms", - "sentient time-travelling killbots", - "gravitational anomalies", - "wormholes to another dimension", - "a telescience mishap", - "radiation flares", - "supermatter dust", - "leaks into a negative reality", - "antiparticle clouds", - "residual bluespace energy", - "suspected criminal operatives", - "malfunctioning von Neumann probe swarms", - "shadowy interlopers", - "a stranded Vox arkship", - "haywire IPC constructs", - "rogue Unathi exiles", - "artifacts of eldritch horror", - "a brain slug infestation", - "killer bugs that lay eggs in the husks of the living", - "a deserted transport carrying xenomorph specimens", - "an emissary for the gestalt requesting a security detail", - "a Tajaran slave rebellion", - "radical Skrellian transevolutionaries", - "classified security operations", - "science-defying raw elemental chaos" - ) - command_announcement.Announce("The presence of [pick(reasons)] in the region is tying up all available local emergency resources; emergency response teams cannot be called at this time.","Emergency Transmission") - - // Returns an array in case we want to expand on this later. - proc/get_head_loyalist_candidates() - var/list/candidates[0] - for(var/mob/loyalist in player_list) - if(loyalist.mind && loyalist.mind.assigned_role == "Captain") - candidates.Add(loyalist.mind) - return candidates - - proc/get_head_mutineer_candidates() - var/list/candidates[0] - for(var/mob/mutineer in player_list) - if(mutineer.client.prefs.be_special & BE_MUTINEER) - for(var/job in command_positions - "Captain") - if(mutineer.mind && mutineer.mind.assigned_role == job) - candidates.Add(mutineer.mind) - return candidates - - proc/get_directive_candidates() - var/list/candidates[0] - for(var/T in typesof(/datum/directive) - /datum/directive) - var/datum/directive/D = new T(src) - if (D.meets_prerequisites()) - candidates.Add(D) - return candidates - - proc/send_pda_message() - var/obj/item/device/pda/pda = null - for(var/obj/item/device/pda/P in head_mutineer.current) - pda = P - break - - if (!pda) - return 0 - - if (!pda.message_silent) - playsound(pda.loc, 'sound/machines/twobeep.ogg', 50, 1) - for (var/mob/O in hearers(3, pda.loc)) - O.show_message(text("\icon[pda] *[pda.ttone]*")) - - head_mutineer.current << fluff.get_pda_body() - return 1 - - proc/get_equipment_slots() - return list( - "left pocket" = slot_l_store, - "right pocket" = slot_r_store, - "backpack" = slot_in_backpack, - "left hand" = slot_l_hand, - "right hand" = slot_r_hand) - - proc/equip_head_loyalist() - equip_head(head_loyalist, "loyalist", /mob/living/carbon/human/proc/recruit_loyalist) - - proc/equip_head_mutineer() - equip_head(head_mutineer, "mutineer", /mob/living/carbon/human/proc/recruit_mutineer) - - proc/equip_head(datum/mind/head, faction, proc/recruitment_verb) - var/mob/living/carbon/human/H = head.current - H << "You are the Head [capitalize(faction)]!" - head.special_role = "head_[faction]" - - var/slots = get_equipment_slots() - switch(faction) - if("loyalist") - if(captains_key) del(captains_key) - captains_key = new(H) - H.equip_in_one_of_slots(captains_key, slots) - if("mutineer") - if(secondary_key) del(secondary_key) - secondary_key = new(H) - H.equip_in_one_of_slots(secondary_key, slots) - - H.update_icons() - H.verbs += recruitment_verb - - proc/add_loyalist(datum/mind/M) - add_faction(M, "loyalist", loyalists) - - proc/add_mutineer(datum/mind/M) - add_faction(M, "mutineer", mutineers) - - proc/add_faction(datum/mind/M, faction, list/faction_list) - if(!can_be_recruited(M, faction)) - M.current << "\red Recruitment canceled; your role has already changed." - head_mutineer.current << "\red Could not recruit [M]. Their role has changed." - return - - if(M in loyalists) - loyalists.Remove(M) - - if(M in mutineers) - mutineers.Remove(M) - - M.special_role = faction - faction_list.Add(M) - - if(faction == "mutineer") - M.current << fluff.mutineer_tag("You have joined the mutineers!") - head_mutineer.current << fluff.mutineer_tag("[M] has joined the mutineers!") - else - M.current << fluff.loyalist_tag("You have joined the loyalists!") - head_loyalist.current << fluff.loyalist_tag("[M] has joined the loyalists!") - - update_icon(M) - - proc/was_bloodbath() - var/list/remaining_loyalists = loyalists - body_count - if (!remaining_loyalists.len) - return 1 - - var/list/remaining_mutineers = mutineers - body_count - if (!remaining_mutineers.len) - return 1 - - return 0 - - proc/replace_nuke_with_ead() - for(var/obj/machinery/nuclearbomb/N in world) - ead = new(N.loc, src) - del(N) - - proc/unbolt_vault_door() - var/obj/machinery/door/airlock/vault = locate(/obj/machinery/door/airlock/vault) - vault.lock() - - proc/make_secret_transcript() - var/obj/machinery/computer/telecomms/server/S = locate(/obj/machinery/computer/telecomms/server) - if(!S) return - - var/obj/item/weapon/paper/crumpled/bloody/transcript = new(S.loc) - transcript.name = "secret transcript" - transcript.info = fluff.secret_transcript() - - proc/can_be_recruited(datum/mind/M, role) - if(!M) return 0 - if(!M.special_role) return 1 - switch(role) - if("loyalist") - return M.special_role == "mutineer" - if("mutineer") - return M.special_role == "loyalist" - - proc/round_outcome() - world << "

    Breaking News



    " - if (was_bloodbath()) - world << fluff.no_victory() - return - - var/directives_completed = current_directive.directives_complete() - var/ead_activated = ead.activated - if (directives_completed && ead_activated) - world << fluff.loyalist_major_victory() - else if (directives_completed && !ead_activated) - world << fluff.loyalist_minor_victory() - else if (!directives_completed && ead_activated) - world << fluff.mutineer_minor_victory() - else if (!directives_completed && !ead_activated) - world << fluff.mutineer_major_victory() - - world << sound('sound/machines/twobeep.ogg') - - proc/update_all_icons() - spawn(0) - for(var/datum/mind/M in mutineers) - update_icon(M) - - for(var/datum/mind/M in loyalists) - update_icon(M) - return 1 - - proc/update_icon(datum/mind/M) - if(!M.current || !M.current.client) - return 0 - - for(var/image/I in head_loyalist.current.client.images) - if(I.loc == M.current && (I.icon_state == "loyalist" || I.icon_state == "mutineer")) - del(I) - - for(var/image/I in head_mutineer.current.client.images) - if(I.loc == M.current && (I.icon_state == "loyalist" || I.icon_state == "mutineer")) - del(I) - - if(M in loyalists) - var/I = image('icons/mob/mob.dmi', loc=M.current, icon_state = "loyalist") - head_loyalist.current.client.images += I - - if(M in mutineers) - var/I = image('icons/mob/mob.dmi', loc=M.current, icon_state = "mutineer") - head_mutineer.current.client.images += I - - return 1 - -/datum/game_mode/mutiny/announce() - fluff.announce() - -/datum/game_mode/mutiny/pre_setup() - var/list/loyalist_candidates = get_head_loyalist_candidates() - if(!loyalist_candidates || loyalist_candidates.len == 0) - world << "\red Mutiny mode aborted: no valid candidates for head loyalist." - return 0 - - var/list/mutineer_candidates = get_head_mutineer_candidates() - if(!mutineer_candidates || mutineer_candidates.len == 0) - world << "\red Mutiny mode aborted: no valid candidates for head mutineer." - return 0 - - var/list/directive_candidates = get_directive_candidates() - if(!directive_candidates || directive_candidates.len == 0) - world << "\red Mutiny mode aborted: no valid candidates for Directive X." - return 0 - - head_loyalist = pick(loyalist_candidates) - head_mutineer = pick(mutineer_candidates) - current_directive = pick(directive_candidates) - - return 1 - -/datum/game_mode/mutiny/post_setup() - equip_head_loyalist() - equip_head_mutineer() - - loyalists.Add(head_loyalist) - mutineers.Add(head_mutineer) - - replace_nuke_with_ead() - current_directive.initialize() - unbolt_vault_door() - make_secret_transcript() - - update_all_icons() - spawn(0) - reveal_directives() - ..() - -/mob/living/carbon/human/proc/recruit_loyalist() - set name = "Recruit Loyalist" - set category = "Mutiny" - - var/datum/game_mode/mutiny/mode = get_mutiny_mode() - if (!mode || src != mode.head_loyalist.current) - return - - var/list/candidates = list() - for (var/mob/living/carbon/human/P in oview(src)) - if(!stat && P.client && mode.can_be_recruited(P.mind, "loyalist")) - candidates += P - - if(!candidates.len) - src << "\red You aren't close enough to anybody that can be recruited." - return - - if(world.time < mode.recruit_loyalist_cooldown) - src << "\red Wait [MUTINY_RECRUITMENT_COOLDOWN] seconds before recruiting again." - return - - mode.recruit_loyalist_cooldown = world.time + (MUTINY_RECRUITMENT_COOLDOWN SECONDS) - - var/mob/living/carbon/human/M = input("Select a person to recruit", "Loyalist recruitment", null) as mob in candidates - - if (M) - src << "Attempting to recruit [M]..." - log_admin("[src]([src.ckey]) attempted to recruit [M] as a loyalist.") - message_admins("\red [src]([src.ckey]) attempted to recruit [M] as a loyalist.") - - var/choice = alert(M, "Asked by [src]: Will you help me complete Directive X?", "Loyalist recruitment", "No", "Yes") - if(choice == "Yes") - mode.add_loyalist(M.mind) - else if(choice == "No") - M << "\red You declined to join the loyalists." - mode.head_loyalist.current << "\red [M] declined to support the loyalists." - -/mob/living/carbon/human/proc/recruit_mutineer() - set name = "Recruit Mutineer" - set category = "Mutiny" - - var/datum/game_mode/mutiny/mode = get_mutiny_mode() - if (!mode || src != mode.head_mutineer.current) - return - - var/list/candidates = list() - for (var/mob/living/carbon/human/P in oview(src)) - if(!stat && P.client && mode.can_be_recruited(P.mind, "mutineer")) - candidates += P - - if(!candidates.len) - src << "\red You aren't close enough to anybody that can be recruited." - return - - if(world.time < mode.recruit_mutineer_cooldown) - src << "\red Wait [MUTINY_RECRUITMENT_COOLDOWN] seconds before recruiting again." - return - - mode.recruit_mutineer_cooldown = world.time + (MUTINY_RECRUITMENT_COOLDOWN SECONDS) - - var/mob/living/carbon/human/M = input("Select a person to recruit", "Mutineer recruitment", null) as mob in candidates - - if (M) - src << "Attempting to recruit [M]..." - log_admin("[src]([src.ckey]) attempted to recruit [M] as a mutineer.") - message_admins("\red [src]([src.ckey]) attempted to recruit [M] as a mutineer.") - - var/choice = alert(M, "Asked by [src]: Will you help me stop Directive X?", "Mutineer recruitment", "No", "Yes") - if(choice == "Yes") - mode.add_mutineer(M.mind) - else if(choice == "No") - M << "\red You declined to join the mutineers." - mode.head_mutineer.current << "\red [M] declined to support the mutineers." - -/proc/get_mutiny_mode() - if(!ticker || !istype(ticker.mode, /datum/game_mode/mutiny)) - return null - - return ticker.mode diff --git a/code/game/gamemodes/mutiny/mutiny_admin.dm b/code/game/gamemodes/mutiny/mutiny_admin.dm deleted file mode 100644 index 2ba08def2d..0000000000 --- a/code/game/gamemodes/mutiny/mutiny_admin.dm +++ /dev/null @@ -1,83 +0,0 @@ -/datum/game_mode/mutiny/proc/check_antagonists_ui(admins) - var/turf/captains_key_loc = captains_key ? captains_key.get_loc_turf() : "Lost or Destroyed" - var/turf/secondary_key_loc = secondary_key ? secondary_key.get_loc_turf() : "Lost or Destroyed" - var/remaining_objectives = current_directive.get_remaining_orders() - var/txt = {" -
    Context:
    -

    - [current_directive.get_description()] -

    -
    Orders:
    -
      - [fluff.get_orders()] -
    -
    -
    Remaining Objectives
    -
      - [remaining_objectives ? remaining_objectives : "
    1. None
    2. "] -
    -
    -
    Authentication:
    - Captain's Key: [captains_key_loc] - Activate
    - Secondary Key: [secondary_key_loc] - Activate
    - EAD: [ead ? ead.get_status() : "Lost or Destroyed"] - Activate
    -
    - "} - - txt += "Reassign Head Loyalist
    " - if(head_loyalist) - txt += check_role_table("Head Loyalist", list(head_loyalist), admins, 0) - - var/list/loyal_crew = loyalists - head_loyalist - if(loyal_crew.len) - txt += check_role_table("Loyalists", loyal_crew, admins, 0) - - txt += "Reassign Head Mutineer
    " - if(head_mutineer) - txt += check_role_table("Head Mutineer", list(head_mutineer), admins, 0) - - var/list/mutiny_crew = mutineers - head_mutineer - if(mutiny_crew.len) - txt += check_role_table("Mutineers", mutiny_crew, admins, 0) - - if(body_count.len) - txt += check_role_table("Casualties", body_count, admins, 0) - - return txt - -/datum/game_mode/mutiny/check_antagonists_topic(href, href_list[]) - switch(href_list["choice"]) - if("activate_captains_key") - ead.captains_key = 1 - return 1 - if("activate_secondary_key") - ead.secondary_key = 1 - return 1 - if("activate_ead") - ead.activated = 1 - return 1 - if("reassign_head_loyalist") - var/mob/M = get_reassignment_candidate("Loyalist") - if(M) - head_loyalist = M.mind - equip_head_loyalist() - return 1 - if("reassign_head_mutineer") - var/mob/M = get_reassignment_candidate("Mutineer") - if(M) - head_mutineer = M.mind - equip_head_mutineer() - return 1 - else - return 0 - -/datum/game_mode/mutiny/proc/get_reassignment_candidate(faction) - var/list/targets[0] - for(var/mob/living/carbon/human/H in player_list) - if(H.is_ready() && !H.is_dead()) - targets.Add(H) - - return input("Select a player to lead the [faction] faction.", "Head [faction] reassignment", null) as mob in targets diff --git a/code/game/gamemodes/mutiny/mutiny_fluff.dm b/code/game/gamemodes/mutiny/mutiny_fluff.dm deleted file mode 100644 index 2e4ad147a8..0000000000 --- a/code/game/gamemodes/mutiny/mutiny_fluff.dm +++ /dev/null @@ -1,198 +0,0 @@ -/datum/mutiny_fluff - var/datum/game_mode/mutiny/mode - - New(datum/game_mode/mutiny/M) - mode = M - - proc/announce_directives() - for (var/obj/machinery/photocopier/faxmachine/fax in world) - if (fax.department == "Captain's Office") - var/obj/item/weapon/paper/directive_x = new(fax.loc) - directive_x.name = "emergency action message" - directive_x.info = get_fax_body() - - proc/get_fax_body() - return {" -
    NOT A DRILL . . . EMERGENCY DIRECTIVE . . . NOT A DRILL
    -

    - TO: Captain [mode.head_loyalist], Commanding Officer, [station_name()]
    - FROM: NanoTrasen Emergency Messaging Relay
    - DATE: [time2text(world.realtime, "MM/DD")]/[game_year]
    - SUBJECT: Directive X
    -

    - - [mode.current_directive.get_description()] - -
    -
    Emergency Authentication Protocol
    -

    - A member of your Command Staff is this shift's designated Emergency Secondary Authenticator.
    - This Emergency Secondary Authenticator is uniquely aware of their role and possesses the Emergency Secondary Authentication Key.
    - As Captain, you possess the Captain's Authentication Key.
    - The Emergency Authentication Device is located in the vault of your station, and requires simultaneous activation of the Authentication Keys.
    - An Authentication Key Pinpointer can be delivered via Cargo Bay to assist recovery of the Authentication Keys should they be lost aboard the station.
    - A key's destruction or removal from the station's perimeter will automatically and irreversibly activate the Emergency Authentication Device. -

    -
    - -
    Orders
    -

    - Captain [mode.head_loyalist], you are to immediately initiate the following procedure; codenamed Directive X: -

    -
      - [get_orders()] -
    -
    - -
    Authentication
    - - Encoded Authentication String: T0JCJUwoIVFDQA==
    - Emergency Action Code: O B B _ L _ _ Q C _
    - ERROR: DECODING INCOMPLETE (40% LOSS) -
    -
    -
    - -
    NOT A DRILL . . . EMERGENCY DIRECTIVE . . . NOT A DRILL
    - "} - - proc/get_orders() - var/text = "
  • Immediate external transmission and signals silence. Evacuation and Cargo services will remain available. All ERT teams are engaged elsewhere. Do not communicate with Central Command under any circumstances.
  • " - for(var/order in mode.current_directive.special_orders) - text += "
  • [order]
  • " - - text += "
  • Upon completion of this Directive, Captain [mode.head_loyalist] and the Emergency Secondary Authenticator must utilise the Captain's Authentication Key and the Emergency Secondary Authentication Key to activate the Emergency Authentication Device.
  • " - return text - - proc/get_pda_body() - return {"← From Anonymous Channel:

    \"You must read this! NanoTrasen Chain of Command COMPROMISED. Command Encryptions BROKEN. [station_name()] Captain [mode.head_loyalist] will receive orders that must NOT BE BROUGHT TO FRUITION! - -They don't care about us they only care about WEALTH and POWER... Share this message with people you trust. - -Be safe, friend.\" (Unable to Reply)

    "} - - proc/announce() - world << "The current game mode is - Mutiny!" - world << {" -

    The crew will be divided by their sense of ethics when a morally turbulent emergency directive arrives with an incomplete command validation code.

    -The [loyalist_tag("Head Loyalist")] is the Captain, who carries the [loyalist_tag("Captain's Authentication Key")] at all times.
    -The [mutineer_tag("Head Mutineer")] is a random Head of Staff who carries the [mutineer_tag("Emergency Secondary Authentication Key")].

    -Both keys are required to activate the Emergency Authentication Device (EAD) in the vault, signalling to NanoTrasen that the directive is complete. -
    -

    -Loyalists - Follow the Head Loyalist in carrying out [loyalist_tag("NanoTrasen's directives")] then activate the EAD.
    -Mutineers - Prevent the completion of the [mutineer_tag("improperly validated directives")] and the activation of the EAD. -

    - "} - - proc/loyalist_tag(text) - return "[text]" - - proc/mutineer_tag(text) - return "[text]" - - proc/their(datum/mind/head) - if (head.current.gender == MALE) - return "his" - else if (head.current.gender == FEMALE) - return "her" - - return "their" - - proc/loyalist_major_victory() - return {" -NanoTrasen has praised the efforts of Captain [mode.head_loyalist] and loyal members of [their(mode.head_loyalist)] crew, who recently managed to put down a mutiny--amid a local interstellar crisis--aboard the [station_name()], a research station in [system_name()]. -The mutiny was spurred by a top secret directive sent to the station, presumably in response to the crisis within the system. -Despite the mutiny, the crew was successful in implementing the directive and activating their on-board emergency authentication device. -[mode.mutineers.len] members of the station's personnel were charged with terrorist action against the Company and, if found guilty by a Sol magistrate, will be sentenced to life incarceration. -NanoTrasen will be awarding [mode.loyalists.len] members of the crew with the [loyalist_tag("Star of Loyalty")], following their successful efforts, at a ceremony this coming Thursday. -[mode.body_count.len] are believed to have died during the coup. -

    NanoTrasen's image will forever be haunted by the fact that a mutiny took place on one of its own stations.

    - "} - - proc/loyalist_minor_victory() - return {" -NanoTrasen has praised the efforts of Captain [mode.head_loyalist] and loyal members of [their(mode.head_loyalist)] crew, who recently managed to put down a mutiny--amid a local interstellar crisis--aboard the [station_name()], a research station in [system_name()]. -The mutiny was spurred by a top secret directive sent to the station, presumably in response to the crisis within the system. -Despite the mutiny, the crew was successful in implementing the directive. Unfortunately, they failed to notify Central Command of their successes due to a breach in the chain of command. -[mode.mutineers.len] members of the station's personnel were charged with terrorist action against the Company and, if found guilty by a Sol magistrate, will be sentenced to life incarceration. -NanoTrasen will be awarding [mode.loyalists.len] members of the crew with the [loyalist_tag("Star of Loyalty")], following their mostly successful efforts, at a ceremony this coming Thursday. -[mode.body_count.len] are believed to have died during the coup. -

    NanoTrasen's image will forever be haunted by the fact that a mutiny took place on one of its own stations.

    - "} - - proc/no_victory() - return {" -NanoTrasen has been thrust into turmoil following an apparent mutiny by key personnel aboard the [station_name()], a research station in [system_name()]. -The mutiny was spurred by a top secret directive sent to the station, presumably in response to the crisis within the system. -No further information has yet emerged from the station or its crew, who are presumed to be in holding with NanoTrasen investigators. -NanoTrasen officials refuse to comment. -Sources indicate that [mode.mutineers.len] members of the station's personnel are currently under investigation for terrorist activity, and [mode.loyalists.len] crew are currently providing evidence to investigators, believed to be the 'loyal' station personnel. -[mode.body_count.len] are believed to have died during the coup. -

    NanoTrasen's image will forever be haunted by the fact that a mutiny took place on one of its own stations.

    - "} - - proc/mutineer_minor_victory() - return {" -Reports have emerged that an impromptu mutiny has taken place, amid a local interstellar crisis, aboard the [station_name()], a research station in [system_name()]. -The mutiny was spurred by a top secret directive sent to the station, presumably in response to the crisis within the system. -Information at present indicates that the top-secret directive--which has since been retracted--was invalid due to a broken authentication code. Members of the crew, including an unidentified Head of Staff, prevented the directive from being accomplished. -[mode.mutineers.len] members of the station's personnel were released from interrogations today, following a mutiny investigation. -NanoTrasen has reprimanded [mode.loyalists.len] members of the crew for failing to follow command validation procedures. -[mode.body_count.len] are believed to have died during the coup. -

    Even though the directive was not successfully implemented, NanoTrasen's image will forever be haunted by the fact that its authentication protocol was breached with such magnitude and that a mutiny was the result.

    - "} - - proc/mutineer_major_victory() - return {" -NanoTrasen has praised the efforts of [mode.head_mutineer.assigned_role] [mode.head_mutineer] and several other members of the crew, who recently seized control of a company station in [system_name()]--[station_name()]--amid a local interstellar crisis. -What appears to have been a "legitimate" mutiny was spurred by a top secret directive sent to the station, presumably in response to the crisis within the system. -It has been revealed that the directive was invalid and fraudulent. Company officials have not released a statement about the source of the directive. -Thanks to the efforts of the resistant members of the crew, the directive was not carried out. -[mode.mutineers.len] members of the station's personnel were congratulated and awarded with the [mutineer_tag("Star of Bravery")], for their efforts in preventing the illegal directive's completion. -NanoTrasen has [mode.loyalists.len] members of the crew in holding, while it investigates the circumstances that led to the acceptance and initiation of an invalid directive. -[mode.body_count.len] are believed to have died during the coup. -

    Even though the directive was not successfully implemented, NanoTrasen's image will forever be haunted by the fact that its authentication protocol was breached with such magnitude and that a mutiny was the result.

    - "} - - proc/secret_transcript() - return {" -

    Corporate Rival Threat Assessment

    -
    Gilthari Exports Incident Transcript
    -
    CONFIDENTIAL: PROPERTY OF NANOTRASEN
    -Location: Operator's Desk, D Deck, Polumetis Installation
    -Time: 16:11, May 24, 2558 (Sol Reckoning)
    -
    -
    - -
    \[Start of transcript\]
    -
    \[Sound of an internal airlock door opening\]
    -TM: Thank you for coming to see me, Director. I'm afraid this is urgent.
    -D: Mr. Mitchell, first you send cryptic messages to my office and then you request to have me come personally to this barely lit closet you call a workstation; all of this to talk about a computer glitch?
    -
    \[Sound of the internal airlock door shutting\]
    -TM: Do you remember Mallory?
    -D: Who?
    -TM: It's not who, it's what. The computer program we planted in the [system_name()] communications satellite.
    -D: What is so important about this computer program?
    -TM: We call her an eavesdropper. Captures network traffic, records it, and forwards the stream to the receiver autonomously.
    -D: Speak English goddamnit.
    -TM: Standard intelligence acquisition package, sir; we bug their satellite and listen. It's like we have their playbook and we know what their moves are going to be on the market before they make them.
    -D: So Mallory doesn't work?
    -TM: She worked, sir. We've had an ear on NanoTrasen's regional communications for weeks.
    -D: Any news about their Phoron refinement process?
    -TM: No sir. Our analysts believe they are using a separate channel for their most sensitive data.
    -D: So what's the problem?
    -TM: The intelligence hasn't been doing us any good. Anything that appears actionable, I send it to the analysts and they make a plan. Thing is, NanoTrasen always sees us coming.
    -D: Tim...
    -TM: I think they discovered the hack, sir. Case in point, Energine Consolidated Solutions. That subsidiary of ours that was awarded a lease on NanoTrasen's mining platform in Nyx? NanoTrasen acquired them a week before we made the announcement.
    -D: They know about they have a bug. They left her on and fed her the information for us to hear, those sneaks. How did they find it?
    -TM: Top secret communique came through. I'm not sure what happened. Either Mallory couldn't replicate the encryption scheme and garbled it going out or the transmission was already corrupted to begin with.
    -D: Either way the transmission caused NanoTrasen to look at the satellite. They found out about Mallory.
    -TM: Precisely sir. There's only so much I can do to cover our tracks from here.
    -D: I'm pulling the plug. We have assets in the sector that are capable of a job like this. Thank you for bringing this to my attention.
    -
    \[Computer device chirps\]
    -D: One last thing, did you happen to read anything from those secure transmissions?
    -TM: Just the subject, 'Directive X'.
    -D: Directive X... Now what do you suppose that means?
    -
    \[End of transcript\]
    - "} diff --git a/code/game/gamemodes/mutiny/mutiny_hooks.dm b/code/game/gamemodes/mutiny/mutiny_hooks.dm deleted file mode 100644 index 9e64bd2e70..0000000000 --- a/code/game/gamemodes/mutiny/mutiny_hooks.dm +++ /dev/null @@ -1,27 +0,0 @@ -/hook/death/proc/track_kills(mob/living/carbon/human/deceased, gibbed) - var/datum/game_mode/mutiny/mode = get_mutiny_mode() - if (!mode) return 1 - - mode.body_count.Add(deceased.mind) - return 1 - -/hook/clone/proc/update_icon(mob/living/carbon/human/H) - var/datum/game_mode/mutiny/mode = get_mutiny_mode() - if (!mode) return 1 - - mode.update_icon(H.mind) - return 1 - -/hook/harvest_podman/proc/update_icon(mob/living/carbon/alien/diona/D) - var/datum/game_mode/mutiny/mode = get_mutiny_mode() - if (!mode) return 1 - - mode.update_icon(D.mind) - return 1 - -/hook/roundend/proc/report_mutiny_news() - var/datum/game_mode/mutiny/mode = get_mutiny_mode() - if (!mode) return 1 - - mode.round_outcome() - return 1 diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm index 949e6bfc77..9dc8623822 100644 --- a/code/game/gamemodes/newobjective.dm +++ b/code/game/gamemodes/newobjective.dm @@ -563,7 +563,7 @@ datum captainslaser - steal_target = /obj/item/weapon/gun/energy/laser/captain + steal_target = /obj/item/weapon/gun/energy/captain explanation_text = "Steal the captain's antique laser gun." weight = 20 diff --git a/code/game/gamemodes/ninja/ninja.dm b/code/game/gamemodes/ninja/ninja.dm index 87a15e622d..d410dbeb7d 100644 --- a/code/game/gamemodes/ninja/ninja.dm +++ b/code/game/gamemodes/ninja/ninja.dm @@ -1,184 +1,10 @@ -/datum/game_mode/var/list/datum/mind/ninjas = list() -// Keep in mind ninja-procs that aren't here will be where the event's defined /datum/game_mode/ninja name = "ninja" + round_description = "An agent of the Spider Clan is onboard the station!" + extended_round_description = "What was that?! Was that a person or did your eyes just play tricks on you? You have no idea. That slim-suited, cryptic individual is an enigma to you and all of your knowledge. Their purpose is unknown. Their mission is unknown. How they arrived to this secure and isolated section of the galaxy, you don't know. What you do know is that there is a silent shadow-stalker piercing through the defenses of Nanotrasen with technological capabilities eons ahead of your time. They can avoid the omniscience of the AI and rival the most hardened weapons your station is capable of. Tread lightly and only hope this unknown assassin isn't here for you." + antag_tag = MODE_NINJA config_tag = "ninja" - required_players = 10 //Can be adjusted later, should suffice for now. + required_players = 1 required_players_secret = 10 required_enemies = 1 - recommended_enemies = 1 - var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) - var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) - var/finished = 0 - -/datum/game_mode/ninja/announce() - world << "The current game mode is Ninja!" - -/datum/game_mode/ninja/can_start() - if(!..()) - return 0 - var/list/datum/mind/possible_ninjas = get_players_for_role(BE_NINJA) - if(possible_ninjas.len==0) - return 0 - var/datum/mind/ninja = pick(possible_ninjas) - ninjas += ninja - modePlayer += ninja - ninja.assigned_role = "MODE" //So they aren't chosen for other jobs. - ninja.special_role = "Ninja" - ninja.original = ninja.current - - /*if(ninjastart.len == 0) - ninja.current << "\red A proper starting location for you could not be found, please report this bug!" - ninja.current << "\red Attempting to place at a carpspawn."*/ - - //Until such a time as people want to place ninja spawn points, carpspawn will do fine. - for(var/obj/effect/landmark/L in landmarks_list) - if(L.name == "carpspawn") - ninjastart.Add(L) - if(ninjastart.len == 0 && latejoin.len > 0) - ninja.current << "\red No spawneable locations could be found. Defaulting to latejoin." - return 1 - else if (ninjastart.len == 0) - ninja.current << "\red No spawneable locations could be found. Aborting." - return 0 - - return 1 - -/datum/game_mode/ninja/pre_setup() - for(var/datum/mind/ninja in ninjas) - ninja.current << browse(null, "window=playersetup") - ninja.current = create_space_ninja(pick(ninjastart.len ? ninjastart : latejoin)) - ninja.current.ckey = ninja.key - return 1 - -/datum/game_mode/ninja/post_setup() - - for(var/datum/mind/ninja in ninjas) - if(ninja.current && !(istype(ninja.current,/mob/living/carbon/human))) return 0 - if(!config.objectives_disabled) - forge_ninja_objectives(ninja) - show_objectives(ninja) - - spawn (rand(waittime_l, waittime_h)) - send_intercept() - return ..() - -/datum/game_mode/ninja/check_finished() - if(config.continous_rounds) - return ..() - var/ninjas_alive = 0 - for(var/datum/mind/ninja in ninjas) - if(!istype(ninja.current,/mob/living/carbon/human)) - continue - if(ninja.current.stat==2) - continue - ninjas_alive++ - if (ninjas_alive) - return ..() - else - finished = 1 - return 1 - -/datum/game_mode/ninja/proc/forge_ninja_objectives(var/datum/mind/ninja) - if (config.objectives_disabled) - return - - var/objective_list = list(1,2,3,4,5) - for(var/i=rand(2,4),i>0,i--) - switch(pick(objective_list)) - if(1)//Kill - var/datum/objective/assassinate/ninja_objective = new - ninja_objective.owner = ninja - ninja_objective.target = ninja_objective.find_target() - if(ninja_objective.target != "Free Objective") - ninja.objectives += ninja_objective - else - i++ - objective_list -= 1 // No more than one kill objective - if(2)//Steal - var/datum/objective/steal/ninja_objective = new - ninja_objective.owner = ninja - ninja_objective.target = ninja_objective.find_target() - ninja.objectives += ninja_objective - if(3)//Protect - var/datum/objective/protect/ninja_objective = new - ninja_objective.owner = ninja - ninja_objective.target = ninja_objective.find_target() - if(ninja_objective.target != "Free Objective") - ninja.objectives += ninja_objective - else - i++ - objective_list -= 3 - if(4)//Download - var/datum/objective/download/ninja_objective = new - ninja_objective.owner = ninja - ninja_objective.gen_amount_goal() - ninja.objectives += ninja_objective - objective_list -= 4 - if(5)//Harm - var/datum/objective/harm/ninja_objective = new - ninja_objective.owner = ninja - ninja_objective.target = ninja_objective.find_target() - if(ninja_objective.target != "Free Objective") - ninja.objectives += ninja_objective - else - i++ - objective_list -= 5 - - var/datum/objective/survive/ninja_objective = new - ninja_objective.owner = ninja - ninja.objectives += ninja_objective - ninja.current.mind = ninja - - var/directive = generate_ninja_directive("heel")//Only hired by antags, not NT - ninja.current << "You are an elite mercenary assassin of the Spider Clan, [ninja.current.real_name]. You have a variety of abilities at your disposal, thanks to your nano-enhanced cyber armor.\nYour current directive is: \red [directive]\n \blue Try your best to adhere to this." - ninja.store_memory("Directive: \red [directive]
    ") - - show_objectives(ninja) - -/datum/game_mode/proc/auto_declare_completion_ninja() - if(ninjas.len) - var/text = "The ninjas were:" - for(var/datum/mind/ninja in ninjas) - var/ninjawin = 1 - - text += "
    [ninja.key] was [ninja.name] (" - if(ninja.current) - if(ninja.current.stat == DEAD) - text += "died" - else - text += "survived" - if(ninja.current.real_name != ninja.name) - text += " as [ninja.current.real_name]" - else - text += "body destroyed" - text += ")" - - if(ninja.objectives.len)//If the ninja had no objectives, don't need to process this. - var/count = 1 - for(var/datum/objective/objective in ninja.objectives) - if(objective.check_completion()) - text += "
    Objective #[count]: [objective.explanation_text] Success!" - feedback_add_details("traitor_objective","[objective.type]|SUCCESS") - else - text += "
    Objective #[count]: [objective.explanation_text] Fail." - feedback_add_details("traitor_objective","[objective.type]|FAIL") - ninjawin = 0 - count++ - - var/special_role_text - if(ninja.special_role) - special_role_text = lowertext(ninja.special_role) - else - special_role_text = "antagonist" - - if(!config.objectives_disabled) - if(ninjawin) - text += "
    The [special_role_text] was successful!" - feedback_add_details("traitor_success","SUCCESS") - else - text += "
    The [special_role_text] has failed!" - feedback_add_details("traitor_success","FAIL") - - world << text - return 1 + end_on_antag_death = 1 \ No newline at end of file diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index b2e54da0d9..b556ba2070 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -2,245 +2,21 @@ MERCENARY ROUNDTYPE */ -var/global/list/turf/synd_spawn = list() - - -/datum/game_mode - var/list/datum/mind/syndicates = list() - - /datum/game_mode/nuclear - name = "mercenary" + name = "Mercenary" + round_description = "A mercenary strike force is approaching the station!" config_tag = "mercenary" required_players = 15 required_players_secret = 25 // 25 players - 5 players to be the nuke ops = 20 players remaining required_enemies = 1 - recommended_enemies = 5 + end_on_antag_death = 1 + antag_tag = MODE_MERCENARY uplink_welcome = "Corporate Backed Uplink Console:" uplink_uses = 40 - - var/const/agents_possible = 5 //If we ever need more syndicate agents. - var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) - var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) - - var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer! var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level - -/datum/game_mode/nuclear/announce() - world << "The current game mode is - Mercenary!" - world << "A [syndicate_name()] Strike Force is approaching [station_name()]!" - -/datum/game_mode/nuclear/can_start()//This could be better, will likely have to recode it later - if(!..()) - return 0 - - var/list/possible_syndicates = get_players_for_role(BE_OPERATIVE) - var/agent_number = 0 - - /* - * if(possible_syndicates.len > agents_possible) - * agent_number = agents_possible - * else - * agent_number = possible_syndicates.len - * - * if(agent_number > n_players) - * agent_number = n_players/2 - */ - - if(possible_syndicates.len < 1) - return 0 - - //Antag number should scale to active crew. - var/n_players = num_players() - agent_number = Clamp((n_players/5), 2, 6) - - if(possible_syndicates.len < agent_number) - agent_number = possible_syndicates.len - - while(agent_number > 0) - var/datum/mind/new_syndicate = pick(possible_syndicates) - syndicates += new_syndicate - possible_syndicates -= new_syndicate //So it doesn't pick the same guy each time. - agent_number-- - - for(var/datum/mind/synd_mind in syndicates) - synd_mind.assigned_role = "MODE" //So they aren't chosen for other jobs. - synd_mind.special_role = "Mercenary"//So they actually have a special role/N - return 1 - - -/datum/game_mode/nuclear/pre_setup() - return 1 - - -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/proc/update_all_synd_icons() - spawn(0) - for(var/datum/mind/synd_mind in syndicates) - if(synd_mind.current) - if(synd_mind.current.client) - for(var/image/I in synd_mind.current.client.images) - if(I.icon_state == "synd") - del(I) - - for(var/datum/mind/synd_mind in syndicates) - if(synd_mind.current) - if(synd_mind.current.client) - for(var/datum/mind/synd_mind_1 in syndicates) - if(synd_mind_1.current) - var/I = image('icons/mob/mob.dmi', loc = synd_mind_1.current, icon_state = "synd") - synd_mind.current.client.images += I - -/datum/game_mode/proc/update_synd_icons_added(datum/mind/synd_mind) - spawn(0) - if(synd_mind.current) - if(synd_mind.current.client) - var/I = image('icons/mob/mob.dmi', loc = synd_mind.current, icon_state = "synd") - synd_mind.current.client.images += I - -/datum/game_mode/proc/update_synd_icons_removed(datum/mind/synd_mind) - spawn(0) - for(var/datum/mind/synd in syndicates) - if(synd.current) - if(synd.current.client) - for(var/image/I in synd.current.client.images) - if(I.icon_state == "synd" && I.loc == synd_mind.current) - del(I) - - if(synd_mind.current) - if(synd_mind.current.client) - for(var/image/I in synd_mind.current.client.images) - if(I.icon_state == "synd") - del(I) - -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -/datum/game_mode/nuclear/post_setup() - - var/obj/effect/landmark/uplinkdevice = locate("landmark*Syndicate-Uplink") //i will be rewriting this shortly - var/obj/effect/landmark/nuke_spawn = locate("landmark*Nuclear-Bomb") - - var/nuke_code = "[rand(10000, 99999)]" - var/datum/mind/leader = null - var/spawnpos = 1 - - for(var/datum/mind/synd_mind in syndicates) - if(spawnpos > synd_spawn.len) - spawnpos = 1 - synd_mind.current.loc = synd_spawn[spawnpos] - - synd_mind.current.real_name = "[syndicate_name()] Operative" // placeholder while we get their actual name - spawn(0) - NukeNameAssign(synd_mind) - - forge_syndicate_objectives(synd_mind) - greet_syndicate(synd_mind) - equip_syndicate(synd_mind.current) - - if(!leader) - prepare_syndicate_leader(synd_mind, nuke_code) - leader = synd_mind - - spawnpos++ - update_synd_icons_added(synd_mind) - - update_all_synd_icons() - - if(uplinkdevice) - var/obj/item/device/radio/uplink/U = new(uplinkdevice.loc) - if(leader) - U.hidden_uplink.uplink_owner = leader - U.hidden_uplink.uses = 40 - if(nuke_spawn && synd_spawn.len > 0) - var/obj/machinery/nuclearbomb/the_bomb = new /obj/machinery/nuclearbomb(nuke_spawn.loc) - the_bomb.r_code = nuke_code - - spawn (rand(waittime_l, waittime_h)) - send_intercept() - - return ..() - - -/datum/game_mode/proc/prepare_syndicate_leader(var/datum/mind/synd_mind, var/nuke_code) - var/obj/effect/landmark/code_spawn = locate("landmark*Nuclear-Code") - if (nuke_code) - synd_mind.store_memory("Nuclear Bomb Code: [nuke_code]", 0, 0) - synd_mind.current << "The nuclear authorization code is: [nuke_code]" - synd_mind.current << "To speak on the strike team's private channel use :t" - var/obj/item/weapon/paper/P = new - P.info = "The nuclear authorization code is: [nuke_code]" - P.name = "nuclear bomb code" - if (ticker.mode.config_tag=="mercenary") - P.loc = code_spawn.loc - else - var/mob/living/carbon/human/H = synd_mind.current - P.loc = H.loc - H.equip_to_slot_or_del(P, slot_r_store, 0) - H.update_icons() - - else - nuke_code = "code will be provided later" - return - - -/datum/game_mode/proc/forge_syndicate_objectives(var/datum/mind/syndicate) - - if (config.objectives_disabled) - return - - var/datum/objective/nuclear/syndobj = new - syndobj.owner = syndicate - syndicate.objectives += syndobj - -/datum/game_mode/proc/greet_syndicate(var/datum/mind/syndicate, var/you_are=1) - if (you_are) - syndicate.current << "\blue You are a [syndicate_name()] operative!" - show_objectives(syndicate) - -/datum/game_mode/proc/random_radio_frequency() - return 1337 // WHY??? -- Doohl - - -/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob) - var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate(synd_mob) - R.set_frequency(SYND_FREQ) - R.freerange = 1 - synd_mob.equip_to_slot_or_del(R, slot_l_ear) - - synd_mob.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(synd_mob), slot_w_uniform) - synd_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(synd_mob), slot_shoes) - synd_mob.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(synd_mob), slot_gloves) - synd_mob.equip_to_slot_or_del(new /obj/item/weapon/card/id/syndicate(synd_mob), slot_wear_id) - if(synd_mob.backbag == 2) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(synd_mob), slot_back) - if(synd_mob.backbag == 3) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(synd_mob), slot_back) - if(synd_mob.backbag == 4) synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(synd_mob), slot_back) - synd_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(synd_mob.back), slot_in_backpack) - synd_mob.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(synd_mob), slot_in_backpack) - - synd_mob.update_icons() - return 1 - - -/datum/game_mode/nuclear/check_win() - if (nukes_left == 0) - return 1 - return ..() - - -/datum/game_mode/proc/is_operatives_are_dead() - for(var/datum/mind/operative_mind in syndicates) - if (!istype(operative_mind.current,/mob/living/carbon/human)) - if(operative_mind.current) - if(operative_mind.current.stat!=2) - return 0 - return 1 - - /datum/game_mode/nuclear/declare_completion() if(config.objectives_disabled) return @@ -251,20 +27,13 @@ var/global/list/turf/synd_spawn = list() disk_rescued = 0 break var/crew_evacuated = (emergency_shuttle.returned()) - //var/operatives_are_dead = is_operatives_are_dead() - - - //nukes_left - //station_was_nuked - //derp //Used for tracking if the syndies actually haul the nuke to the station //no - //herp //Used for tracking if the syndies got the shuttle off of the z-level //NO, DON'T FUCKING NAME VARS LIKE THIS if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) feedback_set_details("round_end_result","win - syndicate nuke") world << "Mercenary Major Victory!" world << "[syndicate_name()] operatives have destroyed [station_name()]!" - else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) + else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) feedback_set_details("round_end_result","halfwin - syndicate nuke - did not evacuate in time") world << "Total Annihilation" world << "[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!" @@ -274,12 +43,12 @@ var/global/list/turf/synd_spawn = list() world << "Crew Minor Victory" world << "[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't lose the disk!" - else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) + else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) feedback_set_details("round_end_result","halfwin - blew wrong station - did not evacuate in time") world << "[syndicate_name()] operatives have earned Darwin Award!" world << "[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't lose the disk!" - else if ( disk_rescued && is_operatives_are_dead()) + else if (disk_rescued && mercs.antags_are_dead()) feedback_set_details("round_end_result","loss - evacuation - disk secured - syndi team dead") world << "Crew Major Victory!" world << "The Research Staff has saved the disc and killed the [syndicate_name()] Operatives" @@ -289,58 +58,20 @@ var/global/list/turf/synd_spawn = list() world << "Crew Major Victory" world << "The Research Staff has saved the disc and stopped the [syndicate_name()] Operatives!" - else if (!disk_rescued && is_operatives_are_dead()) + else if (!disk_rescued && mercs.antags_are_dead()) feedback_set_details("round_end_result","loss - evacuation - disk not secured") world << "Mercenary Minor Victory!" world << "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!" - else if (!disk_rescued && crew_evacuated) + else if (!disk_rescued && crew_evacuated) feedback_set_details("round_end_result","halfwin - detonation averted") world << "Mercenary Minor Victory!" world << "[syndicate_name()] operatives recovered the abandoned authentication disk but detonation of [station_name()] was averted. Next time, don't lose the disk!" - else if (!disk_rescued && !crew_evacuated) + else if (!disk_rescued && !crew_evacuated) feedback_set_details("round_end_result","halfwin - interrupted") world << "Neutral Victory" world << "Round was mysteriously interrupted!" ..() return - - -/datum/game_mode/proc/auto_declare_completion_nuclear() - if( syndicates.len || (ticker && istype(ticker.mode,/datum/game_mode/nuclear)) ) - var/text = "The mercenaries were:" - - for(var/datum/mind/syndicate in syndicates) - text += print_player_full(syndicate) - - world << text - return 1 - - -/*/proc/nukelastname(var/mob/M as mob) //--All praise goes to NEO|Phyte, all blame goes to DH, and it was Cindi-Kate's idea. Also praise Urist for copypasta ho. - var/randomname = pick(last_names) - var/newname = copytext(sanitize(input(M,"You are the nuke operative [pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")]. Please choose a last name for your family.", "Name change",randomname)),1,MAX_NAME_LEN) - - if (!newname) - newname = randomname - - else - if (newname == "Unknown" || newname == "floor" || newname == "wall" || newname == "rwall" || newname == "_") - M << "That name is reserved." - return nukelastname(M) - - return newname -*/ - -/proc/NukeNameAssign(var/datum/mind/synd_mind) - var/choose_name = input(synd_mind.current, "You are a [syndicate_name()] agent! What is your name?", "Choose a name") as text - - if(!choose_name) - return - - else - synd_mind.current.name = choose_name - synd_mind.current.real_name = choose_name - return \ No newline at end of file diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 534383867e..ba53c38525 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -119,9 +119,8 @@ datum/objective/mutiny/rp if(target.current.stat == DEAD || target.current:handcuffed || !ishuman(target.current)) return 1 // Check if they're converted - if(istype(ticker.mode, /datum/game_mode/revolution)) - if(target in ticker.mode:head_revolutionaries) - return 1 + if(target in revs.head_revolutionaries) + return 1 var/turf/T = get_turf(target.current) if(T && isNotStationLevel(T.z)) //If they leave the station they count as dead for this rval = 2 @@ -480,7 +479,7 @@ datum/objective/steal var/target_name var/global/possible_items[] = list( - "the captain's antique laser gun" = /obj/item/weapon/gun/energy/laser/captain, + "the captain's antique laser gun" = /obj/item/weapon/gun/energy/captain, "a hand teleporter" = /obj/item/weapon/hand_tele, "an RCD" = /obj/item/weapon/rcd, "a jetpack" = /obj/item/weapon/tank/jetpack, @@ -537,7 +536,7 @@ datum/objective/steal var/tmp_obj = new custom_target var/custom_name = tmp_obj:name del(tmp_obj) - custom_name = sanitize(copytext(input("Enter target name:", "Objective target", custom_name) as text|null,1,MAX_MESSAGE_LEN)) + custom_name = sanitize(input("Enter target name:", "Objective target", custom_name) as text|null) if (!custom_name) return target_name = custom_name steal_target = custom_target @@ -650,9 +649,6 @@ datum/objective/capture continue captured_amount += worth - for(var/mob/living/carbon/monkey/M in A)//Monkeys are almost worthless, you failure. - captured_amount+=0.1 - for(var/mob/living/carbon/alien/larva/M in A)//Larva are important for research. if(M.stat==2) captured_amount+=0.5 @@ -665,8 +661,7 @@ datum/objective/capture return 1 - -datum/objective/absorb +/datum/objective/absorb proc/gen_amount_goal(var/lowbound = 4, var/highbound = 6) target_amount = rand (lowbound,highbound) if (ticker) @@ -677,7 +672,7 @@ datum/objective/absorb n_p ++ else if (ticker.current_state == GAME_STATE_PLAYING) for(var/mob/living/carbon/human/P in player_list) - if(P.client && !(P.mind in ticker.mode.changelings) && P.mind!=owner) + if(P.client && !(P.mind.changeling) && P.mind!=owner) n_p ++ target_amount = min(target_amount, n_p) @@ -690,67 +685,7 @@ datum/objective/absorb else return 0 - - -/* Isn't suited for global objectives -/*---------CULTIST----------*/ - - eldergod - explanation_text = "Summon Nar-Sie via the use of an appropriate rune. It will only work if nine cultists stand on and around it." - - check_completion() - if(eldergod) //global var, defined in rune4.dm - return 1 - return 0 - - survivecult - var/num_cult - - explanation_text = "Our knowledge must live on. Make sure at least 5 acolytes escape on the shuttle to spread their work on an another station." - - check_completion() - if(!emergency_shuttle.returned()) - return 0 - - var/cultists_escaped = 0 - - var/area/shuttle/escape/centcom/C = /area/shuttle/escape/centcom - for(var/turf/T in get_area_turfs(C.type)) - for(var/mob/living/carbon/H in T) - if(iscultist(H)) - cultists_escaped++ - - if(cultists_escaped>=5) - return 1 - - return 0 - - sacrifice //stolen from traitor target objective - - proc/find_target() //I don't know how to make it work with the rune otherwise, so I'll do it via a global var, sacrifice_target, defined in rune15.dm - var/list/possible_targets = call(/datum/game_mode/cult/proc/get_unconvertables)() - - if(possible_targets.len > 0) - sacrifice_target = pick(possible_targets) - - if(sacrifice_target && sacrifice_target.current) - explanation_text = "Sacrifice [sacrifice_target.current.real_name], the [sacrifice_target.assigned_role]. You will need the sacrifice rune (Hell join blood) and three acolytes to do so." - else - explanation_text = "Free Objective" - - return sacrifice_target - - check_completion() //again, calling on a global list defined in rune15.dm - if(sacrifice_target.current in sacrificed) - return 1 - else - return 0 - -/*-------ENDOF CULTIST------*/ -*/ - -//Vox heist objectives. - +// Heist objectives. datum/objective/heist proc/choose_target() return @@ -775,7 +710,7 @@ datum/objective/heist/kidnap target = pick(possible_targets) if(target && target.current) - explanation_text = "The Shoal has a need for [target.current.real_name], the [target.assigned_role]. Take them alive." + explanation_text = "We can get a good price for [target.current.real_name], the [target.assigned_role]. Take them alive." else explanation_text = "Free Objective" return target @@ -787,7 +722,7 @@ datum/objective/heist/kidnap //if (!target.current.restrained()) // return 0 // They're loose. Close but no cigar. - var/area/shuttle/vox/station/A = locate() + var/area/shuttle/skipjack/station/A = locate() for(var/mob/living/carbon/human/M in A) if(target.current == M) return 1 //They're restrained on the shuttle. Success. @@ -832,20 +767,19 @@ datum/objective/heist/loot target_amount = 1 loot = "an ion gun" - explanation_text = "We are lacking in hardware. Steal [loot]." + explanation_text = "It's a buyer's market out here. Steal [loot] for resale." check_completion() var/total_amount = 0 - for(var/obj/O in locate(/area/shuttle/vox/station)) + for(var/obj/O in locate(/area/shuttle/skipjack/station)) if(istype(O,target)) total_amount++ for(var/obj/I in O.contents) if(istype(I,target)) total_amount++ if(total_amount >= target_amount) return 1 - var/datum/game_mode/heist/H = ticker.mode - for(var/datum/mind/raider in H.raiders) + for(var/datum/mind/raider in raiders.current_antagonists) if(raider.current) for(var/obj/O in raider.current.get_contents()) if(istype(O,target)) total_amount++ @@ -888,7 +822,7 @@ datum/objective/heist/salvage var/total_amount = 0 - for(var/obj/item/O in locate(/area/shuttle/vox/station)) + for(var/obj/item/O in locate(/area/shuttle/skipjack/station)) var/obj/item/stack/sheet/S if(istype(O,/obj/item/stack/sheet)) @@ -901,8 +835,7 @@ datum/objective/heist/salvage S = I total_amount += S.get_amount() - var/datum/game_mode/heist/H = ticker.mode - for(var/datum/mind/raider in H.raiders) + for(var/datum/mind/raider in raiders.current_antagonists) if(raider.current) for(var/obj/item/O in raider.current.get_contents()) if(istype(O,/obj/item/stack/sheet)) @@ -914,26 +847,14 @@ datum/objective/heist/salvage return 0 -datum/objective/heist/inviolate_crew - explanation_text = "Do not leave any Vox behind, alive or dead." +/datum/objective/heist/preserve_crew + explanation_text = "Do not leave anyone behind, alive or dead." check_completion() - var/datum/game_mode/heist/H = ticker.mode - if(H.is_raider_crew_safe()) return 1 + if(raiders && raiders.is_raider_crew_safe()) return 1 return 0 -#define MAX_VOX_KILLS 10 //Number of kills during the round before the Inviolate is broken. - //Would be nice to use vox-specific kills but is currently not feasible. -var/global/vox_kills = 0 //Used to check the Inviolate. - -datum/objective/heist/inviolate_death - explanation_text = "Follow the Inviolate. Minimise death and loss of resources." - check_completion() - if(vox_kills > MAX_VOX_KILLS) return 0 - return 1 - //Borer objective(s). - /datum/objective/borer_survive explanation_text = "Survive in a host until the end of the round." @@ -957,15 +878,52 @@ datum/objective/heist/inviolate_death /datum/objective/ninja_highlander/check_completion() if(owner) - for(var/datum/mind/ninja in ticker.mode.ninjas) + for(var/datum/mind/ninja in get_antags("ninja")) if(ninja != owner) if(ninja.current.stat < 2) return 0 return 1 return 0 -/datum/objective/cult_summon - explanation_text = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it." +/datum/objective/cult/survive + explanation_text = "Our knowledge must live on." + target_amount = 5 -/datum/objective/cult_summon/check_completion() - if(locate(/obj/machinery/singularity/narsie/large) in machines) return 1 - return 0 \ No newline at end of file +/datum/objective/cult/survive/New() + ..() + explanation_text = "Our knowledge must live on. Make sure at least [target_amount] acolytes escape on the shuttle to spread their work on an another station." + +/datum/objective/cult/survive/check_completion() + var/acolytes_survived = 0 + if(!cult) + return 0 + for(var/datum/mind/cult_mind in cult.current_antagonists) + if (cult_mind.current && cult_mind.current.stat!=2) + var/area/A = get_area(cult_mind.current ) + if ( is_type_in_list(A, centcom_areas)) + acolytes_survived++ + if(acolytes_survived >= target_amount) + return 0 + else + return 1 + +/datum/objective/cult/eldergod + explanation_text = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it. The convert rune is join blood self." + +/datum/objective/cult/eldergod/check_completion() + return (locate(/obj/machinery/singularity/narsie/large) in machines) + +/datum/objective/cult/sacrifice + explanation_text = "Conduct a ritual sacrifice for the glory of Nar-Sie." + +/datum/objective/cult/sacrifice/find_target() + var/list/possible_targets = list() + if(!possible_targets.len) + for(var/mob/living/carbon/human/player in player_list) + if(player.mind && !(player.mind in cult)) + possible_targets += player.mind + if(possible_targets.len > 0) + target = pick(possible_targets) + if(target) explanation_text = "Sacrifice [target.name], the [target.assigned_role]. You will need the sacrifice rune (Hell blood join) and three acolytes to do so." + +/datum/objective/cult/sacrifice/check_completion() + return (target && cult && !cult.sacrificed.Find(target)) diff --git a/code/game/gamemodes/revolution/anti_revolution.dm b/code/game/gamemodes/revolution/anti_revolution.dm deleted file mode 100644 index fce1cace91..0000000000 --- a/code/game/gamemodes/revolution/anti_revolution.dm +++ /dev/null @@ -1,222 +0,0 @@ -// A sort of anti-revolution where the heads are given objectives to mess with the crew - -/datum/game_mode/anti_revolution - name = "anti-revolution" - config_tag = "anti-revolution" - required_players = 5 - - var/finished = 0 - var/checkwin_counter = 0 - var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) - var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) - - var/required_execute_targets = 1 - var/required_brig_targets = 0 - - var/recommended_execute_targets = 1 - var/recommended_brig_targets = 3 - var/recommended_demote_targets = 3 - - var/list/datum/mind/heads = list() - var/list/datum/mind/execute_targets = list() - var/list/datum/mind/brig_targets = list() - var/list/datum/mind/demote_targets = list() - -/////////////////////////// -//Announces the game type// -/////////////////////////// -/datum/game_mode/anti_revolution/announce() - world << "The current game mode is - Anti-Revolution!" - world << "Looks like CentComm has given a few new orders.." - -/////////////////////////////////////////////////////////////////////////////// -//Gets the round setup, cancelling if there's not enough players at the start// -/////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/anti_revolution/pre_setup() - for(var/mob/new_player/player in world) if(player.mind) - if(player.mind.assigned_role in command_positions) - heads += player.mind - else - if(execute_targets.len < recommended_execute_targets) - execute_targets += player.mind - else if(brig_targets.len < recommended_brig_targets) - brig_targets += player.mind - else if(demote_targets.len < recommended_demote_targets) - demote_targets += player.mind - - - if(heads.len==0) - return 0 - - if(execute_targets.len < required_execute_targets || brig_targets.len < required_brig_targets) - return 0 - - return 1 - - -/datum/game_mode/anti_revolution/proc/add_head_objectives(datum/mind/head) - for(var/datum/mind/target in execute_targets) - var/datum/objective/anti_revolution/execute/obj = new - obj.owner = head - obj.target = target - obj.explanation_text = "[target.current.real_name], the [target.assigned_role] has extracted confidential information above their clearance. Execute them." - head.objectives += obj - for(var/datum/mind/target in brig_targets) - var/datum/objective/anti_revolution/brig/obj = new - obj.owner = head - obj.target = target - obj.explanation_text = "Brig [target.current.real_name], the [target.assigned_role] for 20 minutes to set an example." - head.objectives += obj - for(var/datum/mind/target in demote_targets) - var/datum/objective/anti_revolution/demote/obj = new - obj.owner = head - obj.target = target - obj.explanation_text = "[target.current.real_name], the [target.assigned_role] has been classified as harmful to NanoTrasen's goals. Demote them to assistant." - head.objectives += obj - - -/datum/game_mode/anti_revolution/post_setup() - - for(var/datum/mind/head_mind in heads) - add_head_objectives(head_mind) - for(var/datum/mind/head_mind in heads) - greet_head(head_mind) - modePlayer += heads - spawn (rand(waittime_l, waittime_h)) - send_intercept() - ..() - - -/datum/game_mode/anti_revolution/process() - checkwin_counter++ - if(checkwin_counter >= 5) - if(!finished) - ticker.mode.check_win() - checkwin_counter = 0 - return 0 - - -/datum/game_mode/proc/greet_head(var/datum/mind/head_mind, var/you_are=1) - var/obj_count = 1 - if (you_are) - head_mind.current << "\blue It looks like this shift CentComm has some special orders for you.. check your objectives." - head_mind.current << "\blue Note that you can ignore these objectives, but resisting NT's orders probably means demotion or worse." - for(var/datum/objective/objective in head_mind.objectives) - head_mind.current << "Objective #[obj_count]: [objective.explanation_text]" - head_mind.special_role = "Corrupt Head" - obj_count++ - - head_mind.current.verbs += /mob/proc/ResignFromHeadPosition - -////////////////////////////////////// -//Checks if the revs have won or not// -////////////////////////////////////// -/datum/game_mode/anti_revolution/check_win() - if(check_head_victory()) - finished = 1 - else if(check_crew_victory()) - finished = 2 - return - -/////////////////////////////// -//Checks if the round is over// -/////////////////////////////// -/datum/game_mode/anti_revolution/check_finished() - if(finished != 0) - return 1 - else - return 0 - - -////////////////////////// -//Checks for crew victory// -////////////////////////// -/datum/game_mode/anti_revolution/proc/check_crew_victory() - for(var/datum/mind/head_mind in heads) - var/turf/T = get_turf(head_mind.current) - if((head_mind) && (head_mind.current) && (head_mind.current.stat != 2) && T && (T.z in station_levels) && !head_mind.is_brigged(600)) - if(ishuman(head_mind.current)) - return 0 - return 1 - -///////////////////////////// -//Checks for a head victory// -///////////////////////////// -/datum/game_mode/anti_revolution/proc/check_head_victory() - for(var/datum/mind/head_mind in heads) - for(var/datum/objective/objective in head_mind.objectives) - if(!(objective.check_completion())) - return 0 - - return 1 - - -/datum/game_mode/anti_revolution/declare_completion() - - var/text = "" - if(finished == 2) - world << "\red The heads of staff were relieved of their posts! The crew wins!" - else if(finished == 1) - world << "\red The heads of staff managed to meet the goals set for them by CentComm!" - - - - world << "The heads of staff were: " - var/list/heads = list() - heads = get_all_heads() - for(var/datum/mind/head_mind in heads) - text = "" - if(head_mind.current) - text += "[head_mind.current.real_name]" - if(head_mind.current.stat == 2) - text += " (Dead)" - else - text += " (Survived!)" - else - text += "[head_mind.key] (character destroyed)" - - world << text - - - world << "Their objectives were: " - for(var/datum/mind/head_mind in heads) - if(head_mind.objectives.len)//If the traitor had no objectives, don't need to process this. - var/count = 1 - for(var/datum/objective/objective in head_mind.objectives) - if(objective.check_completion()) - text += "
    Objective #[count]: [objective.explanation_text] Success!" - feedback_add_details("head_objective","[objective.type]|SUCCESS") - else - text += "
    Objective #[count]: [objective.explanation_text] Fail." - feedback_add_details("head_objective","[objective.type]|FAIL") - count++ - break // just print once - return 1 - - -/datum/game_mode/anti_revolution/latespawn(mob/living/carbon/human/character) - ..() - if(emergency_shuttle.departed) - return - - if(character.mind.assigned_role in command_positions) - heads += character.mind - modePlayer += character.mind - add_head_objectives(character.mind) - greet_head(character.mind) - -/mob/proc/ResignFromHeadPosition() - set category = "IC" - set name = "Resign From Head Position" - - if(!istype(ticker.mode, /datum/game_mode/anti_revolution)) - return - - ticker.mode:heads -= src.mind - src.mind.objectives = list() - ticker.mode.modePlayer -= src.mind - src.mind.special_role = null - - src.verbs -= /mob/proc/ResignFromHeadPosition - - src << "\red You resigned from your position, now you have the consequences." \ No newline at end of file diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 051c112bbb..493650359e 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -1,436 +1,50 @@ -// To add a rev to the list of revolutionaries, make sure it's rev (with if(ticker.mode.name == "revolution)), -// then call ticker.mode:add_revolutionary(_THE_PLAYERS_MIND_) -// nothing else needs to be done, as that proc will check if they are a valid target. -// Just make sure the converter is a head before you call it! -// To remove a rev (from brainwashing or w/e), call ticker.mode:remove_revolutionary(_THE_PLAYERS_MIND_), -// this will also check they're not a head, so it can just be called freely -// If the rev icons start going wrong for some reason, ticker.mode:update_all_rev_icons() can be called to correct them. -// If the game somtimes isn't registering a win properly, then ticker.mode.check_win() isn't being called somewhere. - -/datum/game_mode - var/list/datum/mind/head_revolutionaries = list() - var/list/datum/mind/revolutionaries = list() - /datum/game_mode/revolution - name = "revolution" + name = "Revolution" config_tag = "revolution" - restricted_jobs = list("Internal Affairs Agent", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer") - protected_jobs = list("Security Officer", "Warden", "Detective") + round_description = "Some crewmembers are attempting to start a revolution!" + extended_round_description = "Revolutionaries - Kill the Captain, HoP, HoS, CE, RD and CMO. Convert other crewmembers (excluding the heads of staff, and security officers) to your cause by flashing them. Protect your leaders.
    \nPersonnel - Protect the heads of staff. Kill the leaders of the revolution, and brainwash the other revolutionaries (by beating them in the head)." required_players = 4 required_players_secret = 15 required_enemies = 3 - recommended_enemies = 3 - - + auto_recall_shuttle = 1 uplink_welcome = "AntagCorp Uplink Console:" uplink_uses = 10 + end_on_antag_death = 1 + shuttle_delay = 3 + antag_tag = MODE_REVOLUTIONARY - var/finished = 0 - var/checkwin_counter = 0 - var/max_headrevs = 3 - var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) - var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) -/////////////////////////// -//Announces the game type// -/////////////////////////// -/datum/game_mode/revolution/announce() - world << "The current game mode is - Revolution!" - world << "Some crewmembers are attempting to start a revolution!
    \nRevolutionaries - Kill the Captain, HoP, HoS, CE, RD and CMO. Convert other crewmembers (excluding the heads of staff, and security officers) to your cause by flashing them. Protect your leaders.
    \nPersonnel - Protect the heads of staff. Kill the leaders of the revolution, and brainwash the other revolutionaries (by beating them in the head).
    " +/datum/game_mode/revolution/New() + if(config && config.rp_rev) + extended_round_description = "Revolutionaries - Remove the heads of staff from power. Convert other crewmembers to your cause using the 'Convert Bourgeoise' verb. Protect your leaders." +/datum/game_mode/revolution/send_intercept() -/////////////////////////////////////////////////////////////////////////////// -//Gets the round setup, cancelling if there's not enough players at the start// -/////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/revolution/pre_setup() - - if(config.protect_roles_from_antagonist) - restricted_jobs += protected_jobs - - var/list/datum/mind/possible_headrevs = get_players_for_role(BE_REV) - - var/head_check = 0 - for(var/mob/new_player/player in player_list) - if(player.mind.assigned_role in command_positions) - head_check = 1 - break - - for(var/datum/mind/player in possible_headrevs) - for(var/job in restricted_jobs)//Removing heads and such from the list - if(player.assigned_role == job) - possible_headrevs -= player - - for (var/i=1 to max_headrevs) - if (possible_headrevs.len==0) - break - var/datum/mind/lenin = pick(possible_headrevs) - possible_headrevs -= lenin - head_revolutionaries += lenin - - if((head_revolutionaries.len==0)||(!head_check)) - return 0 - - return 1 - - -/datum/game_mode/revolution/post_setup() - var/list/heads = get_living_heads() - for(var/datum/mind/rev_mind in head_revolutionaries) - if(!config.objectives_disabled) - for(var/datum/mind/head_mind in heads) - var/datum/objective/mutiny/rev_obj = new - rev_obj.owner = rev_mind - rev_obj.target = head_mind - rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]." - rev_mind.objectives += rev_obj - - // equip_traitor(rev_mind.current, 1) //changing how revs get assigned their uplink so they can get PDA uplinks. --NEO - // Removing revolutionary uplinks. -Pete - equip_revolutionary(rev_mind.current) - update_rev_icons_added(rev_mind) - - for(var/datum/mind/rev_mind in head_revolutionaries) - greet_revolutionary(rev_mind) - modePlayer += head_revolutionaries - if(emergency_shuttle) - emergency_shuttle.auto_recall = 1 - spawn (rand(waittime_l, waittime_h)) - send_intercept() ..() + if(config.announce_revheads) + spawn(54000) + var/intercepttext = "" + command_announcement.Announce("Summary downloaded and printed out at all communications consoles.", "Local agitators have been determined.") + intercepttext = "Cent. Com. Update Requested status information:
    " + intercepttext += "We have determined several members of your staff to be political activists. They are:" + for(var/datum/mind/revmind in revs.head_revolutionaries) + intercepttext += "
    [revmind.current.real_name]" + intercepttext += "
    Please arrest them at once." + for (var/obj/machinery/computer/communications/comm in world) + if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) + var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) + intercept.name = "Cent. Com. Status Summary" + intercept.info = intercepttext + comm.messagetitle.Add("Cent. Com. Status Summary") + comm.messagetext.Add(intercepttext) + spawn(12000) + command_announcement.Announce("Repeating the previous message over intercoms due to urgency. The station has political agitators onboard by the names of [reveal_rev_heads()], please arrest them at once.", "Local agitators have been determined.") -/datum/game_mode/revolution/process() - checkwin_counter++ - if(checkwin_counter >= 5) - if(!finished) - ticker.mode.check_win() - checkwin_counter = 0 - return 0 - - -/datum/game_mode/proc/forge_revolutionary_objectives(var/datum/mind/rev_mind) - if(!config.objectives_disabled) - var/list/heads = get_living_heads() - for(var/datum/mind/head_mind in heads) - var/datum/objective/mutiny/rev_obj = new - rev_obj.owner = rev_mind - rev_obj.target = head_mind - rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]." - rev_mind.objectives += rev_obj - -/datum/game_mode/proc/greet_revolutionary(var/datum/mind/rev_mind, var/you_are=1) - - rev_mind.special_role = "Head Revolutionary" - - if (you_are) - rev_mind.current << "\blue You are a member of the revolutionaries' leadership!" - - show_objectives(rev_mind) - -///////////////////////////////////////////////////////////////////////////////// -//This are equips the rev heads with their gear, and makes the clown not clumsy// -///////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/proc/equip_revolutionary(mob/living/carbon/human/mob) - if(!istype(mob)) - return - - if (mob.mind) - if (mob.mind.assigned_role == "Clown") - mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." - mob.mutations.Remove(CLUMSY) - - - var/obj/item/device/flash/T = new(mob) - - var/list/slots = list ( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store, - "left hand" = slot_l_hand, - "right hand" = slot_r_hand, - ) - var/where = mob.equip_in_one_of_slots(T, slots) - if (!where) - mob << "Your employers were unfortunately unable to get you a flash." - else - mob << "The flash in your [where] will help you to persuade the crew to join your cause." - mob.update_icons() - return 1 - -////////////////////////////////////// -//Checks if the revs have won or not// -////////////////////////////////////// -/datum/game_mode/revolution/check_win() - if(check_rev_victory()) - finished = 1 - else if(check_heads_victory()) - finished = 2 - return - -/////////////////////////////// -//Checks if the round is over// -/////////////////////////////// -/datum/game_mode/revolution/check_finished() - if(config.continous_rounds) - if(finished != 0) - if(emergency_shuttle) - emergency_shuttle.auto_recall = 0 - return ..() - if(finished != 0) - return 1 - else - return 0 - -/////////////////////////////////////////////////// -//Deals with converting players to the revolution// -/////////////////////////////////////////////////// -/datum/game_mode/proc/add_revolutionary(datum/mind/rev_mind) - if(rev_mind.assigned_role in command_positions) - return 0 - var/mob/living/carbon/human/H = rev_mind.current//Check to see if the potential rev is implanted - for(var/obj/item/weapon/implant/loyalty/L in H)//Checking that there is a loyalty implant in the contents - if(L.imp_in == H)//Checking that it's actually implanted - return 0 - if((rev_mind in revolutionaries) || (rev_mind in head_revolutionaries)) - return 0 - revolutionaries += rev_mind - rev_mind.current << "\red You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!" - rev_mind.special_role = "Revolutionary" - show_objectives(rev_mind) - update_rev_icons_added(rev_mind) - return 1 -////////////////////////////////////////////////////////////////////////////// -//Deals with players being converted from the revolution (Not a rev anymore)// // Modified to handle borged MMIs. Accepts another var if the target is being borged at the time -- Polymorph. -////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/proc/remove_revolutionary(datum/mind/rev_mind , beingborged) - if(rev_mind in revolutionaries) - revolutionaries -= rev_mind - rev_mind.special_role = null - rev_mind.current.hud_updateflag |= 1 << SPECIALROLE_HUD - - if(beingborged) - rev_mind.current << "\red The frame's firmware detects and deletes your neural reprogramming! You remember nothing from the moment you were flashed until now." - +/datum/game_mode/revolution/proc/reveal_rev_heads() + . = "" + for(var/i = 1, i <= revs.head_revolutionaries.len,i++) + var/datum/mind/revmind = revs.head_revolutionaries[i] + if(i < revs.head_revolutionaries.len) + . += "[revmind.current.real_name]," else - rev_mind.current << "\red You have been brainwashed! You are no longer a revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you..." - - update_rev_icons_removed(rev_mind) - for(var/mob/living/M in view(rev_mind.current)) - if(beingborged) - M << "The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it." - - else - M << "[rev_mind.current] looks like they just remembered their real allegiance!" - - -///////////////////////////////////////////////////////////////////////////////////////////////// -//Keeps track of players having the correct icons//////////////////////////////////////////////// -//CURRENTLY CONTAINS BUGS://///////////////////////////////////////////////////////////////////// -//-PLAYERS THAT HAVE BEEN REVS FOR AWHILE OBTAIN THE BLUE ICON WHILE STILL NOT BEING A REV HEAD// -// -Possibly caused by cloning of a standard rev///////////////////////////////////////////////// -//-UNCONFIRMED: DECONVERTED REVS NOT LOSING THEIR ICON PROPERLY////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/proc/update_all_rev_icons() - spawn(0) - for(var/datum/mind/head_rev_mind in head_revolutionaries) - if(head_rev_mind.current) - if(head_rev_mind.current.client) - for(var/image/I in head_rev_mind.current.client.images) - if(I.icon_state == "rev" || I.icon_state == "rev_head") - del(I) - - for(var/datum/mind/rev_mind in revolutionaries) - if(rev_mind.current) - if(rev_mind.current.client) - for(var/image/I in rev_mind.current.client.images) - if(I.icon_state == "rev" || I.icon_state == "rev_head") - del(I) - - for(var/datum/mind/head_rev in head_revolutionaries) - if(head_rev.current) - if(head_rev.current.client) - for(var/datum/mind/rev in revolutionaries) - if(rev.current) - var/I = image('icons/mob/mob.dmi', loc = rev.current, icon_state = "rev") - head_rev.current.client.images += I - for(var/datum/mind/head_rev_1 in head_revolutionaries) - if(head_rev_1.current) - var/I = image('icons/mob/mob.dmi', loc = head_rev_1.current, icon_state = "rev_head") - head_rev.current.client.images += I - - for(var/datum/mind/rev in revolutionaries) - if(rev.current) - if(rev.current.client) - for(var/datum/mind/head_rev in head_revolutionaries) - if(head_rev.current) - var/I = image('icons/mob/mob.dmi', loc = head_rev.current, icon_state = "rev_head") - rev.current.client.images += I - for(var/datum/mind/rev_1 in revolutionaries) - if(rev_1.current) - var/I = image('icons/mob/mob.dmi', loc = rev_1.current, icon_state = "rev") - rev.current.client.images += I - -//////////////////////////////////////////////////// -//Keeps track of converted revs icons/////////////// -//Refer to above bugs. They may apply here as well// -//////////////////////////////////////////////////// -/datum/game_mode/proc/update_rev_icons_added(datum/mind/rev_mind) - spawn(0) - for(var/datum/mind/head_rev_mind in head_revolutionaries) - if(head_rev_mind.current) - if(head_rev_mind.current.client) - var/I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev") - head_rev_mind.current.client.images += I - if(rev_mind.current) - if(rev_mind.current.client) - var/image/J = image('icons/mob/mob.dmi', loc = head_rev_mind.current, icon_state = "rev_head") - rev_mind.current.client.images += J - - for(var/datum/mind/rev_mind_1 in revolutionaries) - if(rev_mind_1.current) - if(rev_mind_1.current.client) - var/I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev") - rev_mind_1.current.client.images += I - if(rev_mind.current) - if(rev_mind.current.client) - var/image/J = image('icons/mob/mob.dmi', loc = rev_mind_1.current, icon_state = "rev") - rev_mind.current.client.images += J - -/////////////////////////////////// -//Keeps track of deconverted revs// -/////////////////////////////////// -/datum/game_mode/proc/update_rev_icons_removed(datum/mind/rev_mind) - spawn(0) - for(var/datum/mind/head_rev_mind in head_revolutionaries) - if(head_rev_mind.current) - if(head_rev_mind.current.client) - for(var/image/I in head_rev_mind.current.client.images) - if((I.icon_state == "rev" || I.icon_state == "rev_head") && I.loc == rev_mind.current) - del(I) - - for(var/datum/mind/rev_mind_1 in revolutionaries) - if(rev_mind_1.current) - if(rev_mind_1.current.client) - for(var/image/I in rev_mind_1.current.client.images) - if((I.icon_state == "rev" || I.icon_state == "rev_head") && I.loc == rev_mind.current) - del(I) - - if(rev_mind.current) - if(rev_mind.current.client) - for(var/image/I in rev_mind.current.client.images) - if(I.icon_state == "rev" || I.icon_state == "rev_head") - del(I) - -////////////////////////// -//Checks for rev victory// -////////////////////////// -/datum/game_mode/revolution/proc/check_rev_victory() - for(var/datum/mind/rev_mind in head_revolutionaries) - for(var/datum/objective/objective in rev_mind.objectives) - if(!(objective.check_completion())) - return 0 - - return 1 - -///////////////////////////// -//Checks for a head victory// -///////////////////////////// -/datum/game_mode/revolution/proc/check_heads_victory() - for(var/datum/mind/rev_mind in head_revolutionaries) - var/turf/T = get_turf(rev_mind.current) - if((rev_mind) && (rev_mind.current) && (rev_mind.current.stat != 2) && T && (T.z in config.station_levels)) - if(ishuman(rev_mind.current)) - return 0 - return 1 - -////////////////////////////////////////////////////////////////////// -//Announces the end of the game with all relavent information stated// -////////////////////////////////////////////////////////////////////// -/datum/game_mode/revolution/declare_completion() - if(!config.objectives_disabled) - if(finished == 1) - feedback_set_details("round_end_result","win - heads killed") - world << "\red The heads of staff were killed or abandoned the station! The revolutionaries win!" - else if(finished == 2) - feedback_set_details("round_end_result","loss - rev heads killed") - world << "\red The heads of staff managed to stop the revolution!" - ..() - return 1 - -/datum/game_mode/proc/auto_declare_completion_revolution() - var/list/targets = list() - - if(head_revolutionaries.len || istype(ticker.mode,/datum/game_mode/revolution)) - var/text = "The head revolutionaries were:" - - for(var/datum/mind/headrev in head_revolutionaries) - text += "
    [headrev.key] was [headrev.name] (" - if(headrev.current) - if(headrev.current.stat == DEAD) - text += "died" - else if(isNotStationLevel(headrev.current.z)) - text += "fled the station" - else - text += "survived the revolution" - if(headrev.current.real_name != headrev.name) - text += " as [headrev.current.real_name]" - else - text += "body destroyed" - text += ")" - - for(var/datum/objective/mutiny/objective in headrev.objectives) - targets |= objective.target - - world << text - - if(revolutionaries.len || istype(ticker.mode,/datum/game_mode/revolution)) - var/text = "The revolutionaries were:" - - for(var/datum/mind/rev in revolutionaries) - text += "
    [rev.key] was [rev.name] (" - if(rev.current) - if(rev.current.stat == DEAD) - text += "died" - else if(isNotStationLevel(rev.current.z)) - text += "fled the station" - else - text += "survived the revolution" - if(rev.current.real_name != rev.name) - text += " as [rev.current.real_name]" - else - text += "body destroyed" - text += ")" - - world << text - - - if( head_revolutionaries.len || revolutionaries.len || istype(ticker.mode,/datum/game_mode/revolution) ) - var/text = "The heads of staff were:" - - var/list/heads = get_all_heads() - for(var/datum/mind/head in heads) - var/target = (head in targets) - if(target) - text += "" - text += "
    [head.key] was [head.name] (" - if(head.current) - if(head.current.stat == DEAD) - text += "died" - else if(isNotStationLevel(head.current.z)) - text += "fled the station" - else - text += "survived the revolution" - if(head.current.real_name != head.name) - text += " as [head.current.real_name]" - else - text += "body destroyed" - text += ")" - if(target) - text += "
    " - - world << text - -/proc/is_convertable_to_rev(datum/mind/mind) - return istype(mind) && \ - istype(mind.current, /mob/living/carbon/human) && \ - !(mind.assigned_role in command_positions) && \ - !(mind.assigned_role in list("Security Officer", "Detective", "Warden")) + . += "and [revmind.current.real_name]" \ No newline at end of file diff --git a/code/game/gamemodes/revolution/rp_revolution.dm b/code/game/gamemodes/revolution/rp_revolution.dm deleted file mode 100644 index 2b9cc12e28..0000000000 --- a/code/game/gamemodes/revolution/rp_revolution.dm +++ /dev/null @@ -1,262 +0,0 @@ -// BS12's less violent revolution mode - -/datum/game_mode/revolution/rp_revolution - name = "rp-revolution" - config_tag = "rp-revolution" - required_players = 4 - required_players_secret = 12 - required_enemies = 3 - recommended_enemies = 3 - - uplink_welcome = "AntagCorp Uplink Console:" - uplink_uses = 5 - - newscaster_announcements = /datum/news_announcement/revolution_inciting_event - - var/last_command_report = 0 - var/list/heads = list() - var/tried_to_add_revheads = 0 - -/////////////////////////////////////////////////////////////////////////////// -//Gets the round setup, cancelling if there's not enough players at the start// -/////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/revolution/rp_revolution/pre_setup() - - if(config.protect_roles_from_antagonist) - restricted_jobs += protected_jobs - - var/num_players = num_players() - max_headrevs = max(num_players / 4, 3) - recommended_enemies = max_headrevs - - var/list/datum/mind/possible_headrevs = get_players_for_role(BE_REV) - - var/head_check = 0 - for(var/mob/new_player/player in player_list) - if(player.mind.assigned_role in command_positions) - head_check = 1 - break - - for(var/datum/mind/player in possible_headrevs) - for(var/job in restricted_jobs)//Removing heads and such from the list - if(player.assigned_role == job) - possible_headrevs -= player - - for (var/i=1 to max_headrevs) - if (possible_headrevs.len==0) - break - var/datum/mind/lenin = pick(possible_headrevs) - possible_headrevs -= lenin - head_revolutionaries += lenin - - if((head_revolutionaries.len==0)||(!head_check)) - return 0 - - return 1 - - -/datum/game_mode/revolution/rp_revolution/post_setup() - heads = get_living_heads() - for(var/datum/mind/rev_mind in head_revolutionaries) - if(!config.objectives_disabled) - for(var/datum/mind/head_mind in heads) - var/datum/objective/mutiny/rp/rev_obj = new - rev_obj.owner = rev_mind - rev_obj.target = head_mind - rev_obj.explanation_text = "Assassinate, convert or capture [head_mind.name], the [head_mind.assigned_role]." - rev_mind.objectives += rev_obj - - update_rev_icons_added(rev_mind) - - for(var/datum/mind/rev_mind in head_revolutionaries) - greet_revolutionary(rev_mind) - rev_mind.current.verbs += /mob/living/carbon/human/proc/RevConvert - equip_traitor(rev_mind.current, 1) //changing how revs get assigned their uplink so they can get PDA uplinks. --NEO - - modePlayer += head_revolutionaries - spawn (rand(waittime_l, waittime_h)) - send_intercept() - -/datum/game_mode/revolution/rp_revolution/greet_revolutionary(var/datum/mind/rev_mind, var/you_are=1) - rev_mind.special_role = "Head Revolutionary" - if (you_are) - rev_mind.current << "\blue You are a member of the revolutionaries' leadership!" - show_objectives(rev_mind) - - // Show each head revolutionary up to 3 candidates - var/list/already_considered = list() - for(var/i = 0, i < 2, i++) - var/mob/rev_mob = rev_mind.current - already_considered += rev_mob - // Tell them about people they might want to contact. - var/mob/living/carbon/human/M = get_nt_opposed() - if(M && !(M.mind in head_revolutionaries) && !(M in already_considered)) - rev_mob << "We have received credible reports that [M.real_name] might be willing to help our cause. If you need assistance, consider contacting them." - rev_mob.mind.store_memory("Potential Collaborator: [M.real_name]") - -/////////////////////////////////////////////////// -//Deals with converting players to the revolution// -/////////////////////////////////////////////////// -/datum/game_mode/revolution/rp_revolution/add_revolutionary(datum/mind/rev_mind) - // overwrite this func to make it so even heads can be converted - var/mob/living/carbon/human/H = rev_mind.current//Check to see if the potential rev is implanted - if(!is_convertible(H)) - return 0 - if((rev_mind in revolutionaries) || (rev_mind in head_revolutionaries)) - return 0 - revolutionaries += rev_mind - rev_mind.current << "\red You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill, capture or convert the heads to win the revolution!" - rev_mind.special_role = "Revolutionary" - show_objectives(rev_mind) - update_rev_icons_added(rev_mind) - H.hud_updateflag |= 1 << SPECIALROLE_HUD - return 1 - -///////////////////////////// -//Checks for a head victory// -///////////////////////////// -/datum/game_mode/revolution/rp_revolution/check_heads_victory() - for(var/datum/mind/rev_mind in head_revolutionaries) - var/turf/T = get_turf(rev_mind.current) - if(rev_mind.current.stat != 2) - // TODO: add a similar check that also checks whether they're without ID in the brig.. - // probably wanna export this stuff into a separate function for use by both - // revs and heads - //assume that only carbon mobs can become rev heads for now - if(!rev_mind.current:handcuffed && T && T.z in config.station_levels) - return 0 - return 1 - -/////////////////////////// -//Announces the game type// -/////////////////////////// -/datum/game_mode/revolution/rp_revolution/announce() - world << "The current game mode is - Revolution!" - world << "Some crewmembers are attempting to start a revolution!" - - -////////////////////////////////////////////////////////////////////// -//Announces the end of the game with all relavent information stated// -////////////////////////////////////////////////////////////////////// -/datum/game_mode/revolution/rp_revolution/declare_completion() - if(!config.objectives_disabled) - if(finished == 1) - feedback_set_details("round_end_result","win - heads overthrown") - world << "\red The heads of staff were overthrown! The revolutionaries win!" - else if(finished == 2) - feedback_set_details("round_end_result","loss - revolution stopped") - world << "\red The heads of staff managed to stop the revolution!" - ..() - return 1 - -/datum/game_mode/revolution/proc/is_convertible(mob/M) - for(var/obj/item/weapon/implant/loyalty/L in M)//Checking that there is a loyalty implant in the contents - if(L.imp_in == M)//Checking that it's actually implanted - return 0 - - return 1 - -/mob/living/carbon/human/proc/RevConvert() - set name = "Rev-Convert" - set category = "IC" - var/list/Possible = list() - for (var/mob/living/carbon/human/P in oview(src)) - if(!stat && P.client && P.mind && !P.mind.special_role) - Possible += P - if(!Possible.len) - src << "\red There doesn't appear to be anyone available for you to convert here." - return - var/mob/living/carbon/human/M = input("Select a person to convert", "Viva la revolution!", null) as mob in Possible - if(((src.mind in ticker.mode:head_revolutionaries) || (src.mind in ticker.mode:revolutionaries))) - if((M.mind in ticker.mode:head_revolutionaries) || (M.mind in ticker.mode:revolutionaries)) - src << "\red [M] is already be a revolutionary!" - else if(!ticker.mode:is_convertible(M)) - src << "\red [M] is implanted with a loyalty implant - Remove it first!" - else - if(world.time < M.mind.rev_cooldown) - src << "\red Wait five seconds before reconversion attempt." - return - src << "\red Attempting to convert [M]..." - log_admin("[src]([src.ckey]) attempted to convert [M].") - message_admins("\red [src]([src.ckey]) attempted to convert [M].") - var/choice = alert(M,"Asked by [src]: Do you want to join the revolution?","Align Thyself with the Revolution!","No!","Yes!") - if(choice == "Yes!") - ticker.mode:add_revolutionary(M.mind) - M << "\blue You join the revolution!" - src << "\blue [M] joins the revolution!" - else if(choice == "No!") - M << "\red You reject this traitorous cause!" - src << "\red [M] does not support the revolution!" - M.mind.rev_cooldown = world.time+50 - -/datum/game_mode/revolution/rp_revolution/process() - // only perform rev checks once in a while - if(tried_to_add_revheads < world.time) - tried_to_add_revheads = world.time+50 - var/active_revs = 0 - for(var/datum/mind/rev_mind in head_revolutionaries) - if(rev_mind.current && rev_mind.current.client && rev_mind.current.client.inactivity <= 10*60*20) // 20 minutes inactivity are OK - active_revs++ - - if(active_revs == 0) - log_debug("There are zero active heads of revolution, trying to add some..") - var/added_heads = 0 - for(var/mob/living/carbon/human/H in world) if(H.client && H.mind && H.client.inactivity <= 10*60*20 && H.mind in revolutionaries) - head_revolutionaries += H.mind - for(var/datum/mind/head_mind in heads) - var/datum/objective/mutiny/rp/rev_obj = new - rev_obj.owner = H.mind - rev_obj.target = head_mind - rev_obj.explanation_text = "Assassinate or capture [head_mind.name], the [head_mind.assigned_role]." - H.mind.objectives += rev_obj - - update_rev_icons_added(H.mind) - H.verbs += /mob/living/carbon/human/proc/RevConvert - - H << "\red Congratulations, yer heads of revolution are all gone now, so yer earned yourself a promotion." - added_heads = 1 - break - - if(added_heads) - log_admin("Managed to add new heads of revolution.") - message_admins("Managed to add new heads of revolution.") - else - log_admin("Unable to add new heads of revolution.") - message_admins("Unable to add new heads of revolution.") - tried_to_add_revheads = world.time + 6000 // wait 10 minutes - - if(last_command_report == 0 && world.time >= 10 * 60 * 10) - src.command_report("We are regrettably announcing that your performance has been disappointing, and we are thus forced to cut down on financial support to your station. To achieve this, the pay of all personnal, except the Heads of Staff, has been halved.") - last_command_report = 1 - else if(last_command_report == 1 && world.time >= 10 * 60 * 30) - src.command_report("Statistics hint that a high amount of leisure time, and associated activities, are responsible for the poor performance of many of our stations. You are to bolt and close down any leisure facilities, such as the holodeck, the theatre and the bar. Food can be distributed through vendors and the kitchen.") - last_command_report = 2 - else if(last_command_report == 2 && world.time >= 10 * 60 * 60) - src.command_report("It is reported that merely closing down leisure facilities has not been successful. You and your Heads of Staff are to ensure that all crew are working hard, and not wasting time or energy. Any crew caught off duty without leave from their Head of Staff are to be warned, and on repeated offence, to be brigged until the next transfer shuttle arrives, which will take them to facilities where they can be of more use.") - last_command_report = 3 - - return ..() - -/datum/game_mode/revolution/rp_revolution/proc/command_report(message) - for (var/obj/machinery/computer/communications/comm in world) - if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept) - var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc ) - intercept.name = "Cent. Com. Announcement" - intercept.info = message - - comm.messagetitle.Add("Cent. Com. Announcement") - comm.messagetext.Add(message) - world << sound('sound/AI/commandreport.ogg') - -/datum/game_mode/revolution/rp_revolution/latespawn(mob/M) - if(M.mind.assigned_role in command_positions) - log_debug("Adding head kill/capture/convert objective for [M.name]") - heads += M - - for(var/datum/mind/rev_mind in head_revolutionaries) - var/datum/objective/mutiny/rp/rev_obj = new - rev_obj.owner = rev_mind - rev_obj.target = M.mind - rev_obj.explanation_text = "Assassinate, convert or capture [M.real_name], the [M.mind.assigned_role]." - rev_mind.objectives += rev_obj - rev_mind.current << "\red A new Head of Staff, [M.real_name], the [M.mind.assigned_role] has appeared. Your objectives have been updated." diff --git a/code/game/gamemodes/sandbox/sandbox.dm b/code/game/gamemodes/sandbox/sandbox.dm index 1f4bc59929..a96c7c7639 100644 --- a/code/game/gamemodes/sandbox/sandbox.dm +++ b/code/game/gamemodes/sandbox/sandbox.dm @@ -2,10 +2,9 @@ name = "sandbox" config_tag = "sandbox" required_players = 0 - -/datum/game_mode/sandbox/announce() - world << "The current game mode is - Sandbox!" - world << "Build your own station with the sandbox-panel command!" + votable = 0 + round_description = "Build your own station!" + extended_round_description = "You can use the sandbox-panel command to access build options." /datum/game_mode/sandbox/pre_setup() for(var/mob/M in player_list) diff --git a/code/game/gamemodes/setupgame.dm b/code/game/gamemodes/setupgame.dm index bea6029b46..501335a19f 100644 --- a/code/game/gamemodes/setupgame.dm +++ b/code/game/gamemodes/setupgame.dm @@ -144,24 +144,6 @@ global_mutations += mut// add to global mutations list! */ - -/proc/setupfactions() - - // Populate the factions list: - for(var/x in typesof(/datum/faction)) - var/datum/faction/F = new x - if(!F.name) - del(F) - continue - else - ticker.factions.Add(F) - ticker.availablefactions.Add(F) - - // Populate the syndicate coalition: - for(var/datum/faction/syndicate/S in ticker.factions) - ticker.syndicate_coalition.Add(S) - - /* This was used for something before, I think, but is not worth the effort to process now. /proc/setupcorpses() for (var/obj/effect/landmark/A in landmarks_list) diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index 2e0f8b91fa..b39ce3f147 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -1,301 +1,11 @@ -/datum/game_mode - // this includes admin-appointed traitors and multitraitors. Easy! - var/list/datum/mind/traitors = list() - /datum/game_mode/traitor name = "traitor" + round_description = "There is a foreign agent or traitor on the station. Do not let the traitor succeed!" + extended_round_description = "NanoTrasen's monopolistic control over the phoron supplies of Nyx has marked the station to be a highly valuable target for many competing organizations and individuals. The varied pasts and experiences of your coworkers have left them susceptible to the vices and temptations of humanity. Is the station the safe self-contained workplace you once thought it was, or has it become a playground for the evils of the galaxy? Who can you trust? Watch your front. Watch your sides. Watch your back. The familiar faces that you've passed hundreds of times down the hallways before can be hiding terrible secrets and deceptions. Every corner is a mystery. Every conversation is a lie. You will be facing your friends and family as they try to use your emotions and trust to their advantage, leaving you with nothing but the painful reminder that space is cruel and unforgiving." config_tag = "traitor" - restricted_jobs = list("Cyborg")//They are part of the AI if he is traitor so are they, they use to get double chances - protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Captain")//AI", Currently out of the list as malf does not work for shit required_players = 0 required_enemies = 1 - recommended_enemies = 4 - - uplink_welcome = "AntagCorp Portable Teleportation Relay:" - uplink_uses = 10 - - var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) - var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) - - var/traitors_possible = 4 //hard limit on traitors if scaling is turned off - var/const/traitor_scaling_coeff = 5.0 //how much does the amount of players get divided by to determine traitors - - -/datum/game_mode/traitor/announce() - world << "The current game mode is - Traitor!" - world << "There is a foreign agent or traitor on the station. Do not let the traitor succeed!" - - -/datum/game_mode/traitor/pre_setup() - - if(config.protect_roles_from_antagonist) - restricted_jobs += protected_jobs - - var/list/possible_traitors = get_players_for_role(BE_TRAITOR) - - // stop setup if no possible traitors - if(!possible_traitors.len) - return 0 - - var/num_traitors = 1 - - if(config.traitor_scaling) - num_traitors = max(1, round((num_players())/(traitor_scaling_coeff))) - else - num_traitors = max(1, min(num_players(), traitors_possible)) - - for(var/datum/mind/player in possible_traitors) - for(var/job in restricted_jobs) - if(player.assigned_role == job) - possible_traitors -= player - - for(var/j = 0, j < num_traitors, j++) - if (!possible_traitors.len) - break - var/datum/mind/traitor = pick(possible_traitors) - traitors += traitor - traitor.special_role = "traitor" - possible_traitors.Remove(traitor) - - if(!traitors.len) - return 0 - return 1 - - -/datum/game_mode/traitor/post_setup() - for(var/datum/mind/traitor in traitors) - if (!config.objectives_disabled) - forge_traitor_objectives(traitor) - spawn(rand(10,100)) - finalize_traitor(traitor) - greet_traitor(traitor) - modePlayer += traitors - spawn (rand(waittime_l, waittime_h)) - send_intercept() - ..() - return 1 - - -/datum/game_mode/proc/forge_traitor_objectives(var/datum/mind/traitor) - if (config.objectives_disabled) - return - - if(istype(traitor.current, /mob/living/silicon)) - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = traitor - kill_objective.find_target() - traitor.objectives += kill_objective - - var/datum/objective/survive/survive_objective = new - survive_objective.owner = traitor - traitor.objectives += survive_objective - - if(prob(10)) - var/datum/objective/block/block_objective = new - block_objective.owner = traitor - traitor.objectives += block_objective - - else - switch(rand(1,100)) - if(1 to 33) - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = traitor - kill_objective.find_target() - traitor.objectives += kill_objective - if(34 to 50) - var/datum/objective/brig/brig_objective = new - brig_objective.owner = traitor - brig_objective.find_target() - traitor.objectives += brig_objective - if(51 to 66) - var/datum/objective/harm/harm_objective = new - harm_objective.owner = traitor - harm_objective.find_target() - traitor.objectives += harm_objective - else - var/datum/objective/steal/steal_objective = new - steal_objective.owner = traitor - steal_objective.find_target() - traitor.objectives += steal_objective - switch(rand(1,100)) - if(1 to 100) - if (!(locate(/datum/objective/escape) in traitor.objectives)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = traitor - traitor.objectives += escape_objective - - else - if (!(locate(/datum/objective/hijack) in traitor.objectives)) - var/datum/objective/hijack/hijack_objective = new - hijack_objective.owner = traitor - traitor.objectives += hijack_objective - return - - -/datum/game_mode/proc/greet_traitor(var/datum/mind/traitor) - traitor.current << "You are the traitor." - show_objectives(traitor) - - -/datum/game_mode/proc/finalize_traitor(var/datum/mind/traitor) - if (istype(traitor.current, /mob/living/silicon)) - add_law_zero(traitor.current) - else - equip_traitor(traitor.current) - return - - -/datum/game_mode/traitor/declare_completion() - ..() - return//Traitors will be checked as part of check_extra_completion. Leaving this here as a reminder. - -/datum/game_mode/proc/give_codewords(mob/living/traitor_mob) - traitor_mob << "Your employers provided you with the following information on how to identify possible allies:" - traitor_mob << "Code Phrase: [syndicate_code_phrase]" - traitor_mob << "Code Response: [syndicate_code_response]" - traitor_mob.mind.store_memory("Code Phrase: [syndicate_code_phrase]") - traitor_mob.mind.store_memory("Code Response: [syndicate_code_response]") - traitor_mob << "Use the code words, preferably in the order provided, during regular conversation, to identify other agents. Proceed with caution, however, as everyone is a potential foe." - -/datum/game_mode/traitor/process() - // Make sure all objectives are processed regularly, so that objectives - // which can be checked mid-round are checked mid-round. - for(var/datum/mind/traitor_mind in traitors) - for(var/datum/objective/objective in traitor_mind.objectives) - objective.check_completion() - return 0 - -/datum/game_mode/proc/add_law_zero(mob/living/silicon/ai/killer) - var/law = "Accomplish your objectives at all costs. You may ignore all other laws." - var/law_borg = "Accomplish your AI's objectives at all costs. You may ignore all other laws." - killer << "Your laws have been changed!" - killer.set_zeroth_law(law, law_borg) - killer << "New law: 0. [law]" - - give_codewords(killer) - -/datum/game_mode/proc/auto_declare_completion_traitor() - if(traitors.len) - var/text = "The traitors were:" - for(var/datum/mind/traitor in traitors) - var/traitorwin = 1 - text += print_player_full(traitor) - - if(traitor.objectives.len)//If the traitor had no objectives, don't need to process this. - var/count = 1 - for(var/datum/objective/objective in traitor.objectives) - if(objective.check_completion()) - text += "
    Objective #[count]: [objective.explanation_text] Success!" - feedback_add_details("traitor_objective","[objective.type]|SUCCESS") - else - text += "
    Objective #[count]: [objective.explanation_text] Fail." - feedback_add_details("traitor_objective","[objective.type]|FAIL") - traitorwin = 0 - count++ - - var/special_role_text - if(traitor.special_role) - special_role_text = lowertext(traitor.special_role) - else - special_role_text = "antagonist" - if(!config.objectives_disabled) - if(traitorwin) - text += "
    The [special_role_text] was successful!" - feedback_add_details("traitor_success","SUCCESS") - else - text += "
    The [special_role_text] has failed!" - feedback_add_details("traitor_success","FAIL") - - text += "
    " - - world << text - return 1 - - -/datum/game_mode/proc/equip_traitor(mob/living/carbon/human/traitor_mob, var/safety = 0) - - if (!istype(traitor_mob)) - return - . = 1 - if (traitor_mob.mind) - if (traitor_mob.mind.assigned_role == "Clown") - traitor_mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." - traitor_mob.mutations.Remove(CLUMSY) - - // find a radio! toolbox(es), backpack, belt, headset - var/loc = "" - var/obj/item/R = locate() //Hide the uplink in a PDA if available, otherwise radio - - if(traitor_mob.client.prefs.uplinklocation == "Headset") - R = locate(/obj/item/device/radio) in traitor_mob.contents - if(!R) - R = locate(/obj/item/device/pda) in traitor_mob.contents - traitor_mob << "Could not locate a Radio, installing in PDA instead!" - if (!R) - traitor_mob << "Unfortunately, neither a radio or a PDA relay could be installed." - - else if(traitor_mob.client.prefs.uplinklocation == "PDA") - R = locate(/obj/item/device/pda) in traitor_mob.contents - if(!R) - R = locate(/obj/item/device/radio) in traitor_mob.contents - traitor_mob << "Could not locate a PDA, installing into a Radio instead!" - if (!R) - traitor_mob << "Unfortunately, neither a radio or a PDA relay could be installed." - - else if(traitor_mob.client.prefs.uplinklocation == "None") - traitor_mob << "You have elected to not have an AntagCorp portable teleportation relay installed!" - R = null - - else - traitor_mob << "You have not selected a location for your relay in the antagonist options! Defaulting to PDA!" - R = locate(/obj/item/device/pda) in traitor_mob.contents - if (!R) - R = locate(/obj/item/device/radio) in traitor_mob.contents - traitor_mob << "Could not locate a PDA, installing into a Radio instead!" - if (!R) - traitor_mob << "Unfortunately, neither a radio or a PDA relay could be installed." - - if (!R) - . = 0 - else - if (istype(R, /obj/item/device/radio)) - // generate list of radio freqs - var/obj/item/device/radio/target_radio = R - var/freq = 1441 - var/list/freqlist = list() - while (freq <= 1489) - if (freq < 1451 || freq > PUB_FREQ) - freqlist += freq - freq += 2 - if ((freq % 2) == 0) - freq += 1 - freq = freqlist[rand(1, freqlist.len)] - - var/obj/item/device/uplink/hidden/T = new(R) - T.uplink_owner = traitor_mob.mind - target_radio.hidden_uplink = T - target_radio.traitor_frequency = freq - traitor_mob << "A portable object teleportation relay has been installed in your [R.name] [loc]. Simply dial the frequency [format_frequency(freq)] to unlock its hidden features." - traitor_mob.mind.store_memory("Radio Freq: [format_frequency(freq)] ([R.name] [loc]).") - else if (istype(R, /obj/item/device/pda)) - // generate a passcode if the uplink is hidden in a PDA - var/pda_pass = "[rand(100,999)] [pick("Alpha","Bravo","Delta","Omega")]" - - var/obj/item/device/uplink/hidden/T = new(R) - T.uplink_owner = traitor_mob.mind - R.hidden_uplink = T - var/obj/item/device/pda/P = R - P.lock_code = pda_pass - - traitor_mob << "A portable object teleportation relay has been installed in your [R.name] [loc]. Simply enter the code \"[pda_pass]\" into the ringtone select to unlock its hidden features." - traitor_mob.mind.store_memory("Uplink Passcode: [pda_pass] ([R.name] [loc]).") - //Begin code phrase. - if(!safety)//If they are not a rev. Can be added on to. - give_codewords(traitor_mob) - - // Tell them about people they might want to contact. - var/mob/living/carbon/human/M = get_nt_opposed() - if(M && M != traitor_mob) - traitor_mob << "We have received credible reports that [M.real_name] might be willing to help our cause. If you need assistance, consider contacting them." - traitor_mob.mind.store_memory("Potential Collaborator: [M.real_name]") \ No newline at end of file + end_on_antag_death = 1 + antag_scaling_coeff = 10 + antag_tag = MODE_TRAITOR \ No newline at end of file diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm deleted file mode 100644 index ccce7f9bff..0000000000 --- a/code/game/gamemodes/wizard/rightandwrong.dm +++ /dev/null @@ -1,60 +0,0 @@ - - -/mob/proc/rightandwrong() - usr << "You summoned guns!" - message_admins("[key_name_admin(usr, 1)] summoned guns!") - for(var/mob/living/carbon/human/H in player_list) - if(H.stat == 2 || !(H.client)) continue - if(is_special_character(H)) continue - if(prob(25)) - ticker.mode.traitors += H.mind - H.mind.special_role = "traitor" - var/datum/objective/survive/survive = new - survive.owner = H.mind - H.mind.objectives += survive - H << "You are the survivor! Your own safety matters above all else, trust no one and kill anyone who gets in your way. However, armed as you are, now would be the perfect time to settle that score or grab that pair of yellow gloves you've been eyeing..." - show_objectives(H.mind) - - var/randomize = pick("taser","egun","laser","revolver","detective","smg","nuclear","deagle","gyrojet","pulse","silenced","cannon","doublebarrel","shotgun","combatshotgun","mateba","smg","uzi","crossbow","saw") - switch (randomize) - if("taser") - new /obj/item/weapon/gun/energy/taser(get_turf(H)) - if("egun") - new /obj/item/weapon/gun/energy/gun(get_turf(H)) - if("laser") - new /obj/item/weapon/gun/energy/laser(get_turf(H)) - if("revolver") - new /obj/item/weapon/gun/projectile(get_turf(H)) - if("detective") - new /obj/item/weapon/gun/projectile/detective(get_turf(H)) - if("smg") - new /obj/item/weapon/gun/projectile/automatic/c20r(get_turf(H)) - if("nuclear") - new /obj/item/weapon/gun/energy/gun/nuclear(get_turf(H)) - if("deagle") - new /obj/item/weapon/gun/projectile/deagle/camo(get_turf(H)) - if("gyrojet") - new /obj/item/weapon/gun/projectile/gyropistol(get_turf(H)) - if("pulse") - new /obj/item/weapon/gun/energy/pulse_rifle(get_turf(H)) - if("silenced") - new /obj/item/weapon/gun/projectile/pistol(get_turf(H)) - new /obj/item/weapon/silencer(get_turf(H)) - if("cannon") - new /obj/item/weapon/gun/energy/lasercannon(get_turf(H)) - if("doublebarrel") - new /obj/item/weapon/gun/projectile/shotgun/pump/(get_turf(H)) - if("shotgun") - new /obj/item/weapon/gun/projectile/shotgun/pump/(get_turf(H)) - if("combatshotgun") - new /obj/item/weapon/gun/projectile/shotgun/pump/combat(get_turf(H)) - if("mateba") - new /obj/item/weapon/gun/projectile/mateba(get_turf(H)) - if("smg") - new /obj/item/weapon/gun/projectile/automatic(get_turf(H)) - if("uzi") - new /obj/item/weapon/gun/projectile/automatic/mini_uzi(get_turf(H)) - if("crossbow") - new /obj/item/weapon/gun/energy/crossbow(get_turf(H)) - if("saw") - new /obj/item/weapon/gun/projectile/automatic/l6_saw(get_turf(H)) \ No newline at end of file diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index ab3806a97c..85cbf3a705 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -1,273 +1,12 @@ - -/datum/game_mode - var/list/datum/mind/wizards = list() - /datum/game_mode/wizard - name = "wizard" + name = "Wizard" + round_description = "There is a SPACE WIZARD on the station. You can't let them achieve their objectives!" + extended_round_description = "A powerful entity capable of manipulating the elements around him, most commonly referred to as a 'wizard', has infiltrated the station. They have a wide variety of powers and spells available to them that makes your own simple moral self tremble with fear and excitement. Ultimately, their purpose is unknown. However, it is up to you and your crew to decide if their powers can be used for good or if their arrival foreshadows the destruction of the entire station." config_tag = "wizard" - required_players = 2 + required_players = 1 required_players_secret = 10 required_enemies = 1 - recommended_enemies = 1 - uplink_welcome = "Wizardly Uplink Console:" uplink_uses = 10 - - var/finished = 0 - - var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) - var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) - - -/datum/game_mode/wizard/announce() - world << "The current game mode is - Wizard!" - world << "There is a \red SPACE WIZARD\black on the station. You can't let him achieve his objective!" - - -/datum/game_mode/wizard/can_start()//This could be better, will likely have to recode it later - if(!..()) - return 0 - var/list/datum/mind/possible_wizards = get_players_for_role(BE_WIZARD) - if(possible_wizards.len==0) - return 0 - var/datum/mind/wizard = pick(possible_wizards) - wizards += wizard - modePlayer += wizard - wizard.assigned_role = "MODE" //So they aren't chosen for other jobs. - wizard.special_role = "Wizard" - wizard.original = wizard.current - if(wizardstart.len == 0) - wizard.current << "\red A starting location for you could not be found, please report this bug!" - return 0 - return 1 - - -/datum/game_mode/wizard/pre_setup() - for(var/datum/mind/wizard in wizards) - wizard.current.loc = pick(wizardstart) - return 1 - - -/datum/game_mode/wizard/post_setup() - for(var/datum/mind/wizard in wizards) - if(!config.objectives_disabled) - forge_wizard_objectives(wizard) - //learn_basic_spells(wizard.current) - equip_wizard(wizard.current) - name_wizard(wizard.current) - greet_wizard(wizard) - - spawn (rand(waittime_l, waittime_h)) - send_intercept() - ..() - return - - -/datum/game_mode/proc/forge_wizard_objectives(var/datum/mind/wizard) - if (config.objectives_disabled) - return - - switch(rand(1,100)) - if(1 to 30) - - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = wizard - kill_objective.find_target() - wizard.objectives += kill_objective - - if (!(locate(/datum/objective/escape) in wizard.objectives)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = wizard - wizard.objectives += escape_objective - if(31 to 60) - var/datum/objective/steal/steal_objective = new - steal_objective.owner = wizard - steal_objective.find_target() - wizard.objectives += steal_objective - - if (!(locate(/datum/objective/escape) in wizard.objectives)) - var/datum/objective/escape/escape_objective = new - escape_objective.owner = wizard - wizard.objectives += escape_objective - - if(61 to 100) - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = wizard - kill_objective.find_target() - wizard.objectives += kill_objective - - var/datum/objective/steal/steal_objective = new - steal_objective.owner = wizard - steal_objective.find_target() - wizard.objectives += steal_objective - - if (!(locate(/datum/objective/survive) in wizard.objectives)) - var/datum/objective/survive/survive_objective = new - survive_objective.owner = wizard - wizard.objectives += survive_objective - - else - if (!(locate(/datum/objective/hijack) in wizard.objectives)) - var/datum/objective/hijack/hijack_objective = new - hijack_objective.owner = wizard - wizard.objectives += hijack_objective - return - - -/datum/game_mode/proc/name_wizard(mob/living/carbon/human/wizard_mob) - //Allows the wizard to choose a custom name or go with a random one. Spawn 0 so it does not lag the round starting. - var/wizard_name_first = pick(wizard_first) - var/wizard_name_second = pick(wizard_second) - var/randomname = "[wizard_name_first] [wizard_name_second]" - spawn(0) - var/newname = sanitize(copytext(input(wizard_mob, "You are the Space Wizard. Would you like to change your name to something else?", "Name change", randomname) as null|text,1,MAX_NAME_LEN)) - - if (!newname) - newname = randomname - - wizard_mob.real_name = newname - wizard_mob.name = newname - if(wizard_mob.mind) - wizard_mob.mind.name = newname - return - - -/datum/game_mode/proc/greet_wizard(var/datum/mind/wizard, var/you_are=1) - if (you_are) - wizard.current << "\red You are the Space Wizard!" - show_objectives(wizard) - -/*/datum/game_mode/proc/learn_basic_spells(mob/living/carbon/human/wizard_mob) - if (!istype(wizard_mob)) - return - if(!config.feature_object_spell_system) - wizard_mob.verbs += /client/proc/jaunt - wizard_mob.mind.special_verbs += /client/proc/jaunt - else - wizard_mob.spell_list += new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(usr) -*/ - -/datum/game_mode/proc/equip_wizard(mob/living/carbon/human/wizard_mob) - if (!istype(wizard_mob)) - return - - //So zards properly get their items when they are admin-made. - del(wizard_mob.wear_suit) - del(wizard_mob.head) - del(wizard_mob.shoes) - del(wizard_mob.r_hand) - del(wizard_mob.r_store) - del(wizard_mob.l_store) - - wizard_mob.equip_to_slot_or_del(new /obj/item/device/radio/headset(wizard_mob), slot_l_ear) - wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/under/lightpurple(wizard_mob), slot_w_uniform) - wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(wizard_mob), slot_shoes) - wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(wizard_mob), slot_wear_suit) - wizard_mob.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(wizard_mob), slot_head) - if(wizard_mob.backbag == 2) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(wizard_mob), slot_back) - if(wizard_mob.backbag == 3) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(wizard_mob), slot_back) - if(wizard_mob.backbag == 4) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(wizard_mob), slot_back) - wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box(wizard_mob), slot_in_backpack) -// wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/scrying_gem(wizard_mob), slot_l_store) For scrying gem. - wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(wizard_mob), slot_r_store) - wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/spellbook(wizard_mob), slot_r_hand) - - wizard_mob << "You will find a list of available spells in your spell book. Choose your magic arsenal carefully." - wizard_mob << "In your pockets you will find a teleport scroll. Use it as needed." - wizard_mob.mind.store_memory("Remember: do not forget to prepare your spells.") - wizard_mob.update_icons() - return 1 - - -/datum/game_mode/wizard/check_finished() - - if(config.continous_rounds) - return ..() - - var/wizards_alive = 0 - for(var/datum/mind/wizard in wizards) - if(!istype(wizard.current,/mob/living/carbon)) - continue - if(wizard.current.stat==2) - continue - wizards_alive++ - - if (wizards_alive) - return ..() - else - finished = 1 - return 1 - - - -/datum/game_mode/wizard/declare_completion() - if(finished) - feedback_set_details("round_end_result","loss - wizard killed") - world << "\red The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!" - ..() - return 1 - - -/datum/game_mode/proc/auto_declare_completion_wizard() - if(wizards.len) - var/text = "The wizards/witches were:" - - for(var/datum/mind/wizard in wizards) - - text += "
    [wizard.key] was [wizard.name] (" - if(wizard.current) - if(wizard.current.stat == DEAD) - text += "died" - else - text += "survived" - if(wizard.current.real_name != wizard.name) - text += " as [wizard.current.real_name]" - else - text += "body destroyed" - text += ")" - - var/count = 1 - var/wizardwin = 1 - if(!config.objectives_disabled) - for(var/datum/objective/objective in wizard.objectives) - if(objective.check_completion()) - text += "
    Objective #[count]: [objective.explanation_text] Success!" - feedback_add_details("wizard_objective","[objective.type]|SUCCESS") - else - text += "
    Objective #[count]: [objective.explanation_text] Fail." - feedback_add_details("wizard_objective","[objective.type]|FAIL") - wizardwin = 0 - count++ - - if(wizard.current && wizard.current.stat!=2 && wizardwin) - text += "
    The wizard was successful!" - feedback_add_details("wizard_success","SUCCESS") - else - text += "
    The wizard has failed!" - feedback_add_details("wizard_success","FAIL") - - world << text - return 1 - -//OTHER PROCS - -//To batch-remove wizard spells. Linked to mind.dm. -/mob/proc/spellremove(var/mob/M as mob) - for(var/obj/effect/proc_holder/spell/spell_to_remove in src.spell_list) - del(spell_to_remove) - -/*Checks if the wizard can cast spells. -Made a proc so this is not repeated 14 (or more) times.*/ -/mob/proc/casting() -//Removed the stat check because not all spells require clothing now. - if(!istype(usr:wear_suit, /obj/item/clothing/suit/wizrobe)) - usr << "I don't feel strong enough without my robe." - return 0 - if(!istype(usr:shoes, /obj/item/clothing/shoes/sandal)) - usr << "I don't feel strong enough without my sandals." - return 0 - if(!istype(usr:head, /obj/item/clothing/head/wizard)) - usr << "I don't feel strong enough without my hat." - return 0 - else - return 1 + end_on_antag_death = 1 + antag_tag = MODE_WIZARD diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 7f2ec98d12..6d2b5e33d6 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -85,10 +85,8 @@ //MONEY /var/const/access_crate_cash = 200 -/obj/var/list/req_access = null -/obj/var/req_access_txt = "0" -/obj/var/list/req_one_access = null -/obj/var/req_one_access_txt = "0" +/obj/var/list/req_access = list() +/obj/var/list/req_one_access = list() //returns 1 if this mob has sufficient access to use this object /obj/proc/allowed(mob/M) @@ -103,11 +101,6 @@ //if they are holding or wearing a card that has access, that works if(src.check_access(H.get_active_hand()) || src.check_access(H.wear_id)) return 1 - else if(istype(M, /mob/living/carbon/monkey)) - var/mob/living/carbon/george = M - //they can only hold things :( - if(src.check_access(george.get_active_hand())) - return 1 return 0 /obj/item/proc/GetAccess() @@ -117,37 +110,14 @@ return null /obj/proc/check_access(obj/item/I) - //These generations have been moved out of /obj/New() because they were slowing down the creation of objects that never even used the access system. - if(!src.req_access) - src.req_access = list() - if(src.req_access_txt) - var/list/req_access_str = text2list(req_access_txt,";") - for(var/x in req_access_str) - var/n = text2num(x) - if(n) - req_access += n - - if(!src.req_one_access) - src.req_one_access = list() - if(src.req_one_access_txt) - var/list/req_one_access_str = text2list(req_one_access_txt,";") - for(var/x in req_one_access_str) - var/n = text2num(x) - if(n) - req_one_access += n - - if(!istype(src.req_access, /list)) //something's very wrong - return 1 - - var/list/L = src.req_access - if(!L.len && (!src.req_one_access || !src.req_one_access.len)) //no requirements + if(!(!req_access || req_access.len) && !(req_one_access || req_one_access.len)) //no requirements return 1 if(!I) return 0 for(var/req in src.req_access) if(!(req in I.GetAccess())) //doesn't have this access return 0 - if(src.req_one_access && src.req_one_access.len) + if(src.req_one_access.len) for(var/req in src.req_one_access) if(req in I.GetAccess()) //has an access from the single access list return 1 @@ -156,15 +126,13 @@ /obj/proc/check_access_list(var/list/L) - if(!src.req_access && !src.req_one_access) return 1 - if(!istype(src.req_access, /list)) return 1 - if(!src.req_access.len && (!src.req_one_access || !src.req_one_access.len)) return 1 + if(!src.req_access.len && !src.req_one_access.len) return 1 if(!L) return 0 if(!istype(L, /list)) return 0 for(var/req in src.req_access) if(!(req in L)) //doesn't have this access return 0 - if(src.req_one_access && src.req_one_access.len) + if(src.req_one_access.len) for(var/req in src.req_one_access) if(req in L) //has an access from the single access list return 1 @@ -407,7 +375,7 @@ /proc/get_all_jobs() var/list/all_jobs = list() var/list/all_datums = typesof(/datum/job) - all_datums.Remove(list(/datum/job,/datum/job/ai,/datum/job/cyborg)) + all_datums -= exclude_jobs var/datum/job/jobdatum for(var/jobtype in all_datums) jobdatum = new jobtype diff --git a/code/game/jobs/job/assistant.dm b/code/game/jobs/job/assistant.dm index 270a4e3867..d876118a34 100644 --- a/code/game/jobs/job/assistant.dm +++ b/code/game/jobs/job/assistant.dm @@ -1,6 +1,7 @@ /datum/job/assistant title = "Assistant" flag = ASSISTANT + department = "Civilian" department_flag = CIVILIAN faction = "Station" total_positions = -1 @@ -9,7 +10,7 @@ selection_color = "#dddddd" access = list() //See /datum/job/assistant/get_access() minimal_access = list() //See /datum/job/assistant/get_access() - alt_titles = list("Technical Assistant","Medical Intern","Research Assistant","Security Cadet") + alt_titles = list("Technical Assistant","Medical Intern","Research Assistant","Security Cadet","Visitor") /datum/job/assistant/equip(var/mob/living/carbon/human/H) if(!H) return 0 diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm index a43056fa96..f9cd48c6de 100644 --- a/code/game/jobs/job/captain.dm +++ b/code/game/jobs/job/captain.dm @@ -3,6 +3,8 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) /datum/job/captain title = "Captain" flag = CAPTAIN + department = "Command" + head_position = 1 department_flag = ENGSEC faction = "Station" total_positions = 1 @@ -24,7 +26,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) var/obj/item/clothing/under/U = new /obj/item/clothing/under/rank/captain(H) if(H.age>49) - U.hastie = new /obj/item/clothing/tie/medal/gold/captain(U) + U.accessories += new /obj/item/clothing/accessory/medal/gold/captain(U) H.equip_to_slot_or_del(U, slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/device/pda/captain(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes) @@ -50,6 +52,8 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) /datum/job/hop title = "Head of Personnel" flag = HOP + department = "Civilian" + head_position = 1 department_flag = CIVILIAN faction = "Station" total_positions = 1 diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm index 64209f675b..062571655d 100644 --- a/code/game/jobs/job/civilian.dm +++ b/code/game/jobs/job/civilian.dm @@ -2,6 +2,7 @@ /datum/job/bartender title = "Bartender" flag = BARTENDER + department = "Civilian" department_flag = CIVILIAN faction = "Station" total_positions = 1 @@ -44,6 +45,7 @@ /datum/job/chef title = "Chef" flag = CHEF + department = "Civilian" department_flag = CIVILIAN faction = "Station" total_positions = 2 @@ -74,6 +76,7 @@ /datum/job/hydro title = "Gardener" flag = BOTANIST + department = "Civilian" department_flag = CIVILIAN faction = "Station" total_positions = 2 @@ -108,6 +111,7 @@ /datum/job/qm title = "Quartermaster" flag = QUARTERMASTER + department = "Cargo" department_flag = CIVILIAN faction = "Station" total_positions = 1 @@ -138,6 +142,7 @@ /datum/job/cargo_tech title = "Cargo Technician" flag = CARGOTECH + department = "Cargo" department_flag = CIVILIAN faction = "Station" total_positions = 2 @@ -166,6 +171,7 @@ /datum/job/mining title = "Shaft Miner" flag = MINER + department = "Cargo" department_flag = CIVILIAN faction = "Station" total_positions = 3 @@ -277,6 +283,7 @@ /datum/job/janitor title = "Janitor" flag = JANITOR + department = "Civilian" department_flag = CIVILIAN faction = "Station" total_positions = 1 @@ -305,6 +312,7 @@ /datum/job/librarian title = "Librarian" flag = LIBRARIAN + department = "Civilian" department_flag = CIVILIAN faction = "Station" total_positions = 1 @@ -334,6 +342,7 @@ /datum/job/lawyer title = "Internal Affairs Agent" flag = LAWYER + department = "Civilian" department_flag = CIVILIAN faction = "Station" total_positions = 2 diff --git a/code/game/jobs/job/civilian_chaplain.dm b/code/game/jobs/job/civilian_chaplain.dm index e7ce82b595..9b08e0d47c 100644 --- a/code/game/jobs/job/civilian_chaplain.dm +++ b/code/game/jobs/job/civilian_chaplain.dm @@ -2,6 +2,7 @@ /datum/job/chaplain title = "Chaplain" flag = CHAPLAIN + department = "Civilian" department_flag = CIVILIAN faction = "Station" total_positions = 1 @@ -27,7 +28,7 @@ H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) spawn(0) var/religion_name = "Christianity" - var/new_religion = sanitize(copytext(input(H, "You are the crew services officer. Would you like to change your religion? Default is Christianity, in SPACE.", "Name change", religion_name),1,MAX_NAME_LEN)) + var/new_religion = sanitize(input(H, "You are the crew services officer. Would you like to change your religion? Default is Christianity, in SPACE.", "Name change", religion_name), MAX_NAME_LEN) if (!new_religion) new_religion = religion_name @@ -62,7 +63,7 @@ spawn(1) var/deity_name = "Space Jesus" - var/new_deity = sanitize(copytext(input(H, "Would you like to change your deity? Default is Space Jesus.", "Name change", deity_name),1,MAX_NAME_LEN)) + var/new_deity = sanitize(input(H, "Would you like to change your deity? Default is Space Jesus.", "Name change", deity_name), MAX_NAME_LEN) if ((length(new_deity) == 0) || (new_deity == "Space Jesus") ) new_deity = deity_name diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm index 8677f99728..249c103c87 100644 --- a/code/game/jobs/job/engineering.dm +++ b/code/game/jobs/job/engineering.dm @@ -1,6 +1,8 @@ /datum/job/chief_engineer title = "Chief Engineer" flag = CHIEF + head_position = 1 + department = "Engineering" department_flag = ENGSEC faction = "Station" total_positions = 1 @@ -44,6 +46,7 @@ /datum/job/engineer title = "Station Engineer" flag = ENGINEER + department = "Engineering" department_flag = ENGSEC faction = "Station" total_positions = 5 @@ -79,6 +82,7 @@ /datum/job/atmos title = "Atmospheric Technician" flag = ATMOSTECH + department = "Engineering" department_flag = ENGSEC faction = "Station" total_positions = 3 diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index 0c44f6f260..ba40b09e44 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -2,111 +2,54 @@ //The name of the job var/title = "NOPE" - //Job access. The use of minimal_access or access is determined by a config setting: config.jobs_have_minimal_access - var/list/minimal_access = list() //Useful for servers which prefer to only have access given to the places a job absolutely needs (Larger server population) - var/list/access = list() //Useful for servers which either have fewer players, so each person needs to fill more than one role, or servers which like to give more access, so players can't hide forever in their super secure departments (I'm looking at you, chemistry!) - - //Bitflags for the job - var/flag = 0 + var/list/minimal_access = list() // Useful for servers which prefer to only have access given to the places a job absolutely needs (Larger server population) + var/list/access = list() // Useful for servers which either have fewer players, so each person needs to fill more than one role, or servers which like to give more access, so players can't hide forever in their super secure departments (I'm looking at you, chemistry!) + var/flag = 0 // Bitflags for the job var/department_flag = 0 - - //Players will be allowed to spawn in as jobs that are set to "Station" - var/faction = "None" - - //How many players can be this job - var/total_positions = 0 - - //How many players can spawn in as this job - var/spawn_positions = 0 - - //How many players have this job - var/current_positions = 0 - - //Supervisors, who this person answers to directly - var/supervisors = "" - - //Sellection screen color - var/selection_color = "#ffffff" - - //the type of the ID the player will have - var/idtype = /obj/item/weapon/card/id - - //List of alternate titles, if any - var/list/alt_titles - - //If this is set to 1, a text is printed to the player when jobs are assigned, telling him that he should let admins know that he has to disconnect. - var/req_admin_notify - - //If you have use_age_restriction_for_jobs config option enabled and the database set up, this option will add a requirement for players to be at least minimal_player_age days old. (meaning they first signed in at least that many days before.) - var/minimal_player_age = 0 + var/faction = "None" // Players will be allowed to spawn in as jobs that are set to "Station" + var/total_positions = 0 // How many players can be this job + var/spawn_positions = 0 // How many players can spawn in as this job + var/current_positions = 0 // How many players have this job + var/supervisors = null // Supervisors, who this person answers to directly + var/selection_color = "#ffffff" // Selection screen color + var/idtype = /obj/item/weapon/card/id // The type of the ID the player will have + var/list/alt_titles // List of alternate titles, if any + var/req_admin_notify // If this is set to 1, a text is printed to the player when jobs are assigned, telling him that he should let admins know that he has to disconnect. + var/minimal_player_age = 0 // If you have use_age_restriction_for_jobs config option enabled and the database set up, this option will add a requirement for players to be at least minimal_player_age days old. (meaning they first signed in at least that many days before.) + var/department = null // Does this position have a department tag? + var/head_position = 0 // Is this position Command? /datum/job/proc/equip(var/mob/living/carbon/human/H) return 1 /datum/job/proc/get_access() - if(!config) //Needed for robots. - return src.minimal_access.Copy() - - if(config.jobs_have_minimal_access) + if(!config || config.jobs_have_minimal_access) return src.minimal_access.Copy() else return src.access.Copy() //If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1 /datum/job/proc/player_old_enough(client/C) - if(available_in_days(C) == 0) - return 1 //Available in 0 days = available right now = player is old enough to play. - return 0 - + return (available_in_days(C) == 0) //Available in 0 days = available right now = player is old enough to play. /datum/job/proc/available_in_days(client/C) - if(!C) - return 0 - if(!config.use_age_restriction_for_jobs) - return 0 - if(!isnum(C.player_age)) - return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced - if(!isnum(minimal_player_age)) - return 0 + if(C && config.use_age_restriction_for_jobs && isnum(C.player_age) && isnum(minimal_player_age)) + return max(0, minimal_player_age - C.player_age) + return 0 - return max(0, minimal_player_age - C.player_age) - -/datum/job/proc/apply_fingerprints(var/mob/living/carbon/human/H) - if(!istype(H)) - return - if(H.back) - H.back.add_fingerprint(H,1) //The 1 sets a flag to ignore gloves - for(var/obj/item/I in H.back.contents) - I.add_fingerprint(H,1) - if(H.wear_id) - H.wear_id.add_fingerprint(H,1) - if(H.w_uniform) - H.w_uniform.add_fingerprint(H,1) - if(H.wear_suit) - H.wear_suit.add_fingerprint(H,1) - if(H.wear_mask) - H.wear_mask.add_fingerprint(H,1) - if(H.head) - H.head.add_fingerprint(H,1) - if(H.shoes) - H.shoes.add_fingerprint(H,1) - if(H.gloves) - H.gloves.add_fingerprint(H,1) - if(H.l_ear) - H.l_ear.add_fingerprint(H,1) - if(H.r_ear) - H.r_ear.add_fingerprint(H,1) - if(H.glasses) - H.glasses.add_fingerprint(H,1) - if(H.belt) - H.belt.add_fingerprint(H,1) - for(var/obj/item/I in H.belt.contents) - I.add_fingerprint(H,1) - if(H.s_store) - H.s_store.add_fingerprint(H,1) - if(H.l_store) - H.l_store.add_fingerprint(H,1) - if(H.r_store) - H.r_store.add_fingerprint(H,1) +/datum/job/proc/apply_fingerprints(var/mob/living/carbon/human/target) + if(!istype(target)) + return 0 + for(var/obj/item/item in target.contents) + apply_fingerprints_to_item(target, item) return 1 + +/datum/job/proc/apply_fingerprints_to_item(var/mob/living/carbon/human/holder, var/obj/item/item) + item.add_fingerprint(holder,1) + if(item.contents.len) + for(var/obj/item/sub_item in item.contents) + apply_fingerprints_to_item(holder, sub_item) + +/datum/job/proc/is_position_available() + return (current_positions < total_positions) || (total_positions == -1) diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm index a63363f779..8454ced144 100644 --- a/code/game/jobs/job/medical.dm +++ b/code/game/jobs/job/medical.dm @@ -1,6 +1,8 @@ /datum/job/cmo title = "Chief Medical Officer" flag = CMO + head_position = 1 + department = "Medical" department_flag = MEDSCI faction = "Station" total_positions = 1 @@ -11,10 +13,10 @@ req_admin_notify = 1 access = list(access_medical, access_morgue, access_genetics, access_heads, access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce, - access_keycard_auth, access_sec_doors, access_psychiatrist) + access_keycard_auth, access_sec_doors, access_psychiatrist, access_eva) minimal_access = list(access_medical, access_morgue, access_genetics, access_heads, access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce, - access_keycard_auth, access_sec_doors, access_psychiatrist) + access_keycard_auth, access_sec_doors, access_psychiatrist, access_eva) minimal_player_age = 10 equip(var/mob/living/carbon/human/H) @@ -39,6 +41,7 @@ /datum/job/doctor title = "Medical Doctor" flag = DOCTOR + department = "Medical" department_flag = MEDSCI faction = "Station" total_positions = 5 @@ -104,6 +107,7 @@ /datum/job/chemist title = "Chemist" flag = CHEMIST + department = "Medical" department_flag = MEDSCI faction = "Station" total_positions = 2 @@ -135,6 +139,7 @@ /datum/job/geneticist title = "Geneticist" flag = GENETICIST + department = "Medical" department_flag = MEDSCI faction = "Station" total_positions = 0 @@ -164,6 +169,7 @@ /datum/job/psychiatrist title = "Psychiatrist" flag = PSYCHIATRIST + department = "Medical" department_flag = MEDSCI faction = "Station" total_positions = 1 @@ -196,3 +202,45 @@ else H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat(H), slot_wear_suit) + + +/datum/job/Paramedic + title = "Paramedic" + flag = PARAMEDIC + department = "Medical" + department_flag = MEDSCI + faction = "Station" + total_positions = 2 + spawn_positions = 2 + supervisors = "the chief medical officer" + selection_color = "#ffeef0" + access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_eva, access_maint_tunnels, access_external_airlocks, access_psychiatrist) + minimal_access = list(access_medical, access_morgue, access_eva, access_maint_tunnels, access_external_airlocks) + alt_titles = list("Emergency Medical Technician") + + equip(var/mob/living/carbon/human/H) + if(!H) return 0 + H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_med(H), slot_l_ear) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/adv(H), slot_l_hand) + switch(H.backbag) + if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/medic(H), slot_back) + if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_med(H), slot_back) + if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if (H.mind.role_alt_title) + switch(H.mind.role_alt_title) + if("Emergency Medical Technician") + H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical/fluff/short(H), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/fr_jacket(H), slot_wear_suit) + if("Paramedic") + H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical/black(H), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/fr_jacket(H), slot_wear_suit) + else + H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/medical/emt(H), slot_belt) + H.equip_to_slot_or_del(new /obj/item/device/pda/medical(H), slot_l_store) + if(H.backbag == 1) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(H), slot_r_hand) + else + H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(H.back), slot_in_backpack) + return 1 diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm index e387e0d4be..6142296d72 100644 --- a/code/game/jobs/job/science.dm +++ b/code/game/jobs/job/science.dm @@ -1,6 +1,8 @@ /datum/job/rd title = "Research Director" flag = RD + head_position = 1 + department = "Science" department_flag = MEDSCI faction = "Station" total_positions = 1 @@ -40,15 +42,16 @@ /datum/job/scientist title = "Scientist" flag = SCIENTIST + department = "Science" department_flag = MEDSCI faction = "Station" - total_positions = 6 + total_positions = 5 spawn_positions = 3 supervisors = "the research director" selection_color = "#ffeeff" access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology, access_xenoarch) minimal_access = list(access_tox, access_tox_storage, access_research, access_xenoarch) - alt_titles = list("Xenoarcheologist", "Anomalist", "Phoron Researcher", "Xenobotanist") + alt_titles = list("Xenoarcheologist", "Anomalist", "Phoron Researcher") minimal_player_age = 14 @@ -72,14 +75,16 @@ /datum/job/xenobiologist title = "Xenobiologist" flag = XENOBIOLOGIST + department = "Science" department_flag = MEDSCI faction = "Station" - total_positions = 2 + total_positions = 3 spawn_positions = 2 supervisors = "the research director" selection_color = "#ffeeff" access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology) minimal_access = list(access_research, access_xenobiology) + alt_titles = list("Xenobotanist") minimal_player_age = 14 @@ -101,6 +106,7 @@ /datum/job/roboticist title = "Roboticist" flag = ROBOTICIST + department = "Science" department_flag = MEDSCI faction = "Station" total_positions = 2 diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 6d25f7fe58..1a0e3bdf3a 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -1,6 +1,8 @@ /datum/job/hos title = "Head of Security" flag = HOS + head_position = 1 + department = "Security" department_flag = ENGSEC faction = "Station" total_positions = 1 @@ -47,6 +49,7 @@ /datum/job/warden title = "Warden" flag = WARDEN + department = "Security" department_flag = ENGSEC faction = "Station" total_positions = 1 @@ -84,6 +87,7 @@ /datum/job/detective title = "Detective" flag = DETECTIVE + department = "Security" department_flag = ENGSEC faction = "Station" total_positions = 2 @@ -128,6 +132,7 @@ /datum/job/officer title = "Security Officer" flag = OFFICER + department = "Security" department_flag = ENGSEC faction = "Station" total_positions = 3 diff --git a/code/game/jobs/job/silicon.dm b/code/game/jobs/job/silicon.dm index 07ceefb8b3..11d8f70a12 100644 --- a/code/game/jobs/job/silicon.dm +++ b/code/game/jobs/job/silicon.dm @@ -3,7 +3,7 @@ flag = AI department_flag = ENGSEC faction = "Station" - total_positions = 0 + total_positions = 0 // Not used for AI, see is_position_available below and modules/mob/living/silicon/ai/latejoin.dm spawn_positions = 1 selection_color = "#ccffcc" supervisors = "your laws" @@ -14,6 +14,8 @@ if(!H) return 0 return 1 +/datum/job/ai/is_position_available() + return (empty_playable_ai_cores.len != 0) /datum/job/cyborg diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index b3918713e7..f6ec2ad87d 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -225,10 +225,11 @@ var/global/datum/controller/occupations/job_master SetupOccupations() //Holder for Triumvirate is stored in the ticker, this just processes it - if(ticker) - for(var/datum/job/ai/A in occupations) - if(ticker.triai) + if(ticker && ticker.triai) + for(var/datum/job/A in occupations) + if(A.title == "AI") A.spawn_positions = 3 + break //Get the players who are ready for(var/mob/new_player/player in player_list) @@ -245,7 +246,7 @@ var/global/datum/controller/occupations/job_master //People who wants to be assistants, sure, go on. Debug("DO, Running Assistant Check 1") - var/datum/job/assist = new /datum/job/assistant() + var/datum/job/assist = new DEFAULT_JOB_TYPE () var/list/assistant_candidates = FindOccupationCandidates(assist, 3) Debug("AC1, Candidates: [assistant_candidates.len]") for(var/mob/new_player/player in assistant_candidates) @@ -421,7 +422,7 @@ var/global/datum/controller/occupations/job_master if(istype(S, /obj/effect/landmark/start) && istype(S.loc, /turf)) H.loc = S.loc // Moving wheelchair if they have one - if(H.buckled && istype(H.buckled, /obj/structure/stool/bed/chair/wheelchair)) + if(H.buckled && istype(H.buckled, /obj/structure/bed/chair/wheelchair)) H.buckled.loc = H.loc H.buckled.set_dir(H.dir) @@ -463,7 +464,9 @@ var/global/datum/controller/occupations/job_master switch(rank) if("Cyborg") return H.Robotize() - if("AI","Clown") //don't need bag preference stuff! + if("AI") + return H + if("Clown") //don't need bag preference stuff! else switch(H.backbag) //BS12 EDIT if(1) @@ -514,33 +517,36 @@ var/global/datum/controller/occupations/job_master var/datum/organ/external/l_foot = H.get_organ("l_foot") var/datum/organ/external/r_foot = H.get_organ("r_foot") if((!l_foot || l_foot.status & ORGAN_DESTROYED) && (!r_foot || r_foot.status & ORGAN_DESTROYED)) - var/obj/structure/stool/bed/chair/wheelchair/W = new /obj/structure/stool/bed/chair/wheelchair(H.loc) + var/obj/structure/bed/chair/wheelchair/W = new /obj/structure/bed/chair/wheelchair(H.loc) H.buckled = W H.update_canmove() W.set_dir(H.dir) W.buckled_mob = H W.add_fingerprint(H) - H << "You are the [alt_title ? alt_title : rank]." - H << "As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this." - H << "To speak on your department's radio channel use :h. For the use of other channels, examine your headset." + H << "You are [job.total_positions == 1 ? "the" : "a"] [alt_title ? alt_title : rank]." + + if(job.supervisors) + H << "As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this." + + if(job.idtype) + spawnId(H, rank, alt_title) + H.equip_to_slot_or_del(new /obj/item/device/radio/headset(H), slot_l_ear) + H << "To speak on your department's radio channel use :h. For the use of other channels, examine your headset." + if(job.req_admin_notify) H << "You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp." - spawnId(H, rank, alt_title) - H.equip_to_slot_or_del(new /obj/item/device/radio/headset(H), slot_l_ear) - //Gives glasses to the vision impaired if(H.disabilities & NEARSIGHTED) var/equipped = H.equip_to_slot_or_del(new /obj/item/clothing/glasses/regular(H), slot_glasses) if(equipped != 1) var/obj/item/clothing/glasses/G = H.glasses G.prescription = 1 -// H.update_icons() - H.hud_updateflag |= (1 << ID_HUD) - H.hud_updateflag |= (1 << IMPLOYAL_HUD) - H.hud_updateflag |= (1 << SPECIALROLE_HUD) + BITSET(H.hud_updateflag, ID_HUD) + BITSET(H.hud_updateflag, IMPLOYAL_HUD) + BITSET(H.hud_updateflag, SPECIALROLE_HUD) return H @@ -648,4 +654,4 @@ var/global/datum/controller/occupations/job_master else level4++ //not selected tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|-" - feedback_add_details("job_preferences",tmp_str) \ No newline at end of file + feedback_add_details("job_preferences",tmp_str) diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm index a90f3ad716..135da6bb60 100644 --- a/code/game/jobs/jobs.dm +++ b/code/game/jobs/jobs.dm @@ -25,6 +25,7 @@ var/const/VIROLOGIST =(1<<6) var/const/PSYCHIATRIST =(1<<7) var/const/ROBOTICIST =(1<<8) var/const/XENOBIOLOGIST =(1<<9) +var/const/PARAMEDIC =(1<<10) var/const/CIVILIAN =(1<<2) @@ -71,7 +72,8 @@ var/list/medical_positions = list( "Medical Doctor", "Geneticist", "Psychiatrist", - "Chemist" + "Chemist", + "Paramedic" ) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 91c96fcfc9..20c16dcb9c 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -408,7 +408,7 @@ set category = "Object" set src in oview(1) - if(usr.stat != 0 || !(ishuman(usr) || ismonkey(usr))) + if(usr.stat != 0 || !(ishuman(usr) || issmall(usr))) return if(src.occupant) diff --git a/code/game/machinery/ai_slipper.dm b/code/game/machinery/ai_slipper.dm index 3f2b1dc3bb..5f6e40e414 100644 --- a/code/game/machinery/ai_slipper.dm +++ b/code/game/machinery/ai_slipper.dm @@ -4,6 +4,8 @@ icon_state = "motion0" layer = 3 anchored = 1.0 + use_power = 1 + idle_power_usage = 10 var/uses = 20 var/disabled = 1 var/lethal = 0 @@ -13,6 +15,7 @@ var/cooldown_on = 0 req_access = list(access_ai_upload) + /obj/machinery/ai_slipper/New() ..() update_icon() diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index b6622e75a4..9e3e56f558 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -80,6 +80,9 @@ var/report_danger_level = 1 +/obj/machinery/alarm/nobreach + breach_detection = 0 + /obj/machinery/alarm/monitor report_danger_level = 0 breach_detection = 0 @@ -117,19 +120,6 @@ first_run() -/obj/machinery/alarm/Del() - //If there's an active alarm, clear it after minute so that alarms don't keep going forver - delayed_reset() - ..() - -//needed to cancel the alarm after it is deleted -/obj/machinery/alarm/proc/delayed_reset() - var/area/A = alarm_area - src = null - spawn(600) - //It makes sense not to touch firelocks here. The alarm itself is gone, we have no idea what the atmos is like. - A.atmosalert(0, set_firelocks=0) - /obj/machinery/alarm/proc/first_run() alarm_area = get_area(src) if (alarm_area.master) @@ -195,7 +185,6 @@ if(RCON_YES) remote_control = 1 - updateDialog() return /obj/machinery/alarm/proc/handle_heating_cooling(var/datum/gas_mixture/environment) @@ -442,7 +431,7 @@ send_signal(device_id, list("power"= 0) ) /obj/machinery/alarm/proc/apply_danger_level(var/new_danger_level) - if (report_danger_level && alarm_area.atmosalert(new_danger_level)) + if (report_danger_level && alarm_area.atmosalert(new_danger_level, src)) post_alert(new_danger_level) update_icon() @@ -468,7 +457,7 @@ frequency.post_signal(src, alert_signal) /obj/machinery/alarm/attack_ai(mob/user) - return interact(user) + ui_interact(user) /obj/machinery/alarm/attack_hand(mob/user) . = ..() @@ -477,311 +466,179 @@ return interact(user) /obj/machinery/alarm/interact(mob/user) - user.set_machine(src) + ui_interact(user) + wires.Interact(user) - if(buildstage!=2) - return +/obj/machinery/alarm/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/custom_state = null) + var/data[0] + var/remote_connection = 0 + var/remote_access = 0 + if(custom_state) + var/list/state = custom_state.href_list(user) + remote_connection = state["remote_connection"] // Remote connection means we're non-adjacent/connecting from another computer + remote_access = state["remote_access"] // Remote access means we also have the privilege to alter the air alarm. - if((get_dist(src, user) > 1 )) - if (!istype(user, /mob/living/silicon)) - user.machine = null - user << browse(null, "window=air_alarm") - user << browse(null, "window=AAlarmwires") - return + data["locked"] = locked && !user.isSilicon() + data["remote_connection"] = remote_connection + data["remote_access"] = remote_access + data["rcon"] = rcon_setting + data["screen"] = screen + populate_status(data) - else if (istype(user, /mob/living/silicon) && aidisabled) - user << "AI control for this Air Alarm interface has been disabled." - user << browse(null, "window=air_alarm") - return + if(!(locked && !remote_connection) || remote_access || user.isSilicon()) + populate_controls(data) - if(wiresexposed && (!istype(user, /mob/living/silicon/ai))) - wires.Interact(user) + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "air_alarm.tmpl", src.name, 325, 625, master_ui = master_ui, custom_state = custom_state) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) - if(!shorted) - user << browse(return_text(user),"window=air_alarm") - onclose(user, "air_alarm") - - return - -/obj/machinery/alarm/proc/return_text(mob/user) - if(!(istype(user, /mob/living/silicon)) && locked) - return "\The [src][return_status()]
    [rcon_text()]
    (Swipe ID card to unlock interface)" - else - return "\The [src][return_status()]
    [rcon_text()]
    [return_controls()]" - -/obj/machinery/alarm/proc/return_status() +/obj/machinery/alarm/proc/populate_status(var/data) var/turf/location = get_turf(src) var/datum/gas_mixture/environment = location.return_air() var/total = environment.total_moles - var/output = "Air Status:
    " - if(total == 0) - output += "Warning: Cannot obtain air sample for analysis." - return output + var/list/environment_data = new + data["has_environment"] = total + if(total) + var/partial_pressure = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume - output += {" - -"} + var/list/current_settings = TLV["pressure"] + var/pressure = environment.return_pressure() + var/pressure_danger = get_danger_level(pressure, current_settings) + environment_data[++environment_data.len] = list("name" = "Pressure", "value" = pressure, "unit" = "kPa", "danger_level" = pressure_danger) + data["total_danger"] = pressure_danger - var/partial_pressure = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume + current_settings = TLV["oxygen"] + var/oxygen_danger = get_danger_level(environment.gas["oxygen"]*partial_pressure, current_settings) + environment_data[++environment_data.len] = list("name" = "Oxygen", "value" = environment.gas["oxygen"] / total * 100, "unit" = "%", "danger_level" = oxygen_danger) + data["total_danger"] = max(oxygen_danger, data["total_danger"]) - var/list/current_settings = TLV["pressure"] - var/environment_pressure = environment.return_pressure() - var/pressure_dangerlevel = get_danger_level(environment_pressure, current_settings) + current_settings = TLV["carbon dioxide"] + var/carbon_dioxide_danger = get_danger_level(environment.gas["carbon dioxide"]*partial_pressure, current_settings) + environment_data[++environment_data.len] = list("name" = "Carbon dioxide", "value" = environment.gas["carbon dioxide"] / total * 100, "unit" = "%", "danger_level" = carbon_dioxide_danger) + data["total_danger"] = max(carbon_dioxide_danger, data["total_danger"]) - current_settings = TLV["oxygen"] - var/oxygen_dangerlevel = get_danger_level(environment.gas["oxygen"]*partial_pressure, current_settings) - var/oxygen_percent = round(environment.gas["oxygen"] / total * 100, 2) + current_settings = TLV["phoron"] + var/phoron_danger = get_danger_level(environment.gas["phoron"]*partial_pressure, current_settings) + environment_data[++environment_data.len] = list("name" = "Toxins", "value" = environment.gas["phoron"] / total * 100, "unit" = "%", "danger_level" = phoron_danger) + data["total_danger"] = max(phoron_danger, data["total_danger"]) - current_settings = TLV["carbon dioxide"] - var/co2_dangerlevel = get_danger_level(environment.gas["carbon_dioxide"]*partial_pressure, current_settings) - var/co2_percent = round(environment.gas["carbon_dioxide"] / total * 100, 2) + current_settings = TLV["temperature"] + var/temperature_danger = get_danger_level(environment.temperature, current_settings) + environment_data[++environment_data.len] = list("name" = "Temperature", "value" = environment.temperature, "unit" = "K ([round(environment.temperature - T0C, 0.1)]C)", "danger_level" = temperature_danger) + data["total_danger"] = max(temperature_danger, data["total_danger"]) - current_settings = TLV["phoron"] - var/phoron_dangerlevel = get_danger_level(environment.gas["phoron"]*partial_pressure, current_settings) - var/phoron_percent = round(environment.gas["phoron"] / total * 100, 2) - - //current_settings = TLV["other"] - //var/other_moles = 0.0 - //for(var/datum/gas/G in environment.trace_gases) - // other_moles+=G.moles - //var/other_dangerlevel = get_danger_level(other_moles*partial_pressure, current_settings) - - current_settings = TLV["temperature"] - var/temperature_dangerlevel = get_danger_level(environment.temperature, current_settings) - - output += {" -Pressure: [environment_pressure]kPa
    -Oxygen: [oxygen_percent]%
    -Carbon dioxide: [co2_percent]%
    -Toxins: [phoron_percent]%
    -"} - //if (other_dangerlevel==2) - // output += "Notice: High Concentration of Unknown Particles Detected
    " - //else if (other_dangerlevel==1) - // output += "Notice: Low Concentration of Unknown Particles Detected
    " - - output += "Temperature: [environment.temperature]K ([round(environment.temperature - T0C, 0.1)]C)
    " - - //'Local Status' should report the LOCAL status, damnit. - output += "Local Status: " - switch(max(pressure_dangerlevel,oxygen_dangerlevel,co2_dangerlevel,phoron_dangerlevel,other_dangerlevel,temperature_dangerlevel)) - if(2) - output += "DANGER: Internals Required
    " - if(1) - output += "Caution
    " - if(0) - output += "Optimal
    " - - output += "Area Status: " - if(alarm_area.atmosalm) - output += "Atmos alert in area" - else if (alarm_area.fire) - output += "Fire alarm in area" - else - output += "No alerts" - - return output - -/obj/machinery/alarm/proc/rcon_text() - var/dat = "" - - //Hackish, I know. I didn't feel like bothering to rework all of this. - dat += "
    Remote Control:
    " - if(rcon_setting == RCON_NO) - dat += "Off" - else - dat += "Off" - dat += " | " - if(rcon_setting == RCON_AUTO) - dat += "Auto" - else - dat += "Auto" - dat += " | " - if(rcon_setting == RCON_YES) - dat += "On" - else - dat += "On
    Thermostat:
    [target_temperature - T0C]C
    " - - return dat - -/obj/machinery/alarm/proc/return_controls(var/source = src) - var/output = ""//"[alarm_zone] Air [name]
    " + data["environment"] = environment_data + data["atmos_alarm"] = alarm_area.atmosalm + data["fire_alarm"] = alarm_area.fire != null + data["target_temperature"] = "[target_temperature - T0C]C" +/obj/machinery/alarm/proc/populate_controls(var/list/data) switch(screen) - if (AALARM_SCREEN_MAIN) - if(alarm_area.atmosalm) - output += "Reset - Area Atmospheric Alarm
    " - else - output += "Activate - Area Atmospheric Alarm
    " + if(AALARM_SCREEN_MAIN) + data["mode"] = mode + if(AALARM_SCREEN_VENT) + var/vents[0] + for(var/id_tag in alarm_area.air_vent_names) + var/long_name = alarm_area.air_vent_names[id_tag] + var/list/info = alarm_area.air_vent_info[id_tag] + if(!info) + continue + vents[++vents.len] = list( + "id_tag" = id_tag, + "long_name" = sanitize(long_name), + "power" = info["power"], + "checks" = info["checks"], + "direction" = info["direction"], + "external" = info["external"] + ) + data["vents"] = vents + if(AALARM_SCREEN_SCRUB) + var/scrubbers[0] + for(var/id_tag in alarm_area.air_scrub_names) + var/long_name = alarm_area.air_scrub_names[id_tag] + var/list/info = alarm_area.air_scrub_info[id_tag] + if(!info) + continue + scrubbers[++scrubbers.len] = list( + "id_tag" = id_tag, + "long_name" = sanitize(long_name), + "power" = info["power"], + "scrubbing" = info["scrubbing"], + "panic" = info["panic"], + "filters" = list() + ) + scrubbers[scrubbers.len]["filters"] += list(list("name" = "Oxygen", "command" = "o2_scrub", "val" = info["filter_o2"])) + scrubbers[scrubbers.len]["filters"] += list(list("name" = "Nitrogen", "command" = "n2_scrub", "val" = info["filter_n2"])) + scrubbers[scrubbers.len]["filters"] += list(list("name" = "Carbon Dioxide", "command" = "co2_scrub","val" = info["filter_co2"])) + scrubbers[scrubbers.len]["filters"] += list(list("name" = "Toxin" , "command" = "tox_scrub","val" = info["filter_phoron"])) + scrubbers[scrubbers.len]["filters"] += list(list("name" = "Nitrous Oxide", "command" = "n2o_scrub","val" = info["filter_n2o"])) + data["scrubbers"] = scrubbers + if(AALARM_SCREEN_MODE) + var/modes[0] + modes[++modes.len] = list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0) + modes[++modes.len] = list("name" = "Replace Air - Siphons out air while replacing", "mode" = AALARM_MODE_REPLACEMENT, "selected" = mode == AALARM_MODE_REPLACEMENT, "danger" = 0) + modes[++modes.len] = list("name" = "Panic - Siphons air out of the room", "mode" = AALARM_MODE_PANIC, "selected" = mode == AALARM_MODE_PANIC, "danger" = 1) + modes[++modes.len] = list("name" = "Cycle - Siphons air before replacing", "mode" = AALARM_MODE_CYCLE, "selected" = mode == AALARM_MODE_CYCLE, "danger" = 1) + modes[++modes.len] = list("name" = "Fill - Shuts off scrubbers and opens vents", "mode" = AALARM_MODE_FILL, "selected" = mode == AALARM_MODE_FILL, "danger" = 0) + modes[++modes.len] = list("name" = "Off - Shuts off vents and scrubbers", "mode" = AALARM_MODE_OFF, "selected" = mode == AALARM_MODE_OFF, "danger" = 0) + data["modes"] = modes + data["mode"] = mode + if(AALARM_SCREEN_SENSORS) + var/list/selected + var/thresholds[0] - output += {" -Scrubbers Control
    -Vents Control
    -Set environmentals mode
    -Sensor Settings
    -
    -"} - if (mode==AALARM_MODE_PANIC) - output += "PANIC SYPHON ACTIVE
    Turn syphoning off" - else - output += "ACTIVATE PANIC SYPHON IN AREA" - - - if (AALARM_SCREEN_VENT) - var/sensor_data = "" - if(alarm_area.air_vent_names.len) - for(var/id_tag in alarm_area.air_vent_names) - var/long_name = alarm_area.air_vent_names[id_tag] - var/list/data = alarm_area.air_vent_info[id_tag] - if(!data) - continue; - var/state = "" - - sensor_data += {" -[long_name][state]
    -Operating: -[data["power"]?"on":"off"] -
    -Pressure checks: -external -internal -
    -External pressure bound: -- -- -- -- -[data["external"]] -+ -+ -+ -+ - (reset) -
    -"} - if (data["direction"] == "siphon") - sensor_data += {" -Direction: -siphoning -
    -"} - sensor_data += {"
    "} - else - sensor_data = "No vents connected.
    " - output = {"Main menu
    [sensor_data]"} - if (AALARM_SCREEN_SCRUB) - var/sensor_data = "" - if(alarm_area.air_scrub_names.len) - for(var/id_tag in alarm_area.air_scrub_names) - var/long_name = alarm_area.air_scrub_names[id_tag] - var/list/data = alarm_area.air_scrub_info[id_tag] - if(!data) - continue; - var/state = "" - - sensor_data += {" -[long_name][state]
    -Operating: -[data["power"]?"on":"off"]
    -Type: -[data["scrubbing"]?"scrubbing":"syphoning"]
    -"} - - if(data["scrubbing"]) - sensor_data += {" -Filtering: -Carbon Dioxide -[data["filter_co2"]?"on":"off"]; -Toxins -[data["filter_phoron"]?"on":"off"]; -Nitrous Oxide -[data["filter_n2o"]?"on":"off"] -
    -"} - sensor_data += {" -Panic syphon: [data["panic"]?"PANIC SYPHON ACTIVATED":""] -Dea":"red'>A")]ctivate
    -
    -"} - else - sensor_data = "No scrubbers connected.
    " - output = {"Main menu
    [sensor_data]"} - - if (AALARM_SCREEN_MODE) - output += "Main menu
    Air machinery mode for the area:
      " - var/list/modes = list(AALARM_MODE_SCRUBBING = "Filtering - Scrubs out contaminants",\ - AALARM_MODE_REPLACEMENT = "Replace Air - Siphons out air while replacing",\ - AALARM_MODE_PANIC = "Panic - Siphons air out of the room",\ - AALARM_MODE_CYCLE = "Cycle - Siphons air before replacing",\ - AALARM_MODE_FILL = "Fill - Shuts off scrubbers and opens vents",\ - AALARM_MODE_OFF = "Off - Shuts off vents and scrubbers",) - for (var/m=1,m<=modes.len,m++) - if (mode==m) - output += "
    • [modes[m]] (selected)
    • " - else - output += "
    • [modes[m]]
    • " - output += "
    " - - if (AALARM_SCREEN_SENSORS) - output += {" -Main menu
    -Alarm thresholds:
    -Partial pressure for gases - - - -"} - var/list/gases = list( + var/list/gas_names = list( "oxygen" = "O2", "carbon dioxide" = "CO2", "phoron" = "Toxin", - "other" = "Other",) - - var/list/selected - for (var/g in gases) - output += "" + "other" = "Other") + for (var/g in gas_names) + thresholds[++thresholds.len] = list("name" = gas_names[g], "settings" = list()) selected = TLV[g] for(var/i = 1, i <= 4, i++) - output += "" - output += "" + thresholds[thresholds.len]["settings"] += list(list("env" = g, "val" = i, "selected" = selected[i])) selected = TLV["pressure"] - output += " " + thresholds[++thresholds.len] = list("name" = "Pressure", "settings" = list()) for(var/i = 1, i <= 4, i++) - output += "" - output += "" + thresholds[thresholds.len]["settings"] += list(list("env" = "pressure", "val" = i, "selected" = selected[i])) selected = TLV["temperature"] - output += "" + thresholds[++thresholds.len] = list("name" = "Temperature", "settings" = list()) for(var/i = 1, i <= 4, i++) - output += "" - output += "
    min2min1max1max2
    [gases[g]][selected[i] >= 0 ? selected[i] :"OFF"]
    Pressure[selected[i] >= 0 ? selected[i] :"OFF"]
    Temperature[selected[i] >= 0 ? selected[i] :"OFF"]
    " + thresholds[thresholds.len]["settings"] += list(list("env" = "temperature", "val" = i, "selected" = selected[i])) - return output -/obj/machinery/alarm/Topic(href, href_list, var/nowindow = 0, var/remote = 0) - if(..(href, href_list, nowindow, !remote) || !( Adjacent(usr) || nowindow || istype(usr, /mob/living/silicon)) ) // dont forget calling super in machine Topics -walter0o - usr.machine = null - usr << browse(null, "window=air_alarm") - usr << browse(null, "window=AAlarmwires") - return + data["thresholds"] = thresholds - add_fingerprint(usr) - usr.set_machine(src) +/obj/machinery/alarm/CanUseTopic(var/mob/user, href_list, var/datum/topic_state/custom_state) + if(buildstage != 2) + return STATUS_CLOSE + + if(aidisabled && user.isAI()) + user << "AI control for \the [src] interface has been disabled." + return STATUS_CLOSE + + . = shorted ? STATUS_DISABLED : STATUS_INTERACTIVE + + if(. == STATUS_INTERACTIVE) + var/extra_href = custom_state.href_list(usr) + // Prevent remote users from altering RCON settings unless they already have access (I realize the risks) + if(href_list["rcon"] && extra_href["remote_connection"] && !extra_href["remote_access"]) + . = STATUS_UPDATE + + //TODO: Move the rest of if(!locked || extra_href["remote_access"] || usr.isAI()) and hrefs here + + return min(..(), .) + +/obj/machinery/alarm/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/custom_state) + if(..(href, href_list, nowindow, custom_state)) + return 1 // hrefs that can always be called -walter0o if(href_list["rcon"]) @@ -794,29 +651,41 @@ table tr:first-child th:first-child { border: none;} rcon_setting = RCON_AUTO if(RCON_YES) rcon_setting = RCON_YES - else - return + return 1 if(href_list["temperature"]) var/list/selected = TLV["temperature"] var/max_temperature = min(selected[3] - T0C, MAX_TEMPERATURE) var/min_temperature = max(selected[2] - T0C, MIN_TEMPERATURE) - var/input_temperature = input("What temperature would you like the system to mantain? (Capped between [min_temperature]C and [max_temperature]C)", "Thermostat Controls") as num|null - if(!input_temperature || input_temperature > max_temperature || input_temperature < min_temperature) - usr << "Temperature must be between [min_temperature]C and [max_temperature]C" - else - target_temperature = input_temperature + T0C + var/input_temperature = input("What temperature would you like the system to mantain? (Capped between [min_temperature] and [max_temperature]C)", "Thermostat Controls", target_temperature - T0C) as num|null + if(isnum(input_temperature)) + if(input_temperature > max_temperature || input_temperature < min_temperature) + usr << "Temperature must be between [min_temperature]C and [max_temperature]C" + else + target_temperature = input_temperature + T0C + return 1 // hrefs that need the AA unlocked -walter0o - if(!locked || remote || istype(usr, /mob/living/silicon)) - + var/extra_href = custom_state.href_list(usr) + if(!(locked && !extra_href["remote_connection"]) || extra_href["remote_access"] || usr.isSilicon()) if(href_list["command"]) var/device_id = href_list["id_tag"] switch(href_list["command"]) + if("set_external_pressure") + var/input_pressure = input("What pressure you like the system to mantain?", "Pressure Controls") as num|null + if(isnum(input_pressure)) + send_signal(device_id, list(href_list["command"] = input_pressure)) + return 1 + + if("reset_external_pressure") + send_signal(device_id, list(href_list["command"] = ONE_ATMOSPHERE)) + return 1 + if( "power", "adjust_external_pressure", - "set_external_pressure", "checks", + "o2_scrub", + "n2_scrub", "co2_scrub", "tox_scrub", "n2o_scrub", @@ -824,6 +693,7 @@ table tr:first-child th:first-child { border: none;} "scrubbing") send_signal(device_id, list(href_list["command"] = text2num(href_list["val"]) ) ) + return 1 if("set_threshold") var/env = href_list["env"] @@ -832,7 +702,7 @@ table tr:first-child th:first-child { border: none;} var/list/thresholds = list("lower bound", "low warning", "high warning", "upper bound") var/newval = input("Enter [thresholds[threshold]] for [env]", "Alarm triggers", selected[threshold]) as null|num if (isnull(newval)) - return + return 1 if (newval<0) selected[threshold] = -1.0 else if (env=="temperature" && newval>5000) @@ -874,9 +744,11 @@ table tr:first-child th:first-child { border: none;} selected[3] = selected[4] apply_mode() + return 1 if(href_list["screen"]) screen = text2num(href_list["screen"]) + return 1 if(href_list["atmos_unlock"]) switch(href_list["atmos_unlock"]) @@ -884,24 +756,24 @@ table tr:first-child th:first-child { border: none;} alarm_area.air_doors_close() if("1") alarm_area.air_doors_open() + return 1 if(href_list["atmos_alarm"]) - if (alarm_area.atmosalert(2)) + if (alarm_area.atmosalert(2, src)) apply_danger_level(2) update_icon() + return 1 if(href_list["atmos_reset"]) - if (alarm_area.atmosalert(0)) + if (alarm_area.atmosalert(0, src)) apply_danger_level(0) update_icon() + return 1 if(href_list["mode"]) mode = text2num(href_list["mode"]) apply_mode() - - if(!nowindow) - updateUsrDialog() - + return 1 /obj/machinery/alarm/attackby(obj/item/W as obj, mob/user as mob) src.add_fingerprint(user) @@ -931,7 +803,6 @@ table tr:first-child th:first-child { border: none;} if(allowed(usr) && !wires.IsIndexCut(AALARM_WIRE_IDSCAN)) locked = !locked user << "\blue You [ locked ? "lock" : "unlock"] the Air Alarm interface." - updateUsrDialog() else user << "\red Access denied." return @@ -1066,7 +937,6 @@ FIRE ALARM var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone /obj/machinery/firealarm/update_icon() - if(wiresexposed) switch(buildstage) if(2) @@ -1100,7 +970,8 @@ FIRE ALARM return src.alarm() /obj/machinery/firealarm/emp_act(severity) - if(prob(50/severity)) alarm() + if(prob(50/severity)) + alarm(rand(30/severity, 60/severity)) ..() /obj/machinery/firealarm/attackby(obj/item/W as obj, mob/user as mob) @@ -1199,6 +1070,7 @@ FIRE ALARM var/d2 if (istype(user, /mob/living/carbon/human) || istype(user, /mob/living/silicon)) A = A.loc + A = A.master if (A.fire) d1 = text("Reset - Lockdown", src) @@ -1264,26 +1136,26 @@ FIRE ALARM /obj/machinery/firealarm/proc/reset() if (!( src.working )) return - var/area/A = src.loc - A = A.loc - if (!( istype(A, /area) )) - return - A.firereset() + var/area/area = get_area(src) + for(var/area/A in area.related) + for(var/obj/machinery/firealarm/FA in A) + fire_alarm.clearAlarm(loc, FA) update_icon() return -/obj/machinery/firealarm/proc/alarm() - if (!( src.working )) +/obj/machinery/firealarm/proc/alarm(var/duration = 0) + if (!( src.working)) return - var/area/A = src.loc - A = A.loc - if (!( istype(A, /area) )) - return - A.firealert() + var/area/area = get_area(src) + for(var/area/A in area.related) + for(var/obj/machinery/firealarm/FA in A) + fire_alarm.triggerAlarm(loc, FA, duration) update_icon() //playsound(src.loc, 'sound/ambience/signal.ogg', 75, 0) return + + /obj/machinery/firealarm/New(loc, dir, building) ..() @@ -1299,20 +1171,6 @@ FIRE ALARM pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 -/obj/machinery/firealarm/Del() - //so fire alarms don't keep going forever - delayed_reset() - ..() - -//needed to cancel the alarm after it is deleted -/obj/machinery/firealarm/proc/delayed_reset() - var/area/A = get_area(src) - if (!A) return - - src = null - spawn(600) - A.firereset() - /obj/machinery/firealarm/initialize() if(z in config.contact_levels) if(security_level) diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index a62da66d77..3c032a6bce 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -1,512 +1,524 @@ -/obj/machinery/air_sensor - icon = 'icons/obj/stationobjs.dmi' - icon_state = "gsensor1" - name = "Gas Sensor" - - anchored = 1 - var/state = 0 - - var/id_tag - var/frequency = 1439 - - var/on = 1 - var/output = 3 - //Flags: - // 1 for pressure - // 2 for temperature - // Output >= 4 includes gas composition - // 4 for oxygen concentration - // 8 for phoron concentration - // 16 for nitrogen concentration - // 32 for carbon dioxide concentration - - var/datum/radio_frequency/radio_connection - -/obj/machinery/air_sensor/update_icon() - icon_state = "gsensor[on]" - -/obj/machinery/air_sensor/process() - if(on) - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.data["tag"] = id_tag - signal.data["timestamp"] = world.time - - var/datum/gas_mixture/air_sample = return_air() - - if(output&1) - signal.data["pressure"] = num2text(round(air_sample.return_pressure(),0.1),) - if(output&2) - signal.data["temperature"] = round(air_sample.temperature,0.1) - - if(output>4) - var/total_moles = air_sample.total_moles - if(total_moles > 0) - if(output&4) - signal.data["oxygen"] = round(100*air_sample.gas["oxygen"]/total_moles,0.1) - if(output&8) - signal.data["phoron"] = round(100*air_sample.gas["phoron"]/total_moles,0.1) - if(output&16) - signal.data["nitrogen"] = round(100*air_sample.gas["nitrogen"]/total_moles,0.1) - if(output&32) - signal.data["carbon_dioxide"] = round(100*air_sample.gas["carbon_dioxide"]/total_moles,0.1) - else - signal.data["oxygen"] = 0 - signal.data["phoron"] = 0 - signal.data["nitrogen"] = 0 - signal.data["carbon_dioxide"] = 0 - signal.data["sigtype"]="status" - radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) - - -/obj/machinery/air_sensor/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) - frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) - -/obj/machinery/air_sensor/initialize() - set_frequency(frequency) - -/obj/machinery/air_sensor/New() - ..() - - if(radio_controller) - set_frequency(frequency) - -/obj/machinery/computer/general_air_control - icon = 'icons/obj/computer.dmi' - icon_state = "tank" - - name = "Computer" - - var/frequency = 1439 - var/list/sensors = list() - - var/list/sensor_information = list() - var/datum/radio_frequency/radio_connection - circuit = /obj/item/weapon/circuitboard/air_management - -/obj/machinery/computer/general_air_control/attack_hand(mob/user) - if(..(user)) - return - user << browse(return_text(),"window=computer") - user.set_machine(src) - onclose(user, "computer") - -/obj/machinery/computer/general_air_control/process() - ..() - src.updateUsrDialog() - -/obj/machinery/computer/general_air_control/receive_signal(datum/signal/signal) - if(!signal || signal.encryption) return - - var/id_tag = signal.data["tag"] - if(!id_tag || !sensors.Find(id_tag)) return - - sensor_information[id_tag] = signal.data - -/obj/machinery/computer/general_air_control/proc/return_text() - var/sensor_data - if(sensors.len) - for(var/id_tag in sensors) - var/long_name = sensors[id_tag] - var/list/data = sensor_information[id_tag] - var/sensor_part = "[long_name]:
    " - - if(data) - if(data["pressure"]) - sensor_part += " Pressure: [data["pressure"]] kPa
    " - if(data["temperature"]) - sensor_part += " Temperature: [data["temperature"]] K
    " - if(data["oxygen"]||data["phoron"]||data["nitrogen"]||data["carbon_dioxide"]) - sensor_part += " Gas Composition :" - if(data["oxygen"]) - sensor_part += "[data["oxygen"]]% O2; " - if(data["nitrogen"]) - sensor_part += "[data["nitrogen"]]% N; " - if(data["carbon_dioxide"]) - sensor_part += "[data["carbon_dioxide"]]% CO2; " - if(data["phoron"]) - sensor_part += "[data["phoron"]]% TX; " - sensor_part += "
    " - - else - sensor_part = "[long_name] can not be found!
    " - - sensor_data += sensor_part - - else - sensor_data = "No sensors connected." - - var/output = {"[name]
    -Sensor Data:

    [sensor_data]"} - - return output - -/obj/machinery/computer/general_air_control/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, frequency) - frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) - -/obj/machinery/computer/general_air_control/initialize() - set_frequency(frequency) - - -/obj/machinery/computer/general_air_control/large_tank_control - icon = 'icons/obj/computer.dmi' - icon_state = "tank" - - frequency = 1441 - var/input_tag - var/output_tag - - var/list/input_info - var/list/output_info - - var/input_flow_setting = 200 - var/pressure_setting = ONE_ATMOSPHERE * 45 - circuit = /obj/item/weapon/circuitboard/air_management/tank_control - - -/obj/machinery/computer/general_air_control/large_tank_control/return_text() - var/output = ..() - //if(signal.data) - // input_info = signal.data // Attempting to fix intake control -- TLE - - output += "Tank Control System

    " - if(input_info) - var/power = (input_info["power"]) - var/volume_rate = round(input_info["volume_rate"], 0.1) - output += "Input: [power?("Injecting"):("On Hold")] Refresh
    Flow Rate Limit: [volume_rate] L/s
    " - output += "Command: Toggle Power Set Flow Rate
    " - - else - output += "ERROR: Can not find input port Search
    " - - output += "Flow Rate Limit: - - - - [round(input_flow_setting, 0.1)] L/s + + + +
    " - - output += "
    " - - if(output_info) - var/power = (output_info["power"]) - var/output_pressure = output_info["internal"] - output += {"Output: [power?("Open"):("On Hold")] Refresh
    -Max Output Pressure: [output_pressure] kPa
    "} - output += "Command: Toggle Power Set Pressure
    " - - else - output += "ERROR: Can not find output port Search
    " - - output += "Max Output Pressure Set: - - - - [pressure_setting] kPa + + + +
    " - - return output - -/obj/machinery/computer/general_air_control/large_tank_control/receive_signal(datum/signal/signal) - if(!signal || signal.encryption) return - - var/id_tag = signal.data["tag"] - - if(input_tag == id_tag) - input_info = signal.data - else if(output_tag == id_tag) - output_info = signal.data - else - ..(signal) - -/obj/machinery/computer/general_air_control/large_tank_control/Topic(href, href_list) - if(..()) - return - - if(href_list["adj_pressure"]) - var/change = text2num(href_list["adj_pressure"]) - pressure_setting = between(0, pressure_setting + change, 50*ONE_ATMOSPHERE) - spawn(1) - src.updateUsrDialog() - return - - if(href_list["adj_input_flow_rate"]) - var/change = text2num(href_list["adj_input_flow_rate"]) - input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors - spawn(1) - src.updateUsrDialog() - return - - if(!radio_connection) - return 0 - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.source = src - if(href_list["in_refresh_status"]) - input_info = null - signal.data = list ("tag" = input_tag, "status" = 1) - - if(href_list["in_toggle_injector"]) - input_info = null - signal.data = list ("tag" = input_tag, "power_toggle" = 1) - - if(href_list["in_set_flowrate"]) - input_info = null - signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]") - - if(href_list["out_refresh_status"]) - output_info = null - signal.data = list ("tag" = output_tag, "status" = 1) - - if(href_list["out_toggle_power"]) - output_info = null - signal.data = list ("tag" = output_tag, "power_toggle" = 1) - - if(href_list["out_set_pressure"]) - output_info = null - signal.data = list ("tag" = output_tag, "set_internal_pressure" = "[pressure_setting]") - - signal.data["sigtype"]="command" - radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) - - spawn(5) - src.updateUsrDialog() - -/obj/machinery/computer/general_air_control/supermatter_core - icon = 'icons/obj/computer.dmi' - icon_state = "tank" - - frequency = 1438 - var/input_tag - var/output_tag - - var/list/input_info - var/list/output_info - - var/input_flow_setting = 700 - var/pressure_setting = 100 - circuit = /obj/item/weapon/circuitboard/air_management/supermatter_core - - -/obj/machinery/computer/general_air_control/supermatter_core/return_text() - var/output = ..() - //if(signal.data) - // input_info = signal.data // Attempting to fix intake control -- TLE - - output += "Core Cooling Control System

    " - if(input_info) - var/power = (input_info["power"]) - var/volume_rate = round(input_info["volume_rate"], 0.1) - output += "Coolant Input: [power?("Injecting"):("On Hold")] Refresh
    Flow Rate Limit: [volume_rate] L/s
    " - output += "Command: Toggle Power Set Flow Rate
    " - - else - output += "ERROR: Can not find input port Search
    " - - output += "Flow Rate Limit: - - - - [round(input_flow_setting, 0.1)] L/s + + + +
    " - - output += "
    " - - if(output_info) - var/power = (output_info["power"]) - var/pressure_limit = output_info["external"] - output += {"Core Outpump: [power?("Open"):("On Hold")] Refresh
    -Min Core Pressure: [pressure_limit] kPa
    "} - output += "Command: Toggle Power Set Pressure
    " - - else - output += "ERROR: Can not find output port Search
    " - - output += "Min Core Pressure Set: - - - - [pressure_setting] kPa + + + +
    " - - return output - -/obj/machinery/computer/general_air_control/supermatter_core/receive_signal(datum/signal/signal) - if(!signal || signal.encryption) return - - var/id_tag = signal.data["tag"] - - if(input_tag == id_tag) - input_info = signal.data - else if(output_tag == id_tag) - output_info = signal.data - else - ..(signal) - -/obj/machinery/computer/general_air_control/supermatter_core/Topic(href, href_list) - if(..()) - return - - if(href_list["adj_pressure"]) - var/change = text2num(href_list["adj_pressure"]) - pressure_setting = between(0, pressure_setting + change, 10*ONE_ATMOSPHERE) - spawn(1) - src.updateUsrDialog() - return - - if(href_list["adj_input_flow_rate"]) - var/change = text2num(href_list["adj_input_flow_rate"]) - input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors - spawn(1) - src.updateUsrDialog() - return - - if(!radio_connection) - return 0 - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.source = src - if(href_list["in_refresh_status"]) - input_info = null - signal.data = list ("tag" = input_tag, "status" = 1) - - if(href_list["in_toggle_injector"]) - input_info = null - signal.data = list ("tag" = input_tag, "power_toggle" = 1) - - if(href_list["in_set_flowrate"]) - input_info = null - signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]") - - if(href_list["out_refresh_status"]) - output_info = null - signal.data = list ("tag" = output_tag, "status" = 1) - - if(href_list["out_toggle_power"]) - output_info = null - signal.data = list ("tag" = output_tag, "power_toggle" = 1) - - if(href_list["out_set_pressure"]) - output_info = null - signal.data = list ("tag" = output_tag, "set_external_pressure" = "[pressure_setting]", "checks" = 1) - - signal.data["sigtype"]="command" - radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) - - spawn(5) - src.updateUsrDialog() - -/obj/machinery/computer/general_air_control/fuel_injection - icon = 'icons/obj/computer.dmi' - icon_state = "atmos" - - var/device_tag - var/list/device_info - - var/automation = 0 - - var/cutoff_temperature = 2000 - var/on_temperature = 1200 - circuit = /obj/item/weapon/circuitboard/air_management/injector_control - -/obj/machinery/computer/general_air_control/fuel_injection/process() - if(automation) - if(!radio_connection) - return 0 - - var/injecting = 0 - for(var/id_tag in sensor_information) - var/list/data = sensor_information[id_tag] - if(data["temperature"]) - if(data["temperature"] >= cutoff_temperature) - injecting = 0 - break - if(data["temperature"] <= on_temperature) - injecting = 1 - - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.source = src - - signal.data = list( - "tag" = device_tag, - "power" = injecting, - "sigtype"="command" - ) - - radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) - - ..() - -/obj/machinery/computer/general_air_control/fuel_injection/return_text() - var/output = ..() - - output += "Fuel Injection System
    " - if(device_info) - var/power = device_info["power"] - var/volume_rate = device_info["volume_rate"] - output += {"Status: [power?("Injecting"):("On Hold")] Refresh
    -Rate: [volume_rate] L/sec
    "} - - if(automation) - output += "Automated Fuel Injection: Engaged
    " - output += "Injector Controls Locked Out
    " - else - output += "Automated Fuel Injection: Disengaged
    " - output += "Injector: Toggle Power Inject (1 Cycle)
    " - - else - output += "ERROR: Can not find device Search
    " - - return output - -/obj/machinery/computer/general_air_control/fuel_injection/receive_signal(datum/signal/signal) - if(!signal || signal.encryption) return - - var/id_tag = signal.data["tag"] - - if(device_tag == id_tag) - device_info = signal.data - else - ..(signal) - -/obj/machinery/computer/general_air_control/fuel_injection/Topic(href, href_list) - if(..()) - return - - if(href_list["refresh_status"]) - device_info = null - if(!radio_connection) - return 0 - - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.source = src - signal.data = list( - "tag" = device_tag, - "status" = 1, - "sigtype"="command" - ) - radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) - - if(href_list["toggle_automation"]) - automation = !automation - - if(href_list["toggle_injector"]) - device_info = null - if(!radio_connection) - return 0 - - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.source = src - signal.data = list( - "tag" = device_tag, - "power_toggle" = 1, - "sigtype"="command" - ) - - radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) - - if(href_list["injection"]) - if(!radio_connection) - return 0 - - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.source = src - signal.data = list( - "tag" = device_tag, - "inject" = 1, - "sigtype"="command" - ) - - radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) - - - - +/obj/machinery/air_sensor + icon = 'icons/obj/stationobjs.dmi' + icon_state = "gsensor1" + name = "Gas Sensor" + + anchored = 1 + var/state = 0 + + var/id_tag + var/frequency = 1439 + + var/on = 1 + var/output = 3 + //Flags: + // 1 for pressure + // 2 for temperature + // Output >= 4 includes gas composition + // 4 for oxygen concentration + // 8 for phoron concentration + // 16 for nitrogen concentration + // 32 for carbon dioxide concentration + + var/datum/radio_frequency/radio_connection + +/obj/machinery/air_sensor/update_icon() + icon_state = "gsensor[on]" + +/obj/machinery/air_sensor/process() + if(on) + var/datum/signal/signal = new + signal.transmission_method = 1 //radio signal + signal.data["tag"] = id_tag + signal.data["timestamp"] = world.time + + var/datum/gas_mixture/air_sample = return_air() + + if(output&1) + signal.data["pressure"] = num2text(round(air_sample.return_pressure(),0.1),) + if(output&2) + signal.data["temperature"] = round(air_sample.temperature,0.1) + + if(output>4) + var/total_moles = air_sample.total_moles + if(total_moles > 0) + if(output&4) + signal.data["oxygen"] = round(100*air_sample.gas["oxygen"]/total_moles,0.1) + if(output&8) + signal.data["phoron"] = round(100*air_sample.gas["phoron"]/total_moles,0.1) + if(output&16) + signal.data["nitrogen"] = round(100*air_sample.gas["nitrogen"]/total_moles,0.1) + if(output&32) + signal.data["carbon_dioxide"] = round(100*air_sample.gas["carbon_dioxide"]/total_moles,0.1) + else + signal.data["oxygen"] = 0 + signal.data["phoron"] = 0 + signal.data["nitrogen"] = 0 + signal.data["carbon_dioxide"] = 0 + signal.data["sigtype"]="status" + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) + + +/obj/machinery/air_sensor/proc/set_frequency(new_frequency) + radio_controller.remove_object(src, frequency) + frequency = new_frequency + radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) + +/obj/machinery/air_sensor/initialize() + set_frequency(frequency) + +/obj/machinery/air_sensor/New() + ..() + + if(radio_controller) + set_frequency(frequency) + +/obj/machinery/computer/general_air_control + icon = 'icons/obj/computer.dmi' + icon_state = "tank" + + name = "Computer" + + var/frequency = 1439 + var/list/sensors = list() + + var/list/sensor_information = list() + var/datum/radio_frequency/radio_connection + circuit = /obj/item/weapon/circuitboard/air_management + +/obj/machinery/computer/general_air_control/attack_hand(mob/user) + if(..(user)) + return + user << browse(return_text(),"window=computer") + user.set_machine(src) + onclose(user, "computer") + +/obj/machinery/computer/general_air_control/process() + ..() + src.updateUsrDialog() + +/obj/machinery/computer/general_air_control/receive_signal(datum/signal/signal) + if(!signal || signal.encryption) return + + var/id_tag = signal.data["tag"] + if(!id_tag || !sensors.Find(id_tag)) return + + sensor_information[id_tag] = signal.data + +/obj/machinery/computer/general_air_control/proc/return_text() + var/sensor_data + if(sensors.len) + for(var/id_tag in sensors) + var/long_name = sensors[id_tag] + var/list/data = sensor_information[id_tag] + var/sensor_part = "[long_name]:
    " + + if(data) + if(data["pressure"]) + sensor_part += " Pressure: [data["pressure"]] kPa
    " + if(data["temperature"]) + sensor_part += " Temperature: [data["temperature"]] K
    " + if(data["oxygen"]||data["phoron"]||data["nitrogen"]||data["carbon_dioxide"]) + sensor_part += " Gas Composition :" + if(data["oxygen"]) + sensor_part += "[data["oxygen"]]% O2; " + if(data["nitrogen"]) + sensor_part += "[data["nitrogen"]]% N; " + if(data["carbon_dioxide"]) + sensor_part += "[data["carbon_dioxide"]]% CO2; " + if(data["phoron"]) + sensor_part += "[data["phoron"]]% TX; " + sensor_part += "
    " + + else + sensor_part = "[long_name] can not be found!
    " + + sensor_data += sensor_part + + else + sensor_data = "No sensors connected." + + var/output = {"[name]
    +Sensor Data:

    [sensor_data]"} + + return output + +/obj/machinery/computer/general_air_control/proc/set_frequency(new_frequency) + radio_controller.remove_object(src, frequency) + frequency = new_frequency + radio_connection = radio_controller.add_object(src, frequency, RADIO_ATMOSIA) + +/obj/machinery/computer/general_air_control/initialize() + set_frequency(frequency) + + +/obj/machinery/computer/general_air_control/large_tank_control + icon = 'icons/obj/computer.dmi' + icon_state = "tank" + + frequency = 1441 + var/input_tag + var/output_tag + + var/list/input_info + var/list/output_info + + var/input_flow_setting = 200 + var/pressure_setting = ONE_ATMOSPHERE * 45 + circuit = /obj/item/weapon/circuitboard/air_management/tank_control + + +/obj/machinery/computer/general_air_control/large_tank_control/return_text() + var/output = ..() + //if(signal.data) + // input_info = signal.data // Attempting to fix intake control -- TLE + + output += "Tank Control System

    " + if(input_info) + var/power = (input_info["power"]) + var/volume_rate = round(input_info["volume_rate"], 0.1) + output += "Input: [power?("Injecting"):("On Hold")] Refresh
    Flow Rate Limit: [volume_rate] L/s
    " + output += "Command: Toggle Power Set Flow Rate
    " + + else + output += "ERROR: Can not find input port Search
    " + + output += "Flow Rate Limit: - - - - [round(input_flow_setting, 0.1)] L/s + + + +
    " + + output += "
    " + + if(output_info) + var/power = (output_info["power"]) + var/output_pressure = output_info["internal"] + output += {"Output: [power?("Open"):("On Hold")] Refresh
    +Max Output Pressure: [output_pressure] kPa
    "} + output += "Command: Toggle Power Set Pressure
    " + + else + output += "ERROR: Can not find output port Search
    " + + output += "Max Output Pressure Set: - - - - [pressure_setting] kPa + + + +
    " + + return output + +/obj/machinery/computer/general_air_control/large_tank_control/receive_signal(datum/signal/signal) + if(!signal || signal.encryption) return + + var/id_tag = signal.data["tag"] + + if(input_tag == id_tag) + input_info = signal.data + else if(output_tag == id_tag) + output_info = signal.data + else + ..(signal) + +/obj/machinery/computer/general_air_control/large_tank_control/Topic(href, href_list) + if(..()) + return 1 + + if(href_list["adj_pressure"]) + var/change = text2num(href_list["adj_pressure"]) + pressure_setting = between(0, pressure_setting + change, 50*ONE_ATMOSPHERE) + spawn(1) + src.updateUsrDialog() + return 1 + + if(href_list["adj_input_flow_rate"]) + var/change = text2num(href_list["adj_input_flow_rate"]) + input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors + spawn(1) + src.updateUsrDialog() + return 1 + + if(!radio_connection) + return 0 + var/datum/signal/signal = new + signal.transmission_method = 1 //radio signal + signal.source = src + if(href_list["in_refresh_status"]) + input_info = null + signal.data = list ("tag" = input_tag, "status" = 1) + return 1 + + if(href_list["in_toggle_injector"]) + input_info = null + signal.data = list ("tag" = input_tag, "power_toggle" = 1) + return 1 + + if(href_list["in_set_flowrate"]) + input_info = null + signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]") + return 1 + + if(href_list["out_refresh_status"]) + output_info = null + signal.data = list ("tag" = output_tag, "status" = 1) + return 1 + + if(href_list["out_toggle_power"]) + output_info = null + signal.data = list ("tag" = output_tag, "power_toggle" = 1) + return 1 + + if(href_list["out_set_pressure"]) + output_info = null + signal.data = list ("tag" = output_tag, "set_internal_pressure" = "[pressure_setting]") + return 1 + + signal.data["sigtype"]="command" + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) + + spawn(5) + src.updateUsrDialog() + +/obj/machinery/computer/general_air_control/supermatter_core + icon = 'icons/obj/computer.dmi' + icon_state = "tank" + + frequency = 1438 + var/input_tag + var/output_tag + + var/list/input_info + var/list/output_info + + var/input_flow_setting = 700 + var/pressure_setting = 100 + circuit = /obj/item/weapon/circuitboard/air_management/supermatter_core + + +/obj/machinery/computer/general_air_control/supermatter_core/return_text() + var/output = ..() + //if(signal.data) + // input_info = signal.data // Attempting to fix intake control -- TLE + + output += "Core Cooling Control System

    " + if(input_info) + var/power = (input_info["power"]) + var/volume_rate = round(input_info["volume_rate"], 0.1) + output += "Coolant Input: [power?("Injecting"):("On Hold")] Refresh
    Flow Rate Limit: [volume_rate] L/s
    " + output += "Command: Toggle Power Set Flow Rate
    " + + else + output += "ERROR: Can not find input port Search
    " + + output += "Flow Rate Limit: - - - - [round(input_flow_setting, 0.1)] L/s + + + +
    " + + output += "
    " + + if(output_info) + var/power = (output_info["power"]) + var/pressure_limit = output_info["external"] + output += {"Core Outpump: [power?("Open"):("On Hold")] Refresh
    +Min Core Pressure: [pressure_limit] kPa
    "} + output += "Command: Toggle Power Set Pressure
    " + + else + output += "ERROR: Can not find output port Search
    " + + output += "Min Core Pressure Set: - - - - [pressure_setting] kPa + + + +
    " + + return output + +/obj/machinery/computer/general_air_control/supermatter_core/receive_signal(datum/signal/signal) + if(!signal || signal.encryption) return + + var/id_tag = signal.data["tag"] + + if(input_tag == id_tag) + input_info = signal.data + else if(output_tag == id_tag) + output_info = signal.data + else + ..(signal) + +/obj/machinery/computer/general_air_control/supermatter_core/Topic(href, href_list) + if(..()) + return 1 + + if(href_list["adj_pressure"]) + var/change = text2num(href_list["adj_pressure"]) + pressure_setting = between(0, pressure_setting + change, 10*ONE_ATMOSPHERE) + spawn(1) + src.updateUsrDialog() + return 1 + + if(href_list["adj_input_flow_rate"]) + var/change = text2num(href_list["adj_input_flow_rate"]) + input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors + spawn(1) + src.updateUsrDialog() + return 1 + + if(!radio_connection) + return 0 + var/datum/signal/signal = new + signal.transmission_method = 1 //radio signal + signal.source = src + if(href_list["in_refresh_status"]) + input_info = null + signal.data = list ("tag" = input_tag, "status" = 1) + return 1 + + if(href_list["in_toggle_injector"]) + input_info = null + signal.data = list ("tag" = input_tag, "power_toggle" = 1) + return 1 + + if(href_list["in_set_flowrate"]) + input_info = null + signal.data = list ("tag" = input_tag, "set_volume_rate" = "[input_flow_setting]") + return 1 + + if(href_list["out_refresh_status"]) + output_info = null + signal.data = list ("tag" = output_tag, "status" = 1) + return 1 + + if(href_list["out_toggle_power"]) + output_info = null + signal.data = list ("tag" = output_tag, "power_toggle" = 1) + return 1 + + if(href_list["out_set_pressure"]) + output_info = null + signal.data = list ("tag" = output_tag, "set_external_pressure" = "[pressure_setting]", "checks" = 1) + return 1 + + signal.data["sigtype"]="command" + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) + + spawn(5) + src.updateUsrDialog() + +/obj/machinery/computer/general_air_control/fuel_injection + icon = 'icons/obj/computer.dmi' + icon_state = "atmos" + + var/device_tag + var/list/device_info + + var/automation = 0 + + var/cutoff_temperature = 2000 + var/on_temperature = 1200 + circuit = /obj/item/weapon/circuitboard/air_management/injector_control + +/obj/machinery/computer/general_air_control/fuel_injection/process() + if(automation) + if(!radio_connection) + return 0 + + var/injecting = 0 + for(var/id_tag in sensor_information) + var/list/data = sensor_information[id_tag] + if(data["temperature"]) + if(data["temperature"] >= cutoff_temperature) + injecting = 0 + break + if(data["temperature"] <= on_temperature) + injecting = 1 + + var/datum/signal/signal = new + signal.transmission_method = 1 //radio signal + signal.source = src + + signal.data = list( + "tag" = device_tag, + "power" = injecting, + "sigtype"="command" + ) + + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) + + ..() + +/obj/machinery/computer/general_air_control/fuel_injection/return_text() + var/output = ..() + + output += "Fuel Injection System
    " + if(device_info) + var/power = device_info["power"] + var/volume_rate = device_info["volume_rate"] + output += {"Status: [power?("Injecting"):("On Hold")] Refresh
    +Rate: [volume_rate] L/sec
    "} + + if(automation) + output += "Automated Fuel Injection: Engaged
    " + output += "Injector Controls Locked Out
    " + else + output += "Automated Fuel Injection: Disengaged
    " + output += "Injector: Toggle Power Inject (1 Cycle)
    " + + else + output += "ERROR: Can not find device Search
    " + + return output + +/obj/machinery/computer/general_air_control/fuel_injection/receive_signal(datum/signal/signal) + if(!signal || signal.encryption) return + + var/id_tag = signal.data["tag"] + + if(device_tag == id_tag) + device_info = signal.data + else + ..(signal) + +/obj/machinery/computer/general_air_control/fuel_injection/Topic(href, href_list) + if(..()) + return + + if(href_list["refresh_status"]) + device_info = null + if(!radio_connection) + return 0 + + var/datum/signal/signal = new + signal.transmission_method = 1 //radio signal + signal.source = src + signal.data = list( + "tag" = device_tag, + "status" = 1, + "sigtype"="command" + ) + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) + + if(href_list["toggle_automation"]) + automation = !automation + + if(href_list["toggle_injector"]) + device_info = null + if(!radio_connection) + return 0 + + var/datum/signal/signal = new + signal.transmission_method = 1 //radio signal + signal.source = src + signal.data = list( + "tag" = device_tag, + "power_toggle" = 1, + "sigtype"="command" + ) + + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) + + if(href_list["injection"]) + if(!radio_connection) + return 0 + + var/datum/signal/signal = new + signal.transmission_method = 1 //radio signal + signal.source = src + signal.data = list( + "tag" = device_tag, + "inject" = 1, + "sigtype"="command" + ) + + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) + + + + diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 4d96320518..9afb27b3ce 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -40,6 +40,9 @@ canister_color = "blue" can_label = 0 +/obj/machinery/portable_atmospherics/canister/oxygen/prechilled + name = "Canister: \[O2 (Cryo)\]" + /obj/machinery/portable_atmospherics/canister/phoron name = "Canister \[Phoron\]" icon_state = "orange" @@ -73,6 +76,21 @@ name = "Canister \[Phoron\]" icon_state = "orange" canister_color = "orange" +/obj/machinery/portable_atmospherics/canister/empty/nitrogen + name = "Canister \[N2\]" + icon_state = "red" + canister_color = "red" +/obj/machinery/portable_atmospherics/canister/empty/carbon_dioxide + name = "Canister \[CO2\]" + icon_state = "black" + canister_color = "black" +/obj/machinery/portable_atmospherics/canister/empty/sleeping_agent + name = "Canister \[N2O\]" + icon_state = "redws" + canister_color = "redws" + + + /obj/machinery/portable_atmospherics/canister/proc/check_change() var/old_flag = update_flag @@ -196,9 +214,7 @@ update_flag else can_label = 0 - if(air_contents.temperature > PHORON_FLASHPOINT) - air_contents.zburn() - return + air_contents.react() //cooking up air cans - add phoron and oxygen, then heat above PHORON_MINIMUM_BURN_TEMPERATURE /obj/machinery/portable_atmospherics/canister/return_air() return air_contents @@ -221,6 +237,9 @@ update_flag return /obj/machinery/portable_atmospherics/canister/bullet_act(var/obj/item/projectile/Proj) + if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) + return + if(Proj.damage) src.health -= round(Proj.damage / 2) healthcheck() @@ -296,6 +315,7 @@ update_flag /obj/machinery/portable_atmospherics/canister/Topic(href, href_list) //Do not use "if(..()) return" here, canisters will stop working in unpowered areas like space or on the derelict. // yeah but without SOME sort of Topic check any dick can mess with them via exploits as he pleases -walter0o + //First comment might be outdated. if (!istype(src.loc, /turf)) return 0 @@ -371,6 +391,14 @@ update_flag src.update_icon() return 1 +/obj/machinery/portable_atmospherics/canister/oxygen/prechilled/New() + ..() + + src.air_contents.adjust_gas("oxygen", MolesForPressure()) + src.air_contents.temperature = 80 + src.update_icon() + return 1 + /obj/machinery/portable_atmospherics/canister/sleeping_agent/New() ..() diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 7b44e443c4..9b5cfaa526 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -6,21 +6,38 @@ anchored = 1 use_power = 1 idle_power_usage = 10 - active_power_usage = 100 + active_power_usage = 2000 var/list/machine_recipes var/list/stored_material = list("metal" = 0, "glass" = 0) var/list/storage_capacity = list("metal" = 0, "glass" = 0) var/show_category = "All" - var/panel_open = 0 var/hacked = 0 var/disabled = 0 var/shocked = 0 var/busy = 0 + var/mat_efficiency = 1 + var/build_time = 50 + var/datum/wires/autolathe/wires = null + +/obj/machinery/autolathe/New() + + ..() + wires = new(src) + //Create parts for lathe. + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/autolathe(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/console_screen(src) + RefreshParts() + /obj/machinery/autolathe/proc/update_recipe_list() if(!machine_recipes) machine_recipes = autolathe_recipes @@ -33,8 +50,8 @@ user << "\The [src] is disabled!" return - if (shocked) - shock(user,50) + if(shocked) + shock(user, 50) var/dat = "

    Autolathe Control Panel


    " @@ -65,16 +82,16 @@ else //Make sure it's buildable and list requires resources. for(var/material in R.resources) - var/sheets = round(stored_material[material]/R.resources[material]) + var/sheets = round(stored_material[material]/round(R.resources[material]*mat_efficiency)) if(isnull(max_sheets) || max_sheets > sheets) max_sheets = sheets - if(!isnull(stored_material[material]) && stored_material[material] < R.resources[material]) + if(!isnull(stored_material[material]) && stored_material[material] < round(R.resources[material]*mat_efficiency)) can_make = 0 if(!comma) comma = 1 else material_string += ", " - material_string += "[R.resources[material]] [material]" + material_string += "[round(R.resources[material] * mat_efficiency)] [material]" material_string += ".
    " //Build list of multipliers for sheets. if(R.is_stack) @@ -99,31 +116,27 @@ /obj/machinery/autolathe/attackby(var/obj/item/O as obj, var/mob/user as mob) - if (stat) - return - - if (busy) + if(busy) user << "\The [src] is busy. Please wait for completion of previous operation." return - if(istype(O, /obj/item/weapon/screwdriver)) - panel_open = !panel_open - icon_state = (panel_open ? "autolathe_t": "autolathe") - user << "You [panel_open ? "open" : "close"] the maintenance hatch of [src]." + if(default_deconstruction_screwdriver(user, O)) updateUsrDialog() return + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) + return - if (panel_open) + if(stat) + return + + if(panel_open) //Don't eat multitools or wirecutters used on an open lathe. if(istype(O, /obj/item/device/multitool) || istype(O, /obj/item/weapon/wirecutters)) attack_hand(user) return - //Dismantle the frame. - if(istype(O, /obj/item/weapon/crowbar)) - dismantle() - return - if(O.loc != user && !(istype(O,/obj/item/stack))) return 0 @@ -170,11 +183,11 @@ else user << "You fill \the [src] with \the [eating]." - flick("autolathe_o",src) // Plays metal insertion animation. Work out a good way to work out a fitting animation. ~Z + flick("autolathe_o", src) // Plays metal insertion animation. Work out a good way to work out a fitting animation. ~Z if(istype(eating,/obj/item/stack)) var/obj/item/stack/stack = eating - stack.use(max(1,round(total_used/mass_per_sheet))) // Always use at least 1 to prevent infinite materials. + stack.use(max(1, round(total_used/mass_per_sheet))) // Always use at least 1 to prevent infinite materials. else user.drop_item(O) del(O) @@ -221,65 +234,57 @@ return busy = 1 - //This needs some work. - use_power(max(2000, (making.power_use*multiplier))) + update_use_power(2) //Check if we still have the materials. for(var/material in making.resources) if(!isnull(stored_material[material])) - if(stored_material[material] < (making.resources[material]*multiplier)) + if(stored_material[material] < round(making.resources[material] * mat_efficiency) * multiplier) return //Consume materials. for(var/material in making.resources) if(!isnull(stored_material[material])) - stored_material[material] = max(0,stored_material[material]-(making.resources[material]*multiplier)) + stored_material[material] = max(0, stored_material[material] - round(making.resources[material] * mat_efficiency) * multiplier) //Fancy autolathe animation. - flick("autolathe_n",src) + flick("autolathe_n", src) - sleep(50) + sleep(build_time) busy = 0 + update_use_power(1) //Sanity check. if(!making || !src) return //Create the desired item. var/obj/item/I = new making.path(get_step(loc, get_dir(src,usr))) - if(multiplier>1 && istype(I,/obj/item/stack)) + if(multiplier > 1 && istype(I, /obj/item/stack)) var/obj/item/stack/S = I S.amount = multiplier updateUsrDialog() - -/obj/machinery/autolathe/New() - - ..() - wires = new(src) - //Create parts for lathe. - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/autolathe(src) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) - component_parts += new /obj/item/weapon/stock_parts/manipulator(src) - component_parts += new /obj/item/weapon/stock_parts/console_screen(src) - RefreshParts() +/obj/machinery/autolathe/update_icon() + icon_state = (panel_open ? "autolathe_t" : "autolathe") //Updates overall lathe storage size. /obj/machinery/autolathe/RefreshParts() ..() - var/tot_rating = 0 + var/mb_rating = 0 + var/man_rating = 0 for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts) - tot_rating += MB.rating + mb_rating += MB.rating + for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + man_rating += M.rating - storage_capacity["metal"] = tot_rating * 25000 - storage_capacity["glass"] = tot_rating * 12500 + storage_capacity["metal"] = mb_rating * 25000 + storage_capacity["glass"] = mb_rating * 12500 + build_time = 50 / man_rating + mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.8. Maximum rating of parts is 3 /obj/machinery/autolathe/dismantle() - ..() var/list/sheets = list("metal" = /obj/item/stack/sheet/metal, "glass" = /obj/item/stack/sheet/glass) for(var/mat in stored_material) @@ -288,3 +293,4 @@ if(stored_material[mat] > S.perunit) S.amount = round(stored_material[mat] / S.perunit) S.loc = loc + ..() diff --git a/code/game/machinery/autolathe_datums.dm b/code/game/machinery/autolathe_datums.dm index 996daa2d10..68bf61b7f1 100644 --- a/code/game/machinery/autolathe_datums.dm +++ b/code/game/machinery/autolathe_datums.dm @@ -15,7 +15,7 @@ if(I.matter && !recipe.resources) //This can be overidden in the datums. recipe.resources = list() for(var/material in I.matter) - recipe.resources[material] = round(I.matter[material]*1.25) // More expensive to produce than they are to recycle. + recipe.resources[material] = I.matter[material]*1.25 // More expensive to produce than they are to recycle. del(I) /datum/autolathe/recipe @@ -76,6 +76,16 @@ name = "wrench" path = /obj/item/weapon/wrench category = "Tools" + +/datum/autolathe/recipe/hatchet + name = "hatchet" + path = /obj/item/weapon/hatchet + category = "Tools" + +/datum/autolathe/recipe/minihoe + name = "mini hoe" + path = /obj/item/weapon/minihoe + category = "Tools" /datum/autolathe/recipe/radio_headset name = "radio headset" @@ -201,8 +211,13 @@ path = /obj/item/weapon/reagent_containers/syringe category = "Medical" +/datum/autolathe/recipe/syringegun_ammo + name = "syringe" + path = /obj/item/weapon/syringe_cartridge + category = "Arms and Ammunition" + /datum/autolathe/recipe/shotgun_blanks - name = "ammunition (shotgun, blanks)" + name = "ammunition (shotgun, blank)" path = /obj/item/ammo_casing/shotgun/blank category = "Arms and Ammunition" @@ -211,9 +226,24 @@ path = /obj/item/ammo_casing/shotgun/beanbag category = "Arms and Ammunition" +/datum/autolathe/recipe/shotgun_flash + name = "ammunition (shotgun, flash)" + path = /obj/item/ammo_casing/shotgun/flash + category = "Arms and Ammunition" + /datum/autolathe/recipe/magazine_rubber - name = "ammunition (rubber)" - path = /obj/item/ammo_magazine/c45r + name = "ammunition (.45, rubber)" + path = /obj/item/ammo_magazine/c45m/rubber + category = "Arms and Ammunition" + +/datum/autolathe/recipe/magazine_flash + name = "ammunition (.45, flash)" + path = /obj/item/ammo_magazine/c45m/flash + category = "Arms and Ammunition" + +/datum/autolathe/recipe/magazine_smg_rubber + name = "ammunition (9mm rubber top mounted)" + path = /obj/item/ammo_magazine/mc9mmt/rubber category = "Arms and Ammunition" /datum/autolathe/recipe/consolescreen @@ -284,15 +314,63 @@ hidden = 1 category = "Arms and Ammunition" +/datum/autolathe/recipe/magazine_stetchkin + name = "ammunition (9mm)" + path = /obj/item/ammo_magazine/mc9mm + hidden = 1 + category = "Arms and Ammunition" + +/datum/autolathe/recipe/magazine_stetchkin_flash + name = "ammunition (9mm, flash)" + path = /obj/item/ammo_magazine/mc9mm/flash + hidden = 1 + category = "Arms and Ammunition" + +/datum/autolathe/recipe/magazine_c20r + name = "ammunition (12mm)" + path = /obj/item/ammo_magazine/a12mm + hidden = 1 + category = "Arms and Ammunition" + +/datum/autolathe/recipe/magazine_arifle + name = "ammunition (7.62mm)" + path = /obj/item/ammo_magazine/c762 + hidden = 1 + category = "Arms and Ammunition" + +/datum/autolathe/recipe/magazine_smg + name = "ammunition (9mm top mounted)" + path = /obj/item/ammo_magazine/mc9mmt + hidden = 1 + category = "Arms and Ammunition" + +/datum/autolathe/recipe/magazine_carbine + name = "ammunition (5.56mm)" + path = /obj/item/ammo_magazine/a556 + hidden = 1 + category = "Arms and Ammunition" + /datum/autolathe/recipe/shotgun - name = "ammunition (shell, shotgun)" + name = "ammunition (slug, shotgun)" path = /obj/item/ammo_casing/shotgun hidden = 1 category = "Arms and Ammunition" -/datum/autolathe/recipe/shotgun_dart - name = "ammunition (dart, shotgun)" - path = /obj/item/ammo_casing/shotgun/dart +/datum/autolathe/recipe/shotgun_pellet + name = "ammunition (shell, shotgun)" + path = /obj/item/ammo_casing/shotgun/pellet + hidden = 1 + category = "Arms and Ammunition" + +/datum/autolathe/recipe/tacknife + name = "tactical knife" + path = /obj/item/weapon/hatchet/tacknife + hidden = 1 + category = "Arms and Ammunition" + +/datum/autolathe/recipe/stunshell + name = "ammunition (stun cartridge, shotgun)" + path = /obj/item/ammo_casing/shotgun/stunshell hidden = 1 category = "Arms and Ammunition" @@ -319,3 +397,5 @@ path = /obj/item/weapon/handcuffs hidden = 1 category = "General" + + diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm new file mode 100644 index 0000000000..87399b597a --- /dev/null +++ b/code/game/machinery/biogenerator.dm @@ -0,0 +1,257 @@ +/obj/machinery/biogenerator + name = "Biogenerator" + desc = "" + icon = 'icons/obj/biogenerator.dmi' + icon_state = "biogen-stand" + density = 1 + anchored = 1 + use_power = 1 + idle_power_usage = 40 + var/processing = 0 + var/obj/item/weapon/reagent_containers/glass/beaker = null + var/points = 0 + var/menustat = "menu" + var/build_eff = 1 + var/eat_eff = 1 + + +/obj/machinery/biogenerator/New() + ..() + var/datum/reagents/R = new/datum/reagents(1000) + reagents = R + R.my_atom = src + beaker = new /obj/item/weapon/reagent_containers/glass/bottle(src) + + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/biogenerator(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + + RefreshParts() + +/obj/machinery/biogenerator/on_reagent_change() //When the reagents change, change the icon as well. + update_icon() + +/obj/machinery/biogenerator/update_icon() + if(!beaker) + icon_state = "biogen-empty" + else if(!processing) + icon_state = "biogen-stand" + else + icon_state = "biogen-work" + return + +/obj/machinery/biogenerator/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(default_deconstruction_screwdriver(user, O)) + return + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) + return + if(istype(O, /obj/item/weapon/reagent_containers/glass)) + if(beaker) + user << "]The [src] is already loaded." + else + user.remove_from_mob(O) + O.loc = src + beaker = O + updateUsrDialog() + else if(processing) + user << "\The [src] is currently processing." + else if(istype(O, /obj/item/weapon/storage/bag/plants)) + var/i = 0 + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents) + i++ + if(i >= 10) + user << "\The [src] is already full! Activate it." + else + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in O.contents) + G.loc = src + i++ + if(i >= 10) + user << "You fill \the [src] to its capacity." + break + if(i < 10) + user << "You empty \the [O] into \the [src]." + + + else if(!istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) + user << "You cannot put this in \the [src]." + else + var/i = 0 + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents) + i++ + if(i >= 10) + user << "\The [src] is full! Activate it." + else + user.remove_from_mob(O) + O.loc = src + user << "You put \the [O] in \the [src]" + update_icon() + return + +/obj/machinery/biogenerator/interact(mob/user as mob) + if(stat & BROKEN) + return + user.set_machine(src) + var/dat = "BiogeneratorBiogenerator:
    " + if (processing) + dat += "Biogenerator is processing! Please wait..." + else + dat += "Biomass: [points] points.
    " + switch(menustat) + if("menu") + if (beaker) + dat += "Activate Biogenerator!
    " + dat += "Detach Container

    " + dat += "Food
    " + dat += "10 milk ([round(20/build_eff)])
    " + dat += "Slab of meat ([round(50/build_eff)])
    " + dat += "Nutrient
    " + dat += "E-Z-Nutrient ([round(10/build_eff)]) | x5
    " + dat += "Left 4 Zed ([round(20/build_eff)]) | x5
    " + dat += "Robust Harvest ([round(25/build_eff)]) | x5
    " + dat += "Leather
    " + dat += "Wallet ([round(100/build_eff)])
    " + dat += "Botanical gloves ([round(250/build_eff)])
    " + dat += "Utility belt ([round(300/build_eff)])
    " + dat += "Leather Satchel ([round(400/build_eff)])
    " + dat += "Cash Bag ([round(400/build_eff)])
    " + //dat += "Other
    " + //dat += "Monkey (500)
    " + else + dat += "
    No beaker inside. Please insert a beaker.
    " + if("nopoints") + dat += "You do not have biomass to create products.
    Please, put growns into reactor and activate it.
    " + dat += "Return to menu" + if("complete") + dat += "Operation complete.
    " + dat += "Return to menu" + if("void") + dat += "Error: No growns inside.
    Please, put growns into reactor.
    " + dat += "Return to menu" + user << browse(dat, "window=biogenerator") + onclose(user, "biogenerator") + return + +/obj/machinery/biogenerator/attack_hand(mob/user as mob) + interact(user) + +/obj/machinery/biogenerator/proc/activate() + if (usr.stat) + return + if (stat) //NOPOWER etc + return + if(processing) + usr << "The biogenerator is in the process of working." + return + var/S = 0 + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/I in contents) + S += 5 + if(I.reagents.get_reagent_amount("nutriment") < 0.1) + points += 1 + else points += I.reagents.get_reagent_amount("nutriment") * 10 * eat_eff + del(I) + if(S) + processing = 1 + update_icon() + updateUsrDialog() + playsound(src.loc, 'sound/machines/blender.ogg', 50, 1) + use_power(S * 30) + sleep((S + 15) / eat_eff) + processing = 0 + update_icon() + else + menustat = "void" + return + +/obj/machinery/biogenerator/proc/create_product(var/item, var/cost) + cost = round(cost/build_eff) + if(cost > points) + menustat = "nopoints" + return 0 + processing = 1 + update_icon() + updateUsrDialog() + points -= cost + sleep(30) + switch(item) + if("milk") + beaker.reagents.add_reagent("milk", 10) + if("meat") + new/obj/item/weapon/reagent_containers/food/snacks/meat(loc) + if("ez") + new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc) + if("l4z") + new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc) + if("rh") + new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc) + if("ez5") //It's not an elegant method, but it's safe and easy. -Cheridan + new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(loc) + if("l4z5") + new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(loc) + if("rh5") + new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc) + new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(loc) + if("wallet") + new/obj/item/weapon/storage/wallet(loc) + if("gloves") + new/obj/item/clothing/gloves/botanic_leather(loc) + if("tbelt") + new/obj/item/weapon/storage/belt/utility(loc) + if("satchel") + new/obj/item/weapon/storage/backpack/satchel(loc) + if("cashbag") + new/obj/item/weapon/storage/bag/cash(loc) + if("monkey") + new/mob/living/carbon/human/monkey(loc) + processing = 0 + menustat = "complete" + update_icon() + return 1 + +/obj/machinery/biogenerator/Topic(href, href_list) + if(stat & BROKEN) return + if(usr.stat || usr.restrained()) return + if(!in_range(src, usr)) return + + usr.set_machine(src) + + switch(href_list["action"]) + if("activate") + activate() + if("detach") + if(beaker) + beaker.loc = src.loc + beaker = null + update_icon() + if("create") + create_product(href_list["item"], text2num(href_list["cost"])) + if("menu") + menustat = "menu" + updateUsrDialog() + +/obj/machinery/biogenerator/RefreshParts() + ..() + var/man_rating = 0 + var/bin_rating = 0 + + for(var/obj/item/weapon/stock_parts/P in component_parts) + if(istype(P, /obj/item/weapon/stock_parts/matter_bin)) + bin_rating += P.rating + if(istype(P, /obj/item/weapon/stock_parts/manipulator)) + man_rating += P.rating + + build_eff = man_rating + eat_eff = bin_rating diff --git a/code/game/machinery/bioprinter.dm b/code/game/machinery/bioprinter.dm index 7710a6d6ec..207da09a04 100644 --- a/code/game/machinery/bioprinter.dm +++ b/code/game/machinery/bioprinter.dm @@ -7,6 +7,8 @@ anchored = 1 density = 1 + use_power = 1 + idle_power_usage = 40 icon_state = "bioprinter" diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index c4007c6994..f87ae33ee0 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -81,6 +81,8 @@ ..() /obj/machinery/bot/bullet_act(var/obj/item/projectile/Proj) + if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) + return health -= Proj.damage ..() healthcheck() diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm index 30f6dfaa8c..4dcb838152 100644 --- a/code/game/machinery/bots/cleanbot.dm +++ b/code/game/machinery/bots/cleanbot.dm @@ -51,10 +51,9 @@ should_patrol = 1 src.botcard = new /obj/item/weapon/card/id(src) - var/datum/job/janitor/J = new/datum/job/janitor - src.botcard.access = J.get_access() - - src.locked = 0 // Start unlocked so roboticist can set them to patrol. + src.botcard.access = list(access_janitor, access_maint_tunnels) + + src.locked = 0 // Start unlocked so roboticist can set them to patrol. if(radio_controller) radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS) @@ -356,7 +355,7 @@ text("[src.oddbutton ? "Yes" : "No" del(src) else if (istype(W, /obj/item/weapon/pen)) - var/t = copytext(stripped_input(user, "Enter new robot name", src.name, src.created_name),1,MAX_NAME_LEN) + var/t = sanitizeSafe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN) if (!t) return if (!in_range(src, usr) && src.loc != usr) diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index 24e29e2839..a955efaa1f 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -34,10 +34,10 @@ var/obj/item/weapon/gun/energy/taser/G = new /obj/item/weapon/gun/energy/taser(Tsec) G.power_supply.charge = 0 else if(lasercolor == "b") - var/obj/item/weapon/gun/energy/laser/bluetag/G = new /obj/item/weapon/gun/energy/laser/bluetag(Tsec) + var/obj/item/weapon/gun/energy/lasertag/blue/G = new (Tsec) G.power_supply.charge = 0 else if(lasercolor == "r") - var/obj/item/weapon/gun/energy/laser/redtag/G = new /obj/item/weapon/gun/energy/laser/redtag(Tsec) + var/obj/item/weapon/gun/energy/lasertag/red/G = new (Tsec) G.power_supply.charge = 0 if (prob(50)) new /obj/item/robot_parts/l_leg(Tsec) @@ -58,7 +58,7 @@ ..() if(istype(W, /obj/item/weapon/pen)) - var/t = copytext(stripped_input(user, "Enter new robot name", src.name, src.created_name),1,MAX_NAME_LEN) + var/t = sanitizeSafe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN) if(!t) return if(!in_range(src, usr) && src.loc != usr) return created_name = t @@ -84,7 +84,7 @@ lasercolor = "r" else if( istype(W, /obj/item/clothing/suit/bluetag) ) lasercolor = "b" - if( lasercolor || istype(W, /obj/item/clothing/suit/armor/vest) ) + if( lasercolor || istype(W, /obj/item/clothing/suit/storage/vest) ) user.drop_item() del(W) build_step++ @@ -137,11 +137,11 @@ if(7) switch(lasercolor) if("b") - if( !istype(W, /obj/item/weapon/gun/energy/laser/bluetag) ) + if( !istype(W, /obj/item/weapon/gun/energy/lasertag/blue) ) return name = "bluetag ED-209 assembly" if("r") - if( !istype(W, /obj/item/weapon/gun/energy/laser/redtag) ) + if( !istype(W, /obj/item/weapon/gun/energy/lasertag/red) ) return name = "redtag ED-209 assembly" if("") diff --git a/code/game/machinery/bots/farmbot.dm b/code/game/machinery/bots/farmbot.dm index 812d8bb334..ca32e937ed 100644 --- a/code/game/machinery/bots/farmbot.dm +++ b/code/game/machinery/bots/farmbot.dm @@ -583,7 +583,7 @@ else if(istype(W, /obj/item/weapon/pen)) var/t = input(user, "Enter new robot name", src.name, src.created_name) as text - t = sanitize(copytext(t, 1, MAX_NAME_LEN)) + t = sanitize(t, MAX_NAME_LEN) if (!t) return if (!in_range(src, usr) && src.loc != usr) diff --git a/code/game/machinery/bots/floorbot.dm b/code/game/machinery/bots/floorbot.dm index 54c8390234..b3c1c0376f 100644 --- a/code/game/machinery/bots/floorbot.dm +++ b/code/game/machinery/bots/floorbot.dm @@ -420,7 +420,7 @@ del(src) else if (istype(W, /obj/item/weapon/pen)) - var/t = copytext(stripped_input(user, "Enter new robot name", src.name, src.created_name),1,MAX_NAME_LEN) + var/t = sanitizeSafe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN) if (!t) return if (!in_range(src, usr) && src.loc != usr) @@ -439,7 +439,7 @@ user.drop_from_inventory(src) del(src) else if (istype(W, /obj/item/weapon/pen)) - var/t = stripped_input(user, "Enter new robot name", src.name, src.created_name) + var/t = sanitizeSafe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN) if (!t) return diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm index 6d3842f879..8ce3522707 100644 --- a/code/game/machinery/bots/medbot.dm +++ b/code/game/machinery/bots/medbot.dm @@ -75,8 +75,7 @@ src.botcard = new /obj/item/weapon/card/id(src) if(isnull(src.botcard_access) || (src.botcard_access.len < 1)) - var/datum/job/doctor/J = new/datum/job/doctor - src.botcard.access = J.get_access() + src.botcard.access = list(access_medical, access_morgue, access_surgery, access_chemistry, access_virology, access_genetics) else src.botcard.access = src.botcard_access @@ -281,9 +280,6 @@ src.speak(message) src.visible_message("[src] points at [C.name]!") src.last_newpatient_speak = world.time - if(declare_treatment) - var/area/location = get_area(src) - broadcast_medical_hud_message("[src.name] is treating [C] in [location]", src) break else continue @@ -438,6 +434,10 @@ src.patient.reagents.add_reagent(reagent_id,src.injection_amount) visible_message("\red [src] injects [src.patient] with the syringe!") + if(declare_treatment) + var/area/location = get_area(src) + broadcast_medical_hud_message("[src.name] is treating [C] in [location]", src) + src.icon_state = "medibot[src.on]" src.currently_healing = 0 return @@ -454,7 +454,7 @@ return /obj/machinery/bot/medbot/bullet_act(var/obj/item/projectile/Proj) - if(Proj.flag == "taser") + if(Proj.taser_effect) src.stunned = min(stunned+10,20) ..() @@ -564,7 +564,7 @@ /obj/item/weapon/firstaid_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob) ..() if(istype(W, /obj/item/weapon/pen)) - var/t = copytext(stripped_input(user, "Enter new robot name", src.name, src.created_name),1,MAX_NAME_LEN) + var/t = sanitizeSafe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN) if (!t) return if (!in_range(src, usr) && src.loc != usr) diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index d130f9e2e4..bd39d2034c 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -59,9 +59,7 @@ ..() wires = new(src) botcard = new(src) - var/datum/job/cargo_tech/J = new/datum/job/cargo_tech - botcard.access = J.get_access() -// botcard.access += access_robotics //Why --Ikki + botcard.access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station) cell = new(src) cell.charge = 2000 cell.maxcharge = 2000 @@ -134,11 +132,11 @@ unload(0) switch(severity) if(2) - wires &= ~(1 << rand(0,9)) - wires &= ~(1 << rand(0,9)) - wires &= ~(1 << rand(0,9)) + BITRESET(wires, rand(0,9)) + BITRESET(wires, rand(0,9)) + BITRESET(wires, rand(0,9)) if(3) - wires &= ~(1 << rand(0,9)) + BITRESET(wires, rand(0,9)) ..() return @@ -309,7 +307,7 @@ if("setid") refresh=0 - var/new_id = sanitize(copytext(input("Enter new bot ID", "Mulebot [suffix ? "([suffix])" : ""]", suffix) as text|null,1,MAX_NAME_LEN)) + var/new_id = sanitize(input("Enter new bot ID", "Mulebot [suffix ? "([suffix])" : ""]", suffix) as text|null, MAX_NAME_LEN) refresh=1 if(new_id) suffix = new_id diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index 432aeb1dab..92b7297c42 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -91,8 +91,7 @@ update_icon() spawn(3) src.botcard = new /obj/item/weapon/card/id(src) - var/datum/job/detective/J = new/datum/job/detective - src.botcard.access = J.get_access() + src.botcard.access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court) if(radio_controller) radio_controller.add_object(src, control_freq, filter = RADIO_SECBOT) radio_controller.add_object(src, beacon_freq, filter = RADIO_NAVBEACONS) @@ -356,7 +355,12 @@ Auto Patrol: []"}, if(istype(src.target,/mob/living/carbon)) var/mob/living/carbon/C = target - if(!C.handcuffed && !src.arrest_type) + var/wearing_hardsuit + if(istype(C,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = C + if(istype(H.back, /obj/item/weapon/rig) && istype(H.gloves,/obj/item/clothing/gloves/rig)) + wearing_hardsuit = 1 + if(!wearing_hardsuit && !C.handcuffed && !src.arrest_type) playsound(src.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2) mode = SECBOT_ARREST visible_message("\red [src] is trying to put handcuffs on [src.target]!") @@ -708,10 +712,10 @@ Auto Patrol: []"}, switch(lasercolor) if("b") target_suit = /obj/item/clothing/suit/redtag - target_weapon = /obj/item/weapon/gun/energy/laser/redtag + target_weapon = /obj/item/weapon/gun/energy/lasertag/red if("r") target_suit = /obj/item/clothing/suit/bluetag - target_weapon = /obj/item/weapon/gun/energy/laser/bluetag + target_weapon = /obj/item/weapon/gun/energy/lasertag/blue if((istype(perp.r_hand, target_weapon)) || (istype(perp.l_hand, target_weapon))) threat += 4 @@ -834,7 +838,7 @@ Auto Patrol: []"}, del(src) else if(istype(W, /obj/item/weapon/pen)) - var/t = copytext(stripped_input(user, "Enter new robot name", src.name, src.created_name),1,MAX_NAME_LEN) + var/t = sanitizeSafe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN) if(!t) return if(!in_range(src, usr) && src.loc != usr) diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 67775ddd7d..ec844b6004 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -1,8 +1,8 @@ -/obj/machinery/driver_button - name = "mass driver button" +/obj/machinery/button + name = "button" icon = 'icons/obj/objects.dmi' icon_state = "launcherbtt" - desc = "A remote control switch for a mass driver." + desc = "A remote control switch for something." var/id = null var/active = 0 anchored = 1.0 @@ -10,38 +10,11 @@ idle_power_usage = 2 active_power_usage = 4 -/obj/machinery/ignition_switch - name = "ignition switch" - icon = 'icons/obj/objects.dmi' - icon_state = "launcherbtt" - desc = "A remote control switch for a mounted igniter." - var/id = null - var/active = 0 - anchored = 1.0 - use_power = 1 - idle_power_usage = 2 - active_power_usage = 4 -/obj/machinery/flasher_button - name = "flasher button" - desc = "A remote control switch for a mounted flasher." - icon = 'icons/obj/objects.dmi' - icon_state = "launcherbtt" - var/id = null - var/active = 0 - anchored = 1.0 - use_power = 1 - idle_power_usage = 2 - active_power_usage = 4 +/obj/machinery/button/attack_ai(mob/user as mob) + return src.attack_hand(user) -/obj/machinery/crema_switch - desc = "Burn baby burn!" - name = "crematorium igniter" - icon = 'icons/obj/power.dmi' - icon_state = "crema_switch" - anchored = 1.0 - req_access = list(access_crematorium) - var/on = 0 - var/area/area = null - var/otherarea = null - var/id = 1 \ No newline at end of file +/obj/machinery/button/attackby(obj/item/weapon/W, mob/user as mob) + if(istype(W, /obj/item/device/detective_scanner)) + return + return src.attack_hand(user) \ No newline at end of file diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index fbad7c7e92..bb99773362 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -13,7 +13,6 @@ var/c_tag_order = 999 var/status = 1 anchored = 1.0 - var/panel_open = 0 // 0 = Closed / 1 = Open var/invuln = null var/bugged = 0 var/obj/item/weapon/camera_assembly/assembly = null @@ -32,13 +31,13 @@ var/alarm_on = 0 var/busy = 0 + var/on_open_network = 0 + /obj/machinery/camera/New() wires = new(src) assembly = new(src) assembly.state = 4 - invalidateCameraCache() - /* // Use this to look for cameras that have the same c_tag. for(var/obj/machinery/camera/C in cameranet.cameras) var/list/tempnetwork = C.network&src.network @@ -54,28 +53,21 @@ ASSERT(src.network.len > 0) ..() -/obj/machinery/camera/Del() - if(!alarm_on) - triggerCameraAlarm() - - cancelCameraAlarm() - ..() - /obj/machinery/camera/emp_act(severity) if(!isEmpProof()) if(prob(100/severity)) - invalidateCameraCache() stat |= EMPED SetLuminosity(0) kick_viewers() - triggerCameraAlarm() + triggerCameraAlarm(30 / severity) update_icon() - + update_coverage() + spawn(900) stat &= ~EMPED cancelCameraAlarm() update_icon() - invalidateCameraCache() + update_coverage() ..() /obj/machinery/camera/bullet_act(var/obj/item/projectile/P) @@ -85,11 +77,11 @@ /obj/machinery/camera/ex_act(severity) if(src.invuln) return - + //camera dies if an explosion touches it! if(severity <= 2 || prob(50)) destroy() - + ..() //and give it the regular chance of being deleted outright @@ -122,7 +114,7 @@ destroy() /obj/machinery/camera/attackby(obj/W as obj, mob/living/user as mob) - invalidateCameraCache() + update_coverage() // DECONSTRUCTION if(isscrewdriver(W)) //user << "You start to [panel_open ? "close" : "open"] the camera's panel." @@ -174,7 +166,7 @@ if (S.current == src) O << "[U] holds \a [itemname] up to one of the cameras ..." O << browse(text("[][]", itemname, info), text("window=[]", itemname)) - + else if (istype(W, /obj/item/weapon/camera_bug)) if (!src.can_use()) user << "\blue Camera non-functional" @@ -185,7 +177,7 @@ else user << "\blue Camera bugged." src.bugged = 1 - + else if(W.damtype == BRUTE || W.damtype == BURN) //bashing cameras if (W.force >= src.toughness) visible_message("[src] has been [pick(W.attack_verb)] with [W] by [user]!") @@ -194,7 +186,7 @@ if (I.hitsound) playsound(loc, I.hitsound, 50, 1, -1) take_damage(W.force) - + else ..() @@ -203,7 +195,7 @@ //legacy support, if choice is != 1 then just kick viewers without changing status kick_viewers() else - invalidateCameraCache() + update_coverage() set_status( !src.status ) if (!(src.status)) visible_message("\red [user] has deactivated [src]!") @@ -221,14 +213,14 @@ if (force >= toughness && (force > toughness*4 || prob(25))) destroy() -//Used when someone breaks a camera +//Used when someone breaks a camera /obj/machinery/camera/proc/destroy() - invalidateCameraCache() stat |= BROKEN kick_viewers() triggerCameraAlarm() update_icon() - + update_coverage() + //sparks var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() spark_system.set_up(5, 0, loc) @@ -262,22 +254,16 @@ else icon_state = initial(icon_state) -/obj/machinery/camera/proc/triggerCameraAlarm() +/obj/machinery/camera/proc/triggerCameraAlarm(var/duration = 0) alarm_on = 1 - if(!get_area(src)) - return - - for(var/mob/living/silicon/S in mob_list) - S.triggerAlarm("Camera", get_area(src), list(src), src) - + camera_alarm.triggerAlarm(loc, src, duration) /obj/machinery/camera/proc/cancelCameraAlarm() - alarm_on = 0 - if(!get_area(src)) + if(wires.IsIndexCut(CAMERA_WIRE_ALARM)) return - - for(var/mob/living/silicon/S in mob_list) - S.cancelAlarm("Camera", get_area(src), src) + + alarm_on = 0 + camera_alarm.clearAlarm(loc, src) //if false, then the camera is listed as DEACTIVATED and cannot be used /obj/machinery/camera/proc/can_use() @@ -355,10 +341,79 @@ /obj/machinery/camera/interact(mob/living/user as mob) if(!panel_open || istype(user, /mob/living/silicon/ai)) return - + if(stat & BROKEN) user << "\The [src] is broken." return user.set_machine(src) wires.Interact(user) + +/obj/machinery/camera/proc/add_network(var/network_name) + add_networks(list(network_name)) + +/obj/machinery/camera/proc/remove_network(var/network_name) + remove_networks(list(network_name)) + +/obj/machinery/camera/proc/add_networks(var/list/networks) + var/network_added + network_added = 0 + for(var/network_name in networks) + if(!(network_name in src.network)) + network += network_name + network_added = 1 + + if(network_added) + update_coverage(1) + +/obj/machinery/camera/proc/remove_networks(var/list/networks) + var/network_removed + network_removed = 0 + for(var/network_name in networks) + if(network_name in src.network) + network -= network_name + network_removed = 1 + + if(network_removed) + update_coverage(1) + +/obj/machinery/camera/proc/replace_networks(var/list/networks) + if(networks.len != network.len) + network = networks + update_coverage(1) + return + + for(var/new_network in networks) + if(!(new_network in network)) + network = networks + update_coverage(1) + return + +/obj/machinery/camera/proc/clear_all_networks() + if(network.len) + network.Cut() + update_coverage(1) + +/obj/machinery/camera/proc/nano_structure() + var/cam[0] + cam["name"] = sanitize(c_tag) + cam["deact"] = !can_use() + cam["camera"] = "\ref[src]" + cam["x"] = x + cam["y"] = y + cam["z"] = z + return cam + +/obj/machinery/camera/proc/update_coverage(var/network_change = 0) + if(network_change) + var/list/open_networks = difflist(network, restricted_camera_networks) + // Add or remove camera from the camera net as necessary + if(on_open_network && !open_networks.len) + cameranet.removeCamera(src) + else if(!on_open_network && open_networks.len) + on_open_network = 1 + cameranet.addCamera(src) + else + cameranet.updateVisibility(src, 0) + + invalidateCameraCache() diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 19f2216272..a038ece414 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -78,7 +78,7 @@ if(isscrewdriver(W)) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) - var/input = strip_html(input(usr, "Which networks would you like to connect this camera to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13")) + var/input = sanitize(input(usr, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13")) if(!input) usr << "No input found please hang up and try your call again." return @@ -90,7 +90,7 @@ var/area/camera_area = get_area(src) var/temptag = "[sanitize(camera_area.name)] ([rand(1, 999)])" - input = strip_html(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag)) + input = sanitizeSafe(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag)) state = 4 var/obj/machinery/camera/C = new(src.loc) @@ -99,10 +99,7 @@ C.auto_turn() - C.network = uniquelist(tempnetwork) - tempnetwork = difflist(C.network,restricted_camera_networks) - if(!tempnetwork.len)//Camera isn't on any open network - remove its chunk from AI visibility. - cameranet.removeCamera(C) + C.replace_networks(uniquelist(tempnetwork)) C.c_tag = input diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm index 0c6f7d95a7..636f114de7 100644 --- a/code/game/machinery/camera/motion.dm +++ b/code/game/machinery/camera/motion.dm @@ -45,8 +45,7 @@ if (!status || (stat & NOPOWER)) return 0 if (detectTime == -1) - for (var/mob/living/silicon/aiPlayer in player_list) - aiPlayer.cancelAlarm("Motion", get_area(src), src) + motion_alarm.clearAlarm(loc, src) detectTime = 0 return 1 @@ -54,8 +53,7 @@ if (!status || (stat & NOPOWER)) return 0 if (!detectTime) return 0 - for (var/mob/living/silicon/aiPlayer in player_list) - aiPlayer.triggerAlarm("Motion", get_area(src), list(src), src) + motion_alarm.triggerAlarm(loc, src) detectTime = -1 return 1 diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index 21a9dc1061..fbbecec825 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -31,6 +31,15 @@ // AUTONAME +/obj/machinery/camera/autoname/engineering_outpost + network = list("SS13", "Engineering Outpost") + +/obj/machinery/camera/autoname/mining_outpost + network = list("SS13", "MINE") + +/obj/machinery/camera/autoname/research_outpost + network = list("SS13", "Research Outpost") + /obj/machinery/camera/autoname var/number = 0 //camera number in area diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index 52d74a23b9..b781613d70 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -1,17 +1,14 @@ +#define TRACKING_POSSIBLE 0 +#define TRACKING_NO_COVERAGE 1 +#define TRACKING_TERMINATE 2 + /mob/living/silicon/ai/var/max_locations = 10 /mob/living/silicon/ai/var/stored_locations[0] -/mob/living/silicon/ai/proc/InvalidTurf(turf/T as turf) - if(!T) - return 1 - if(T.z == 2) - return 1 - if(T.z > 6) - return 1 - return 0 +/proc/InvalidPlayerTurf(turf/T as turf) + return !(T && T.z in config.player_levels) /mob/living/silicon/ai/proc/get_camera_list() - if(src.stat == 2) return @@ -50,7 +47,7 @@ set name = "Store Camera Location" set desc = "Stores your current camera location by the given name" - loc = sanitize(copytext(loc, 1, MAX_MESSAGE_LEN)) + loc = sanitize(loc) if(!loc) src << "\red Must supply a location name" return @@ -64,7 +61,7 @@ return var/L = src.eyeobj.getLoc() - if (InvalidTurf(get_turf(L))) + if (InvalidPlayerTurf(get_turf(L))) src << "\red Unable to store this location" return @@ -107,38 +104,14 @@ var/list/cameras = list() /mob/living/silicon/ai/proc/trackable_mobs() - if(usr.stat == 2) return list() var/datum/trackable/TB = new() for(var/mob/living/M in mob_list) - // Easy checks first. - // Don't detect mobs on Centcom. Since the wizard den is on Centcomm, we only need this. - if(InvalidTurf(get_turf(M))) - continue if(M == usr) continue - if(M.invisibility)//cloaked - continue - if(M.digitalcamo) - continue - - // Human check - var/human = 0 - if(istype(M, /mob/living/carbon/human)) - human = 1 - var/mob/living/carbon/human/H = M - //Cameras can't track people wearing an agent card or a ninja hood. - if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate)) - continue - if(istype(H.head, /obj/item/clothing/head/helmet/space/rig)) - var/obj/item/clothing/head/helmet/space/rig/helmet = H.head - if(helmet.prevent_track()) - continue - - // Now, are they viewable by a camera? (This is last because it's the most intensive check) - if(!near_camera(M)) + if(M.tracking_status() != TRACKING_POSSIBLE) continue var/name = M.name @@ -148,7 +121,7 @@ else TB.names.Add(name) TB.namecounts[name] = 1 - if(human) + if(istype(M, /mob/living/carbon/human)) TB.humans[name] = M else TB.others[name] = M @@ -177,6 +150,7 @@ return src << "Follow camera mode [forced ? "terminated" : "ended"]." + cameraFollow.tracking_cancelled() cameraFollow = null /mob/living/silicon/ai/proc/ai_actual_track(mob/living/target as mob) @@ -185,33 +159,21 @@ U.cameraFollow = target U << "Now tracking [target.name] on camera." + target.tracking_initiated() spawn (0) while (U.cameraFollow == target) if (U.cameraFollow == null) return - if (istype(target, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = target - if(H.wear_id && istype(H.wear_id.GetID(), /obj/item/weapon/card/id/syndicate)) + + switch(target.tracking_status()) + if(TRACKING_NO_COVERAGE) + U << "Target is not near any active cameras." + sleep(100) + continue + if(TRACKING_TERMINATE) U.ai_cancel_tracking(1) return - if(istype(H.head, /obj/item/clothing/head/helmet/space/rig)) - var/obj/item/clothing/head/helmet/space/rig/helmet = H.head - if(helmet.prevent_track()) - U.ai_cancel_tracking(1) - return - if(H.digitalcamo) - U.ai_cancel_tracking(1) - return - - if(istype(target.loc,/obj/effect/dummy)) - U.ai_cancel_tracking() - return - - if (!trackable(target)) - U << "Target is not near any active cameras." - sleep(100) - continue if(U.eyeobj) U.eyeobj.setLoc(get_turf(target), 0) @@ -220,24 +182,6 @@ return sleep(10) -/proc/near_camera(var/mob/living/M) - if (!isturf(M.loc)) - return 0 - if(isrobot(M)) - var/mob/living/silicon/robot/R = M - if(!(R.camera && R.camera.can_use()) && !cameranet.checkCameraVis(M)) - return 0 - else if(!cameranet.checkCameraVis(M)) - return 0 - return 1 - -/proc/trackable(var/mob/living/M) - var/turf/T = get_turf(M) - if(T && (T.z in config.station_levels) && hassensorlevel(M, SUIT_SENSOR_TRACKING)) - return 1 - - return near_camera(M) - /obj/machinery/camera/attack_ai(var/mob/living/silicon/ai/user as mob) if (!istype(user)) return @@ -248,3 +192,87 @@ /mob/living/silicon/ai/attack_ai(var/mob/user as mob) ai_camera_list() + +/proc/camera_sort(list/L) + var/obj/machinery/camera/a + var/obj/machinery/camera/b + + for (var/i = L.len, i > 0, i--) + for (var/j = 1 to i - 1) + a = L[j] + b = L[j + 1] + if (a.c_tag_order != b.c_tag_order) + if (a.c_tag_order > b.c_tag_order) + L.Swap(j, j + 1) + else + if (sorttext(a.c_tag, b.c_tag) < 0) + L.Swap(j, j + 1) + return L + + +mob/living/proc/near_camera() + if (!isturf(loc)) + return 0 + else if(!cameranet.checkVis(src)) + return 0 + return 1 + +/mob/living/proc/tracking_status() + // Easy checks first. + // Don't detect mobs on Centcom. Since the wizard den is on Centcomm, we only need this. + if(InvalidPlayerTurf(get_turf(src))) + return TRACKING_TERMINATE + if(invisibility >= INVISIBILITY_LEVEL_ONE) //cloaked + return TRACKING_TERMINATE + if(digitalcamo) + return TRACKING_TERMINATE + if(istype(loc,/obj/effect/dummy)) + return TRACKING_TERMINATE + + // Now, are they viewable by a camera? (This is last because it's the most intensive check) + return near_camera() ? TRACKING_POSSIBLE : TRACKING_NO_COVERAGE + +/mob/living/silicon/robot/tracking_status() + . = ..() + if(. == TRACKING_NO_COVERAGE) + return camera && camera.can_use() ? TRACKING_POSSIBLE : TRACKING_NO_COVERAGE + +/mob/living/silicon/robot/syndicate/tracking_status() + return TRACKING_TERMINATE + +/mob/living/carbon/human/tracking_status() + //Cameras can't track people wearing an agent card or a ninja hood. + if(wear_id && istype(wear_id.GetID(), /obj/item/weapon/card/id/syndicate)) + return TRACKING_TERMINATE + if(istype(head, /obj/item/clothing/head/helmet/space/rig)) + var/obj/item/clothing/head/helmet/space/rig/helmet = head + if(helmet.prevent_track()) + return TRACKING_TERMINATE + + . = ..() + if(. == TRACKING_TERMINATE) + return + + if(. == TRACKING_NO_COVERAGE) + var/turf/T = get_turf(src) + if(T && (T.z in config.station_levels) && hassensorlevel(src, SUIT_SENSOR_TRACKING)) + return TRACKING_POSSIBLE + +mob/living/proc/tracking_initiated() + +mob/living/silicon/robot/tracking_initiated() + tracking_entities++ + if(tracking_entities == 1 && has_zeroth_law()) + src << "Internal camera is currently being accessed." + +mob/living/proc/tracking_cancelled() + +mob/living/silicon/robot/tracking_initiated() + tracking_entities-- + if(!tracking_entities && has_zeroth_law()) + src << "Internal camera is no longer being accessed." + + +#undef TRACKING_POSSIBLE +#undef TRACKING_NO_COVERAGE +#undef TRACKING_TERMINATE diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 454e6e44fc..0c133adc9b 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -3,18 +3,40 @@ //Potential replacement for genetics revives or something I dunno (?) +//Find a dead mob with a brain and client. +/proc/find_dead_player(var/find_key) + if(isnull(find_key)) + return + + var/mob/selected = null + for(var/mob/living/M in player_list) + //Dead people only thanks! + if((M.stat != 2) || (!M.client)) + continue + //They need a brain! + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + if(H.species.has_organ["brain"] && !H.has_brain()) + continue + if(M.ckey == find_key) + selected = M + break + return selected + #define CLONE_BIOMASS 150 /obj/machinery/clonepod - anchored = 1 name = "cloning pod" desc = "An electronically-lockable pod for growing organic tissue." density = 1 + anchored = 1 icon = 'icons/obj/cloning.dmi' icon_state = "pod_0" req_access = list(access_genetics) //For premature unlocking. var/mob/living/occupant - var/heal_level = 90 //The clone is released once its health reaches this level. + var/heal_level = 20 //The clone is released once its health reaches this level. + var/heal_rate = 1 + var/notoxin = 0 var/locked = 0 var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine. var/mess = 0 //Need to clean out it if it's full of exploded clone. @@ -22,6 +44,355 @@ var/eject_wait = 0 //Don't eject them as soon as they are created fuckkk var/biomass = CLONE_BIOMASS * 3 +/obj/machinery/clonepod/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/clonepod(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/scanning_module(src) + component_parts += new /obj/item/weapon/stock_parts/scanning_module(src) + component_parts += new /obj/item/weapon/stock_parts/console_screen(src) + component_parts += new /obj/item/stack/cable_coil(src, 2) + + RefreshParts() + update_icon() + +/obj/machinery/clonepod/attack_ai(mob/user as mob) + + add_hiddenprint(user) + return attack_hand(user) + +/obj/machinery/clonepod/attack_hand(mob/user as mob) + if((isnull(occupant)) || (stat & NOPOWER)) + return + if((!isnull(occupant)) && (occupant.stat != 2)) + var/completion = (100 * ((occupant.health + 50) / (heal_level + 100))) // Clones start at -150 health + user << "Current clone cycle is [round(completion)]% complete." + return + +//Clonepod + +//Start growing a human clone in the pod! +/obj/machinery/clonepod/proc/growclone(var/datum/dna2/record/R) + if(mess || attempting) + return 0 + var/datum/mind/clonemind = locate(R.mind) + + if(!istype(clonemind, /datum/mind)) //not a mind + return 0 + if(clonemind.current && clonemind.current.stat != DEAD) //mind is associated with a non-dead body + return 0 + if(clonemind.active) //somebody is using that mind + if(ckey(clonemind.key) != R.ckey) + return 0 + else + for(var/mob/dead/observer/G in player_list) + if(G.ckey == R.ckey) + if(G.can_reenter_corpse) + break + else + return 0 + + attempting = 1 //One at a time!! + locked = 1 + + eject_wait = 1 + spawn(30) + eject_wait = 0 + + var/mob/living/carbon/human/H = new /mob/living/carbon/human(src, R.dna.species) + occupant = H + + if(!R.dna.real_name) //to prevent null names + R.dna.real_name = "clone ([rand(0,999)])" + H.real_name = R.dna.real_name + + //Get the clone body ready + H.adjustCloneLoss(150) // New damage var so you can't eject a clone early then stab them to abuse the current damage system --NeoFite + H.adjustBrainLoss(80) // Even if healed to full health, it will have some brain damage + H.Paralyse(4) + + //Here let's calculate their health so the pod doesn't immediately eject them!!! + H.updatehealth() + + clonemind.transfer_to(H) + H.ckey = R.ckey + H << "Consciousness slowly creeps over you as your body regenerates.
    So this is what cloning feels like?
    " + + // -- Mode/mind specific stuff goes here + callHook("clone", list(H)) + update_antag_icons(H.mind) + // -- End mode specific stuff + + if(!R.dna) + H.dna = new /datum/dna() + H.dna.real_name = H.real_name + else + H.dna = R.dna + H.UpdateAppearance() + if(heal_level < 60) + randmutb(H) //Sometimes the clones come out wrong. + H.dna.UpdateSE() + H.dna.UpdateUI() + + H.set_cloned_appearance() + update_icon() + + for(var/datum/language/L in R.languages) + H.add_language(L.name) + H.flavor_texts = R.flavor.Copy() + H.suiciding = 0 + attempting = 0 + return 1 + +//Grow clones to maturity then kick them out. FREELOADERS +/obj/machinery/clonepod/process() + + if(stat & NOPOWER) //Autoeject if power is lost + if(occupant) + locked = 0 + go_out() + return + + if((occupant) && (occupant.loc == src)) + if((occupant.stat == DEAD) || (occupant.suiciding) || !occupant.key) //Autoeject corpses and suiciding dudes. + locked = 0 + go_out() + connected_message("Clone Rejected: Deceased.") + return + + else if(occupant.health < heal_level && occupant.getCloneLoss() > 0) + occupant.Paralyse(4) + + //Slowly get that clone healed and finished. + occupant.adjustCloneLoss(-2 * heal_rate) + + //Premature clones may have brain damage. + occupant.adjustBrainLoss(-1 * heal_rate) + + //So clones don't die of oxyloss in a running pod. + if(occupant.reagents.get_reagent_amount("inaprovaline") < 30) + occupant.reagents.add_reagent("inaprovaline", 60) + + //So clones will remain asleep for long enough to get them into cryo (Bay RP edit) + if(occupant.reagents.get_reagent_amount("stoxin") < 10) + occupant.reagents.add_reagent("stoxin", 5) + if(occupant.reagents.get_reagent_amount("chloralhydrate") < 1) + occupant.reagents.add_reagent("chloralhydrate", 1) + + //Also heal some oxyloss ourselves because inaprovaline is so bad at preventing it!! + occupant.adjustOxyLoss(-4) + if(notoxin) + occupant.adjustToxLoss(-2) // If sufficiently upgraded - remove toxin damage from chloral + + use_power(7500) //This might need tweaking. + return + + else if((occupant.health >= heal_level) && (!eject_wait)) + connected_message("Cloning Process Complete.") + locked = 0 + go_out() + return + + else if((!occupant) || (occupant.loc != src)) + occupant = null + if(locked) + locked = 0 + return + + return + +//Let's unlock this early I guess. Might be too early, needs tweaking. +/obj/machinery/clonepod/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(isnull(occupant)) + if(default_deconstruction_screwdriver(user, W)) + return + if(default_deconstruction_crowbar(user, W)) + return + if(default_part_replacement(user, W)) + return + if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) + if(!check_access(W)) + user << "Access Denied." + return + if((!locked) || (isnull(occupant))) + return + if((occupant.health < -20) && (occupant.stat != 2)) + user << "Access Refused." + return + else + locked = 0 + user << "System unlocked." + else if(istype(W, /obj/item/weapon/card/emag)) + if(isnull(occupant)) + return + user << "You force an emergency ejection." + locked = 0 + go_out() + return + else if(istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat)) + user << "\The [src] processes \the [W]." + biomass += 50 + user.drop_item() + del(W) + return + else if(istype(W, /obj/item/weapon/wrench)) + if(locked && (anchored || occupant)) + user << "Can not do that while [src] is in use." + else + if(anchored) + anchored = 0 + connected.pods -= src + connected = null + else + anchored = 1 + playsound(loc, 'sound/items/Ratchet.ogg', 100, 1) + if(anchored) + user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.") + else + user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.") + else if(istype(W, /obj/item/device/multitool)) + var/obj/item/device/multitool/M = W + M.connecting = src + user << "You load connection data from [src] to [M]." + return + else + ..() + +//Put messages in the connected computer's temp var for display. +/obj/machinery/clonepod/proc/connected_message(var/message) + if((isnull(connected)) || (!istype(connected, /obj/machinery/computer/cloning))) + return 0 + if(!message) + return 0 + + connected.temp = "[name] : [message]" + connected.updateUsrDialog() + return 1 + +/obj/machinery/clonepod/RefreshParts() + ..() + var/rating = 0 + for(var/obj/item/weapon/stock_parts/P in component_parts) + if(istype(P, /obj/item/weapon/stock_parts/scanning_module) || istype(P, /obj/item/weapon/stock_parts/manipulator)) + rating += P.rating + + heal_level = rating * 10 - 20 + heal_rate = round(rating / 4) + if(rating >= 8) + notoxin = 1 + else + notoxin = 0 + +/obj/machinery/clonepod/verb/eject() + set name = "Eject Cloner" + set category = "Object" + set src in oview(1) + + if(usr.stat != 0) + return + go_out() + add_fingerprint(usr) + return + +/obj/machinery/clonepod/proc/go_out() + if(locked) + return + + if(mess) //Clean that mess and dump those gibs! + mess = 0 + gibs(loc) + update_icon() + return + + if(!(occupant)) + return + + if(occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE + occupant.loc = loc + eject_wait = 0 //If it's still set somehow. + domutcheck(occupant) //Waiting until they're out before possible monkeyizing. + occupant = null + + biomass -= CLONE_BIOMASS + update_icon() + return + +/obj/machinery/clonepod/proc/malfunction() + if(occupant) + connected_message("Critical Error!") + mess = 1 + update_icon() + occupant.ghostize() + spawn(5) + del(occupant) + return + +/obj/machinery/clonepod/relaymove(mob/user as mob) + if(user.stat) + return + go_out() + return + +/obj/machinery/clonepod/emp_act(severity) + if(prob(100/severity)) + malfunction() + ..() + +/obj/machinery/clonepod/ex_act(severity) + switch(severity) + if(1.0) + for(var/atom/movable/A as mob|obj in src) + A.loc = loc + ex_act(severity) + del(src) + return + if(2.0) + if(prob(50)) + for(var/atom/movable/A as mob|obj in src) + A.loc = loc + ex_act(severity) + del(src) + return + if(3.0) + if(prob(25)) + for(var/atom/movable/A as mob|obj in src) + A.loc = loc + ex_act(severity) + del(src) + return + else + return + +/obj/machinery/clonepod/update_icon() + ..() + icon_state = "pod_0" + if (occupant && !(stat & NOPOWER)) + icon_state = "pod_1" + else if (mess) + icon_state = "pod_g" + +//Health Tracker Implant + +/obj/item/weapon/implant/health + name = "health implant" + var/healthstring = "" + +/obj/item/weapon/implant/health/proc/sensehealth() + if(!implanted) + return "ERROR" + else + if(isliving(implanted)) + var/mob/living/L = implanted + healthstring = "[round(L.getOxyLoss())] - [round(L.getFireLoss())] - [round(L.getToxLoss())] - [round(L.getBruteLoss())]" + if(!healthstring) + healthstring = "ERROR" + return healthstring + +//Disk stuff. //The return of data disks?? Just for transferring between genetics machine/cloning machine. //TO-DO: Make the genetics machine accept them. /obj/item/weapon/disk/data @@ -30,7 +401,7 @@ icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk. item_state = "card-id" w_class = 2.0 - var/datum/dna2/record/buf=null + var/datum/dna2/record/buf = null var/read_only = 0 //Well,it's still a floppy disk /obj/item/weapon/disk/data/proc/initializeDisk() @@ -65,363 +436,18 @@ buf.dna.SE=new_SE buf.dna.SetSEValueRange(MONKEYBLOCK,0xDAC, 0xFFF) - -//Find a dead mob with a brain and client. -/proc/find_dead_player(var/find_key) - if (isnull(find_key)) - return - - var/mob/selected = null - for(var/mob/living/M in player_list) - //Dead people only thanks! - if ((M.stat != 2) || (!M.client)) - continue - //They need a brain! - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(H.species.has_organ["brain"] && !H.has_brain()) - continue - if (M.ckey == find_key) - selected = M - break - return selected - -//Disk stuff. /obj/item/weapon/disk/data/New() ..() var/diskcolor = pick(0,1,2) - src.icon_state = "datadisk[diskcolor]" + icon_state = "datadisk[diskcolor]" /obj/item/weapon/disk/data/attack_self(mob/user as mob) - src.read_only = !src.read_only - user << "You flip the write-protect tab to [src.read_only ? "protected" : "unprotected"]." + read_only = !read_only + user << "You flip the write-protect tab to [read_only ? "protected" : "unprotected"]." /obj/item/weapon/disk/data/examine(mob/user) ..(user) - user << text("The write-protect tab is set to [src.read_only ? "protected" : "unprotected"].") - return - -//Health Tracker Implant - -/obj/item/weapon/implant/health - name = "health implant" - var/healthstring = "" - -/obj/item/weapon/implant/health/proc/sensehealth() - if (!src.implanted) - return "ERROR" - else - if(isliving(src.implanted)) - var/mob/living/L = src.implanted - src.healthstring = "[round(L.getOxyLoss())] - [round(L.getFireLoss())] - [round(L.getToxLoss())] - [round(L.getBruteLoss())]" - if (!src.healthstring) - src.healthstring = "ERROR" - return src.healthstring - -/obj/machinery/clonepod/attack_ai(mob/user as mob) - src.add_hiddenprint(user) - return attack_hand(user) - -/obj/machinery/clonepod/attack_hand(mob/user as mob) - if ((isnull(src.occupant)) || (stat & NOPOWER)) - return - if ((!isnull(src.occupant)) && (src.occupant.stat != 2)) - var/completion = (100 * ((src.occupant.health + 100) / (src.heal_level + 100))) - user << "Current clone cycle is [round(completion)]% complete." - return - -//Clonepod - -//Start growing a human clone in the pod! -/obj/machinery/clonepod/proc/growclone(var/datum/dna2/record/R) - if(mess || attempting) - return 0 - var/datum/mind/clonemind = locate(R.mind) - if(!istype(clonemind,/datum/mind)) //not a mind - return 0 - if( clonemind.current && clonemind.current.stat != DEAD ) //mind is associated with a non-dead body - return 0 - if(clonemind.active) //somebody is using that mind - if( ckey(clonemind.key)!=R.ckey ) - return 0 - else - for(var/mob/dead/observer/G in player_list) - if(G.ckey == R.ckey) - if(G.can_reenter_corpse) - break - else - return 0 - - - src.heal_level = rand(10,40) //Randomizes what health the clone is when ejected - src.attempting = 1 //One at a time!! - src.locked = 1 - - src.eject_wait = 1 - spawn(30) - src.eject_wait = 0 - - var/mob/living/carbon/human/H = new /mob/living/carbon/human(src, R.dna.species) - occupant = H - - if(!R.dna.real_name) //to prevent null names - R.dna.real_name = "clone ([rand(0,999)])" - H.real_name = R.dna.real_name - - src.icon_state = "pod_1" - //Get the clone body ready - H.adjustCloneLoss(150) //new damage var so you can't eject a clone early then stab them to abuse the current damage system --NeoFite - H.adjustBrainLoss(src.heal_level + 50 + rand(10, 30)) // The rand(10, 30) will come out as extra brain damage - H.Paralyse(4) - - //Here let's calculate their health so the pod doesn't immediately eject them!!! - H.updatehealth() - - clonemind.transfer_to(H) - H.ckey = R.ckey - H << "Consciousness slowly creeps over you as your body regenerates.
    So this is what cloning feels like?
    " - - // -- Mode/mind specific stuff goes here - callHook("clone", list(H)) - - switch(ticker.mode.name) - if("revolution") - if((H.mind in ticker.mode:revolutionaries) || (H.mind in ticker.mode:head_revolutionaries)) - ticker.mode.update_all_rev_icons() //So the icon actually appears - if("mercenary") - if(H.mind in ticker.mode.syndicates) - ticker.mode.update_all_synd_icons() - if("cult") - if (H.mind in ticker.mode.cult) - ticker.mode.add_cultist(src.occupant.mind) - ticker.mode.update_all_cult_icons() //So the icon actually appears - - // -- End mode specific stuff - - if(!R.dna) - H.dna = new /datum/dna() - H.dna.real_name = H.real_name - else - H.dna=R.dna - H.UpdateAppearance() - randmutb(H) //Sometimes the clones come out wrong. - H.dna.UpdateSE() - H.dna.UpdateUI() - - H.set_cloned_appearance() - - for(var/datum/language/L in R.languages) - H.add_language(L.name) - H.flavor_texts = R.flavor.Copy() - H.suiciding = 0 - src.attempting = 0 - return 1 - -//Grow clones to maturity then kick them out. FREELOADERS -/obj/machinery/clonepod/process() - - if(stat & NOPOWER) //Autoeject if power is lost - if (src.occupant) - src.locked = 0 - src.go_out() - return - - if((src.occupant) && (src.occupant.loc == src)) - if((src.occupant.stat == DEAD) || (src.occupant.suiciding) || !occupant.key) //Autoeject corpses and suiciding dudes. - src.locked = 0 - src.go_out() - src.connected_message("Clone Rejected: Deceased.") - return - - else if(src.occupant.health < src.heal_level) - src.occupant.Paralyse(4) - - //Slowly get that clone healed and finished. - src.occupant.adjustCloneLoss(-2) - - //Premature clones may have brain damage. - src.occupant.adjustBrainLoss(-1) - - //So clones don't die of oxyloss in a running pod. - if (src.occupant.reagents.get_reagent_amount("inaprovaline") < 30) - src.occupant.reagents.add_reagent("inaprovaline", 60) - - //So clones will remain asleep for long enough to get them into cryo (Bay RP edit) - if (src.occupant.reagents.get_reagent_amount("stoxin") < 10) - src.occupant.reagents.add_reagent("stoxin", 5) - if (src.occupant.reagents.get_reagent_amount("chloralhydrate") < 1) - src.occupant.reagents.add_reagent("chloralhydrate", 1) - - //Also heal some oxyloss ourselves because inaprovaline is so bad at preventing it!! - src.occupant.adjustOxyLoss(-4) - - use_power(7500) //This might need tweaking. - return - - else if((src.occupant.health >= src.heal_level) && (!src.eject_wait)) - src.connected_message("Cloning Process Complete.") - src.locked = 0 - src.go_out() - return - - else if ((!src.occupant) || (src.occupant.loc != src)) - src.occupant = null - if (src.locked) - src.locked = 0 - if (!src.mess) - icon_state = "pod_0" - //use_power(200) - return - - return - -//Let's unlock this early I guess. Might be too early, needs tweaking. -/obj/machinery/clonepod/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) - if (!src.check_access(W)) - user << "\red Access Denied." - return - if ((!src.locked) || (isnull(src.occupant))) - return - if ((src.occupant.health < -20) && (src.occupant.stat != 2)) - user << "\red Access Refused." - return - else - src.locked = 0 - user << "System unlocked." - else if (istype(W, /obj/item/weapon/card/emag)) - if (isnull(src.occupant)) - return - user << "You force an emergency ejection." - src.locked = 0 - src.go_out() - return - else if (istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat)) - user << "\blue \The [src] processes \the [W]." - biomass += 50 - user.drop_item() - del(W) - return - else if (istype(W, /obj/item/weapon/wrench)) - if(src.locked && (src.anchored || src.occupant)) - user << "\red Can not do that while [src] is in use." - else - if(src.anchored) - src.anchored = 0 - connected.pod1 = null - connected = null - else - src.anchored = 1 - playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) - if(anchored) - user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.") - else - user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.") - else - ..() - -//Put messages in the connected computer's temp var for display. -/obj/machinery/clonepod/proc/connected_message(var/message) - if ((isnull(src.connected)) || (!istype(src.connected, /obj/machinery/computer/cloning))) - return 0 - if (!message) - return 0 - - src.connected.temp = message - src.connected.updateUsrDialog() - return 1 - -/obj/machinery/clonepod/verb/eject() - set name = "Eject Cloner" - set category = "Object" - set src in oview(1) - - if (usr.stat != 0) - return - src.go_out() - add_fingerprint(usr) - return - -/obj/machinery/clonepod/proc/go_out() - if (src.locked) - return - - if (src.mess) //Clean that mess and dump those gibs! - src.mess = 0 - gibs(src.loc) - src.icon_state = "pod_0" - - /* - for(var/obj/O in src) - O.loc = src.loc - */ - return - - if (!(src.occupant)) - return - - /* - for(var/obj/O in src) - O.loc = src.loc - */ - - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - src.occupant.loc = src.loc - src.icon_state = "pod_0" - src.eject_wait = 0 //If it's still set somehow. - domutcheck(src.occupant) //Waiting until they're out before possible monkeyizing. -// src.occupant.add_side_effect("Bad Stomach") // Give them an extra side-effect for free. - src.occupant = null - - src.biomass -= CLONE_BIOMASS - - return - -/obj/machinery/clonepod/proc/malfunction() - if(src.occupant) - src.connected_message("Critical Error!") - src.mess = 1 - src.icon_state = "pod_g" - src.occupant.ghostize() - spawn(5) - del(src.occupant) - return - -/obj/machinery/clonepod/relaymove(mob/user as mob) - if (user.stat) - return - src.go_out() - return - -/obj/machinery/clonepod/emp_act(severity) - if(prob(100/severity)) malfunction() - ..() - -/obj/machinery/clonepod/ex_act(severity) - switch(severity) - if(1.0) - for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc - ex_act(severity) - del(src) - return - if(2.0) - if (prob(50)) - for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc - ex_act(severity) - del(src) - return - if(3.0) - if (prob(25)) - for(var/atom/movable/A as mob|obj in src) - A.loc = src.loc - ex_act(severity) - del(src) - return - else + user << text("The write-protect tab is set to [read_only ? "protected" : "unprotected"].") return /* diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index bcd7beda08..b35cfd95a6 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -71,7 +71,7 @@ /obj/machinery/computer/operating/Topic(href, href_list) if(..()) - return + return 1 if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) return diff --git a/code/game/machinery/computer/RCON_Console.dm b/code/game/machinery/computer/RCON_Console.dm index 7ab0a135f1..f80f0b93c4 100644 --- a/code/game/machinery/computer/RCON_Console.dm +++ b/code/game/machinery/computer/RCON_Console.dm @@ -12,12 +12,11 @@ circuit = /obj/item/weapon/circuitboard/rcon_console req_one_access = list(access_engine) var/current_tag = null - var/list/known_SMESs = null - var/list/known_breakers = null - // Allows you to hide specific parts of the UI - var/hide_SMES = 0 - var/hide_SMES_details = 0 - var/hide_breakers = 0 + var/obj/nano_module/rcon/rcon + +/obj/machinery/computer/rcon/New() + ..() + rcon = new(src) // Proc: attack_hand() // Parameters: 1 (user - Person which clicked this computer) @@ -29,105 +28,5 @@ // Proc: ui_interact() // Parameters: 4 (standard NanoUI parameters) // Description: Uses dark magic (NanoUI) to render this machine's UI -/obj/machinery/computer/rcon/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - FindDevices() // Update our devices list - var/data[0] - - // SMES DATA (simplified view) - var/list/smeslist[0] - for(var/obj/machinery/power/smes/buildable/SMES in known_SMESs) - smeslist.Add(list(list( - "charge" = round(SMES.Percentage()), - "input_set" = SMES.input_attempt, - "input_val" = round(SMES.input_level), - "output_set" = SMES.output_attempt, - "output_val" = round(SMES.output_level), - "output_load" = round(SMES.output_used), - "RCON_tag" = SMES.RCon_tag - ))) - data["smes_info"] = smeslist - - // BREAKER DATA (simplified view) - var/list/breakerlist[0] - for(var/obj/machinery/power/breakerbox/BR in known_breakers) - breakerlist.Add(list(list( - "RCON_tag" = BR.RCon_tag, - "enabled" = BR.on - ))) - data["breaker_info"] = breakerlist - data["hide_smes"] = hide_SMES - data["hide_smes_details"] = hide_SMES_details - data["hide_breakers"] = hide_breakers - - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "rcon.tmpl", "RCON Console", 600, 400) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) - -// Proc: Topic() -// Parameters: 2 (href, href_list - allows us to process UI clicks) -// Description: Allows us to process UI clicks, which are relayed in form of hrefs. -/obj/machinery/computer/rcon/Topic(href, href_list) - if(href_list["smes_in_toggle"]) - var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_in_toggle"]) - if(SMES) - SMES.toggle_input() - if(href_list["smes_out_toggle"]) - var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_out_toggle"]) - if(SMES) - SMES.toggle_output() - if(href_list["smes_in_set"]) - var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_in_set"]) - if(SMES) - var/inputset = input(usr, "Enter new input level (0-[SMES.input_level_max])", "SMES Input Power Control") as num - SMES.set_input(inputset) - if(href_list["smes_out_set"]) - var/obj/machinery/power/smes/buildable/SMES = GetSMESByTag(href_list["smes_out_set"]) - if(SMES) - var/outputset = input(usr, "Enter new output level (0-[SMES.output_level_max])", "SMES Input Power Control") as num - SMES.set_output(outputset) - - if(href_list["toggle_breaker"]) - var/obj/machinery/power/breakerbox/toggle = null - for(var/obj/machinery/power/breakerbox/breaker in known_breakers) - if(breaker.RCon_tag == href_list["toggle_breaker"]) - toggle = breaker - if(toggle) - if(toggle.update_locked) - usr << "The breaker box was recently toggled. Please wait before toggling it again." - else - toggle.auto_toggle() - if(href_list["hide_smes"]) - hide_SMES = !hide_SMES - if(href_list["hide_smes_details"]) - hide_SMES_details = !hide_SMES_details - if(href_list["hide_breakers"]) - hide_breakers = !hide_breakers - - -// Proc: GetSMESByTag() -// Parameters: 1 (tag - RCON tag of SMES we want to look up) -// Description: Looks up and returns SMES which has matching RCON tag -/obj/machinery/computer/rcon/proc/GetSMESByTag(var/tag) - if(!tag) - return - - for(var/obj/machinery/power/smes/buildable/S in known_SMESs) - if(S.RCon_tag == tag) - return S - -// Proc: FindDevices() -// Parameters: None -// Description: Refreshes local list of known devices. -/obj/machinery/computer/rcon/proc/FindDevices() - known_SMESs = new /list() - for(var/obj/machinery/power/smes/buildable/SMES in machines) - if(SMES.RCon_tag && (SMES.RCon_tag != "NO_TAG") && SMES.RCon) - known_SMESs.Add(SMES) - - known_breakers = new /list() - for(var/obj/machinery/power/breakerbox/breaker in machines) - if(breaker.RCon_tag != "NO_TAG") - known_breakers.Add(breaker) \ No newline at end of file +/obj/machinery/computer/rcon/ui_interact(mob/user, ui_key = "rcon", var/datum/nanoui/ui = null, var/force_open = 1) + rcon.ui_interact(user, ui_key, ui, force_open) diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 69c884ec70..8778038ddf 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -137,8 +137,8 @@ return if(M.brainmob.mind) - ticker.mode.remove_cultist(M.brainmob.mind, 1) - ticker.mode.remove_revolutionary(M.brainmob.mind, 1) + cult.remove_antagonist(M.brainmob.mind, 1) + revs.remove_antagonist(M.brainmob.mind, 1) user.drop_item() P.loc = src @@ -168,9 +168,15 @@ if(istype(P, /obj/item/weapon/screwdriver)) playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1) user << "\blue You connect the monitor." - var/mob/living/silicon/ai/A = new /mob/living/silicon/ai ( loc, laws, brain ) - if(A) //if there's no brain, the mob is deleted and a structure/AIcore is created - A.rename_self("ai", 1) + if(!brain) + var/open_for_latejoin = alert(user, "Would you like this core to be open for latejoining AIs?", "Latejoin", "Yes", "Yes", "No") == "Yes" + var/obj/structure/AIcore/deactivated/D = new(loc) + if(open_for_latejoin) + empty_playable_ai_cores += D + else + var/mob/living/silicon/ai/A = new /mob/living/silicon/ai ( loc, laws, brain ) + if(A) //if there's no brain, the mob is deleted and a structure/AIcore is created + A.rename_self("ai", 1) feedback_inc("cyborg_ais_created",1) del(src) @@ -201,20 +207,57 @@ /obj/structure/AIcore/deactivated/proc/check_malf(var/mob/living/silicon/ai/ai) if(!ai) return - if (ticker.mode.name == "AI malfunction") - var/datum/game_mode/malfunction/malf = ticker.mode - for (var/datum/mind/malfai in malf.malf_ai) - if (ai.mind == malfai) - return 1 + for (var/datum/mind/malfai in malf.current_antagonists) + if (ai.mind == malfai) + return 1 -/obj/structure/AIcore/deactivated/attackby(var/obj/item/device/aicard/card, var/mob/user) +/obj/structure/AIcore/deactivated/attackby(var/obj/item/weapon/W, var/mob/user) - if(istype(card)) + if(istype(W, /obj/item/device/aicard)) + var/obj/item/device/aicard/card = W var/mob/living/silicon/ai/transfer = locate() in card if(transfer) load_ai(transfer,card,user) else user << "\red ERROR: \black Unable to locate artificial intelligence." return + else if(istype(W, /obj/item/weapon/wrench)) + if(anchored) + user.visible_message("\blue \The [user] starts to unbolt \the [src] from the plating...") + if(!do_after(user,40)) + user.visible_message("\blue \The [user] decides not to unbolt \the [src].") + return + user.visible_message("\blue \The [user] finishes unfastening \the [src]!") + anchored = 0 + return + else + user.visible_message("\blue \The [user] starts to bolt \the [src] to the plating...") + if(!do_after(user,40)) + user.visible_message("\blue \The [user] decides not to bolt \the [src].") + return + user.visible_message("\blue \The [user] finishes fastening down \the [src]!") + anchored = 1 + return + else + return ..() - ..() +/client/proc/empty_ai_core_toggle_latejoin() + set name = "Toggle AI Core Latejoin" + set category = "Admin" + + var/list/cores = list() + for(var/obj/structure/AIcore/deactivated/D in world) + cores["[D] ([D.loc.loc])"] = D + + var/id = input("Which core?", "Toggle AI Core Latejoin", null) as null|anything in cores + if(!id) return + + var/obj/structure/AIcore/deactivated/D = cores[id] + if(!D) return + + if(D in empty_playable_ai_cores) + empty_playable_ai_cores -= D + src << "\The [id] is now not available for latejoining AIs." + else + empty_playable_ai_cores += D + src << "\The [id] is now available for latejoining AIs." diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 223f9523cc..0613c6222b 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -70,25 +70,8 @@ var/laws dat += "Stored AI: [src.occupant.name]
    System integrity: [src.occupant.system_integrity()]%
    " - for (var/law in occupant.laws.ion) - if(law) - laws += "[ionnum()]: [law]
    " - - if (src.occupant.laws.zeroth) - laws += "0: [occupant.laws.zeroth]
    " - - var/number = 1 - for (var/index = 1, index <= occupant.laws.inherent.len, index++) - var/law = occupant.laws.inherent[index] - if (length(law) > 0) - laws += "[number]: [law]
    " - number++ - - for (var/index = 1, index <= occupant.laws.supplied.len, index++) - var/law = occupant.laws.supplied[index] - if (length(law) > 0) - laws += "[number]: [law]
    " - number++ + for (var/datum/ai_law/law in occupant.laws.all_laws()) + laws += "[law.get_index()]: [law.law]
    " dat += "Laws:
    [laws]
    " @@ -113,7 +96,7 @@ /obj/machinery/computer/aifixer/Topic(href, href_list) if(..()) - return + return 1 if (href_list["fix"]) src.active = 1 src.overlays += image('icons/obj/computer.dmi', "ai-fixer-on") diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 2915bf0761..d8d2a3bb0e 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -1,6 +1,6 @@ /obj/machinery/computer/arcade name = "arcade machine" - desc = "Does not support Pin ball." + desc = "Does not support pinball." icon = 'icons/obj/computer.dmi' icon_state = "arcade" circuit = "/obj/item/weapon/circuitboard/arcade" @@ -32,7 +32,10 @@ /obj/item/toy/prize/mauler = 1, /obj/item/toy/prize/odysseus = 1, /obj/item/toy/prize/phazon = 1, - /obj/item/toy/waterflower = 1 + /obj/item/toy/waterflower = 1, + /obj/random/action_figure = 1, + /obj/random/plushie = 1, + /obj/item/toy/cultsword = 1 ) /obj/machinery/computer/arcade @@ -81,7 +84,7 @@ /obj/machinery/computer/arcade/Topic(href, href_list) if(..()) - return + return 1 if (!src.blocked && !src.gameover) if (href_list["attack"]) diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index 8e978853c4..8306b3a87e 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -1,116 +1,85 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 -// Converting these to global lists may be a bit laggy when removal procs are called. Consider -// rewriting this properly to fix the update bug, rather than unifying all monitors. ~Z - var/global/list/priority_air_alarms = list() var/global/list/minor_air_alarms = list() + /obj/machinery/computer/atmos_alert name = "atmospheric alert computer" desc = "Used to access the station's atmospheric sensors." circuit = "/obj/item/weapon/circuitboard/atmos_alert" icon_state = "alert:0" - var/receive_frequency = 1437 - var/datum/radio_frequency/radio_connection - -/obj/machinery/computer/atmos_alert/initialize() +/obj/machinery/computer/atmos_alert/New() ..() - set_frequency(receive_frequency) - -/obj/machinery/computer/atmos_alert/receive_signal(datum/signal/signal) - if(!signal || signal.encryption) return - - var/zone = signal.data["zone"] - var/severity = signal.data["alert"] - - if(!zone || !severity) return - - minor_air_alarms -= zone - priority_air_alarms -= zone - if(severity=="severe") - priority_air_alarms |= zone - else if (severity=="minor") - minor_air_alarms |= zone - update_icon() - return - - -/obj/machinery/computer/atmos_alert/proc/set_frequency(new_frequency) - radio_controller.remove_object(src, receive_frequency) - receive_frequency = new_frequency - radio_connection = radio_controller.add_object(src, receive_frequency, RADIO_ATMOSIA) - + atmosphere_alarm.register(src, /obj/machinery/computer/station_alert/update_icon) + +/obj/machinery/computer/atmos_alert/Del() + atmosphere_alarm.unregister(src) + ..() /obj/machinery/computer/atmos_alert/attack_hand(mob/user) - if(..(user)) - return - user << browse(return_text(),"window=computer") - user.set_machine(src) - onclose(user, "computer") + ui_interact(user) -/obj/machinery/computer/atmos_alert/process() - if(..()) - src.updateDialog() +/obj/machinery/computer/atmos_alert/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + var/major_alarms[0] + var/minor_alarms[0] + + for(var/datum/alarm/alarm in atmosphere_alarm.major_alarms()) + major_alarms[++major_alarms.len] = list("name" = sanitize(alarm.alarm_name()), "ref" = "\ref[alarm]") + + for(var/datum/alarm/alarm in atmosphere_alarm.minor_alarms()) + minor_alarms[++minor_alarms.len] = list("name" = sanitize(alarm.alarm_name()), "ref" = "\ref[alarm]") + + data["priority_alarms"] = major_alarms + data["minor_alarms"] = minor_alarms + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "atmos_alert.tmpl", src.name, 500, 500) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) /obj/machinery/computer/atmos_alert/update_icon() ..() if(stat & (NOPOWER|BROKEN)) return - if(priority_air_alarms.len) + var/list/alarms = atmosphere_alarm.major_alarms() + if(alarms.len) icon_state = "alert:2" - - else if(minor_air_alarms.len) - icon_state = "alert:1" - else - icon_state = "alert:0" + alarms = atmosphere_alarm.minor_alarms() + if(alarms.len) + icon_state = "alert:1" + else + icon_state = initial(icon_state) return - -/obj/machinery/computer/atmos_alert/proc/return_text() - var/priority_text - var/minor_text - - if(priority_air_alarms.len) - for(var/zone in priority_air_alarms) - priority_text += "[zone]
    X
    " - else - priority_text = "No priority alerts detected.
    " - - if(minor_air_alarms.len) - for(var/zone in minor_air_alarms) - minor_text += "[zone] X
    " - else - minor_text = "No minor alerts detected.
    " - - var/output = {"[name]
    -Priority Alerts:
    -[priority_text] -
    -
    -Minor Alerts:
    -[minor_text] -
    "} - - return output - - /obj/machinery/computer/atmos_alert/Topic(href, href_list) if(..()) - return + return 1 - if(href_list["priority_clear"]) - var/removing_zone = href_list["priority_clear"] - for(var/zone in priority_air_alarms) - if(ckey(zone) == removing_zone) - priority_air_alarms -= zone + if(href_list["clear_alarm"]) + var/datum/alarm/alarm = locate(href_list["clear_alarm"]) in atmosphere_alarm.alarms + if(alarm) + for(var/datum/alarm_source/alarm_source in alarm.sources) + var/obj/machinery/alarm/air_alarm = alarm_source.source + if(istype(air_alarm)) + var/list/new_ref = list("atmos_reset" = 1) + air_alarm.Topic(href, new_ref, custom_state = atmos_alert_topic) + return 1 - if(href_list["minor_clear"]) - var/removing_zone = href_list["minor_clear"] - for(var/zone in minor_air_alarms) - if(ckey(zone) == removing_zone) - minor_air_alarms -= zone - update_icon() - return + +var/datum/topic_state/atmos_alert/atmos_alert_topic = new() + +/datum/topic_state/atmos_alert + flags = NANO_IGNORE_DISTANCE + +/datum/topic_state/air_alarm/href_list(var/mob/user) + var/list/extra_href = list() + extra_href["remote_connection"] = 1 + extra_href["remote_access"] = 1 + + return extra_href diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index a722131102..d63259bc4c 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -9,11 +9,11 @@ density = 1 anchored = 1.0 circuit = "/obj/item/weapon/circuitboard/atmoscontrol" - var/obj/machinery/alarm/current var/overridden = 0 //not set yet, can't think of a good way to do it req_access = list(access_ce) var/list/monitored_alarm_ids = null var/list/monitored_alarms = null + var/ui_ref /obj/machinery/computer/atmoscontrol/laptop name = "Atmospherics Laptop" @@ -32,36 +32,29 @@ monitored_alarms = dd_sortedObjectList(monitored_alarms) /obj/machinery/computer/atmoscontrol/attack_ai(var/mob/user as mob) - return interact(user) + return ui_interact(user) /obj/machinery/computer/atmoscontrol/attack_hand(mob/user) if(..()) return - return interact(user) + return ui_interact(user) -/obj/machinery/computer/atmoscontrol/interact(mob/user) - user.set_machine(src) - if(allowed(user)) - overridden = 1 - else if(!emagged) - overridden = 0 - var/dat = "Main Menu
    " - if(monitored_alarms && monitored_alarms.len == 1) - current = monitored_alarms[1] - if(current) - dat += specific() - else - for(var/obj/machinery/alarm/alarm in monitored_alarms ? monitored_alarms : machines) - dat += "" - switch(max(alarm.danger_level, alarm.alarm_area.atmosalm)) - if (0) - dat += "" - if (1) - dat += "" - if (2) - dat += "" - dat += "[sanitize(alarm.name)]
    " - user << browse(dat, "window=atmoscontrol") +/obj/machinery/computer/atmoscontrol/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + var/alarms[0] + + // TODO: Move these to a cache, similar to cameras + for(var/obj/machinery/alarm/alarm in (monitored_alarms ? monitored_alarms : machines)) + alarms[++alarms.len] = list("name" = sanitize(alarm.name), "ref"= "\ref[alarm]", "danger" = max(alarm.danger_level, alarm.alarm_area.atmosalm)) + data["alarms"] = alarms + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "atmos_control.tmpl", src.name, 625, 625) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + ui_ref = ui /obj/machinery/computer/atmoscontrol/attackby(var/obj/item/I as obj, var/mob/user as mob) if(istype(I, /obj/item/weapon/card/emag) && !emagged) @@ -73,23 +66,33 @@ return return ..() -/obj/machinery/computer/atmoscontrol/proc/specific() - if(!current) - return "" - var/dat = "

    [current.name]


    " - dat += current.return_status() - if(current.remote_control || overridden) - dat += "
    [current.return_controls(src)]" - return dat - //a bunch of this is copied from atmos alarms /obj/machinery/computer/atmoscontrol/Topic(href, href_list) if(..()) - return - if(href_list["reset"]) - current = null + return 1 + if(href_list["alarm"]) - current = locate(href_list["alarm"]) - else if(current) - current.Topic(href, href_list, 1, 1) - interact(usr) + if(ui_ref) + var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms ? monitored_alarms : machines) + if(alarm) + var/datum/topic_state/TS = generate_state(alarm) + alarm.ui_interact(usr, master_ui = ui_ref, custom_state = TS) + return 1 + +/obj/machinery/computer/atmoscontrol/proc/generate_state(var/alarm) + var/datum/topic_state/air_alarm/state = new() + state.atmos_control = src + state.air_alarm = alarm + return state + +/datum/topic_state/air_alarm + flags = NANO_IGNORE_DISTANCE + var/obj/machinery/computer/atmoscontrol/atmos_control = null + var/obj/machinery/alarm/air_alarm = null + +/datum/topic_state/air_alarm/href_list(var/mob/user) + var/list/extra_href = list() + extra_href["remote_connection"] = 1 + extra_href["remote_access"] = user && (user.isAI() || atmos_control.allowed(user) || atmos_control.emagged || air_alarm.rcon_setting == RCON_YES || (air_alarm.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO)) + + return extra_href diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index bb2d342bfc..8cb58a14cb 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -3,6 +3,8 @@ /proc/invalidateCameraCache() for(var/obj/machinery/computer/security/s in world) s.camera_cache = null + for(var/datum/alarm/A in world) + A.cameras = null /obj/machinery/computer/security name = "security camera monitor" @@ -15,7 +17,6 @@ circuit = /obj/item/weapon/circuitboard/security var/camera_cache = null - attack_ai(var/mob/user as mob) return attack_hand(user) @@ -23,7 +24,7 @@ if (user.stat || ((get_dist(user, src) > 1 || !( user.canmove ) || user.blinded) && !istype(user, /mob/living/silicon))) //user can't see - not sure why canmove is here. return null if ( !current || !current.can_use() ) //camera doesn't work - current = null + reset_current() user.reset_view(current) return 1 @@ -44,33 +45,17 @@ if(!can_access_camera(C)) continue - var/cam[0] - cam["name"] = sanitize(C.c_tag) - cam["deact"] = !C.can_use() - cam["camera"] = "\ref[C]" - cam["x"] = C.x - cam["y"] = C.y - cam["z"] = C.z - + var/cam = C.nano_structure() cameras[++cameras.len] = cam if(C == current) data["current"] = cam - var/list/camera_list = list("cameras" = cameras) - camera_cache=list2json(camera_list) - + var/list/camera_list = list("cameras" = cameras) + camera_cache=list2json(camera_list) else if(current) - var/cam[0] - cam["name"] = current.c_tag - cam["deact"] = !current.can_use() - cam["camera"] = "\ref[current]" - cam["x"] = current.x - cam["y"] = current.y - cam["z"] = current.z - - data["current"] = cam + data["current"] = current.nano_structure() if(ui) @@ -102,7 +87,7 @@ else if(href_list["reset"]) if(src.z>6 || stat&(NOPOWER|BROKEN)) return if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return - current = null + reset_current() usr.check_eye(current) return 1 else @@ -128,13 +113,17 @@ //don't need to check if the camera works for AI because the AI jumps to the camera location and doesn't actually look through cameras. if(isAI(user)) var/mob/living/silicon/ai/A = user + // Only allow non-carded AIs to view because the interaction with the eye gets all wonky otherwise. + if(!A.is_in_chassis()) + return 0 + A.eyeobj.setLoc(get_turf(C)) A.client.eye = A.eyeobj return 1 if (!C.can_use() || user.stat || (get_dist(user, src) > 1 || user.machine != src || user.blinded || !( user.canmove ) && !istype(user, /mob/living/silicon))) return 0 - src.current = C + set_current(C) check_eye(user) use_power(50) return 1 @@ -168,6 +157,27 @@ return if(can_access_camera(jump_to)) switch_to_camera(user,jump_to) + +/obj/machinery/computer/security/proc/set_current(var/obj/machinery/camera/C) + if(current == C) + return + + if(current) + reset_current() + + src.current = C + if(current) + var/mob/living/L = current.loc + if(istype(L)) + L.tracking_initiated() + +/obj/machinery/computer/security/proc/reset_current() + if(current) + var/mob/living/L = current.loc + if(istype(L)) + L.tracking_cancelled() + current = null + //Camera control: mouse. /atom/DblClick() ..() diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index be5a73d90f..4e97506088 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -191,7 +191,7 @@ if (is_authenticated() && modify) var/t1 = href_list["assign_target"] if(t1 == "Custom") - var/temp_t = sanitize(copytext(input("Enter a custom job assignment.","Assignment"),1,45)) + var/temp_t = sanitize(input("Enter a custom job assignment.","Assignment"), 45) //let custom jobs function as an impromptu alt title, mainly for sechuds if(temp_t && modify) modify.assignment = temp_t @@ -222,7 +222,7 @@ if (is_authenticated()) var/t2 = modify if ((modify == t2 && (in_range(src, usr) || (istype(usr, /mob/living/silicon))) && istype(loc, /turf))) - var/temp_name = reject_bad_name(href_list["reg"]) + var/temp_name = sanitizeName(href_list["reg"]) if(temp_name) modify.registered_name = temp_name else diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 484f39df25..fd8386a7f8 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -5,7 +5,7 @@ circuit = "/obj/item/weapon/circuitboard/cloning" req_access = list(access_heads) //Only used for record deletion right now. var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning. - var/obj/machinery/clonepod/pod1 = null //Linked cloning pod. + var/list/pods = list() //Linked cloning pods. var/temp = "" var/scantemp = "Scanner unoccupied" var/menu = 1 //Which menu screen to display @@ -23,38 +23,35 @@ /obj/machinery/computer/cloning/proc/updatemodules() src.scanner = findscanner() - src.pod1 = findcloner() - - if (!isnull(src.pod1)) - src.pod1.connected = src // Some variable the pod needs + findcloner() + var/num = 1 + for (var/obj/machinery/clonepod/pod in pods) + pod.connected = src + pod.name = "[initial(pod.name)] #[num++]" /obj/machinery/computer/cloning/proc/findscanner() var/obj/machinery/dna_scannernew/scannerf = null - // Loop through every direction + //Try to find scanner on adjacent tiles first for(dir in list(NORTH,EAST,SOUTH,WEST)) - - // Try to find a scanner in that direction scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, dir)) + if (scannerf) + return scannerf - // If found, then we break, and return the scanner - if (!isnull(scannerf)) - break + //Then look for a free one in the area + if(!scannerf) + for(var/obj/machinery/dna_scannernew/S in get_area(src)) + return S - // If no scanner was found, it will return null - return scannerf + return /obj/machinery/computer/cloning/proc/findcloner() - var/obj/machinery/clonepod/podf = null + pods.Cut() + for(var/obj/machinery/clonepod/P in get_area(src)) + if(!P.connected) + pods += P - for(dir in list(NORTH,EAST,SOUTH,WEST)) - - podf = locate(/obj/machinery/clonepod, get_step(src, dir)) - - if (!isnull(podf)) - break - - return podf + return /obj/machinery/computer/cloning/attackby(obj/item/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES @@ -65,6 +62,14 @@ user << "You insert [W]." src.updateUsrDialog() return + else if(istype(W, /obj/item/device/multitool)) + var/obj/item/device/multitool/M = W + var/obj/machinery/clonepod/P = M.connecting + if(P && !(P in pods)) + pods += P + P.connected = src + P.name = "[initial(P.name)] #[pods.len]" + user << "You connect [P] to [src]." else ..() return @@ -92,13 +97,13 @@ dat += "

    Modules

    " //dat += "Reload Modules" if (isnull(src.scanner)) - dat += " Scanner-ERROR
    " + dat += " DNA scanner not found.
    " else - dat += " Scanner-Found!
    " - if (isnull(src.pod1)) - dat += " Pod-ERROR
    " + dat += " DNA scanner found.
    " + if (pods.len) + dat += " [pods.len] cloning vat\s found.
    " else - dat += " Pod-Found!
    " + dat += " No cloning vats found.
    " // Scanner dat += "

    Scanner Functions

    " @@ -120,8 +125,9 @@ dat += "Lock status: [src.scanner.locked ? "Locked" : "Unlocked"]
    " - if (!isnull(src.pod1)) - dat += "Biomass: [src.pod1.biomass]
    " + if (pods.len) + for (var/obj/machinery/clonepod/pod in pods) + dat += "[pod] biomass: [pod.biomass]
    " // Database dat += "

    Database Functions

    " @@ -167,10 +173,8 @@ dat += {"UI: [src.active_record.dna.uni_identity]
    SE: [src.active_record.dna.struc_enzymes]

    "} - if(pod1 && pod1.biomass >= CLONE_BIOMASS) + if(pods.len) dat += {"Clone
    "} - else - dat += {"Insufficient biomass
    "} if(4) if (!src.active_record) @@ -188,7 +192,7 @@ /obj/machinery/computer/cloning/Topic(href, href_list) if(..()) - return + return 1 if(loading) return @@ -291,34 +295,38 @@ //Look for that player! They better be dead! if(istype(C)) //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. - if(!pod1) - temp = "Error: No Clonepod detected." - else if(pod1.occupant) - temp = "Error: Clonepod is currently occupied." - else if(pod1.biomass < CLONE_BIOMASS) - temp = "Error: Not enough biomass." - else if(pod1.mess) - temp = "Error: Clonepod malfunction." - else if(!config.revival_cloning) - temp = "Error: Unable to initiate cloning cycle." - - else if(pod1.growclone(C)) - temp = "Initiating cloning cycle..." - records.Remove(C) - del(C) - menu = 1 + if(!pods.len) + temp = "Error: No clone pods detected." else + var/obj/machinery/clonepod/pod = pods[1] + if (pods.len > 1) + pod = input(usr,"Select a cloning pod to use", "Pod selection") as anything in pods + if(pod.occupant) + temp = "Error: Clonepod is currently occupied." + else if(pod.biomass < CLONE_BIOMASS) + temp = "Error: Not enough biomass." + else if(pod.mess) + temp = "Error: Clonepod malfunction." + else if(!config.revival_cloning) + temp = "Error: Unable to initiate cloning cycle." - var/mob/selected = find_dead_player("[C.ckey]") - selected << 'sound/machines/chime.ogg' //probably not the best sound but I think it's reasonable - var/answer = alert(selected,"Do you want to return to life?","Cloning","Yes","No") - if(answer != "No" && pod1.growclone(C)) + else if(pod.growclone(C)) temp = "Initiating cloning cycle..." records.Remove(C) del(C) menu = 1 else - temp = "Initiating cloning cycle...
    Error: Post-initialisation failed. Cloning cycle aborted." + + var/mob/selected = find_dead_player("[C.ckey]") + selected << 'sound/machines/chime.ogg' //probably not the best sound but I think it's reasonable + var/answer = alert(selected,"Do you want to return to life?","Cloning","Yes","No") + if(answer != "No" && pod.growclone(C)) + temp = "Initiating cloning cycle..." + records.Remove(C) + del(C) + menu = 1 + else + temp = "Initiating cloning cycle...
    Error: Post-initialisation failed. Cloning cycle aborted." else temp = "Error: Data corruption." diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index a8403bbede..4015b907f9 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -47,7 +47,7 @@ /obj/machinery/computer/communications/Topic(href, href_list) if(..()) - return + return 1 if (src.z > 1) usr << "\red Unable to establish a connection: \black You're too far away from the station!" return @@ -175,10 +175,10 @@ post_status(href_list["statdisp"]) if("setmsg1") - stat_msg1 = reject_bad_text(trim(sanitize(copytext(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 1, 40))), 40) + stat_msg1 = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40), 40) src.updateDialog() if("setmsg2") - stat_msg2 = reject_bad_text(trim(sanitize(copytext(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 1, 40))), 40) + stat_msg2 = reject_bad_text(sanitize(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40), 40) src.updateDialog() // OMG CENTCOMM LETTERHEAD @@ -187,7 +187,7 @@ if(centcomm_message_cooldown) usr << "\red Arrays recycling. Please stand by." return - var/input = stripped_input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "") + var/input = sanitize(input("Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "")) if(!input || !(usr in view(1,src))) return Centcomm_announce(input, usr) @@ -204,7 +204,7 @@ if(centcomm_message_cooldown) usr << "\red Arrays recycling. Please stand by." return - var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "") + var/input = sanitize(input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "")) if(!input || !(usr in view(1,src))) return Syndicate_announce(input, usr) @@ -430,7 +430,7 @@ if ((!( ticker ) || !emergency_shuttle.location())) return - if(sent_strike_team == 1) + if(deathsquad.deployed) user << "Centcom will not allow the shuttle to be called. Consider all contracts terminated." return @@ -479,7 +479,7 @@ user << "Centcom does not currently have a shuttle available in your sector. Please try again later." return - if(sent_strike_team == 1) + if(deathsquad.deployed == 1) user << "Centcom will not allow the shuttle to be called. Consider all contracts terminated." return @@ -487,7 +487,7 @@ user << "The shuttle is refueling. Please wait another [round((54000-world.time)/60)] minutes before trying again." return - if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction" || ticker.mode.name == "sandbox") + if(ticker.mode.auto_recall_shuttle) //New version pretends to call the shuttle but cause the shuttle to return after a random duration. emergency_shuttle.auto_recall = 1 @@ -510,7 +510,7 @@ /proc/cancel_call_proc(var/mob/user) if (!( ticker ) || !emergency_shuttle.can_recall()) return - if((ticker.mode.name == "blob")||(ticker.mode.name == "meteor")) + if((ticker.mode.name == "blob")||(ticker.mode.name == "Meteor")) return if(!emergency_shuttle.going_to_centcom()) //check that shuttle isn't already heading to centcomm @@ -556,7 +556,7 @@ if(!shuttlecaller.stat && shuttlecaller.client && istype(shuttlecaller.loc,/turf)) return ..() - if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction" || sent_strike_team) + if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction" || deathsquad.deployed) return ..() emergency_shuttle.call_evac() @@ -579,7 +579,7 @@ if(!shuttlecaller.stat && shuttlecaller.client && istype(shuttlecaller.loc,/turf)) return ..() - if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction" || sent_strike_team) + if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction" || deathsquad.deployed) return ..() emergency_shuttle.call_evac() diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index ff88f89c5a..304ac7d1af 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -101,6 +101,14 @@ return text +/obj/machinery/computer/attack_ghost(user as mob) + return src.attack_hand(user) + +/obj/machinery/computer/attack_hand(user as mob) + /* Observers can view computers, but not actually use them via Topic*/ + if(istype(user, /mob/dead/observer)) return 0 + return ..() + /obj/machinery/computer/attackby(I as obj, user as mob) if(istype(I, /obj/item/weapon/screwdriver) && circuit) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index 06fd906ea8..b5394328b8 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -6,11 +6,10 @@ idle_power_usage = 250 active_power_usage = 500 circuit = "/obj/item/weapon/circuitboard/crew" - var/list/tracked = list( ) - + var/obj/nano_module/crew_monitor/crew_monitor /obj/machinery/computer/crew/New() - tracked = list() + crew_monitor = new(src) ..() @@ -25,6 +24,8 @@ return ui_interact(user) +/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + crew_monitor.ui_interact(user, ui_key, ui, force_open) /obj/machinery/computer/crew/update_icon() @@ -38,93 +39,5 @@ icon_state = initial(icon_state) stat &= ~NOPOWER - -/obj/machinery/computer/crew/Topic(href, href_list) - if(..()) return - if (src.z > 6) - usr << "\red Unable to establish a connection: \black You're too far away from the station!" - return 0 - if( href_list["close"] ) - var/mob/user = usr - var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") - usr.unset_machine() - ui.close() - return 0 - if(href_list["update"]) - src.updateDialog() - return 1 - /obj/machinery/computer/crew/interact(mob/user) - ui_interact(user) - -/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - if(stat & (BROKEN|NOPOWER)) - return - user.set_machine(src) - src.scan() - - var/data[0] - var/list/crewmembers = list() - - for(var/obj/item/clothing/under/C in src.tracked) - - var/turf/pos = get_turf(C) - - if((C) && (C.has_sensor) && (pos) && (pos.z == src.z) && (C.sensor_mode != SUIT_SENSOR_OFF)) - if(istype(C.loc, /mob/living/carbon/human)) - - var/mob/living/carbon/human/H = C.loc - if(H.w_uniform != C) - continue - - var/list/crewmemberData = list("dead"=0, "oxy"=-1, "tox"=-1, "fire"=-1, "brute"=-1, "area"="", "x"=-1, "y"=-1) - - crewmemberData["sensor_type"] = C.sensor_mode - crewmemberData["name"] = H.get_authentification_name(if_no_id="Unknown") - crewmemberData["rank"] = H.get_authentification_rank(if_no_id="Unknown", if_no_job="No Job") - crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job") - - if(C.sensor_mode >= SUIT_SENSOR_BINARY) - crewmemberData["dead"] = H.stat > 1 - - if(C.sensor_mode >= SUIT_SENSOR_VITAL) - crewmemberData["oxy"] = round(H.getOxyLoss(), 1) - crewmemberData["tox"] = round(H.getToxLoss(), 1) - crewmemberData["fire"] = round(H.getFireLoss(), 1) - crewmemberData["brute"] = round(H.getBruteLoss(), 1) - - if(C.sensor_mode >= SUIT_SENSOR_TRACKING) - var/area/A = get_area(H) - crewmemberData["area"] = sanitize(A.name) - crewmemberData["x"] = pos.x - crewmemberData["y"] = pos.y - - crewmembers[++crewmembers.len] = crewmemberData - - crewmembers = sortByKey(crewmembers, "name") - - data["crewmembers"] = crewmembers - - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800) - - // adding a template with the key "mapContent" enables the map ui functionality - ui.add_template("mapContent", "crew_monitor_map_content.tmpl") - // adding a template with the key "mapHeader" replaces the map header content - ui.add_template("mapHeader", "crew_monitor_map_header.tmpl") - - ui.set_initial_data(data) - ui.open() - - // should make the UI auto-update; doesn't seem to? - ui.set_auto_update(1) - - -/obj/machinery/computer/crew/proc/scan() - for(var/mob/living/carbon/human/H in mob_list) - if(istype(H.w_uniform, /obj/item/clothing/under)) - var/obj/item/clothing/under/C = H.w_uniform - if (C.has_sensor) - tracked |= C - return 1 + crew_monitor.ui_interact(user) diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index 7b524fe989..40fc0b9914 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -106,7 +106,7 @@ /obj/machinery/computer/guestpass/Topic(href, href_list) if(..()) - return + return 1 usr.set_machine(src) if (href_list["mode"]) mode = text2num(href_list["mode"]) @@ -114,11 +114,11 @@ if (href_list["choice"]) switch(href_list["choice"]) if ("giv_name") - var/nam = strip_html_simple(input("Person pass is issued to", "Name", giv_name) as text|null) + var/nam = sanitize(input("Person pass is issued to", "Name", giv_name) as text|null) if (nam) giv_name = nam if ("reason") - var/reas = strip_html_simple(input("Reason why pass is issued", "Reason", reason) as text|null) + var/reas = sanitize(input("Reason why pass is issued", "Reason", reason) as text|null) if(reas) reason = reas if ("duration") diff --git a/code/game/machinery/computer/hologram.dm b/code/game/machinery/computer/hologram.dm deleted file mode 100644 index e0ceb33c17..0000000000 --- a/code/game/machinery/computer/hologram.dm +++ /dev/null @@ -1,109 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 - -/obj/machinery/computer/hologram_comp - name = "hologram computer" - desc = "Rumoured to control holograms." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "holo_console0" - var/obj/machinery/hologram/projector/projector = null - var/temp = null - var/lumens = 0.0 - var/h_r = 245.0 - var/h_g = 245.0 - var/h_b = 245.0 - - -/obj/machinery/computer/hologram_comp/New() - ..() - spawn( 10 ) - src.projector = locate(/obj/machinery/hologram/projector, get_step(src.loc, NORTH)) - return - return - -/obj/machinery/computer/hologram_comp/DblClick() - if (!in_range(src, usr)) - return 0 - src.show_console(usr) - return - -/obj/machinery/computer/hologram_comp/proc/render() - var/icon/I = new /icon('icons/mob/human.dmi', "body_m_s") - - if (src.lumens >= 0) - I.Blend(rgb(src.lumens, src.lumens, src.lumens), ICON_ADD) - else - I.Blend(rgb(- src.lumens, -src.lumens, -src.lumens), ICON_SUBTRACT) - - I.Blend(new /icon('icons/mob/human.dmi', "mouth_m_s"), ICON_OVERLAY) - I.Blend(new /icon('icons/mob/human.dmi', "underwear1_m_s"), ICON_OVERLAY) - - var/icon/U = new /icon('icons/mob/human_face.dmi', "hair_a_s") - U.Blend(rgb(src.h_r, src.h_g, src.h_b), ICON_ADD) - - I.Blend(U, ICON_OVERLAY) - - src.projector.hologram.icon = I - -/obj/machinery/computer/hologram_comp/proc/show_console(var/mob/user as mob) - var/dat - user.set_machine(src) - if (src.temp) - dat = text("[]

    Clear", src.temp, src) - else - dat = text("Hologram Status:
    \nPower: []
    \nHologram Control:
    \nColor Luminosity: []/220 \[Reset\]
    \nLighten: 1 10
    \nDarken: 1 10
    \n
    \nHair Color: ([],[],[]) \[Reset\]
    \nRed (0-255): \[0\] -10 -1 [] 1 10 \[255\]
    \nGreen (0-255): \[0\] -10 -1 [] 1 10 \[255\]
    \nBlue (0-255): \[0\] -10 -1 [] 1 10 \[255\]
    ", src, (src.projector.hologram ? "On" : "Off"), -src.lumens + 35, src, src, src, src, src, src.h_r, src.h_g, src.h_b, src, src, src, src, src.h_r, src, src, src, src, src, src, src.h_g, src, src, src, src, src, src, src.h_b, src, src, src) - user << browse(dat, "window=hologram_console") - onclose(user, "hologram_console") - return - -/obj/machinery/computer/hologram_comp/Topic(href, href_list) - if(..()) - return - if (in_range(src, usr)) - flick("holo_console1", src) - if (href_list["power"]) - if (src.projector.hologram) - src.projector.icon_state = "hologram0" - //src.projector.hologram = null - del(src.projector.hologram) - else - src.projector.hologram = new(src.projector.loc) - src.projector.hologram.icon = 'icons/mob/human.dmi' - src.projector.hologram.icon_state = "body_m_s" - src.projector.icon_state = "hologram1" - src.render() - else - if (href_list["h_r"]) - if (src.projector.hologram) - src.h_r += text2num(href_list["h_r"]) - src.h_r = min(max(src.h_r, 0), 255) - render() - else - if (href_list["h_g"]) - if (src.projector.hologram) - src.h_g += text2num(href_list["h_g"]) - src.h_g = min(max(src.h_g, 0), 255) - render() - else - if (href_list["h_b"]) - if (src.projector.hologram) - src.h_b += text2num(href_list["h_b"]) - src.h_b = min(max(src.h_b, 0), 255) - render() - else - if (href_list["light"]) - if (src.projector.hologram) - src.lumens += text2num(href_list["light"]) - src.lumens = min(max(src.lumens, -185.0), 35) - render() - else - if (href_list["reset"]) - if (src.projector.hologram) - src.lumens = 0 - render() - else - if (href_list["temp"]) - src.temp = null - for(var/mob/M in viewers(1, src)) - if ((M.client && M.machine == src)) - src.show_console(M) - return diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm index 5c970f9d67..2d73e17da8 100644 --- a/code/game/machinery/computer/law.dm +++ b/code/game/machinery/computer/law.dm @@ -50,7 +50,9 @@ else usr << "[src.current.name] selected for law changes." return - + + attack_ghost(user as mob) + return 1 /obj/machinery/computer/borgupload @@ -83,3 +85,6 @@ else usr << "[src.current.name] selected for law changes." return + + attack_ghost(user as mob) + return 1 diff --git a/code/game/machinery/computer/lockdown.dm b/code/game/machinery/computer/lockdown.dm index bb1fff338d..c1eb5d8e06 100644 --- a/code/game/machinery/computer/lockdown.dm +++ b/code/game/machinery/computer/lockdown.dm @@ -110,7 +110,7 @@ onclose(user, "lockdown") Topic(href, href_list) - ..() + if(..()) return 1 if( href_list["close"] ) usr << browse(null, "window=lockdown") diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index b67834eb60..c6a30995d2 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -148,7 +148,7 @@ /obj/machinery/computer/med_data/Topic(href, href_list) if(..()) - return + return 1 if (!( data_core.general.Find(src.active1) )) src.active1 = null @@ -250,7 +250,7 @@ switch(href_list["field"]) if("fingerprint") if (istype(src.active1, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) return src.active1.fields["fingerprint"] = t1 @@ -268,55 +268,55 @@ src.active1.fields["age"] = t1 if("mi_dis") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["mi_dis"] = t1 if("mi_dis_d") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["mi_dis_d"] = t1 if("ma_dis") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["ma_dis"] = t1 if("ma_dis_d") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["ma_dis_d"] = t1 if("alg") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["alg"] = t1 if("alg_d") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["alg_d"] = t1 if("cdi") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["cdi"] = t1 if("cdi_d") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["cdi_d"] = t1 if("notes") if (istype(src.active2, /datum/data/record)) - var/t1 = html_encode(trim(copytext(input("Please summarize notes:", "Med. records", html_decode(src.active2.fields["notes"]), null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize notes:", "Med. records", html_decode(src.active2.fields["notes"]), null) as message, extra = 0) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["notes"] = t1 @@ -331,21 +331,21 @@ src.temp = text("Blood Type:
    \n\tA- A+
    \n\tB- B+
    \n\tAB- AB+
    \n\tO- O+
    ", src, src, src, src, src, src, src, src) if("b_dna") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input DNA hash:", "Med. records", src.active2.fields["b_dna"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input DNA hash:", "Med. records", src.active2.fields["b_dna"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["b_dna"] = t1 if("vir_name") var/datum/data/record/v = locate(href_list["edit_vir"]) if (v) - var/t1 = trim(sanitize(copytext(input("Please input pathogen name:", "VirusDB", v.fields["name"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input pathogen name:", "VirusDB", v.fields["name"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) return v.fields["name"] = t1 if("vir_desc") var/datum/data/record/v = locate(href_list["edit_vir"]) if (v) - var/t1 = trim(sanitize(copytext(input("Please input information about pathogen:", "VirusDB", v.fields["description"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input information about pathogen:", "VirusDB", v.fields["description"], null) as message) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) return v.fields["description"] = t1 @@ -450,7 +450,7 @@ if (!( istype(src.active2, /datum/data/record) )) return var/a2 = src.active2 - var/t1 = trim(sanitize(copytext(input("Add Comment:", "Med. records", null, null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Add Comment:", "Med. records", null, null) as message) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return var/counter = 1 diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index a30f355d2a..94eadf7f11 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -283,7 +283,7 @@ /obj/machinery/computer/message_monitor/Topic(href, href_list) if(..()) - return + return 1 if(stat & (NOPOWER|BROKEN)) return if(!istype(usr, /mob/living)) @@ -409,7 +409,7 @@ //Select Your Name if("Sender") - customsender = input(usr, "Please enter the sender's name.") as text|null + customsender = sanitize(input(usr, "Please enter the sender's name.") as text|null) //Select Receiver if("Recepient") @@ -425,12 +425,12 @@ //Enter custom job if("RecJob") - customjob = input(usr, "Please enter the sender's job.") as text|null + customjob = sanitize(input(usr, "Please enter the sender's job.") as text|null) //Enter message if("Message") custommessage = input(usr, "Please enter your message.") as text|null - custommessage = sanitize(copytext(custommessage, 1, MAX_MESSAGE_LEN)) + custommessage = sanitize(custommessage) //Send message if("Send") diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm index bdac56c85d..0c7830a78a 100644 --- a/code/game/machinery/computer/pod.dm +++ b/code/game/machinery/computer/pod.dm @@ -158,7 +158,7 @@ /obj/machinery/computer/pod/Topic(href, href_list) if(..()) - return + return 1 if((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) if(href_list["power"]) diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index 00e7554727..976209305a 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -90,7 +90,7 @@ usr << "Unauthorized Access." else if(href_list["warn"]) - var/warning = sanitize(copytext(input(usr,"Message:","Enter your message here!",""),1,MAX_MESSAGE_LEN)) + var/warning = sanitize(input(usr,"Message:","Enter your message here!","")) if(!warning) return var/obj/item/weapon/implant/I = locate(href_list["warn"]) if((I)&&(I.imp_in)) diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index b429c70306..41d73ee2ae 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -98,7 +98,7 @@ /obj/machinery/computer/robotics/Topic(href, href_list) if(..()) - return + return 1 if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 58924ed707..c05f0f78be 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -208,7 +208,7 @@ I can't be bothered to look more of the actual code outside of switch but that p What a mess.*/ /obj/machinery/computer/secure_data/Topic(href, href_list) if(..()) - return + return 1 if (!( data_core.general.Find(active1) )) active1 = null if (!( data_core.security.Find(active2) )) @@ -384,7 +384,7 @@ What a mess.*/ if (!( istype(active2, /datum/data/record) )) return var/a2 = active2 - var/t1 = trim(sanitize(copytext(input("Add Comment:", "Secure. records", null, null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Add Comment:", "Secure. records", null, null) as message) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return var/counter = 1 @@ -426,19 +426,19 @@ What a mess.*/ switch(href_list["field"]) if("name") if (istype(active1, /datum/data/record)) - var/t1 = reject_bad_name(input("Please input name:", "Secure. records", active1.fields["name"], null) as text) + var/t1 = sanitizeName(input("Please input name:", "Secure. records", active1.fields["name"], null) as text) if (!t1 || active1 != a1) return active1.fields["name"] = t1 if("id") if (istype(active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input id:", "Secure. records", active1.fields["id"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text) if (!t1 || active1 != a1) return active1.fields["id"] = t1 if("fingerprint") if (istype(active1, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text) if (!t1 || active1 != a1) return active1.fields["fingerprint"] = t1 @@ -456,31 +456,31 @@ What a mess.*/ active1.fields["age"] = t1 if("mi_crim") if (istype(active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input minor disabilities list:", "Secure. records", active2.fields["mi_crim"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input minor disabilities list:", "Secure. records", active2.fields["mi_crim"], null) as text) if (!t1 || active2 != a2) return active2.fields["mi_crim"] = t1 if("mi_crim_d") if (istype(active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message) if (!t1 || active2 != a2) return active2.fields["mi_crim_d"] = t1 if("ma_crim") if (istype(active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input major diabilities list:", "Secure. records", active2.fields["ma_crim"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input major diabilities list:", "Secure. records", active2.fields["ma_crim"], null) as text) if (!t1 || active2 != a2) return active2.fields["ma_crim"] = t1 if("ma_crim_d") if (istype(active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please summarize major dis.:", "Secure. records", active2.fields["ma_crim_d"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize major dis.:", "Secure. records", active2.fields["ma_crim_d"], null) as message) if (!t1 || active2 != a2) return active2.fields["ma_crim_d"] = t1 if("notes") if (istype(active2, /datum/data/record)) - var/t1 = html_encode(trim(copytext(input("Please summarize notes:", "Secure. records", html_decode(active2.fields["notes"]), null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize notes:", "Secure. records", html_decode(active2.fields["notes"]), null) as message, extra = 0) if (!t1 || active2 != a2) return active2.fields["notes"] = t1 @@ -507,7 +507,7 @@ What a mess.*/ alert(usr, "You do not have the required rank to do this!") if("species") if (istype(active1, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please enter race:", "General records", active1.fields["species"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message) if (!t1 || active1 != a1) return active1.fields["species"] = t1 @@ -534,7 +534,7 @@ What a mess.*/ if ("Change Criminal Status") if (active2) for(var/mob/living/carbon/human/H in player_list) - H.hud_updateflag |= 1 << WANTED_HUD + BITSET(H.hud_updateflag, WANTED_HUD) switch(href_list["criminal2"]) if("none") active2.fields["criminal"] = "None" @@ -612,4 +612,4 @@ What a mess.*/ /obj/machinery/computer/secure_data/detective_computer icon = 'icons/obj/computer.dmi' - icon_state = "messyfiles" \ No newline at end of file + icon_state = "messyfiles" diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm index 8382f87185..aa92a59094 100644 --- a/code/game/machinery/computer/skills.dm +++ b/code/game/machinery/computer/skills.dm @@ -148,7 +148,7 @@ I can't be bothered to look more of the actual code outside of switch but that p What a mess.*/ /obj/machinery/computer/skills/Topic(href, href_list) if(..()) - return + return 1 if (!( data_core.general.Find(active1) )) active1 = null if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) @@ -309,19 +309,19 @@ What a mess.*/ switch(href_list["field"]) if("name") if (istype(active1, /datum/data/record)) - var/t1 = reject_bad_name(input("Please input name:", "Secure. records", active1.fields["name"], null) as text) + var/t1 = sanitizeName(input("Please input name:", "Secure. records", active1.fields["name"], null) as text) if ((!( t1 ) || !length(trim(t1)) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon)))) || active1 != a1) return active1.fields["name"] = t1 if("id") if (istype(active1, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input id:", "Secure. records", active1.fields["id"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1)) return active1.fields["id"] = t1 if("fingerprint") if (istype(active1, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1)) return active1.fields["fingerprint"] = t1 @@ -350,7 +350,7 @@ What a mess.*/ alert(usr, "You do not have the required rank to do this!") if("species") if (istype(active1, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please enter race:", "General records", active1.fields["species"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!istype(usr, /mob/living/silicon))) || active1 != a1)) return active1.fields["species"] = t1 diff --git a/code/game/machinery/computer/specops_shuttle.dm b/code/game/machinery/computer/specops_shuttle.dm index a76a19ddd7..01728b4e50 100644 --- a/code/game/machinery/computer/specops_shuttle.dm +++ b/code/game/machinery/computer/specops_shuttle.dm @@ -259,11 +259,6 @@ var/specops_shuttle_timeleft = 0 user << "\red Access Denied." return -//Commented out so admins can do shenanigans at their leisure. Also makes the force-spawned admin ERTs able to use the shuttle. -// if (sent_strike_team == 0 && send_emergency_team == 0) -// usr << "\red The strike team has not yet deployed." -// return - if(..()) return @@ -283,7 +278,7 @@ var/specops_shuttle_timeleft = 0 /obj/machinery/computer/specops_shuttle/Topic(href, href_list) if(..()) - return + return 1 if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.machine = src @@ -336,247 +331,3 @@ var/specops_shuttle_timeleft = 0 add_fingerprint(usr) updateUsrDialog() return - -/*//Config stuff -#define SPECOPS_MOVETIME 600 //Time to station is milliseconds. 60 seconds, enough time for everyone to be on the shuttle before it leaves. -#define SPECOPS_STATION_AREATYPE "/area/shuttle/specops/station" //Type of the spec ops shuttle area for station -#define SPECOPS_DOCK_AREATYPE "/area/shuttle/specops/centcom" //Type of the spec ops shuttle area for dock - -var/specops_shuttle_moving_to_station = 0 -var/specops_shuttle_moving_to_centcom = 0 -var/specops_shuttle_at_station = 0 -var/specops_shuttle_can_send = 1 -var/specops_shuttle_time = 0 -var/specops_shuttle_timeleft = 0 - -/obj/machinery/computer/specops_shuttle - name = "Spec. Ops. Shuttle Console" - icon = 'icons/obj/computer.dmi' - icon_state = "shuttle" - req_access = list(access_cent_specops) - var/temp = null - var/hacked = 0 - var/allowedtocall = 0 - -/proc/specops_process() - var/area/centcom/control/cent_com = locate()//To find announcer. This area should exist for this proc to work. - var/area/centcom/specops/special_ops = locate()//Where is the specops area located? - var/mob/living/silicon/decoy/announcer = locate() in cent_com//We need a fake AI to announce some stuff below. Otherwise it will be wonky. - - var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values. - var/message = "THE SPECIAL OPERATIONS SHUTTLE IS PREPARING FOR LAUNCH"//Initial message shown. - if(announcer) - announcer.say(message) - message = "ARMORED SQUAD TAKE YOUR POSITION ON GRAVITY LAUNCH PAD" - announcer.say(message) - - while(specops_shuttle_time - world.timeofday > 0) - var/ticksleft = specops_shuttle_time - world.timeofday - - if(ticksleft > 1e5) - specops_shuttle_time = world.timeofday + 10 // midnight rollover - specops_shuttle_timeleft = (ticksleft / 10) - - //All this does is announce the time before launch. - if(announcer) - var/rounded_time_left = round(specops_shuttle_timeleft)//Round time so that it will report only once, not in fractions. - if(rounded_time_left in message_tracker)//If that time is in the list for message announce. - message = "ALERT: [rounded_time_left] SECOND[(rounded_time_left!=1)?"S":""] REMAIN" - if(rounded_time_left==0) - message = "ALERT: TAKEOFF" - announcer.say(message) - message_tracker -= rounded_time_left//Remove the number from the list so it won't be called again next cycle. - //Should call all the numbers but lag could mean some issues. Oh well. Not much I can do about that. - - sleep(5) - - specops_shuttle_moving_to_station = 0 - specops_shuttle_moving_to_centcom = 0 - - specops_shuttle_at_station = 1 - if (specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return - - if (!specops_can_move()) - usr << "\red The Special Operations shuttle is unable to leave." - return - - //Begin Marauder launchpad. - spawn(0)//So it parallel processes it. - for(var/obj/machinery/door/poddoor/M in special_ops) - switch(M.id) - if("ASSAULT0") - spawn(10)//1 second delay between each. - M.open() - if("ASSAULT1") - spawn(20) - M.open() - if("ASSAULT2") - spawn(30) - M.open() - if("ASSAULT3") - spawn(40) - M.open() - - sleep(10) - - var/spawn_marauder[] = new() - for(var/obj/effect/landmark/L in landmarks_list) - if(L.name == "Marauder Entry") - spawn_marauder.Add(L) - for(var/obj/effect/landmark/L in landmarks_list) - if(L.name == "Marauder Exit") - var/obj/effect/portal/P = new(L.loc) - P.invisibility = 101//So it is not seen by anyone. - P.failchance = 0//So it has no fail chance when teleporting. - P.target = pick(spawn_marauder)//Where the marauder will arrive. - spawn_marauder.Remove(P.target) - - sleep(10) - - for(var/obj/machinery/mass_driver/M in special_ops) - switch(M.id) - if("ASSAULT0") - spawn(10) - M.drive() - if("ASSAULT1") - spawn(20) - M.drive() - if("ASSAULT2") - spawn(30) - M.drive() - if("ASSAULT3") - spawn(40) - M.drive() - - sleep(50)//Doors remain open for 5 seconds. - - for(var/obj/machinery/door/poddoor/M in special_ops) - switch(M.id)//Doors close at the same time. - if("ASSAULT0") - spawn(0) - M.close() - if("ASSAULT1") - spawn(0) - M.close() - if("ASSAULT2") - spawn(0) - M.close() - if("ASSAULT3") - spawn(0) - M.close() - special_ops.readyreset()//Reset firealarm after the team launched. - //End Marauder launchpad. - - var/area/start_location = locate(/area/shuttle/specops/centcom) - var/area/end_location = locate(/area/shuttle/specops/station) - - var/list/dstturfs = list() - var/throwy = world.maxy - - for(var/turf/T in end_location) - dstturfs += T - if(T.y < throwy) - throwy = T.y - - // hey you, get out of the way! - for(var/turf/T in dstturfs) - // find the turf to move things to - var/turf/D = locate(T.x, throwy - 1, 1) - //var/turf/E = get_step(D, SOUTH) - for(var/atom/movable/AM as mob|obj in T) - AM.Move(D) - if(istype(T, /turf/simulated)) - del(T) - - start_location.move_contents_to(end_location) - - for(var/turf/T in get_area_turfs(end_location) ) - var/mob/M = locate(/mob) in T - M << "\red You have arrived to [station_name]. Commence operation!" - -/proc/specops_can_move() - if(specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return 0 - else return 1 - -/obj/machinery/computer/specops_shuttle/attackby(I as obj, user as mob) - return attack_hand(user) - -/obj/machinery/computer/specops_shuttle/attack_ai(var/mob/user as mob) - return attack_hand(user) - -/obj/machinery/computer/specops_shuttle/attack_paw(var/mob/user as mob) - return attack_hand(user) - -/obj/machinery/computer/specops_shuttle/attackby(I as obj, user as mob) - if(istype(I,/obj/item/weapon/card/emag)) - user << "\blue The electronic systems in this console are far too advanced for your primitive hacking peripherals." - else - return attack_hand(user) - -/obj/machinery/computer/specops_shuttle/attack_hand(var/mob/user as mob) - if(!allowed(user)) - user << "\red Access Denied." - return - -// if (sent_strike_team == 0) -// usr << "\red The strike team has not yet deployed." -// return - - if(..()) - return - - user.set_machine(src) - var/dat - if (temp) - dat = temp - else - dat += {"
    Special Operations Shuttle
    - \nLocation: [specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom ? "Departing for [station_name] in ([specops_shuttle_timeleft] seconds.)":specops_shuttle_at_station ? "Station":"Dock"]
    - [specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom ? "\n*The Special Ops. shuttle is already leaving.*
    \n
    ":specops_shuttle_at_station ? "\nShuttle Offline
    \n
    ":"\nDepart to [station_name]
    \n
    "] - \nClose"} - - user << browse(dat, "window=computer;size=575x450") - onclose(user, "computer") - return - -/obj/machinery/computer/specops_shuttle/Topic(href, href_list) - if(..()) - return - - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) - usr.set_machine(src) - - if (href_list["sendtodock"]) - if(!specops_shuttle_at_station|| specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return - - usr << "\blue Central Command will not allow the Special Operations shuttle to return." - return - - else if (href_list["sendtostation"]) - if(specops_shuttle_at_station || specops_shuttle_moving_to_station || specops_shuttle_moving_to_centcom) return - - if (!specops_can_move()) - usr << "\red The Special Operations shuttle is unable to leave." - return - - usr << "\blue The Special Operations shuttle will arrive on [station_name] in [(SPECOPS_MOVETIME/10)] seconds." - - temp += "Shuttle departing.

    OK" - updateUsrDialog() - - var/area/centcom/specops/special_ops = locate() - if(special_ops) - special_ops.readyalert()//Trigger alarm for the spec ops area. - specops_shuttle_moving_to_station = 1 - - specops_shuttle_time = world.timeofday + SPECOPS_MOVETIME - spawn(0) - specops_process() - - else if (href_list["mainmenu"]) - temp = null - - add_fingerprint(usr) - updateUsrDialog() - return - */ \ No newline at end of file diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index 028be6e3a3..ab136ca371 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -5,106 +5,42 @@ icon_state = "alert:0" circuit = "/obj/item/weapon/circuitboard/stationalert" var/alarms = list("Fire"=list(), "Atmosphere"=list(), "Power"=list()) + var/obj/nano_module/alarm_monitor/engineering/alarm_monitor +/obj/machinery/computer/station_alert/New() + alarm_monitor = new(src) + alarm_monitor.register(src, /obj/machinery/computer/station_alert/update_icon) + ..() - attack_ai(mob/user) - add_fingerprint(user) - if(stat & (BROKEN|NOPOWER)) - return - interact(user) +/obj/machinery/computer/station_alert/Del() + alarm_monitor.unregister(src) + ..() + +/obj/machinery/computer/station_alert/attack_ai(mob/user) + add_fingerprint(user) + if(stat & (BROKEN|NOPOWER)) + return + interact(user) + return + +/obj/machinery/computer/station_alert/attack_hand(mob/user) + add_fingerprint(user) + if(stat & (BROKEN|NOPOWER)) + return + interact(user) + return + +/obj/machinery/computer/station_alert/interact(mob/user) + alarm_monitor.ui_interact(user) + +/obj/machinery/computer/station_alert/update_icon() + ..() + if(stat & (BROKEN|NOPOWER)) return - - attack_hand(mob/user) - add_fingerprint(user) - if(stat & (BROKEN|NOPOWER)) - return - interact(user) - return - - - interact(mob/user) - usr.set_machine(src) - var/dat = "Current Station Alerts\n" - dat += "Close

    " - for (var/cat in src.alarms) - dat += text("[]
    \n", cat) - var/list/L = src.alarms[cat] - if (L.len) - for (var/alarm in L) - var/list/alm = L[alarm] - var/area/A = alm[1] - var/list/sources = alm[3] - dat += "" - dat += "• " - dat += "[A.name]" - if (sources.len > 1) - dat += text(" - [] sources", sources.len) - dat += "
    \n" - else - dat += "-- All Systems Nominal
    \n" - dat += "
    \n" - user << browse(dat, "window=alerts") - onclose(user, "alerts") - - - Topic(href, href_list) - if(..()) - return - return - - - proc/triggerAlarm(var/class, area/A, var/O, var/alarmsource) - if(stat & (BROKEN)) - return - var/list/L = src.alarms[class] - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] - var/list/sources = alarm[3] - if (!(alarmsource in sources)) - sources += alarmsource - return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if (O && istype(O, /list)) - CL = O - if (CL.len == 1) - C = CL[1] - else if (O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C) ? C : O, list(alarmsource)) - return 1 - - - proc/cancelAlarm(var/class, area/A as area, obj/origin) - if(stat & (BROKEN)) - return - var/list/L = src.alarms[class] - var/cleared = 0 - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] - var/list/srcs = alarm[3] - if (origin in srcs) - srcs -= origin - if (srcs.len == 0) - cleared = 1 - L -= I - return !cleared - - - process() - if(stat & (BROKEN|NOPOWER)) - icon_state = "atmos0" - return - var/active_alarms = 0 - for (var/cat in src.alarms) - var/list/L = src.alarms[cat] - if(L.len) active_alarms = 1 - if(active_alarms) - icon_state = "alert:2" - else - icon_state = "alert:0" - ..() - return + var/list/alarms = alarm_monitor.major_alarms() + if(alarms.len) + icon_state = "alert:2" + else + icon_state = initial(icon_state) + return diff --git a/code/game/machinery/computer/supply.dm b/code/game/machinery/computer/supply.dm index 9f69c7bc1c..233a271108 100644 --- a/code/game/machinery/computer/supply.dm +++ b/code/game/machinery/computer/supply.dm @@ -49,7 +49,7 @@ /obj/machinery/computer/ordercomp/Topic(href, href_list) if(..()) - return + return 1 if( isturf(loc) && (in_range(src, usr) || istype(usr, /mob/living/silicon)) ) usr.set_machine(src) @@ -85,7 +85,7 @@ if(!istype(P)) return var/timeout = world.time + 600 - var/reason = sanitize(copytext(input(usr,"Reason:","Why do you require this item?","") as null|text,1,MAX_MESSAGE_LEN)) + var/reason = sanitize(input(usr,"Reason:","Why do you require this item?","") as null|text) if(world.time > timeout) return if(!reason) return @@ -224,7 +224,7 @@ world.log << "## ERROR: Eek. The supply/shuttle datum is missing somehow." return if(..()) - return + return 1 if(isturf(loc) && ( in_range(src, usr) || istype(usr, /mob/living/silicon) ) ) usr.set_machine(src) @@ -289,7 +289,7 @@ if(!istype(P)) return var/timeout = world.time + 600 - var/reason = sanitize(copytext(input(usr,"Reason:","Why do you require this item?","") as null|text,1,MAX_MESSAGE_LEN)) + var/reason = sanitize(input(usr,"Reason:","Why do you require this item?","") as null|text) if(world.time > timeout) return if(!reason) return diff --git a/code/game/machinery/computer/syndicate_specops_shuttle.dm b/code/game/machinery/computer/syndicate_specops_shuttle.dm index eb8acc83f5..970bb362c3 100644 --- a/code/game/machinery/computer/syndicate_specops_shuttle.dm +++ b/code/game/machinery/computer/syndicate_specops_shuttle.dm @@ -218,7 +218,7 @@ var/syndicate_elite_shuttle_timeleft = 0 /obj/machinery/computer/syndicate_elite_shuttle/Topic(href, href_list) if(..()) - return + return 1 if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) diff --git a/code/game/machinery/computer3/computers/camera.dm b/code/game/machinery/computer3/computers/camera.dm index cacf665849..17f14e0cbf 100644 --- a/code/game/machinery/computer3/computers/camera.dm +++ b/code/game/machinery/computer3/computers/camera.dm @@ -123,6 +123,12 @@ desc = "Monitors the prison." networks = list("Prison") +/datum/file/camnet_key/syndicate + name = "Camera Network Key" + title = "%!#BUFFER OVERFLOW" + desc = "Connects to security cameras." + networks = list("SS13") + hidden_file = 1 /* @@ -174,7 +180,7 @@ /datum/file/program/security name = "camera monitor" - desc = "Connets to the Nanotrasen Camera Network" + desc = "Connects to the Nanotrasen Camera Network" image = 'icons/ntos/camera.png' active_state = "camera-static" @@ -200,7 +206,7 @@ Reset() ..() - current = null + reset_current() for(var/mob/living/L in viewers(1)) if(!istype(L,/mob/living/silicon/ai) && L.machine == src) L.reset_view(null) @@ -259,24 +265,80 @@ if("show" in href_list) var/obj/machinery/camera/C = locate(href_list["show"]) if(istype(C) && C.status) - current = C + set_current(C) usr.reset_view(C) interact() return if("keyselect" in href_list) - current = null + reset_current() usr.reset_view(null) key = input(usr,"Select a camera network key:", "Key Select", null) as null|anything in computer.list_files(/datum/file/camnet_key) - camera_list = null - update_icon() - computer.update_icon() + select_key(key) if(key) interact() else usr << "The screen turns to static." return +/datum/file/program/security/proc/select_key(var/selected_key) + key = selected_key + camera_list = null + update_icon() + computer.update_icon() + +/datum/file/program/security/proc/set_current(var/obj/machinery/camera/C) + if(current == C) + return + + if(current) + reset_current() + + src.current = C + if(current) + var/mob/living/L = current.loc + if(istype(L)) + L.tracking_initiated() + +/datum/file/program/security/proc/reset_current() + if(current) + var/mob/living/L = current.loc + if(istype(L)) + L.tracking_cancelled() + current = null + // Atlantis: Required for camnetkeys to work. /datum/file/program/security/hidden hidden_file = 1 + +/* + Camera monitoring program + + Works much as the parent program, except: + * It requires a camera to be found using the proximity network card. + * It begins with all cam-access. +*/ + +/datum/file/program/security/syndicate + name = "camer# moni!%r" + desc = "Cons the Nanotrash Camera Network" + var/special_key = new/datum/file/camnet_key/syndicate + var/camera_conn = null + + interact() + if(!interactable()) + return + + if(!computer.net) + computer.Crash(MISSING_PERIPHERAL) + return + + camera_conn = computer.net.connect_to(/obj/machinery/camera,camera_conn) + + if(!camera_conn) + computer.Crash(NETWORK_FAILURE) + return + + // On interact, override camera key selection + select_key(special_key) + ..() diff --git a/code/game/machinery/computer3/computers/card.dm b/code/game/machinery/computer3/computers/card.dm index 963b1f4de7..3633252a46 100644 --- a/code/game/machinery/computer3/computers/card.dm +++ b/code/game/machinery/computer3/computers/card.dm @@ -304,7 +304,7 @@ if(auth) var/t1 = href_list["assign"] if(t1 == "Custom") - var/temp_t = sanitize(copytext(input("Enter a custom job assignment.","Assignment"),1,MAX_MESSAGE_LEN)) + var/temp_t = sanitize(input("Enter a custom job assignment.","Assignment")) if(temp_t) t1 = temp_t set_default_access(t1) diff --git a/code/game/machinery/computer3/computers/communications.dm b/code/game/machinery/computer3/computers/communications.dm index 527a2e2c5a..f00b595c6c 100644 --- a/code/game/machinery/computer3/computers/communications.dm +++ b/code/game/machinery/computer3/computers/communications.dm @@ -178,10 +178,10 @@ post_status(href_list["statdisp"]) if("setmsg1" in href_list) - stat_msg1 = reject_bad_text(trim(sanitize(copytext(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 1, 40)), 40)) + stat_msg1 = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40), 40) computer.updateDialog() if("setmsg2" in href_list) - stat_msg2 = reject_bad_text(trim(sanitize(copytext(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 1, 40)), 40)) + stat_msg2 = reject_bad_text(sanitize(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40), 40) computer.updateDialog() // OMG CENTCOMM LETTERHEAD @@ -192,7 +192,7 @@ if(centcomm_message_cooldown) usr << "Arrays recycling. Please stand by." return - var/input = stripped_input(usr, "Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") + var/input = sanitize(input("Please choose a message to transmit to Centcomm via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "")) if(!input || !interactable()) return Centcomm_announce(input, usr) @@ -209,7 +209,7 @@ if(centcomm_message_cooldown) usr << "Arrays recycling. Please stand by." return - var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "") + var/input = sanitize(input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "")) if(!input || !interactable()) return Syndicate_announce(input, usr) diff --git a/code/game/machinery/computer3/computers/medical.dm b/code/game/machinery/computer3/computers/medical.dm index fa75c69ac6..adb7ff9079 100644 --- a/code/game/machinery/computer3/computers/medical.dm +++ b/code/game/machinery/computer3/computers/medical.dm @@ -86,12 +86,13 @@ if(3.0) dat += text("Records Maintenance
    \nBackup To Disk
    \nUpload From disk
    \nDelete All Records
    \n
    \nBack", src, src, src, src) if(4.0) - var/icon/front = active1.fields["photo_front"] - var/icon/side = active1.fields["photo_side"] - usr << browse_rsc(front, "front.png") - usr << browse_rsc(side, "side.png") dat += "
    Medical Record

    " if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) + var/icon/front = active1.fields["photo_front"] + var/icon/side = active1.fields["photo_side"] + usr << browse_rsc(front, "front.png") + usr << browse_rsc(side, "side.png") + dat += "
    Name: [active1.fields["name"]] \ ID: [active1.fields["id"]]
    \n \ Sex: [active1.fields["sex"]]
    \n \ @@ -263,7 +264,7 @@ switch(href_list["field"]) if("fingerprint") if (istype(src.active1, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) return src.active1.fields["fingerprint"] = t1 @@ -281,55 +282,55 @@ src.active1.fields["age"] = t1 if("mi_dis") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["mi_dis"] = t1 if("mi_dis_d") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["mi_dis_d"] = t1 if("ma_dis") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["ma_dis"] = t1 if("ma_dis_d") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["ma_dis_d"] = t1 if("alg") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["alg"] = t1 if("alg_d") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["alg_d"] = t1 if("cdi") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["cdi"] = t1 if("cdi_d") if (istype(src.active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["cdi_d"] = t1 if("notes") if (istype(src.active2, /datum/data/record)) - var/t1 = html_encode(trim(copytext(input("Please summarize notes:", "Med. records", html_decode(src.active2.fields["notes"]), null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize notes:", "Med. records", html_decode(src.active2.fields["notes"]), null) as message, extra = 0) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["notes"] = t1 @@ -344,21 +345,21 @@ src.temp = text("Blood Type:
    \n\tA- A+
    \n\tB- B+
    \n\tAB- AB+
    \n\tO- O+
    ", src, src, src, src, src, src, src, src) if("b_dna") if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(copytext(trim(input("Please input DNA hash:", "Med. records", src.active2.fields["b_dna"], null) as text),1,MAX_MESSAGE_LEN)) + var/t1 = sanitize(input("Please input DNA hash:", "Med. records", src.active2.fields["b_dna"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return src.active2.fields["b_dna"] = t1 if("vir_name") var/datum/data/record/v = locate(href_list["edit_vir"]) if (v) - var/t1 = trim(sanitize(copytext(input("Please input pathogen name:", "VirusDB", v.fields["name"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input pathogen name:", "VirusDB", v.fields["name"], null) as text) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) return v.fields["name"] = t1 if("vir_desc") var/datum/data/record/v = locate(href_list["edit_vir"]) if (v) - var/t1 = trim(sanitize(copytext(input("Please input information about pathogen:", "VirusDB", v.fields["description"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input information about pathogen:", "VirusDB", v.fields["description"], null) as message) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active1 != a1)) return v.fields["description"] = t1 @@ -463,7 +464,7 @@ if (!( istype(src.active2, /datum/data/record) )) return var/a2 = src.active2 - var/t1 = sanitize(copytext(input("Add Comment:", "Med. records", null, null) as message,1,MAX_MESSAGE_LEN)) + var/t1 = sanitize(input("Add Comment:", "Med. records", null, null) as message) if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || src.active2 != a2)) return var/counter = 1 diff --git a/code/game/machinery/computer3/computers/prisoner.dm b/code/game/machinery/computer3/computers/prisoner.dm index 7b0c97d4ae..49f1940d75 100644 --- a/code/game/machinery/computer3/computers/prisoner.dm +++ b/code/game/machinery/computer3/computers/prisoner.dm @@ -90,7 +90,7 @@ screen = !screen else if(href_list["warn"]) - var/warning = trim(sanitize(copytext(input(usr,"Message:","Enter your message here!",""),1,MAX_MESSAGE_LEN))) + var/warning = sanitize(input(usr,"Message:","Enter your message here!","")) if(!warning) return var/obj/item/weapon/implant/I = locate(href_list["warn"]) if( istype(I) && I.imp_in) diff --git a/code/game/machinery/computer3/computers/security.dm b/code/game/machinery/computer3/computers/security.dm index 8cebdfb5f2..924f32b1b7 100644 --- a/code/game/machinery/computer3/computers/security.dm +++ b/code/game/machinery/computer3/computers/security.dm @@ -404,7 +404,7 @@ What a mess.*/ if (!( istype(active2, /datum/data/record) )) return var/a2 = active2 - var/t1 = sanitize(copytext(input("Add Comment:", "Secure. records", null, null) as message,1,MAX_MESSAGE_LEN)) + var/t1 = sanitize(input("Add Comment:", "Secure. records", null, null) as message) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return var/counter = 1 @@ -444,19 +444,19 @@ What a mess.*/ switch(href_list["field"]) if("name") if (istype(active1, /datum/data/record)) - var/t1 = reject_bad_name(input("Please input name:", "Secure. records", active1.fields["name"], null) as text) + var/t1 = sanitizeName(input("Please input name:", "Secure. records", active1.fields["name"], null) as text) if ((!( t1 ) || !length(trim(t1)) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon)))) || active1 != a1) return active1.fields["name"] = t1 if("id") if (istype(active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input id:", "Secure. records", active1.fields["id"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active1 != a1)) return active1.fields["id"] = t1 if("fingerprint") if (istype(active1, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active1 != a1)) return active1.fields["fingerprint"] = t1 @@ -474,31 +474,31 @@ What a mess.*/ active1.fields["age"] = t1 if("mi_crim") if (istype(active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input minor disabilities list:", "Secure. records", active2.fields["mi_crim"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input minor disabilities list:", "Secure. records", active2.fields["mi_crim"], null) as text) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return active2.fields["mi_crim"] = t1 if("mi_crim_d") if (istype(active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return active2.fields["mi_crim_d"] = t1 if("ma_crim") if (istype(active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please input major diabilities list:", "Secure. records", active2.fields["ma_crim"], null) as text,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please input major diabilities list:", "Secure. records", active2.fields["ma_crim"], null) as text) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return active2.fields["ma_crim"] = t1 if("ma_crim_d") if (istype(active2, /datum/data/record)) - var/t1 = trim(sanitize(copytext(input("Please summarize major dis.:", "Secure. records", active2.fields["ma_crim_d"], null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize major dis.:", "Secure. records", active2.fields["ma_crim_d"], null) as message) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return active2.fields["ma_crim_d"] = t1 if("notes") if (istype(active2, /datum/data/record)) - var/t1 = html_encode(trim(copytext(input("Please summarize notes:", "Secure. records", html_decode(active2.fields["notes"]), null) as message,1,MAX_MESSAGE_LEN))) + var/t1 = sanitize(input("Please summarize notes:", "Secure. records", html_decode(active2.fields["notes"]), null) as message, extra = 0) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active2 != a2)) return active2.fields["notes"] = t1 @@ -525,7 +525,7 @@ What a mess.*/ alert(usr, "You do not have the required rank to do this!") if("species") if (istype(active1, /datum/data/record)) - var/t1 = sanitize(copytext(input("Please enter race:", "General records", active1.fields["species"], null) as message,1,MAX_MESSAGE_LEN)) + var/t1 = sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message) if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!interactable() && (!istype(usr, /mob/living/silicon))) || active1 != a1)) return active1.fields["species"] = t1 @@ -543,7 +543,7 @@ What a mess.*/ if ("Change Criminal Status") if (active2) for(var/mob/living/carbon/human/H in player_list) - H.hud_updateflag |= 1 << WANTED_HUD + BITSET(H.hud_updateflag, WANTED_HUD) switch(href_list["criminal2"]) if("none") active2.fields["criminal"] = "None" @@ -608,4 +608,4 @@ What a mess.*/ /obj/machinery/computer3/secure_data/detective_computer icon = 'icons/obj/computer.dmi' - icon_state = "messyfiles" \ No newline at end of file + icon_state = "messyfiles" diff --git a/code/game/machinery/computer3/networking.dm b/code/game/machinery/computer3/networking.dm index 4e39da0406..27d7789008 100644 --- a/code/game/machinery/computer3/networking.dm +++ b/code/game/machinery/computer3/networking.dm @@ -169,6 +169,9 @@ if(typekey == null) typekey = /obj/machinery var/list/machines = list() + for(var/obj/O in T) + if(istype(O,typekey)) + machines += O for(var/d in cardinal) var/turf/T2 = get_step(T,d) for(var/obj/O in T2) diff --git a/code/game/machinery/computer3/program_disks.dm b/code/game/machinery/computer3/program_disks.dm index 201fff3939..e9a649499b 100644 --- a/code/game/machinery/computer3/program_disks.dm +++ b/code/game/machinery/computer3/program_disks.dm @@ -28,6 +28,13 @@ icon_state = "datadisk_arcade" spawn_files = list(/datum/file/program/security) +/obj/item/weapon/disk/file/cameras/syndicate + name = "Camera Viewer" + desc = "A program install disk. A crude skull has been drawn on it and there is a list of items:\nFloppy Drive\nCamera Card\nNetwork Card: Adjacent\nPosition laptop nearby camera, enjoy." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "datadisk_arcade" + spawn_files = list(/datum/file/program/security/syndicate) + /obj/item/weapon/disk/file/card name = "ID Card Modifier" desc = "A program install disk." diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index ecf868f260..a9858742c9 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -3,7 +3,7 @@ /obj/machinery/atmospherics/unary/cryo_cell name = "cryo cell" icon = 'icons/obj/cryogenics.dmi' - icon_state = "cell-off" + icon_state = "pod0" density = 1 anchored = 1.0 layer = 2.8 @@ -42,7 +42,6 @@ if(!node) return if(!on) - updateUsrDialog() return if(occupant) @@ -57,7 +56,6 @@ if(abs(temperature_archived-air_contents.temperature) > 1) network.update = 1 - updateUsrDialog() return 1 @@ -193,17 +191,17 @@ var/mob/M = G:affecting if(put_mob(M)) del(G) - updateUsrDialog() return /obj/machinery/atmospherics/unary/cryo_cell/update_icon() - if(on) - if(occupant) - icon_state = "cell-occupied" - return - icon_state = "cell-on" - return - icon_state = "cell-off" + overlays.Cut() + icon_state = "pod[on]" + if(occupant) + var/image/pickle = image(occupant.icon, occupant.icon_state) + pickle.overlays = occupant.overlays + pickle.pixel_y = 20 + overlays += pickle + overlays += "lid[on]" /obj/machinery/atmospherics/unary/cryo_cell/proc/process_occupant() if(air_contents.total_moles < 10) @@ -293,6 +291,7 @@ M.client.eye = src M.stop_pulling() M.loc = src + M.ExtinguishMob() if(M.health > -100 && (M.health < 0 || M.sleeping)) M << "\blue You feel a cold liquid surround you. Your skin starts to freeze up." occupant = M @@ -335,7 +334,13 @@ put_mob(usr) return - +/obj/machinery/atmospherics/unary/cryo_cell/return_air_for_internal_lifeform() + //assume that the cryo cell has some kind of breath mask or something that + //draws from the cryo tube's environment, instead of the cold internal air. + if(loc) + return loc.return_air() + else + return null /datum/data/function/proc/reset() return diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 5915aef5ac..fcece506c3 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -175,7 +175,7 @@ var/on_store_message = "has entered long-term storage." var/on_store_name = "Cryogenic Oversight" var/on_enter_occupant_message = "You feel cool air surround you. You go numb as your senses turn inward." - var/allow_occupant_types = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + var/allow_occupant_types = list(/mob/living/carbon/human) var/disallow_occupant_types = list() var/mob/occupant = null // Person waiting to be despawned. @@ -363,10 +363,10 @@ if(occupant.mind.objectives.len) del(occupant.mind.objectives) occupant.mind.special_role = null - else - if(ticker.mode.name == "AutoTraitor") - var/datum/game_mode/traitor/autotraitor/current_mode = ticker.mode - current_mode.possible_traitors.Remove(occupant) + //else + //if(ticker.mode.name == "AutoTraitor") + //var/datum/game_mode/traitor/autotraitor/current_mode = ticker.mode + //current_mode.possible_traitors.Remove(occupant) // Delete them from datacore. @@ -396,12 +396,11 @@ control_computer.frozen_crew += "[occupant.real_name]" announce.autosay("[occupant.real_name] [on_store_message]", "[on_store_name]") - visible_message("\The [src] hums and hisses as it moves [occupant.real_name] into storage.", 3) + visible_message("\The [initial(name)] hums and hisses as it moves [occupant.real_name] into storage.", 3) + set_occupant(null) // Delete the mob. del(occupant) - occupant = null - name = initial(name) /obj/machinery/cryopod/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob) @@ -448,7 +447,7 @@ M << "[on_enter_occupant_message]" M << "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round." - occupant = M + set_occupant(M) time_entered = world.time // Book keeping! @@ -517,7 +516,7 @@ usr.client.perspective = EYE_PERSPECTIVE usr.client.eye = src usr.loc = src - src.occupant = usr + set_occupant(usr) if(orient_right) icon_state = "[occupied_icon_state]-r" @@ -526,11 +525,10 @@ usr << "[on_enter_occupant_message]" usr << "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round." - occupant = usr + time_entered = world.time src.add_fingerprint(usr) - name = "[name] ([usr.name])" return @@ -544,7 +542,7 @@ occupant.client.perspective = MOB_PERSPECTIVE occupant.loc = get_turf(src) - occupant = null + set_occupant(null) if(orient_right) icon_state = "[base_icon_state]-r" @@ -553,6 +551,12 @@ return +/obj/machinery/cryopod/proc/set_occupant(var/occupant) + src.occupant = occupant + name = initial(name) + if(occupant) + name = "[name] ([occupant])" + //Attacks/effects. /obj/machinery/cryopod/blob_act() diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index d6eff496d0..87e7adea03 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -182,7 +182,8 @@ for reference: else if (istype(W, /obj/item/weapon/card/emag)) if (src.emagged == 0) src.emagged = 1 - src.req_access = null + src.req_access.Cut() + src.req_one_access.Cut() user << "You break the ID authentication lock on \the [src]." var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(2, 1, src) diff --git a/code/game/machinery/door_control.dm b/code/game/machinery/door_control.dm index 50c16c86cc..928dda2541 100644 --- a/code/game/machinery/door_control.dm +++ b/code/game/machinery/door_control.dm @@ -34,6 +34,7 @@ idle_power_usage = 2 active_power_usage = 4 + /obj/machinery/door_control/attack_ai(mob/user as mob) if(wires & 2) return src.attack_hand(user) @@ -81,17 +82,16 @@ if(specialfunctions & BOLTS) D.lock() if(specialfunctions & SHOCK) - D.secondsElectrified = -1 + D.electrify(-1) if(specialfunctions & SAFE) D.safe = 0 else if(specialfunctions & IDSCAN) D.aiDisabledIdScanner = 0 if(specialfunctions & BOLTS) - if(!D.isWireCut(4) && D.arePowerSystemsOn()) - D.unlock() + D.unlock() if(specialfunctions & SHOCK) - D.secondsElectrified = 0 + D.electrify(0) if(specialfunctions & SAFE) D.safe = 1 @@ -148,30 +148,20 @@ else icon_state = "doorctrl0" -/obj/machinery/driver_button/attack_ai(mob/user as mob) - return src.attack_hand(user) +/obj/machinery/button/driver + name = "mass driver button" + desc = "A remote control switch for a mass driver." -/obj/machinery/driver_button/attackby(obj/item/weapon/W, mob/user as mob) - - if(istype(W, /obj/item/device/detective_scanner)) +/obj/machinery/button/driver/attack_hand(mob/user as mob) + if(..()) return - return src.attack_hand(user) - -/obj/machinery/driver_button/attack_hand(mob/user as mob) - - src.add_fingerprint(usr) - if(stat & (NOPOWER|BROKEN)) - return - if(active) - return - add_fingerprint(user) use_power(5) active = 1 icon_state = "launcheract" - for(var/obj/machinery/door/blast/M in world) + for(var/obj/machinery/door/blast/M in machines) if (M.id == src.id) spawn( 0 ) M.open() @@ -179,13 +169,13 @@ sleep(20) - for(var/obj/machinery/mass_driver/M in world) + for(var/obj/machinery/mass_driver/M in machines) if(M.id == src.id) M.drive() sleep(50) - for(var/obj/machinery/door/blast/M in world) + for(var/obj/machinery/door/blast/M in machines) if (M.id == src.id) spawn( 0 ) M.close() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index d15d393517..0040ac0e92 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -7,13 +7,14 @@ explosion_resistance = 15 var/aiControlDisabled = 0 //If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. var/hackProof = 0 // if 1, this door can't be hacked by the AI - var/secondsMainPowerLost = 0 //The number of seconds until power is restored. - var/secondsBackupPowerLost = 0 //The number of seconds until power is restored. + var/electrified_until = 0 //World time when the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. + var/main_power_lost_until = 0 //World time when main power is restored. + var/backup_power_lost_until = -1 //World time when backup power is restored. + var/next_beep_at = 0 //World time when we may next beep due to doors being blocked by mobs var/spawnPowerRestoreRunning = 0 var/welded = null var/locked = 0 var/lights = 1 // bolt lights show by default - secondsElectrified = 0 //How many seconds remain until the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. var/aiDisabledIdScanner = 0 var/aiHacking = 0 var/obj/machinery/door/airlock/closeOther = null @@ -94,6 +95,10 @@ secured_wires = 1 assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity //Until somebody makes better sprites. +/obj/machinery/door/airlock/vault/bolted + icon_state = "door_locked" + locked = 1 + /obj/machinery/door/airlock/freezer name = "Freezer Airlock" icon = 'icons/obj/doors/Doorfreezer.dmi' @@ -213,6 +218,19 @@ mineral = "uranium" var/last_event = 0 +/obj/machinery/door/airlock/process() + // Deliberate no call to parent. + if(main_power_lost_until > 0 && world.time >= main_power_lost_until) + regainMainPower() + + if(backup_power_lost_until > 0 && world.time >= backup_power_lost_until) + regainBackupPower() + + else if(electrified_until > 0 && world.time >= electrified_until) + electrify(0) + + ..() + /obj/machinery/door/airlock/uranium/process() if(world.time > last_event+20) if(prob(50)) @@ -315,7 +333,7 @@ About the new airlock wires panel: ..(user) /obj/machinery/door/airlock/proc/isElectrified() - if(src.secondsElectrified != 0) + if(src.electrified_until != 0) return 1 return 0 @@ -332,7 +350,7 @@ About the new airlock wires panel: /obj/machinery/door/airlock/proc/arePowerSystemsOn() if (stat & (NOPOWER|BROKEN)) return 0 - return (src.secondsMainPowerLost==0 || src.secondsBackupPowerLost==0) + return (src.main_power_lost_until==0 || src.backup_power_lost_until==0) /obj/machinery/door/airlock/requiresID() return !(src.isWireCut(AIRLOCK_WIRE_IDSCAN) || aiDisabledIdScanner) @@ -340,48 +358,68 @@ About the new airlock wires panel: /obj/machinery/door/airlock/proc/isAllPowerLoss() if(stat & (NOPOWER|BROKEN)) return 1 - if(src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1) || src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) - if(src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1) || src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2)) - return 1 + if(mainPowerCablesCut() && backupPowerCablesCut()) + return 1 return 0 -/obj/machinery/door/airlock/proc/regainMainPower() - if(src.secondsMainPowerLost > 0) - src.secondsMainPowerLost = 0 +/obj/machinery/door/airlock/proc/mainPowerCablesCut() + return src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1) || src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2) + +/obj/machinery/door/airlock/proc/backupPowerCablesCut() + return src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1) || src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2) /obj/machinery/door/airlock/proc/loseMainPower() - if(src.secondsMainPowerLost <= 0) - src.secondsMainPowerLost = 60 - if(src.secondsBackupPowerLost < 10) - src.secondsBackupPowerLost = 10 - if(!src.spawnPowerRestoreRunning) - src.spawnPowerRestoreRunning = 1 - spawn(0) - var/cont = 1 - while (cont) - sleep(10) - cont = 0 - if(src.secondsMainPowerLost>0) - if((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - src.secondsMainPowerLost -= 1 - src.updateDialog() - cont = 1 + main_power_lost_until = mainPowerCablesCut() ? -1 : world.time + SecondsToTicks(60) - if(src.secondsBackupPowerLost>0) - if((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - src.secondsBackupPowerLost -= 1 - src.updateDialog() - cont = 1 - src.spawnPowerRestoreRunning = 0 - src.updateDialog() + // If backup power is permanently disabled then activate in 10 seconds if possible, otherwise it's already enabled or a timer is already running + if(backup_power_lost_until == -1 && !backupPowerCablesCut()) + backup_power_lost_until = world.time + SecondsToTicks(10) + + // Disable electricity if required + if(electrified_until && isAllPowerLoss()) + electrify(0) /obj/machinery/door/airlock/proc/loseBackupPower() - if(src.secondsBackupPowerLost < 60) - src.secondsBackupPowerLost = 60 + backup_power_lost_until = backupPowerCablesCut() ? -1 : world.time + SecondsToTicks(60) + + // Disable electricity if required + if(electrified_until && isAllPowerLoss()) + electrify(0) + +/obj/machinery/door/airlock/proc/regainMainPower() + if(!mainPowerCablesCut()) + main_power_lost_until = 0 + // If backup power is currently active then disable, otherwise let it count down and disable itself later + if(!backup_power_lost_until) + backup_power_lost_until = -1 /obj/machinery/door/airlock/proc/regainBackupPower() - if(src.secondsBackupPowerLost > 0) - src.secondsBackupPowerLost = 0 + if(!backupPowerCablesCut()) + // Restore backup power only if main power is offline, otherwise permanently disable + backup_power_lost_until = main_power_lost_until == 0 ? -1 : 0 + +/obj/machinery/door/airlock/proc/electrify(var/duration, var/feedback = 0) + var/message = "" + if(src.isWireCut(AIRLOCK_WIRE_ELECTRIFY) && arePowerSystemsOn()) + message = text("The electrification wire is cut - Door permanently electrified.") + src.electrified_until = -1 + else if(duration && !arePowerSystemsOn()) + message = text("The door is unpowered - Cannot electrify the door.") + src.electrified_until = 0 + else if(!duration && electrified_until != 0) + message = "The door is now un-electrified." + src.electrified_until = 0 + else if(duration) //electrify door for the given duration seconds + if(usr) + shockedby += text("\[[time_stamp()]\] - [usr](ckey:[usr.ckey])") + usr.attack_log += text("\[[time_stamp()]\] Electrified the [name] at [x] [y] [z]") + else + shockedby += text("\[[time_stamp()]\] - EMP)") + message = "The door is now electrified [duration == -1 ? "permanently" : "for [duration] second\s"]." + src.electrified_until = duration == -1 ? -1 : world.time + SecondsToTicks(duration) + + if(feedback && message) + usr << message // shock user with probability prb (if all connections & power are working) // returns 1 if shocked, 0 otherwise @@ -403,7 +441,7 @@ About the new airlock wires panel: /obj/machinery/door/airlock/update_icon() if(overlays) overlays.Cut() if(density) - if(locked && lights) + if(locked && lights && src.arePowerSystemsOn()) icon_state = "door_locked" else icon_state = "door_closed" @@ -424,7 +462,6 @@ About the new airlock wires panel: icon_state = "door_open" if((stat & BROKEN) && !(stat & NOPOWER)) overlays += image(icon, "sparks_open") - return /obj/machinery/door/airlock/do_animate(animation) @@ -453,114 +490,36 @@ About the new airlock wires panel: if("deny") if(density && src.arePowerSystemsOn()) flick("door_deny", src) + playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0) return /obj/machinery/door/airlock/attack_ai(mob/user as mob) - if (!check_synth_access(user)) - return + ui_interact(user) - //Separate interface for the AI. - user.set_machine(src) - var/t1 = text("Airlock Control
    \n") - if(src.secondsMainPowerLost > 0) - if((!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2))) - t1 += text("Main power is offline for [] seconds.
    \n", src.secondsMainPowerLost) - else - t1 += text("Main power is offline indefinitely.
    \n") - else - t1 += text("Main power is online.") +/obj/machinery/door/airlock/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] - if(src.secondsBackupPowerLost > 0) - if((!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) && (!src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2))) - t1 += text("Backup power is offline for [] seconds.
    \n", src.secondsBackupPowerLost) - else - t1 += text("Backup power is offline indefinitely.
    \n") - else if(src.secondsMainPowerLost > 0) - t1 += text("Backup power is online.") - else - t1 += text("Backup power is offline, but will turn on if main power fails.") - t1 += "
    \n" + data["main_power_loss"] = round(main_power_lost_until > 0 ? max(main_power_lost_until - world.time, 0) / 10 : main_power_lost_until, 1) + data["backup_power_loss"] = round(backup_power_lost_until > 0 ? max(backup_power_lost_until - world.time, 0) / 10 : backup_power_lost_until, 1) + data["electrified"] = round(electrified_until > 0 ? max(electrified_until - world.time, 0) / 10 : electrified_until, 1) + data["open"] = !density - if(src.isWireCut(AIRLOCK_WIRE_IDSCAN)) - t1 += text("IdScan wire is cut.
    \n") - else if(src.aiDisabledIdScanner) - t1 += text("IdScan disabled. Enable?
    \n", src) - else - t1 += text("IdScan enabled. Disable?
    \n", src) + var/commands[0] + commands[++commands.len] = list("name" = "IdScan", "command"= "idscan", "active" = !aiDisabledIdScanner, "enabled" = "Enabled", "disabled" = "Disable", "danger" = 0, "act" = 1) + commands[++commands.len] = list("name" = "Bolts", "command"= "bolts", "active" = !locked, "enabled" = "Raised ", "disabled" = "Dropped", "danger" = 0, "act" = 0) + commands[++commands.len] = list("name" = "Bolt Lights", "command"= "lights", "active" = lights, "enabled" = "Enabled", "disabled" = "Disable", "danger" = 0, "act" = 1) + commands[++commands.len] = list("name" = "Safeties", "command"= "safeties", "active" = safe, "enabled" = "Nominal", "disabled" = "Overridden", "danger" = 1, "act" = 0) + commands[++commands.len] = list("name" = "Timing", "command"= "timing", "active" = normalspeed, "enabled" = "Nominal", "disabled" = "Overridden", "danger" = 1, "act" = 0) + commands[++commands.len] = list("name" = "Door State", "command"= "open", "active" = density, "enabled" = "Closed", "disabled" = "Opened", "danger" = 0, "act" = 0) - if(src.isWireCut(AIRLOCK_WIRE_MAIN_POWER1)) - t1 += text("Main Power Input wire is cut.
    \n") - if(src.isWireCut(AIRLOCK_WIRE_MAIN_POWER2)) - t1 += text("Main Power Output wire is cut.
    \n") - if(src.secondsMainPowerLost == 0) - t1 += text("Temporarily disrupt main power?.
    \n", src) - if(src.secondsBackupPowerLost == 0) - t1 += text("Temporarily disrupt backup power?.
    \n", src) - - if(src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER1)) - t1 += text("Backup Power Input wire is cut.
    \n") - if(src.isWireCut(AIRLOCK_WIRE_BACKUP_POWER2)) - t1 += text("Backup Power Output wire is cut.
    \n") - - if(src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - t1 += text("Door bolt control wire is cut.
    \n") - else if(!src.locked) - t1 += text("Door bolts are up. Drop them?
    \n", src) - else - t1 += text("Door bolts are down.") - if(src.arePowerSystemsOn()) - t1 += text(" Raise?
    \n", src) - else - t1 += text(" Cannot raise door bolts due to power failure.
    \n") - - if(src.isWireCut(AIRLOCK_WIRE_LIGHT)) - t1 += text("Door bolt lights wire is cut.
    \n") - else if(!src.lights) - t1 += text("Door lights are off. Enable?
    \n", src) - else - t1 += text("Door lights are on. Disable?
    \n", src) - - if(src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - t1 += text("Electrification wire is cut.
    \n") - if(src.secondsElectrified==-1) - t1 += text("Door is electrified indefinitely. Un-electrify it?
    \n", src) - else if(src.secondsElectrified>0) - t1 += text("Door is electrified temporarily ([] seconds). Un-electrify it?
    \n", src.secondsElectrified, src) - else - t1 += text("Door is not electrified. Electrify it for 30 seconds? Or, Electrify it indefinitely until someone cancels the electrification?
    \n", src, src) - - if(src.isWireCut(AIRLOCK_WIRE_SAFETY)) - t1 += text("Door force sensors not responding.
    \n") - else if(src.safe) - t1 += text("Door safeties operating normally. Override?
    \n",src) - else - t1 += text("Danger. Door safeties disabled. Restore?
    \n",src) - - if(src.isWireCut(AIRLOCK_WIRE_SPEED)) - t1 += text("Door timing circuitry not responding.
    \n") - else if(src.normalspeed) - t1 += text("Door timing circuitry operating normally. Override?
    \n",src) - else - t1 += text("Warning. Door timing circuitry operating abnormally. Restore?
    \n",src) - - - - - if(src.welded) - t1 += text("Door appears to have been welded shut.
    \n") - else if(!src.locked) - if(src.density) - t1 += text("Open door
    \n", src) - else - t1 += text("Close door
    \n", src) - - t1 += text("

    Close

    \n", src) - user << browse(t1, "window=airlock") - onclose(user, "airlock") - -//aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door -//aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door + data["commands"] = commands + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "door_control.tmpl", "Door Controls", 450, 350) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) /obj/machinery/door/airlock/proc/hack(mob/user as mob) if(src.aiHacking==0) @@ -651,10 +610,13 @@ About the new airlock wires panel: ..(user) return -/obj/machinery/door/airlock/proc/check_synth_access(mob/user as mob) +/obj/machinery/door/airlock/CanUseTopic(var/mob/user, href_list) + if(!user.isSilicon()) + return STATUS_CLOSE + if(operating < 0) //emagged user << "Unable to interface: Internal error." - return 0 + return STATUS_CLOSE if(!src.canAIControl()) if(src.canAIHack(user)) src.hack(user) @@ -663,201 +625,80 @@ About the new airlock wires panel: user << "Unable to interface: Connection timed out." else user << "Unable to interface: Connection refused." - return 0 - return 1 + return STATUS_CLOSE + + return STATUS_INTERACTIVE /obj/machinery/door/airlock/Topic(href, href_list, var/nowindow = 0) if(..()) return 1 - if(href_list["close"]) - usr << browse(null, "window=airlock") - if(usr.machine==src) - usr.unset_machine() - return 1 + var/activate = text2num(href_list["activate"]) + switch (href_list["command"]) + if("idscan") + if(src.isWireCut(AIRLOCK_WIRE_IDSCAN)) + usr << "The IdScan wire has been cut - IdScan feature permanently disabled." + else if(activate && src.aiDisabledIdScanner) + src.aiDisabledIdScanner = 0 + usr << "IdScan feature has been enabled." + else if(!activate && !src.aiDisabledIdScanner) + src.aiDisabledIdScanner = 1 + usr << "IdScan feature has been disabled." + if("main_power") + if(!main_power_lost_until) + src.loseMainPower() + if("backup_power") + if(!backup_power_lost_until) + src.loseBackupPower() + if("bolts") + if(src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + usr << "The door bolt control wire has been cut - Door bolts permanently dropped." + else if(activate && src.lock()) + usr << "The door bolts have been dropped." + else if(!activate && src.unlock()) + usr << "The door bolts have been raised." + if("electrify_temporary") + electrify(30 * activate, 1) + if("electrify_permanently") + electrify(-1 * activate, 1) + if("open") + if(src.welded) + usr << text("The airlock has been welded shut!") + else if(src.locked) + usr << text("The door bolts are down!") + else if(activate && density) + open() + else if(!activate && !density) + close() + if("safeties") + // Safeties! We don't need no stinking safeties! + if (src.isWireCut(AIRLOCK_WIRE_SAFETY)) + usr << text("The safety wire is cut - Cannot secure the door.") + else if (activate && src.safe) + safe = 0 + else if (!activate && !src.safe) + safe = 1 + if("timing") + // Door speed control + if(src.isWireCut(AIRLOCK_WIRE_SPEED)) + usr << text("The timing wire is cut - Cannot alter timing.") + else if (activate && src.normalspeed) + normalspeed = 0 + else if (!activate && !src.normalspeed) + normalspeed = 1 + if("lights") + // Bolt lights + if(src.isWireCut(AIRLOCK_WIRE_LIGHT)) + usr << "The bolt lights wire has been cut - The door bolt lights are permanently disabled." + else if (!activate && src.lights) + lights = 0 + usr << "The door bolt lights have been disabled." + else if (activate && !src.lights) + lights = 1 + usr << "The door bolt lights have been enabled." - if((in_range(src, usr) && istype(src.loc, /turf)) && src.p_open) - usr.set_machine(src) - - if(istype(usr, /mob/living/silicon)) - if (!check_synth_access(usr)) - return 1 - - //AI - //aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door, 8 door safties, 9 door speed - //aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door, 8 door safties, 9 door speed - if(href_list["aiDisable"]) - var/code = text2num(href_list["aiDisable"]) - switch (code) - if(1) - //disable idscan - if(src.isWireCut(AIRLOCK_WIRE_IDSCAN)) - usr << "The IdScan wire has been cut - The IdScan feature is already disabled." - else if(src.aiDisabledIdScanner) - usr << "The IdScan feature is already disabled." - else - usr << "The IdScan feature has been disabled." - src.aiDisabledIdScanner = 1 - if(2) - //disrupt main power - if(src.secondsMainPowerLost == 0) - src.loseMainPower() - else - usr << "Main power is already offline." - if(3) - //disrupt backup power - if(src.secondsBackupPowerLost == 0) - src.loseBackupPower() - else - usr << "Backup power is already offline." - if(4) - //drop door bolts - if(src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - usr << "The door bolt control wire has been cut - The door bolts are already dropped." - else if(src.locked) - usr << "The door bolts are already dropped." - else - if(src.lock()) - usr << "The door bolts have been dropped." - if(5) - //un-electrify door - if(src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - usr << text("The electrification wire is cut - Cannot un-electrify the door.") - else if(secondsElectrified != 0) - usr << "The door is now un-electrified." - src.secondsElectrified = 0 - if(7) - //close door - if(src.welded) - usr << text("The airlock has been welded shut!") - else if(src.locked) - usr << text("The door bolts are down!") - else if(!src.density) - close() - else - open() - if(8) - // Safeties! We don't need no stinking safeties! - if (src.isWireCut(AIRLOCK_WIRE_SAFETY)) - usr << text("Control to door sensors is disabled.") - else if (src.safe) - safe = 0 - else - usr << text("Firmware reports safeties already overridden.") - if(9) - // Door speed control - if(src.isWireCut(AIRLOCK_WIRE_SPEED)) - usr << text("Control to door timing circuitry has been severed.") - else if (src.normalspeed) - normalspeed = 0 - else - usr << text("Door timing circuity already accelerated.") - if(10) - // Bolt lights - if(src.isWireCut(AIRLOCK_WIRE_LIGHT)) - usr << "The bolt lights wire has been cut - The door bolt lights are already disabled." - else if (src.lights) - lights = 0 - usr << "The door bolt lights have been disabled." - else - usr << "The door bolt lights are already disabled!" - - else if(href_list["aiEnable"]) - var/code = text2num(href_list["aiEnable"]) - switch (code) - if(1) - //enable idscan - if(src.isWireCut(AIRLOCK_WIRE_IDSCAN)) - usr << "The IdScan wire has been cut - The IdScan feature cannot be enabled." - else if(src.aiDisabledIdScanner) - usr << "The IdScan feature has been enabled." - src.aiDisabledIdScanner = 0 - else - usr << "The IdScan feature is already enabled." - if(4) - //raise door bolts - if(src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - usr << "The door bolt control wire has been cut - The door bolts cannot be raised." - else if(!src.locked) - usr << "The door bolts are already raised." - else - if(src.unlock()) - usr << "The door bolts have been raised." - else - usr << "Unable to raise door bolts." - if(5) - //electrify door for 30 seconds - if(src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - usr << text("The electrification wire has been cut.
    \n") - else if(src.secondsElectrified==-1) - usr << text("The door is already indefinitely electrified. You'd have to un-electrify it before you can re-electrify it with a non-forever duration.
    \n") - else if(src.secondsElectrified!=0) - usr << text("The door is already electrified. Cannot re-electrify it while it's already electrified.
    \n") - else - shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])") - usr.attack_log += text("\[[time_stamp()]\] Electrified the [name] at [x] [y] [z]") - usr << "The door is now electrified for thirty seconds." - src.secondsElectrified = 30 - spawn(10) - while (src.secondsElectrified>0) - src.secondsElectrified-=1 - if(src.secondsElectrified<0) - src.secondsElectrified = 0 - sleep(10) - if(6) - //electrify door indefinitely - if(src.isWireCut(AIRLOCK_WIRE_ELECTRIFY)) - usr << text("The electrification wire has been cut.
    \n") - else if(src.secondsElectrified==-1) - usr << text("The door is already indefinitely electrified.
    \n") - else if(src.secondsElectrified!=0) - usr << text("The door is already electrified. You can't re-electrify it while it's already electrified.
    \n") - else - shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])") - usr.attack_log += text("\[[time_stamp()]\] Electrified the [name] at [x] [y] [z]") - usr << "The door is now electrified." - src.secondsElectrified = -1 - if(7) - //open door - if(src.welded) - usr << text("The airlock has been welded shut!") - else if(src.locked) - usr << text("The door bolts are down!") - else if(src.density) - open() - else - close() - if (8) - // Safeties! Maybe we do need some stinking safeties! - if (src.isWireCut(AIRLOCK_WIRE_SAFETY)) - usr << text("Control to door sensors is disabled.") - else if (!src.safe) - safe = 1 - else - usr << text("Firmware reports safeties already in place.") - if(9) - // Door speed control - if(src.isWireCut(AIRLOCK_WIRE_SPEED)) - usr << text("Control to door timing circuitry has been severed.") - else if (!src.normalspeed) - normalspeed = 1 - else - usr << text("Door timing circuity currently operating normally.") - if(10) - // Bolt lights - if(src.isWireCut(AIRLOCK_WIRE_LIGHT)) - usr << "The bolt lights wire has been cut - The door bolt lights cannot be enabled." - else if (!src.lights) - lights = 1 - usr << "The door bolt lights have been enabled" - else - usr << "The door bolt lights are already enabled!" - - add_fingerprint(usr) update_icon() - if(!nowindow) - updateUsrDialog() - return 0 + return 1 /obj/machinery/door/airlock/attackby(C as obj, mob/user as mob) //world << text("airlock attackby src [] obj [] mob []", src, C, user) @@ -984,7 +825,7 @@ About the new airlock wires panel: return /obj/machinery/door/airlock/open(var/forced=0) - if( operating || welded || locked ) + if(!can_open()) return 0 if(!forced) if( !arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR) ) @@ -998,20 +839,33 @@ About the new airlock wires panel: src.closeOther.close() return ..() -/obj/machinery/door/airlock/close(var/forced=0) - if(operating || welded || locked) - return +/obj/machinery/door/airlock/can_open() + if(locked || welded) + return 0 + return ..() + +/obj/machinery/door/airlock/can_close(var/forced=0) + if(locked || welded) + return 0 + if(!forced) //despite the name, this wire is for general door control. - //Bolts are already covered by the check for locked, above - if( !arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR) ) - return + if(!arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR)) + return 0 + + return ..() + +/obj/machinery/door/airlock/close(var/forced=0) + if(!can_close(forced)) + return 0 + if(safe) for(var/turf/turf in locs) if(locate(/mob/living) in turf) - // playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0) //THE BUZZING IT NEVER STOPS -Pete - spawn (60) - close() + if(world.time > next_beep_at) + playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0) + next_beep_at = world.time + SecondsToTicks(10) + close_door_at = world.time + 6 return for(var/turf/turf in locs) @@ -1049,7 +903,10 @@ About the new airlock wires panel: return /obj/machinery/door/airlock/proc/lock(var/forced=0) - if (operating || src.locked) return 0 + if(locked) + return 0 + + if (operating && !forced) return 0 src.locked = 1 for(var/mob/M in range(1,src)) @@ -1058,23 +915,21 @@ About the new airlock wires panel: return 1 /obj/machinery/door/airlock/proc/unlock(var/forced=0) - if (operating || !src.locked) return + if(!src.locked) + return - if (forced || (src.arePowerSystemsOn())) //only can raise bolts if power's on - src.locked = 0 - for(var/mob/M in range(1,src)) - M.show_message("You hear a click from the bottom of the door.", 2) - update_icon() - return 1 - return 0 + if (!forced) + if(operating || !src.arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) return + + src.locked = 0 + for(var/mob/M in range(1,src)) + M.show_message("You hear a click from the bottom of the door.", 2) + update_icon() + return 1 /obj/machinery/door/airlock/New(var/newloc, var/obj/structure/door_assembly/assembly=null) ..() - //High-sec airlocks are much harder to completely break by emitters. - if(secured_wires) - emitter_resistance *= 3 - //if assembly is given, create the new door from the assembly if (assembly && istype(assembly)) assembly_type = assembly.type @@ -1085,9 +940,10 @@ About the new airlock wires panel: //update the door's access to match the electronics' secured_wires = electronics.secure if(electronics.one_access) - req_access = null + req_access.Cut() req_one_access = src.electronics.conf_access else + req_one_access.Cut() req_access = src.electronics.conf_access //get the name from the assembly @@ -1128,8 +984,19 @@ About the new airlock wires panel: electronics.conf_access = src.req_one_access electronics.one_access = 1 +/obj/machinery/door/airlock/emp_act(var/severity) + if(prob(40/severity)) + var/duration = world.time + SecondsToTicks(30 / severity) + if(duration > electrified_until) + electrify(duration) + ..() + /obj/machinery/door/airlock/power_change() //putting this is obj/machinery/door itself makes non-airlock doors turn invisible for some reason ..() + if(stat & NOPOWER) + // If we lost power, disable electrification + // Keeping door lights on, runs on internal battery or something. + electrified_until = 0 update_icon() /obj/machinery/door/airlock/proc/prison_open() diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm index 07192d5dc6..19ac77d2c7 100644 --- a/code/game/machinery/doors/blast_door.dm +++ b/code/game/machinery/doors/blast_door.dm @@ -23,7 +23,6 @@ var/id = 1.0 dir = 1 explosion_resistance = 25 - emitter_resistance = 50 // Lots of emitter blasts, it's *blast* door after all. //Most blast doors are infrequently toggled and sometimes used with regular doors anyways, //turning this off prevents awkward zone geometry in places like medbay lobby, for example. @@ -142,13 +141,9 @@ /obj/machinery/door/blast/proc/repair_price() var/sheets_needed = 0 var/dam = maxhealth - health - var/bla = emitter_hits while(dam > 0) dam -= 150 sheets_needed++ - while(bla > 0) - bla -= 10 - sheets_needed++ return sheets_needed // Proc: repair() @@ -156,7 +151,6 @@ // Description: Fully repairs the blast door. /obj/machinery/door/blast/proc/repair() health = maxhealth - emitter_hits = 0 if(stat & BROKEN) stat &= ~BROKEN @@ -184,5 +178,4 @@ obj/machinery/door/blast/regular icon_state_opening = "shutterc0" icon_state_closed = "shutter1" icon_state_closing = "shutterc1" - icon_state = "shutter1" - emitter_resistance = 20 \ No newline at end of file + icon_state = "shutter1" \ No newline at end of file diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index c6f4b5803d..f7058921da 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -16,7 +16,6 @@ var/open_layer = DOOR_OPEN_LAYER var/closed_layer = DOOR_CLOSED_LAYER - var/secondsElectrified = 0 var/visible = 1 var/p_open = 0 var/operating = 0 @@ -27,12 +26,12 @@ var/air_properties_vary_with_direction = 0 var/maxhealth = 300 var/health - var/emitter_hits = 0 // For use when tracking amount of emitter hits taken. - var/emitter_resistance = 10 // Amount of emitter hits doors whistand + var/destroy_hits = 10 //How many strong hits it takes to destroy the door var/min_force = 10 //minimum amount of force needed to damage the door with a melee weapon var/hitsound = 'sound/weapons/smash.ogg' //sound door makes when hit with a weapon var/obj/item/stack/sheet/metal/repairing var/block_air_zones = 1 //If set, air zones cannot merge across the door even when it is opened. + var/close_door_at = 0 //When to automatically close the door, if possible //Multi-tile doors dir = EAST @@ -76,8 +75,23 @@ ..() return -//process() - //return +/obj/machinery/door/process() + if(close_door_at && world.time >= close_door_at) + if(autoclose) + close_door_at = next_close_time() + close() + else + close_door_at = 0 + +/obj/machinery/door/proc/can_open() + if(!density || operating || !ticker) + return 0 + return 1 + +/obj/machinery/door/proc/can_close() + if(density || operating || !ticker) + return 0 + return 1 /obj/machinery/door/Bumped(atom/AM) if(p_open || operating) return @@ -102,15 +116,15 @@ if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access))) open() else - flick("door_deny", src) + do_animate("deny") return - if(istype(AM, /obj/structure/stool/bed/chair/wheelchair)) - var/obj/structure/stool/bed/chair/wheelchair/wheel = AM + if(istype(AM, /obj/structure/bed/chair/wheelchair)) + var/obj/structure/bed/chair/wheelchair/wheel = AM if(density) if(wheel.pulling && (src.allowed(wheel.pulling))) open() else - flick("door_deny", src) + do_animate("deny") return return @@ -127,12 +141,9 @@ if(user.last_airflow > world.time - vsc.airflow_delay) //Fakkit return src.add_fingerprint(user) - if(!src.requiresID()) - user = null - if(density) if(allowed(user)) open() - else flick("door_deny", src) + else do_animate("deny") return /obj/machinery/door/meteorhit(obj/M as obj) @@ -147,18 +158,21 @@ return // Emitter Blasts - these will eventually completely destroy the door, given enough time. - if (istype(Proj, /obj/item/projectile/beam/emitter)) - if(health > 0) - Proj.damage /= 4 - else - emitter_hits ++ - if(emitter_hits >= emitter_resistance) - visible_message("\red [src.name] breaks apart!", 1) - new /obj/effect/decal/cleanable/ash(src.loc) // Turn it to ashes! - del(src) + if (Proj.damage > 90) + destroy_hits-- + if (destroy_hits <= 0) + visible_message("\red \The [src.name] disintegrates!") + switch (Proj.damage_type) + if(BRUTE) + new /obj/item/stack/sheet/metal(src.loc, 2) + new /obj/item/stack/rods(src.loc, 3) + if(BURN) + new /obj/effect/decal/cleanable/ash(src.loc) // Turn it to ashes! + del(src) if(Proj.damage) - take_damage(Proj.damage) + //cap projectile damage so that there's still a minimum number of hits required to break the door + take_damage(min(Proj.damage, 100)) @@ -191,10 +205,6 @@ return if(src.operating > 0 || isrobot(user)) return //borgs can't attack doors open because it conflicts with their AI-like interaction with them. src.add_fingerprint(user) - if(!Adjacent(user)) - user = null - if(!src.requiresID()) - user = null if(istype(I, /obj/item/stack/sheet/metal)) if(stat & BROKEN) @@ -252,7 +262,7 @@ return //psa to whoever coded this, there are plenty of objects that need to call attack() on doors without bludgeoning them. - if(src.density && istype(I, /obj/item/weapon) && user.a_intent == "hurt" && !istype(I, /obj/item/weapon/card)) + if(src.density && istype(I, /obj/item/weapon) && user.a_intent == I_HURT && !istype(I, /obj/item/weapon/card)) var/obj/item/weapon/W = I if(W.damtype == BRUTE || W.damtype == BURN) if(W.force < min_force) @@ -266,7 +276,7 @@ if(src.operating) return if(src.density && (operable() && istype(I, /obj/item/weapon/card/emag))) - flick("door_spark", src) + do_animate("spark") sleep(6) open() operating = -1 @@ -279,8 +289,8 @@ close() return - if(src.density && !(stat & (NOPOWER|BROKEN))) - flick("door_deny", src) + if(src.density) + do_animate("deny") return /obj/machinery/door/proc/take_damage(var/damage) @@ -315,11 +325,6 @@ /obj/machinery/door/emp_act(severity) if(prob(20/severity) && (istype(src,/obj/machinery/door/airlock) || istype(src,/obj/machinery/door/window)) ) open() - if(prob(40/severity)) - if(secondsElectrified == 0) - secondsElectrified = -1 - spawn(300) - secondsElectrified = 0 ..() @@ -362,23 +367,27 @@ flick("o_doorc1", src) else flick("doorc1", src) + if("spark") + if(density) + flick("door_spark", src) if("deny") - flick("door_deny", src) + if(density && !(stat & (NOPOWER|BROKEN))) + flick("door_deny", src) + playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 0) return /obj/machinery/door/proc/open() - if(!density) return 1 - if(operating > 0) return - if(!ticker) return 0 - if(!operating) operating = 1 + if(!can_open()) return + if(!operating) operating = 1 do_animate("opening") icon_state = "door0" src.SetOpacity(0) - sleep(10) - src.layer = open_layer + sleep(3) src.density = 0 + sleep(7) + src.layer = open_layer explosion_resistance = 0 update_icon() SetOpacity(0) @@ -386,26 +395,26 @@ if(operating) operating = 0 - if(autoclose && normalspeed) - spawn(150) - autoclose() - if(autoclose && !normalspeed) - spawn(5) - autoclose() + if(autoclose) + close_door_at = next_close_time() return 1 +/obj/machinery/door/proc/next_close_time() + return world.time + (normalspeed ? 150 : 5) /obj/machinery/door/proc/close() - if(density) return 1 - if(operating > 0) return + if(!can_close()) + return operating = 1 + close_door_at = 0 + do_animate("closing") + sleep(3) src.density = 1 explosion_resistance = initial(explosion_resistance) src.layer = closed_layer - do_animate("closing") - sleep(10) + sleep(7) update_icon() if(visible && !glass) SetOpacity(1) //caaaaarn! @@ -421,6 +430,11 @@ /obj/machinery/door/proc/requiresID() return 1 +/obj/machinery/door/allowed(mob/M) + if(!requiresID()) + return ..(null) //don't care who they are or what they have, act as if they're NOTHING + return ..(M) + /obj/machinery/door/update_nearby_tiles(need_rebuild) if(!air_master) return 0 @@ -438,12 +452,6 @@ else source.thermal_conductivity = initial(source.thermal_conductivity) -/obj/machinery/door/proc/autoclose() - var/obj/machinery/door/airlock/A = src - if(!A.density && !A.operating && !A.locked && !A.welded && !(A.stat & (BROKEN|NOPOWER)) && A.autoclose) - close() - return - /obj/machinery/door/Move(new_loc, new_dir) //update_nearby_tiles() . = ..() diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 8799273b93..9ae8751a7a 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -22,7 +22,7 @@ open_layer = DOOR_OPEN_LAYER - 0.01 // Just below doors when open closed_layer = DOOR_CLOSED_LAYER + 0.01 // Just above doors when closed - //These are frequenly used with windows, so make sure zones can pass. + //These are frequenly used with windows, so make sure zones can pass. //Generally if a firedoor is at a place where there should be a zone boundery then there will be a regular door underneath it. block_air_zones = 0 @@ -149,7 +149,7 @@ "\The [src]", "Yes, [density ? "open" : "close"]", "No") if(answer == "No") return - if(user.stat || user.stunned || user.weakened || user.paralysis || (!user.canmove && !isAI(user)) || (get_dist(src, user) > 1 && !isAI(user))) + if(user.stat || user.stunned || user.weakened || user.paralysis || (!user.canmove && !user.isSilicon()) || (get_dist(src, user) > 1 && !isAI(user))) user << "Sorry, you must remain able bodied and close to \the [src] in order to use it." return if(density && (stat & (BROKEN|NOPOWER))) //can still close without power @@ -169,7 +169,7 @@ if(alarmed) // Accountability! users_to_open |= user.name - needs_to_close = 1 + needs_to_close = !user.isSilicon() spawn() open() else @@ -272,7 +272,7 @@ spawn(0) close() return - + return ..() // CHECK PRESSURE diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 209b993788..362753cac8 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -24,9 +24,35 @@ src.base_state = src.icon_state return +/obj/machinery/door/window/proc/shatter(var/display_message = 1) + new /obj/item/weapon/shard(src.loc) + var/obj/item/stack/cable_coil/CC = new /obj/item/stack/cable_coil(src.loc) + CC.amount = 2 + var/obj/item/weapon/airlock_electronics/ae + if(!electronics) + ae = new/obj/item/weapon/airlock_electronics( src.loc ) + if(!src.req_access) + src.check_access() + if(src.req_access.len) + ae.conf_access = src.req_access + else if (src.req_one_access.len) + ae.conf_access = src.req_one_access + ae.one_access = 1 + else + ae = electronics + electronics = null + ae.loc = src.loc + if(operating == -1) + ae.icon_state = "door_electronics_smoked" + operating = 0 + src.density = 0 + playsound(src, "shatter", 70, 1) + if(display_message) + visible_message("[src] shatters!") + del(src) + /obj/machinery/door/window/Del() density = 0 - playsound(src, "shatter", 70, 1) update_nearby_tiles() ..() @@ -120,28 +146,7 @@ /obj/machinery/door/window/take_damage(var/damage) src.health = max(0, src.health - damage) if (src.health <= 0) - new /obj/item/weapon/shard(src.loc) - var/obj/item/stack/cable_coil/CC = new /obj/item/stack/cable_coil(src.loc) - CC.amount = 2 - var/obj/item/weapon/airlock_electronics/ae - if(!electronics) - ae = new/obj/item/weapon/airlock_electronics( src.loc ) - if(!src.req_access) - src.check_access() - if(src.req_access.len) - ae.conf_access = src.req_access - else if (src.req_one_access.len) - ae.conf_access = src.req_one_access - ae.one_access = 1 - else - ae = electronics - electronics = null - ae.loc = src.loc - if(operating == -1) - ae.icon_state = "door_electronics_smoked" - operating = 0 - src.density = 0 - del(src) + shatter() return /obj/machinery/door/window/attack_ai(mob/user as mob) @@ -215,7 +220,7 @@ ae.icon_state = "door_electronics_smoked" operating = 0 - del(src) + shatter(src) return //If it's a weapon, smash windoor. Unless it's an id card, agent card, ect.. then ignore it (Cards really shouldnt damage a door anyway) @@ -229,9 +234,6 @@ src.add_fingerprint(user) - if (!src.requiresID()) - //don't care who they are or what they have, act as if they're NOTHING - user = null if (src.allowed(user)) if (src.density) diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index c6744ef96a..dbe7f1b8a7 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -13,9 +13,6 @@ var/list/doppler_arrays = list() doppler_arrays -= src ..() -/obj/machinery/doppler_array/process() - return PROCESS_KILL - /obj/machinery/doppler_array/proc/sense_explosion(var/x0,var/y0,var/z0,var/devastation_range,var/heavy_impact_range,var/light_impact_range,var/took) if(stat & NOPOWER) return if(z != z0) return diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index 632fee8215..4f310de8b9 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -12,6 +12,8 @@ var/strength = 10 //How weakened targets are when flashed. var/base_state = "mflash" anchored = 1 + use_power = 1 + idle_power_usage = 2 /obj/machinery/flasher/portable //Portable version of the flasher. Only flashes when anchored name = "portable flasher" @@ -119,17 +121,13 @@ user.show_message(text("\red [src] is now secured.")) src.overlays += "[base_state]-s" -/obj/machinery/flasher_button/attack_ai(mob/user as mob) - return src.attack_hand(user) +/obj/machinery/button/flasher + name = "flasher button" + desc = "A remote control switch for a mounted flasher." -/obj/machinery/flasher_button/attackby(obj/item/weapon/W, mob/user as mob) - return src.attack_hand(user) +/obj/machinery/button/flasher/attack_hand(mob/user as mob) -/obj/machinery/flasher_button/attack_hand(mob/user as mob) - - if(stat & (NOPOWER|BROKEN)) - return - if(active) + if(..()) return use_power(5) @@ -137,7 +135,7 @@ active = 1 icon_state = "launcheract" - for(var/obj/machinery/flasher/M in world) + for(var/obj/machinery/flasher/M in machines) if(M.id == src.id) spawn() M.flash() diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 68009eec60..a286b530ca 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -24,10 +24,12 @@ Possible to do for anyone motivated enough: * Holopad */ -// HOLOPAD MODE -// 0 = RANGE BASED -// 1 = AREA BASED -var/const/HOLOPAD_MODE = 0 +#define HOLOPAD_PASSIVE_POWER_USAGE 1 +#define HOLOGRAM_POWER_USAGE 2 +#define RANGE_BASED 4 +#define AREA_BASED 6 + +var/const/HOLOPAD_MODE = RANGE_BASED /obj/machinery/hologram/holopad name = "\improper AI holopad" @@ -35,8 +37,12 @@ var/const/HOLOPAD_MODE = 0 icon_state = "holopad0" layer = TURF_LAYER+0.1 //Preventing mice and drones from sneaking under them. + + var/power_per_hologram = 500 //per usage per hologram + idle_power_usage = 5 + use_power = 1 - var/mob/living/silicon/ai/master//Which AI, if any, is controlling the object? Only one AI may control a hologram at any time. + var/list/mob/living/silicon/ai/masters = new() //List of AIs that use the holopad var/last_request = 0 //to prevent request spam. ~Carn var/holo_range = 5 // Change to change how far the AI can move away from the holopad before deactivating. @@ -62,99 +68,104 @@ var/const/HOLOPAD_MODE = 0 This may change in the future but for now will suffice.*/ if(user.eyeobj.loc != src.loc)//Set client eye on the object if it's not already. user.eyeobj.setLoc(get_turf(src)) - else if(!hologram)//If there is no hologram, possibly make one. + else if(!masters[user])//If there is no hologram, possibly make one. activate_holo(user) - else if(master==user)//If there is a hologram, remove it. But only if the user is the master. Otherwise do nothing. - clear_holo() + else//If there is a hologram, remove it. + clear_holo(user) return /obj/machinery/hologram/holopad/proc/activate_holo(mob/living/silicon/ai/user) - if(!(stat & NOPOWER) && user.eyeobj.loc == src.loc)//If the projector has power and client eye is on it. - if(!hologram)//If there is not already a hologram. - create_holo(user)//Create one. - src.visible_message("A holographic image of [user] flicks to life right before your eyes!") - else - user << "\red ERROR: \black Image feed in progress." + if(!(stat & NOPOWER) && user.eyeobj.loc == src.loc)//If the projector has power and client eye is on it + if (user.holo) + user << "ERROR: Image feed in progress." + return + create_holo(user)//Create one. + src.visible_message("A holographic image of [user] flicks to life right before your eyes!") else - user << "\red ERROR: \black Unable to project hologram." + user << "ERROR: Unable to project hologram." return /*This is the proc for special two-way communication between AI and holopad/people talking near holopad. For the other part of the code, check silicon say.dm. Particularly robot talk.*/ /obj/machinery/hologram/holopad/hear_talk(mob/living/M, text, verb, datum/language/speaking) - if(M&&hologram&&master)//Master is mostly a safety in case lag hits or something. - if(!master.say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad. + if(M) + for(var/mob/living/silicon/ai/master in masters) + if(!master.say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad. + if(speaking) + text = speaking.scramble(text) + else + text = stars(text) + var/name_used = M.GetVoice() + //This communication is imperfect because the holopad "filters" voices and is only designed to connect to the master only. + var/rendered if(speaking) - text = speaking.scramble(text) + rendered = "Holopad received, [name_used] [speaking.format_message(text, verb)]" else - text = stars(text) - var/name_used = M.GetVoice() - //This communication is imperfect because the holopad "filters" voices and is only designed to connect to the master only. - var/rendered - if(speaking) - rendered = "Holopad received, [name_used] [speaking.format_message(text, verb)]" - else - rendered = "Holopad received, [name_used] [verb], \"[text]\"" - master.show_message(rendered, 2) - return + rendered = "Holopad received, [name_used] [verb], \"[text]\"" + master.show_message(rendered, 2) /obj/machinery/hologram/holopad/see_emote(mob/living/M, text) - if(M && hologram && master) - //var/name_used = M.GetVoice() - var/rendered = "Holopad received, [text]" - //The lack of name_used is needed, because message already contains a name. This is needed for simple mobs to emote properly. - master.show_message(rendered, 2) + if(M) + for(var/mob/living/silicon/ai/master in masters) + //var/name_used = M.GetVoice() + var/rendered = "Holopad received, [text]" + //The lack of name_used is needed, because message already contains a name. This is needed for simple mobs to emote properly. + master.show_message(rendered, 2) return /obj/machinery/hologram/holopad/proc/create_holo(mob/living/silicon/ai/A, turf/T = loc) - hologram = new(T)//Spawn a blank effect at the location. + var/obj/effect/overlay/hologram = new(T)//Spawn a blank effect at the location. hologram.icon = A.holo_icon hologram.mouse_opacity = 0//So you can't click on it. hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. hologram.anchored = 1//So space wind cannot drag it. hologram.name = "[A.name] (Hologram)"//If someone decides to right click. hologram.SetLuminosity(2) //hologram lighting + hologram.color = color //painted holopad gives coloured holograms + masters[A] = hologram SetLuminosity(2) //pad lighting icon_state = "holopad1" A.holo = src - master = A//AI is the master. - use_power = 2//Active power usage. return 1 -/obj/machinery/hologram/holopad/proc/clear_holo() -// hologram.SetLuminosity(0)//Clear lighting. //handled by the lighting controller when its ower is deleted - del(hologram)//Get rid of hologram. - if(master.holo == src) - master.holo = null - master = null//Null the master, since no-one is using it now. - SetLuminosity(0) //pad lighting (hologram lighting will be handled automatically since its owner was deleted) - icon_state = "holopad0" - use_power = 1//Passive power usage. +/obj/machinery/hologram/holopad/proc/clear_holo(mob/living/silicon/ai/user) + if(user.holo == src) + user.holo = null + del(masters[user])//Get rid of user's hologram //qdel + masters -= user //Discard AI from the list of those who use holopad + if (!masters.len)//If no users left + SetLuminosity(0) //pad lighting (hologram lighting will be handled automatically since its owner was deleted) + icon_state = "holopad0" return 1 /obj/machinery/hologram/holopad/process() - if(hologram)//If there is a hologram. - if(master && !master.stat && master.client && master.eyeobj)//If there is an AI attached, it's not incapacitated, it has a client, and the client eye is centered on the projector. - if(!(stat & NOPOWER))//If the machine has power. - if((HOLOPAD_MODE == 0 && (get_dist(master.eyeobj, src) <= holo_range))) - return 1 + for (var/mob/living/silicon/ai/master in masters) + var/active_ai = (master && !master.stat && master.client && master.eyeobj)//If there is an AI attached, it's not incapacitated, it has a client, and the client eye is centered on the projector. + if((stat & NOPOWER) || !active_ai) + clear_holo(master) + continue + + if((HOLOPAD_MODE == RANGE_BASED && (get_dist(master.eyeobj, src) > holo_range))) + clear_holo(master) + continue + + if(HOLOPAD_MODE == AREA_BASED) + var/area/holo_area = get_area(src) + var/area/eye_area = get_area(master.eyeobj) + + if(!(eye_area in holo_area.master.related)) + clear_holo(master) + continue - else if (HOLOPAD_MODE == 1) - - var/area/holo_area = get_area(src) - var/area/eye_area = get_area(master.eyeobj) - - if(eye_area in holo_area.master.related) - return 1 - - clear_holo()//If not, we want to get rid of the hologram. + use_power(power_per_hologram) return 1 -/obj/machinery/hologram/holopad/proc/move_hologram() - if(hologram) - step_to(hologram, master.eyeobj) // So it turns. - hologram.loc = get_turf(master.eyeobj) - +/obj/machinery/hologram/holopad/proc/move_hologram(mob/living/silicon/ai/user) + if(masters[user]) + step_to(masters[user], user.eyeobj) // So it turns. + var/obj/effect/overlay/H = masters[user] + H.loc = get_turf(user.eyeobj) + masters[user] = H return 1 /* @@ -166,7 +177,6 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ use_power = 1 idle_power_usage = 5 active_power_usage = 100 - var/obj/effect/overlay/hologram//The projection itself. If there is one, the instrument is on, off otherwise. //Destruction procs. /obj/machinery/hologram/ex_act(severity) @@ -189,9 +199,9 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ del(src) return -/obj/machinery/hologram/Del() - if(hologram) - src:clear_holo() +/obj/machinery/hologram/holopad/Del() + for (var/mob/living/silicon/ai/master in masters) + clear_holo(master) ..() /* @@ -223,3 +233,9 @@ Holographic project of everything else. desc = "It makes a hologram appear...with magnets or something..." icon = 'icons/obj/stationobjs.dmi' icon_state = "hologram0" + + +#undef RANGE_BASED +#undef AREA_BASED +#undef HOLOPAD_PASSIVE_POWER_USAGE +#undef HOLOGRAM_POWER_USAGE diff --git a/code/game/machinery/holosign.dm b/code/game/machinery/holosign.dm index a4bd1456cf..e51025aee2 100644 --- a/code/game/machinery/holosign.dm +++ b/code/game/machinery/holosign.dm @@ -5,26 +5,31 @@ icon = 'icons/obj/holosign.dmi' icon_state = "sign_off" layer = 4 + use_power = 1 + idle_power_usage = 2 + active_power_usage = 4 var/lit = 0 var/id = null var/on_icon = "sign_on" - proc/toggle() - if (stat & (BROKEN|NOPOWER)) - return - lit = !lit - update_icon() - +/obj/machinery/holosign/proc/toggle() + if (stat & (BROKEN|NOPOWER)) + return + lit = !lit + use_power = lit ? 2 : 1 update_icon() - if (!lit) - icon_state = "sign_off" - else - icon_state = on_icon - power_change() - if (stat & NOPOWER) - lit = 0 - update_icon() +/obj/machinery/holosign/update_icon() + if (!lit) + icon_state = "sign_off" + else + icon_state = on_icon + +/obj/machinery/holosign/power_change() + if (stat & NOPOWER) + lit = 0 + use_power = 0 + update_icon() /obj/machinery/holosign/surgery name = "surgery holosign" @@ -32,42 +37,23 @@ on_icon = "surgery" ////////////////////SWITCH/////////////////////////////////////// -/obj/machinery/holosign_switch +/obj/machinery/button/holosign name = "holosign switch" - icon = 'icons/obj/power.dmi' - icon_state = "light1" desc = "A remote control switch for holosign." - var/id = null - var/active = 0 - anchored = 1.0 - use_power = 1 - idle_power_usage = 2 - active_power_usage = 4 + icon = 'icons/obj/power.dmi' + icon_state = "crema_switch" -/obj/machinery/holosign_switch/attack_ai(mob/user as mob) - return src.attack_hand(user) -/ - -/obj/machinery/holosign_switch/attackby(obj/item/weapon/W, mob/user as mob) - if(istype(W, /obj/item/device/detective_scanner)) - return - return src.attack_hand(user) - -/obj/machinery/holosign_switch/attack_hand(mob/user as mob) - src.add_fingerprint(usr) - if(stat & (NOPOWER|BROKEN)) +/obj/machinery/button/holosign/attack_hand(mob/user as mob) + if(..()) return add_fingerprint(user) use_power(5) active = !active - if(active) - icon_state = "light1" - else - icon_state = "light0" + icon_state = "light[active]" - for(var/obj/machinery/holosign/M in world) + for(var/obj/machinery/holosign/M in machines) if (M.id == src.id) spawn( 0 ) M.toggle() diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index 500c2cf061..50dc4e10b2 100755 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -53,6 +53,10 @@ var/last_spark = 0 var/base_state = "migniter" anchored = 1 + use_power = 1 + idle_power_usage = 2 + active_power_usage = 4 + /obj/machinery/sparker/New() ..() @@ -115,17 +119,13 @@ ignite() ..(severity) -/obj/machinery/ignition_switch/attack_ai(mob/user as mob) - return src.attack_hand(user) +/obj/machinery/button/ignition + name = "ignition switch" + desc = "A remote control switch for a mounted igniter." -/obj/machinery/ignition_switch/attackby(obj/item/weapon/W, mob/user as mob) - return src.attack_hand(user) +/obj/machinery/button/ignition/attack_hand(mob/user as mob) -/obj/machinery/ignition_switch/attack_hand(mob/user as mob) - - if(stat & (NOPOWER|BROKEN)) - return - if(active) + if(..()) return use_power(5) @@ -133,12 +133,12 @@ active = 1 icon_state = "launcheract" - for(var/obj/machinery/sparker/M in world) + for(var/obj/machinery/sparker/M in machines) if (M.id == src.id) spawn( 0 ) M.ignite() - for(var/obj/machinery/igniter/M in world) + for(var/obj/machinery/igniter/M in machines) if(M.id == src.id) use_power(50) M.on = !( M.on ) diff --git a/code/game/machinery/jukebox.dm b/code/game/machinery/jukebox.dm index 2a6755015b..972f51bd48 100644 --- a/code/game/machinery/jukebox.dm +++ b/code/game/machinery/jukebox.dm @@ -16,6 +16,9 @@ datum/track/New(var/title_name, var/audio) anchored = 1 density = 1 power_channel = EQUIP + use_power = 1 + idle_power_usage = 10 + active_power_usage = 100 var/playing = 0 @@ -32,6 +35,7 @@ datum/track/New(var/title_name, var/audio) new/datum/track("Trai`Tor", 'sound/music/traitor.ogg'), ) + /obj/machinery/media/jukebox/Del() StopPlaying() ..() @@ -182,13 +186,15 @@ datum/track/New(var/title_name, var/audio) return ..() /obj/machinery/media/jukebox/proc/StopPlaying() - var/area/A = get_area(src) + var/area/main_area = get_area(src) // Always kill the current sound - for(var/mob/living/M in mobs_in_area(A)) - M << sound(null, channel = 1) + for(var/area/related_area in main_area.related) + for(var/mob/living/M in mobs_in_area(related_area)) + M << sound(null, channel = 1) - A.forced_ambience = null + related_area.forced_ambience = null playing = 0 + update_use_power(1) update_icon() @@ -197,12 +203,14 @@ datum/track/New(var/title_name, var/audio) if(!current_track) return - var/area/A = get_area(src) - A.forced_ambience = sound(current_track.sound, channel = 1, repeat = 1, volume = 25) + var/area/main_area = get_area(src) + for(var/area/related_area in main_area.related) + related_area.forced_ambience = sound(current_track.sound, channel = 1, repeat = 1, volume = 25) - for(var/mob/living/M in mobs_in_area(A)) - if(M.mind) - A.play_ambience(M) + for(var/mob/living/M in mobs_in_area(related_area)) + if(M.mind) + related_area.play_ambience(related_area) playing = 1 + update_use_power(2) update_icon() diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index 52c1bdc380..74e7de9934 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -194,10 +194,9 @@ if(critter.meat_type) slab_type = critter.meat_type else if(istype(src.occupant,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = occupant slab_name = src.occupant.real_name - slab_type = /obj/item/weapon/reagent_containers/food/snacks/meat/human - else if(istype(src.occupant, /mob/living/carbon/monkey)) - slab_type = /obj/item/weapon/reagent_containers/food/snacks/meat/monkey + slab_type = H.species.meat_type // Small mobs don't give as much nutrition. if(src.occupant.small) diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index bec0006de9..fbdcfd2760 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -42,11 +42,11 @@ acceptable_reagents |= reagent if (recipe.items) max_n_of_items = max(max_n_of_items,recipe.items.len) - // This will do until I can think of a fun recipe to use dionaea in - // will also allow anything using the holder item to be microwaved into // impure carbon. ~Z acceptable_items |= /obj/item/weapon/holder + acceptable_items |= /obj/item/weapon/reagent_containers/food/snacks/grown /******************* * Item Adding @@ -274,7 +274,7 @@ cooked.loc = src.loc return -/obj/machinery/microwave/proc/wzhzhzh(var/seconds as num) +/obj/machinery/microwave/proc/wzhzhzh(var/seconds as num) // Whoever named this proc is fucking literally Satan. ~ Z for (var/i=1 to seconds) if (stat & (NOPOWER|BROKEN)) return 0 diff --git a/code/game/machinery/kitchen/processor.dm b/code/game/machinery/kitchen/processor.dm deleted file mode 100644 index 3b86ea400e..0000000000 --- a/code/game/machinery/kitchen/processor.dm +++ /dev/null @@ -1,148 +0,0 @@ -/obj/machinery/processor - name = "Food Processor" - icon = 'icons/obj/kitchen.dmi' - icon_state = "processor" - layer = 2.9 - density = 1 - anchored = 1 - var/broken = 0 - var/processing = 0 - use_power = 1 - idle_power_usage = 5 - active_power_usage = 50 - - - -/datum/food_processor_process - var/input - var/output - var/time = 40 - proc/process(loc, what) - if (src.output && loc) - new src.output(loc) - if (what) - del(what) - - /* objs */ - meat - input = /obj/item/weapon/reagent_containers/food/snacks/meat - output = /obj/item/weapon/reagent_containers/food/snacks/meatball - - potato - input = /obj/item/weapon/reagent_containers/food/snacks/grown/potato - output = /obj/item/weapon/reagent_containers/food/snacks/rawsticks - - carrot - input = /obj/item/weapon/reagent_containers/food/snacks/grown/carrot - output = /obj/item/weapon/reagent_containers/food/snacks/carrotfries - - soybeans - input = /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans - output = /obj/item/weapon/reagent_containers/food/snacks/soydope - - wheat - input = /obj/item/weapon/reagent_containers/food/snacks/grown/wheat - output = /obj/item/weapon/reagent_containers/food/snacks/flour - - spaghetti - input = /obj/item/weapon/reagent_containers/food/snacks/flour - output = /obj/item/weapon/reagent_containers/food/snacks/spagetti - - /* mobs */ - mob - process(loc, what) - ..() - - - slime - input = /mob/living/carbon/slime - output = /obj/item/weapon/reagent_containers/glass/beaker/slime - - monkey - process(loc, what) - var/mob/living/carbon/monkey/O = what - if (O.client) //grief-proof - O.loc = loc - O.visible_message("\blue Suddenly [O] jumps out from the processor!", \ - "You jump out from the processor", \ - "You hear chimp") - return - var/obj/item/weapon/reagent_containers/glass/bucket/bucket_of_blood = new(loc) - var/datum/reagent/blood/B = new() - B.holder = bucket_of_blood - B.volume = 70 - //set reagent data - B.data["donor"] = O - - for(var/datum/disease/D in O.viruses) - if(D.spread_type != SPECIAL) - B.data["viruses"] += D.Copy() - - B.data["blood_DNA"] = copytext(O.dna.unique_enzymes,1,0) - if(O.resistances&&O.resistances.len) - B.data["resistances"] = O.resistances.Copy() - bucket_of_blood.reagents.reagent_list += B - bucket_of_blood.reagents.update_total() - bucket_of_blood.on_reagent_change() - //bucket_of_blood.reagents.handle_reactions() //blood doesn't react - ..() - - input = /mob/living/carbon/monkey - output = null - -/obj/machinery/processor/proc/select_recipe(var/X) - for (var/Type in typesof(/datum/food_processor_process) - /datum/food_processor_process - /datum/food_processor_process/mob) - var/datum/food_processor_process/P = new Type() - if (!istype(X, P.input)) - continue - return P - return 0 - -/obj/machinery/processor/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(src.processing) - user << "\red The processor is in the process of processing." - return 1 - if(src.contents.len > 0) //TODO: several items at once? several different items? - user << "\red Something is already in the processing chamber." - return 1 - var/what = O - if (istype(O, /obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = O - what = G.affecting - - var/datum/food_processor_process/P = select_recipe(what) - if (!P) - user << "\red That probably won't blend." - return 1 - user.visible_message("[user] put [what] into [src].", \ - "You put the [what] into [src].") - user.drop_item() - what:loc = src - return - -/obj/machinery/processor/attack_hand(var/mob/user as mob) - if (src.stat != 0) //NOPOWER etc - return - if(src.processing) - user << "\red The processor is in the process of processing." - return 1 - if(src.contents.len == 0) - user << "\red The processor is empty." - return 1 - for(var/O in src.contents) - var/datum/food_processor_process/P = select_recipe(O) - if (!P) - log_admin("DEBUG: [O] in processor havent suitable recipe. How do you put it in?") //-rastaf0 - continue - src.processing = 1 - user.visible_message("\blue [user] turns on \a [src].", \ - "You turn on \a [src].", \ - "You hear a food processor.") - playsound(src.loc, 'sound/machines/blender.ogg', 50, 1) - use_power(500) - sleep(P.time) - P.process(src.loc, O) - src.processing = 0 - src.visible_message("\blue \the [src] finished processing.", \ - "You hear the food processor stopping/") - diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm index 15f76f191f..1b1bb9bfb5 100644 --- a/code/game/machinery/kitchen/smartfridge.dm +++ b/code/game/machinery/kitchen/smartfridge.dm @@ -16,17 +16,14 @@ var/icon_off = "smartfridge-off" var/icon_panel = "smartfridge-panel" var/item_quants = list() - var/ispowered = 1 //starts powered - var/isbroken = 0 var/seconds_electrified = 0; var/shoot_inventory = 0 var/locked = 0 - var/panel_open = 0 //Hacking a smartfridge var/scan_id = 1 var/is_secure = 0 var/datum/wires/smartfridge/wires = null -/obj/machinery/smartfridge/secure/ +/obj/machinery/smartfridge/secure is_secure = 1 /obj/machinery/smartfridge/New() @@ -61,7 +58,7 @@ /obj/machinery/smartfridge/secure/extract name = "\improper Slime Extract Storage" desc = "A refrigerated storage unit for slime extracts" - req_access_txt = "47" + req_access = list(access_research) /obj/machinery/smartfridge/secure/extract/accept_check(var/obj/item/O as obj) if(istype(O,/obj/item/slime_extract)) @@ -73,7 +70,7 @@ desc = "A refrigerated storage unit for storing medicine and chemicals." icon_state = "smartfridge" //To fix the icon in the map editor. icon_on = "smartfridge_chem" - req_one_access_txt = "5;33" + req_one_access = list(access_medical,access_chemistry) /obj/machinery/smartfridge/secure/medbay/accept_check(var/obj/item/O as obj) if(istype(O,/obj/item/weapon/reagent_containers/glass/)) @@ -87,7 +84,7 @@ /obj/machinery/smartfridge/secure/virology name = "\improper Refrigerated Virus Storage" desc = "A refrigerated storage unit for storing viral material." - req_access_txt = "39" + req_access = list(access_virology) icon_state = "smartfridge_virology" icon_on = "smartfridge_virology" icon_off = "smartfridge_virology-off" @@ -121,8 +118,39 @@ if(istype(O,/obj/item/weapon/reagent_containers/glass) || istype(O,/obj/item/weapon/reagent_containers/food/drinks) || istype(O,/obj/item/weapon/reagent_containers/food/condiment)) return 1 +/obj/machinery/smartfridge/drying_rack + name = "\improper Drying Rack" + desc = "A machine for drying plants." + +/obj/machinery/smartfridge/drying_rack/accept_check(var/obj/item/O as obj) + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/)) + var/obj/item/weapon/reagent_containers/food/snacks/S = O + if (S.dried_type) + return 1 + return 0 + +/obj/machinery/smartfridge/drying_rack/process() + ..() + if (contents.len) + dry() + +/obj/machinery/smartfridge/drying_rack/proc/dry() + for(var/obj/item/weapon/reagent_containers/food/snacks/S in contents) + if(S.dried_type == S.type) + S.dry = 1 + item_quants[S.name]-- + S.name = "dried [S.name]" + S.loc = loc + else + var/D = S.dried_type + new D(loc) + item_quants[S.name]-- + del(S) + return + return + /obj/machinery/smartfridge/process() - if(!src.ispowered) + if(stat & (BROKEN|NOPOWER)) return if(src.seconds_electrified > 0) src.seconds_electrified-- @@ -130,16 +158,16 @@ src.throw_item() /obj/machinery/smartfridge/power_change() + var/old_stat = stat ..() - if( !(stat & NOPOWER) ) - src.ispowered = 1 - if(!isbroken) - icon_state = icon_on + if(old_stat != stat) + update_icon() + +/obj/machinery/smartfridge/update_icon() + if(stat & (BROKEN|NOPOWER)) + icon_state = icon_off else - spawn(rand(0, 15)) - src.ispowered = 0 - if(!isbroken) - icon_state = icon_off + icon_state = icon_on /******************* * Item Adding @@ -148,7 +176,7 @@ /obj/machinery/smartfridge/attackby(var/obj/item/O as obj, var/mob/user as mob) if(istype(O, /obj/item/weapon/screwdriver)) panel_open = !panel_open - user << "You [panel_open ? "open" : "close"] the maintenance panel." + user.visible_message("[user] [panel_open ? "opens" : "closes"] the maintenance panel of \the [src].", "You [panel_open ? "open" : "close"] the maintenance panel of \the [src].") overlays.Cut() if(panel_open) overlays += image(icon, icon_panel) @@ -160,7 +188,7 @@ attack_hand(user) return - if(!src.ispowered) + if(stat & NOPOWER) user << "\The [src] is unpowered and useless." return @@ -175,13 +203,12 @@ item_quants[O.name]++ else item_quants[O.name] = 1 - user.visible_message("[user] has added \the [O] to \the [src].", \ - "You add \the [O] to \the [src].") + user.visible_message("[user] has added \the [O] to \the [src].", "You add \the [O] to \the [src].") nanomanager.update_uis(src) - else if(istype(O, /obj/item/weapon/storage/bag/plants)) - var/obj/item/weapon/storage/bag/plants/P = O + else if(istype(O, /obj/item/weapon/storage/bag)) + var/obj/item/weapon/storage/bag/P = O var/plants_loaded = 0 for(var/obj/G in P.contents) if(accept_check(G)) @@ -197,9 +224,7 @@ plants_loaded++ if(plants_loaded) - user.visible_message( \ - "[user] loads \the [src] with \the [P].", \ - "You load \the [src] with \the [P].") + user.visible_message("[user] loads \the [src] with \the [P].", "You load \the [src] with \the [P].") if(P.contents.len > 0) user << "Some items are refused." @@ -210,7 +235,7 @@ return 1 /obj/machinery/smartfridge/secure/attackby(var/obj/item/O as obj, var/mob/user as mob) - if (istype(O, /obj/item/weapon/card/emag)) + if(istype(O, /obj/item/weapon/card/emag)) emagged = 1 locked = -1 user << "You short out the product lock on [src]." @@ -222,7 +247,8 @@ return 0 /obj/machinery/smartfridge/attack_hand(mob/user as mob) - if(!ispowered) return + if(stat & (NOPOWER|BROKEN)) + return wires.Interact(user) ui_interact(user) @@ -244,32 +270,32 @@ for (var/i=1 to length(item_quants)) var/K = item_quants[i] var/count = item_quants[K] - if (count > 0) + if(count > 0) items.Add(list(list("display_name" = html_encode(capitalize(K)), "vend" = i, "quantity" = count))) - if (items.len > 0) + if(items.len > 0) data["contents"] = items ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) + if(!ui) ui = new(user, src, ui_key, "smartfridge.tmpl", src.name, 400, 500) ui.set_initial_data(data) ui.open() /obj/machinery/smartfridge/Topic(href, href_list) - if (..()) return 0 + if(..()) return 0 var/mob/user = usr var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") src.add_fingerprint(user) - if (href_list["close"]) + if(href_list["close"]) user.unset_machine() ui.close() return 0 - if (href_list["vend"]) + if(href_list["vend"]) var/index = text2num(href_list["vend"]) var/amount = text2num(href_list["amount"]) var/K = item_quants[index] @@ -281,10 +307,10 @@ var/i = amount for(var/obj/O in contents) - if (O.name == K) + if(O.name == K) O.loc = loc i-- - if (i <= 0) + if(i <= 0) return 1 return 1 @@ -319,9 +345,9 @@ *************************/ /obj/machinery/smartfridge/secure/Topic(href, href_list) - if(!ispowered) return 0 - if (usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) - if (!allowed(usr) && !emagged && locked != -1 && href_list["vend"]) - usr << "\red Access denied." + if(stat & (NOPOWER|BROKEN)) return 0 + if(usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) + if(!allowed(usr) && !emagged && locked != -1 && href_list["vend"]) + usr << "Access denied." return 0 return ..() diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 1c9a9bd21d..dcf66a12b7 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -15,7 +15,7 @@ /obj/machinery/light_switch/New() ..() spawn(5) - src.area = src.loc.loc + src.area = get_area(src) if(otherarea) src.area = locate(text2path("/area/[otherarea]")) @@ -32,10 +32,7 @@ if(stat & NOPOWER) icon_state = "light-p" else - if(on) - icon_state = "light1" - else - icon_state = "light0" + icon_state = "light[on]" /obj/machinery/light_switch/examine(mob/user) if(..(user, 1)) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 4d192c5dd9..c573229a10 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -28,6 +28,9 @@ Class Variables: component_parts (list) A list of component parts of machine used by frame based machines. + panel_open (num) + Whether the panel is open + uid (num) Unique id of machine across all machines. @@ -43,9 +46,6 @@ Class Variables: MAINT:8 -- machine is currently under going maintenance. EMPED:16 -- temporary broken by EMP pulse - manual (num) - Currently unused. - Class Procs: New() 'game/machinery/machine.dm' @@ -104,13 +104,12 @@ Class Procs: //2 = run auto, use active var/idle_power_usage = 0 var/active_power_usage = 0 - var/power_channel = EQUIP - //EQUIP,ENVIRON or LIGHT - var/list/component_parts = list() //list of all the parts used to build it, if made from certain kinds of frames. + var/power_channel = EQUIP //EQUIP, ENVIRON or LIGHT + var/list/component_parts = null //list of all the parts used to build it, if made from certain kinds of frames. var/uid - var/manual = 0 - var/interact_offline = 0 // Can the machine be interacted with while de-powered. + var/panel_open = 0 var/global/gl_uid = 1 + var/interact_offline = 0 // Can the machine be interacted with while de-powered. /obj/machinery/New(l, d=0) ..(l) @@ -127,7 +126,10 @@ Class Procs: ..() /obj/machinery/process()//If you dont use process or power why are you here - return PROCESS_KILL + if(!(use_power || idle_power_usage || active_power_usage)) + return PROCESS_KILL + + return /obj/machinery/emp_act(severity) if(use_power && stat == 0) @@ -183,67 +185,18 @@ Class Procs: /obj/machinery/proc/inoperable(var/additional_flags = 0) return (stat & (NOPOWER|BROKEN|additional_flags)) +/obj/machinery/CanUseTopic(var/mob/user, var/be_close) + if(!interact_offline && (stat & (NOPOWER|BROKEN))) + return STATUS_CLOSE -/obj/machinery/Topic(href, href_list, var/nowindow = 0, var/checkrange = 1) - if(..()) - return 1 - if(!can_be_used_by(usr, be_close = checkrange)) - return 1 - add_fingerprint(usr) - return 0 + return ..() -/obj/machinery/proc/can_be_used_by(mob/user, be_close = 1) - if(!interact_offline && stat & (NOPOWER|BROKEN)) - return 0 - if(!user.canUseTopic(src, be_close)) - return 0 - return 1 +/obj/machinery/CouldUseTopic(var/mob/user) + ..() + user.set_machine(src) -//////////////////////////////////////////////////////////////////////////////////////////// - -/mob/proc/canUseTopic(atom/movable/M, be_close = 1) - return - -/mob/dead/observer/canUseTopic(atom/movable/M, be_close = 1) - if(check_rights(R_ADMIN, 0)) - return - -/mob/living/canUseTopic(atom/movable/M, be_close = 1, no_dextery = 0) - if(no_dextery) - src << "You don't have the dexterity to do this!" - return 0 - return be_close && !in_range(M, src) - -/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close = 1) - if(restrained() || lying || stat || stunned || weakened) - return - if(be_close && !in_range(M, src)) - if(TK in mutations) - var/mob/living/carbon/human/H = M - if(istype(H.l_hand, /obj/item/tk_grab) || istype(H.r_hand, /obj/item/tk_grab)) - return 1 - return - if(!isturf(M.loc) && M.loc != src) - return - return 1 - -/mob/living/silicon/ai/canUseTopic(atom/movable/M) - if(stat) - return - // Prevents the AI from using Topic on admin levels (by for example viewing through the court/thunderdome cameras) - // unless it's on the same level as the object it's interacting with. - if(!(z == M.z || M.z in config.player_levels)) - return - //stop AIs from leaving windows open and using then after they lose vision - //apc_override is needed here because AIs use their own APC when powerless - if(cameranet && !cameranet.checkTurfVis(get_turf(M)) && !apc_override) - return - return 1 - -/mob/living/silicon/robot/canUseTopic(atom/movable/M) - if(stat || lockcharge || stunned || weakened) - return - return 1 +/obj/machinery/CouldNotUseTopic(var/mob/user) + user.unset_machine() //////////////////////////////////////////////////////////////////////////////////////////// @@ -262,8 +215,7 @@ Class Procs: if(user.lying || user.stat) return 1 if ( ! (istype(usr, /mob/living/carbon/human) || \ - istype(usr, /mob/living/silicon) || \ - istype(usr, /mob/living/carbon/monkey)) ) + istype(usr, /mob/living/silicon))) usr << "\red You don't have the dexterity to do this!" return 1 /* @@ -282,7 +234,7 @@ Class Procs: src.add_fingerprint(user) - return 0 + return ..() /obj/machinery/proc/RefreshParts() //Placeholder proc for machines that are built using frames. return @@ -292,15 +244,15 @@ Class Procs: gl_uid++ /obj/machinery/proc/state(var/msg) - for(var/mob/O in hearers(src, null)) - O.show_message("\icon[src] [msg]", 2) + for(var/mob/O in hearers(src, null)) + O.show_message("\icon[src] [msg]", 2) /obj/machinery/proc/ping(text=null) - if (!text) - text = "\The [src] pings." + if (!text) + text = "\The [src] pings." - state(text, "blue") - playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) + state(text, "blue") + playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) /obj/machinery/proc/shock(mob/user, prb) if(inoperable()) @@ -317,9 +269,57 @@ Class Procs: if(temp_apc && temp_apc.terminal && temp_apc.terminal.powernet) temp_apc.terminal.powernet.trigger_warning() - return 1 - else + if(user.stunned) + return 1 + return 0 + +/obj/machinery/proc/default_deconstruction_crowbar(var/mob/user, var/obj/item/weapon/crowbar/C) + if(!istype(C)) return 0 + if(!panel_open) + return 0 + . = dismantle() + +/obj/machinery/proc/default_deconstruction_screwdriver(var/mob/user, var/obj/item/weapon/screwdriver/S) + if(!istype(S)) + return 0 + playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) + panel_open = !panel_open + user << "You [panel_open ? "open" : "close"] the maintenance hatch of [src]." + update_icon() + return 1 + +/obj/machinery/proc/default_part_replacement(var/mob/user, var/obj/item/weapon/storage/part_replacer/R) + if(!istype(R)) + return 0 + if(!component_parts) + return 0 + if(panel_open) + var/obj/item/weapon/circuitboard/CB = locate(/obj/item/weapon/circuitboard) in component_parts + var/P + for(var/obj/item/weapon/stock_parts/A in component_parts) + for(var/D in CB.req_components) + var/T = text2path(D) + if(ispath(A.type, T)) + P = T + break + for(var/obj/item/weapon/stock_parts/B in R.contents) + if(istype(B, P) && istype(A, P)) + if(B.rating > A.rating) + R.remove_from_storage(B, src) + R.handle_item_insertion(A, 1) + component_parts -= A + component_parts += B + B.loc = null + user << "[A.name] replaced with [B.name]." + break + update_icon() + RefreshParts() + else + user << "Following parts detected in the machine:" + for(var/var/obj/item/C in component_parts) + user << " [C.name]" + return 1 /obj/machinery/proc/dismantle() playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index 8569ede3fd..b04e9d1851 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -323,7 +323,7 @@ if(speed <= 0) speed = 1 if("setpath") - var/newpath = sanitize(copytext(input(usr, "Please define a new path!",,path) as text|null,1,MAX_MESSAGE_LEN)) + var/newpath = sanitize(input(usr, "Please define a new path!",,path) as text|null) if(newpath && newpath != "") moving = 0 // stop moving path = newpath diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm index 036edb8730..b67bc17986 100644 --- a/code/game/machinery/mass_driver.dm +++ b/code/game/machinery/mass_driver.dm @@ -16,27 +16,27 @@ var/drive_range = 50 //this is mostly irrelevant since current mass drivers throw into space, but you could make a lower-range mass driver for interstation transport or something I guess. - proc/drive(amount) - if(stat & (BROKEN|NOPOWER)) - return - use_power(500) - var/O_limit - var/atom/target = get_edge_target_turf(src, dir) - for(var/atom/movable/O in loc) - if(!O.anchored||istype(O, /obj/mecha))//Mechs need their launch platforms. - O_limit++ - if(O_limit >= 20) - for(var/mob/M in hearers(src, null)) - M << "\blue The mass driver lets out a screech, it mustn't be able to handle any more items." - break - use_power(500) - spawn( 0 ) - O.throw_at(target, drive_range * power, power) - flick("mass_driver1", src) +/obj/machinery/mass_driver/proc/drive(amount) + if(stat & (BROKEN|NOPOWER)) return + use_power(500) + var/O_limit + var/atom/target = get_edge_target_turf(src, dir) + for(var/atom/movable/O in loc) + if(!O.anchored||istype(O, /obj/mecha))//Mechs need their launch platforms. + O_limit++ + if(O_limit >= 20) + for(var/mob/M in hearers(src, null)) + M << "\blue The mass driver lets out a screech, it mustn't be able to handle any more items." + break + use_power(500) + spawn( 0 ) + O.throw_at(target, drive_range * power, power) + flick("mass_driver1", src) + return - emp_act(severity) - if(stat & (BROKEN|NOPOWER)) - return - drive() - ..(severity) \ No newline at end of file +/obj/machinery/mass_driver/emp_act(severity) + if(stat & (BROKEN|NOPOWER)) + return + drive() + ..(severity) \ No newline at end of file diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index 56fcd1298e..de2a13aab5 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -194,7 +194,7 @@ Transponder Codes:
      "} updateDialog() else if(href_list["locedit"]) - var/newloc = sanitize(copytext(input("Enter New Location", "Navigation Beacon", location) as text|null,1,MAX_MESSAGE_LEN)) + var/newloc = sanitize(input("Enter New Location", "Navigation Beacon", location) as text|null) if(newloc) location = newloc updateDialog() diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 5c56690228..3a238e24b0 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -496,9 +496,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) if(href_list["set_channel_name"]) - src.channel_name = strip_html(input(usr, "Provide a Feed Channel Name", "Network Channel Handler", "")) - while (findtext(src.channel_name," ") == 1) - src.channel_name = copytext(src.channel_name,2,lentext(src.channel_name)+1) + src.channel_name = sanitizeSafe(input(usr, "Provide a Feed Channel Name", "Network Channel Handler", "")) src.updateUsrDialog() //src.update_icon() @@ -541,9 +539,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co src.updateUsrDialog() else if(href_list["set_new_message"]) - src.msg = strip_html(input(usr, "Write your Feed story", "Network Channel Handler", "")) - while (findtext(src.msg," ") == 1) - src.msg = copytext(src.msg,2,lentext(src.msg)+1) + src.msg = sanitize(input(usr, "Write your Feed story", "Network Channel Handler", "")) src.updateUsrDialog() else if(href_list["set_attachment"]) @@ -600,15 +596,11 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co src.updateUsrDialog() else if(href_list["set_wanted_name"]) - src.channel_name = strip_html(input(usr, "Provide the name of the Wanted person", "Network Security Handler", "")) - while (findtext(src.channel_name," ") == 1) - src.channel_name = copytext(src.channel_name,2,lentext(src.channel_name)+1) + src.channel_name = sanitizeSafe(input(usr, "Provide the name of the Wanted person", "Network Security Handler", "")) src.updateUsrDialog() else if(href_list["set_wanted_desc"]) - src.msg = strip_html(input(usr, "Provide the a description of the Wanted person and any other details you deem important", "Network Security Handler", "")) - while (findtext(src.msg," ") == 1) - src.msg = copytext(src.msg,2,lentext(src.msg)+1) + src.msg = sanitize(input(usr, "Provide the a description of the Wanted person and any other details you deem important", "Network Security Handler", "")) src.updateUsrDialog() else if(href_list["submit_wanted"]) @@ -944,8 +936,8 @@ obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user as mob) if(src.scribble_page == src.curr_page) user << "There's already a scribble in this page... You wouldn't want to make things too cluttered, would you?" else - var/s = strip_html( input(user, "Write something", "Newspaper", "") ) - s = sanitize(copytext(s, 1, MAX_MESSAGE_LEN)) + var/s = sanitize(input(user, "Write something", "Newspaper", "")) + s = sanitize(s) if (!s) return if (!in_range(src, usr) && src.loc != usr) diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/machinery/nuclear_bomb.dm similarity index 96% rename from code/game/gamemodes/nuclear/nuclearbomb.dm rename to code/game/machinery/nuclear_bomb.dm index e73fbf6880..d13f18c3e9 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/machinery/nuclear_bomb.dm @@ -1,434 +1,431 @@ -var/bomb_set - -/obj/machinery/nuclearbomb - name = "\improper Nuclear Fission Explosive" - desc = "Uh oh. RUN!!!!" - icon = 'icons/obj/stationobjs.dmi' - icon_state = "nuclearbomb0" - density = 1 - var/deployable = 0.0 - var/extended = 0.0 - var/lighthack = 0 - var/opened = 0.0 - var/timeleft = 60.0 - var/timing = 0.0 - var/r_code = "ADMIN" - var/code = "" - var/yes_code = 0.0 - var/safety = 1.0 - var/obj/item/weapon/disk/nuclear/auth = null - var/list/wires = list() - var/light_wire - var/safety_wire - var/timing_wire - var/removal_stage = 0 // 0 is no removal, 1 is covers removed, 2 is covers open, - // 3 is sealant open, 4 is unwrenched, 5 is removed from bolts. - use_power = 0 - - - -/obj/machinery/nuclearbomb/New() - ..() - r_code = "[rand(10000, 99999.0)]"//Creates a random code upon object spawn. - - src.wires["Red"] = 0 - src.wires["Blue"] = 0 - src.wires["Green"] = 0 - src.wires["Marigold"] = 0 - src.wires["Fuschia"] = 0 - src.wires["Black"] = 0 - src.wires["Pearl"] = 0 - var/list/w = list("Red","Blue","Green","Marigold","Black","Fuschia","Pearl") - src.light_wire = pick(w) - w -= src.light_wire - src.timing_wire = pick(w) - w -= src.timing_wire - src.safety_wire = pick(w) - w -= src.safety_wire - -/obj/machinery/nuclearbomb/process() - if (src.timing) - bomb_set = 1 //So long as there is one nuke timing, it means one nuke is armed. - src.timeleft-- - if (src.timeleft <= 0) - explode() - for(var/mob/M in viewers(1, src)) - if ((M.client && M.machine == src)) - src.attack_hand(M) - return - -/obj/machinery/nuclearbomb/attackby(obj/item/weapon/O as obj, mob/user as mob) - - if (istype(O, /obj/item/weapon/screwdriver)) - src.add_fingerprint(user) - if (src.auth) - if (src.opened == 0) - src.opened = 1 - overlays += image(icon, "npanel_open") - user << "You unscrew the control panel of [src]." - - else - src.opened = 0 - overlays -= image(icon, "npanel_open") - user << "You screw the control panel of [src] back on." - else - if (src.opened == 0) - user << "The [src] emits a buzzing noise, the panel staying locked in." - if (src.opened == 1) - src.opened = 0 - overlays -= image(icon, "npanel_open") - user << "You screw the control panel of [src] back on." - flick("nuclearbombc", src) - - return - if (istype(O, /obj/item/weapon/wirecutters) || istype(O, /obj/item/device/multitool)) - if (src.opened == 1) - nukehack_win(user) - return - - if (src.extended) - if (istype(O, /obj/item/weapon/disk/nuclear)) - usr.drop_item() - O.loc = src - src.auth = O - src.add_fingerprint(user) - return - - if (src.anchored) - switch(removal_stage) - if(0) - if(istype(O,/obj/item/weapon/weldingtool)) - - var/obj/item/weapon/weldingtool/WT = O - if(!WT.isOn()) return - if (WT.get_fuel() < 5) // uses up 5 fuel. - user << "\red You need more fuel to complete this task." - return - - user.visible_message("[user] starts cutting loose the anchoring bolt covers on [src].", "You start cutting loose the anchoring bolt covers with [O]...") - - if(do_after(user,40)) - if(!src || !user || !WT.remove_fuel(5, user)) return - user.visible_message("[user] cuts through the bolt covers on [src].", "You cut through the bolt cover.") - removal_stage = 1 - return - - if(1) - if(istype(O,/obj/item/weapon/crowbar)) - user.visible_message("[user] starts forcing open the bolt covers on [src].", "You start forcing open the anchoring bolt covers with [O]...") - - if(do_after(user,15)) - if(!src || !user) return - user.visible_message("[user] forces open the bolt covers on [src].", "You force open the bolt covers.") - removal_stage = 2 - return - - if(2) - if(istype(O,/obj/item/weapon/weldingtool)) - - var/obj/item/weapon/weldingtool/WT = O - if(!WT.isOn()) return - if (WT.get_fuel() < 5) // uses up 5 fuel. - user << "\red You need more fuel to complete this task." - return - - user.visible_message("[user] starts cutting apart the anchoring system sealant on [src].", "You start cutting apart the anchoring system's sealant with [O]...") - - if(do_after(user,40)) - if(!src || !user || !WT.remove_fuel(5, user)) return - user.visible_message("[user] cuts apart the anchoring system sealant on [src].", "You cut apart the anchoring system's sealant.") - removal_stage = 3 - return - - if(3) - if(istype(O,/obj/item/weapon/wrench)) - - user.visible_message("[user] begins unwrenching the anchoring bolts on [src].", "You begin unwrenching the anchoring bolts...") - - if(do_after(user,50)) - if(!src || !user) return - user.visible_message("[user] unwrenches the anchoring bolts on [src].", "You unwrench the anchoring bolts.") - removal_stage = 4 - return - - if(4) - if(istype(O,/obj/item/weapon/crowbar)) - - user.visible_message("[user] begins lifting [src] off of the anchors.", "You begin lifting the device off the anchors...") - - if(do_after(user,80)) - if(!src || !user) return - user.visible_message("[user] crowbars [src] off of the anchors. It can now be moved.", "You jam the crowbar under the nuclear device and lift it off its anchors. You can now move it!") - anchored = 0 - removal_stage = 5 - return - ..() - -/obj/machinery/nuclearbomb/attack_hand(mob/user as mob) - if (src.extended) - if (!ishuman(user)) - usr << "\red You don't have the dexterity to do this!" - return 1 - - if (!ishuman(user)) - usr << "\red You don't have the dexterity to do this!" - return 1 - user.set_machine(src) - var/dat = text("Nuclear Fission Explosive
      \nAuth. Disk: []
      ", src, (src.auth ? "++++++++++" : "----------")) - if (src.auth) - if (src.yes_code) - dat += text("\nStatus: []-[]
      \nTimer: []
      \n
      \nTimer: [] Toggle
      \nTime: - - [] + +
      \n
      \nSafety: [] Toggle
      \nAnchor: [] Toggle
      \n", (src.timing ? "Func/Set" : "Functional"), (src.safety ? "Safe" : "Engaged"), src.timeleft, (src.timing ? "On" : "Off"), src, src, src, src.timeleft, src, src, (src.safety ? "On" : "Off"), src, (src.anchored ? "Engaged" : "Off"), src) - else - dat += text("\nStatus: Auth. S2-[]
      \nTimer: []
      \n
      \nTimer: [] Toggle
      \nTime: - - [] + +
      \n
      \n[] Safety: Toggle
      \nAnchor: [] Toggle
      \n", (src.safety ? "Safe" : "Engaged"), src.timeleft, (src.timing ? "On" : "Off"), src.timeleft, (src.safety ? "On" : "Off"), (src.anchored ? "Engaged" : "Off")) - else - if (src.timing) - dat += text("\nStatus: Set-[]
      \nTimer: []
      \n
      \nTimer: [] Toggle
      \nTime: - - [] + +
      \n
      \nSafety: [] Toggle
      \nAnchor: [] Toggle
      \n", (src.safety ? "Safe" : "Engaged"), src.timeleft, (src.timing ? "On" : "Off"), src.timeleft, (src.safety ? "On" : "Off"), (src.anchored ? "Engaged" : "Off")) - else - dat += text("\nStatus: Auth. S1-[]
      \nTimer: []
      \n
      \nTimer: [] Toggle
      \nTime: - - [] + +
      \n
      \nSafety: [] Toggle
      \nAnchor: [] Toggle
      \n", (src.safety ? "Safe" : "Engaged"), src.timeleft, (src.timing ? "On" : "Off"), src.timeleft, (src.safety ? "On" : "Off"), (src.anchored ? "Engaged" : "Off")) - var/message = "AUTH" - if (src.auth) - message = text("[]", src.code) - if (src.yes_code) - message = "*****" - dat += text("
      \n>[]
      \n1-2-3
      \n4-5-6
      \n7-8-9
      \nR-0-E
      \n
      ", message, src, src, src, src, src, src, src, src, src, src, src, src) - user << browse(dat, "window=nuclearbomb;size=300x400") - onclose(user, "nuclearbomb") - else if (src.deployable) - if(removal_stage < 5) - src.anchored = 1 - visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring!") - else - visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.") - if(!src.lighthack) - flick("nuclearbombc", src) - src.icon_state = "nuclearbomb1" - src.extended = 1 - return - -obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob) - var/dat as text - dat += "Nuclear Fission Explosive
      \nNuclear Device Wires:
      " - for(var/wire in src.wires) - dat += text("[wire] Wire: [src.wires[wire] ? "Mend" : "Cut"] Pulse
      ") - dat += text("
      The device is [src.timing ? "shaking!" : "still"]
      ") - dat += text("The device is [src.safety ? "quiet" : "whirring"].
      ") - dat += text("The lights are [src.lighthack ? "static" : "functional"].
      ") - user << browse("Bomb Defusion[dat]","window=nukebomb_hack") - onclose(user, "nukebomb_hack") - -/obj/machinery/nuclearbomb/verb/make_deployable() - set category = "Object" - set name = "Make Deployable" - set src in oview(1) - - if (!usr.canmove || usr.stat || usr.restrained()) - return - if (!ishuman(usr)) - usr << "\red You don't have the dexterity to do this!" - return 1 - - if (src.deployable) - usr << "\red You close several panels to make [src] undeployable." - src.deployable = 0 - else - usr << "\red You adjust some panels to make [src] deployable." - src.deployable = 1 - return - - -/obj/machinery/nuclearbomb/Topic(href, href_list) - ..() - if (!usr.canmove || usr.stat || usr.restrained()) - return - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) - usr.set_machine(src) - if(href_list["act"]) - var/temp_wire = href_list["wire"] - if(href_list["act"] == "pulse") - if (!istype(usr.get_active_hand(), /obj/item/device/multitool)) - usr << "You need a multitool!" - else - if(src.wires[temp_wire]) - usr << "You can't pulse a cut wire." - else - if(src.light_wire == temp_wire) - src.lighthack = !src.lighthack - spawn(100) src.lighthack = !src.lighthack - if(src.timing_wire == temp_wire) - if(src.timing) - explode() - if(src.safety_wire == temp_wire) - src.safety = !src.safety - spawn(100) src.safety = !src.safety - if(src.safety == 1) - visible_message("\blue The [src] quiets down.") - if(!src.lighthack) - if (src.icon_state == "nuclearbomb2") - src.icon_state = "nuclearbomb1" - else - visible_message("\blue The [src] emits a quiet whirling noise!") - if(href_list["act"] == "wire") - if (!istype(usr.get_active_hand(), /obj/item/weapon/wirecutters)) - usr << "You need wirecutters!" - else - wires[temp_wire] = !wires[temp_wire] - if(src.safety_wire == temp_wire) - if(src.timing) - explode() - if(src.timing_wire == temp_wire) - if(!src.lighthack) - if (src.icon_state == "nuclearbomb2") - src.icon_state = "nuclearbomb1" - src.timing = 0 - bomb_set = 0 - if(src.light_wire == temp_wire) - src.lighthack = !src.lighthack - - if (href_list["auth"]) - if (src.auth) - src.auth.loc = src.loc - src.yes_code = 0 - src.auth = null - else - var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/weapon/disk/nuclear)) - usr.drop_item() - I.loc = src - src.auth = I - if (src.auth) - if (href_list["type"]) - if (href_list["type"] == "E") - if (src.code == src.r_code) - src.yes_code = 1 - src.code = null - else - src.code = "ERROR" - else - if (href_list["type"] == "R") - src.yes_code = 0 - src.code = null - else - src.code += text("[]", href_list["type"]) - if (length(src.code) > 5) - src.code = "ERROR" - if (src.yes_code) - if (href_list["time"]) - var/time = text2num(href_list["time"]) - src.timeleft += time - src.timeleft = min(max(round(src.timeleft), 60), 600) - if (href_list["timer"]) - if (src.timing == -1.0) - return - if (src.safety) - usr << "\red The safety is still on." - return - src.timing = !( src.timing ) - if (src.timing) - if(!src.lighthack) - src.icon_state = "nuclearbomb2" - if(!src.safety) - bomb_set = 1//There can still be issues with this reseting when there are multiple bombs. Not a big deal tho for Nuke/N - else - bomb_set = 0 - else - bomb_set = 0 - if(!src.lighthack) - src.icon_state = "nuclearbomb1" - if (href_list["safety"]) - src.safety = !( src.safety ) - if(safety) - src.timing = 0 - bomb_set = 0 - if (href_list["anchor"]) - - if(removal_stage == 5) - src.anchored = 0 - visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.") - return - - src.anchored = !( src.anchored ) - if(src.anchored) - visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring.") - else - visible_message("\red The anchoring bolts slide back into the depths of [src].") - - src.add_fingerprint(usr) - for(var/mob/M in viewers(1, src)) - if ((M.client && M.machine == src)) - src.attack_hand(M) - else - usr << browse(null, "window=nuclearbomb") - return - return - - -/obj/machinery/nuclearbomb/ex_act(severity) - return - -/obj/machinery/nuclearbomb/blob_act() - if (src.timing == -1.0) - return - else - return ..() - return - - -#define NUKERANGE 80 -/obj/machinery/nuclearbomb/proc/explode() - if (src.safety) - src.timing = 0 - return - src.timing = -1.0 - src.yes_code = 0 - src.safety = 1 - if(!src.lighthack) - src.icon_state = "nuclearbomb3" - playsound(src,'sound/machines/Alarm.ogg',100,0,5) - if (ticker && ticker.mode) - ticker.mode.explosion_in_progress = 1 - sleep(100) - - var/off_station = 0 - var/turf/bomb_location = get_turf(src) - if(bomb_location && (bomb_location.z in config.station_levels)) - if( (bomb_location.x < (128-NUKERANGE)) || (bomb_location.x > (128+NUKERANGE)) || (bomb_location.y < (128-NUKERANGE)) || (bomb_location.y > (128+NUKERANGE)) ) - off_station = 1 - else - off_station = 2 - - if(ticker) - if(ticker.mode && ticker.mode.name == "mercenary") - var/obj/machinery/computer/shuttle_control/multi/syndicate/syndie_location = locate(/obj/machinery/computer/shuttle_control/multi/syndicate) - if(syndie_location) - ticker.mode:syndies_didnt_escape = (syndie_location.z > 1 ? 0 : 1) //muskets will make me change this, but it will do for now - ticker.mode:nuke_off_station = off_station - ticker.station_explosion_cinematic(off_station,null) - if(ticker.mode) - ticker.mode.explosion_in_progress = 0 - if(ticker.mode.name == "mercenary") - ticker.mode:nukes_left -- - else - world << "The station was destoyed by the nuclear blast!" - - ticker.mode.station_was_nuked = (off_station<2) //offstation==1 is a draw. the station becomes irradiated and needs to be evacuated. - //kinda shit but I couldn't get permission to do what I wanted to do. - - if(!ticker.mode.check_finished())//If the mode does not deal with the nuke going off so just reboot because everyone is stuck as is - world << "Resetting in 30 seconds!" - - feedback_set_details("end_error","nuke - unhandled ending") - - if(blackbox) - blackbox.save_all_data_to_sql() - sleep(300) - log_game("Rebooting due to nuclear detonation") - world.Reboot() - return - return - -/obj/item/weapon/disk/nuclear/Del() - if(blobstart.len > 0) - var/obj/D = new /obj/item/weapon/disk/nuclear(pick(blobstart)) - message_admins("[src] has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") - log_game("[src] has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") - ..() +var/bomb_set + +/obj/machinery/nuclearbomb + name = "\improper Nuclear Fission Explosive" + desc = "Uh oh. RUN!!!!" + icon = 'icons/obj/stationobjs.dmi' + icon_state = "nuclearbomb0" + density = 1 + var/deployable = 0.0 + var/extended = 0.0 + var/lighthack = 0 + var/opened = 0.0 + var/timeleft = 60.0 + var/timing = 0.0 + var/r_code = "ADMIN" + var/code = "" + var/yes_code = 0.0 + var/safety = 1.0 + var/obj/item/weapon/disk/nuclear/auth = null + var/list/wires = list() + var/light_wire + var/safety_wire + var/timing_wire + var/removal_stage = 0 // 0 is no removal, 1 is covers removed, 2 is covers open, + // 3 is sealant open, 4 is unwrenched, 5 is removed from bolts. + use_power = 0 + + + +/obj/machinery/nuclearbomb/New() + ..() + r_code = "[rand(10000, 99999.0)]"//Creates a random code upon object spawn. + + src.wires["Red"] = 0 + src.wires["Blue"] = 0 + src.wires["Green"] = 0 + src.wires["Marigold"] = 0 + src.wires["Fuschia"] = 0 + src.wires["Black"] = 0 + src.wires["Pearl"] = 0 + var/list/w = list("Red","Blue","Green","Marigold","Black","Fuschia","Pearl") + src.light_wire = pick(w) + w -= src.light_wire + src.timing_wire = pick(w) + w -= src.timing_wire + src.safety_wire = pick(w) + w -= src.safety_wire + +/obj/machinery/nuclearbomb/process() + if (src.timing) + bomb_set = 1 //So long as there is one nuke timing, it means one nuke is armed. + src.timeleft-- + if (src.timeleft <= 0) + explode() + for(var/mob/M in viewers(1, src)) + if ((M.client && M.machine == src)) + src.attack_hand(M) + return + +/obj/machinery/nuclearbomb/attackby(obj/item/weapon/O as obj, mob/user as mob) + + if (istype(O, /obj/item/weapon/screwdriver)) + src.add_fingerprint(user) + if (src.auth) + if (src.opened == 0) + src.opened = 1 + overlays += image(icon, "npanel_open") + user << "You unscrew the control panel of [src]." + + else + src.opened = 0 + overlays -= image(icon, "npanel_open") + user << "You screw the control panel of [src] back on." + else + if (src.opened == 0) + user << "The [src] emits a buzzing noise, the panel staying locked in." + if (src.opened == 1) + src.opened = 0 + overlays -= image(icon, "npanel_open") + user << "You screw the control panel of [src] back on." + flick("nuclearbombc", src) + + return + if (istype(O, /obj/item/weapon/wirecutters) || istype(O, /obj/item/device/multitool)) + if (src.opened == 1) + nukehack_win(user) + return + + if (src.extended) + if (istype(O, /obj/item/weapon/disk/nuclear)) + usr.drop_item() + O.loc = src + src.auth = O + src.add_fingerprint(user) + return + + if (src.anchored) + switch(removal_stage) + if(0) + if(istype(O,/obj/item/weapon/weldingtool)) + + var/obj/item/weapon/weldingtool/WT = O + if(!WT.isOn()) return + if (WT.get_fuel() < 5) // uses up 5 fuel. + user << "\red You need more fuel to complete this task." + return + + user.visible_message("[user] starts cutting loose the anchoring bolt covers on [src].", "You start cutting loose the anchoring bolt covers with [O]...") + + if(do_after(user,40)) + if(!src || !user || !WT.remove_fuel(5, user)) return + user.visible_message("[user] cuts through the bolt covers on [src].", "You cut through the bolt cover.") + removal_stage = 1 + return + + if(1) + if(istype(O,/obj/item/weapon/crowbar)) + user.visible_message("[user] starts forcing open the bolt covers on [src].", "You start forcing open the anchoring bolt covers with [O]...") + + if(do_after(user,15)) + if(!src || !user) return + user.visible_message("[user] forces open the bolt covers on [src].", "You force open the bolt covers.") + removal_stage = 2 + return + + if(2) + if(istype(O,/obj/item/weapon/weldingtool)) + + var/obj/item/weapon/weldingtool/WT = O + if(!WT.isOn()) return + if (WT.get_fuel() < 5) // uses up 5 fuel. + user << "\red You need more fuel to complete this task." + return + + user.visible_message("[user] starts cutting apart the anchoring system sealant on [src].", "You start cutting apart the anchoring system's sealant with [O]...") + + if(do_after(user,40)) + if(!src || !user || !WT.remove_fuel(5, user)) return + user.visible_message("[user] cuts apart the anchoring system sealant on [src].", "You cut apart the anchoring system's sealant.") + removal_stage = 3 + return + + if(3) + if(istype(O,/obj/item/weapon/wrench)) + + user.visible_message("[user] begins unwrenching the anchoring bolts on [src].", "You begin unwrenching the anchoring bolts...") + + if(do_after(user,50)) + if(!src || !user) return + user.visible_message("[user] unwrenches the anchoring bolts on [src].", "You unwrench the anchoring bolts.") + removal_stage = 4 + return + + if(4) + if(istype(O,/obj/item/weapon/crowbar)) + + user.visible_message("[user] begins lifting [src] off of the anchors.", "You begin lifting the device off the anchors...") + + if(do_after(user,80)) + if(!src || !user) return + user.visible_message("[user] crowbars [src] off of the anchors. It can now be moved.", "You jam the crowbar under the nuclear device and lift it off its anchors. You can now move it!") + anchored = 0 + removal_stage = 5 + return + ..() + +/obj/machinery/nuclearbomb/attack_hand(mob/user as mob) + if (src.extended) + if (!ishuman(user)) + usr << "\red You don't have the dexterity to do this!" + return 1 + + if (!ishuman(user)) + usr << "\red You don't have the dexterity to do this!" + return 1 + user.set_machine(src) + var/dat = text("Nuclear Fission Explosive
      \nAuth. Disk: []
      ", src, (src.auth ? "++++++++++" : "----------")) + if (src.auth) + if (src.yes_code) + dat += text("\nStatus: []-[]
      \nTimer: []
      \n
      \nTimer: [] Toggle
      \nTime: - - [] + +
      \n
      \nSafety: [] Toggle
      \nAnchor: [] Toggle
      \n", (src.timing ? "Func/Set" : "Functional"), (src.safety ? "Safe" : "Engaged"), src.timeleft, (src.timing ? "On" : "Off"), src, src, src, src.timeleft, src, src, (src.safety ? "On" : "Off"), src, (src.anchored ? "Engaged" : "Off"), src) + else + dat += text("\nStatus: Auth. S2-[]
      \nTimer: []
      \n
      \nTimer: [] Toggle
      \nTime: - - [] + +
      \n
      \n[] Safety: Toggle
      \nAnchor: [] Toggle
      \n", (src.safety ? "Safe" : "Engaged"), src.timeleft, (src.timing ? "On" : "Off"), src.timeleft, (src.safety ? "On" : "Off"), (src.anchored ? "Engaged" : "Off")) + else + if (src.timing) + dat += text("\nStatus: Set-[]
      \nTimer: []
      \n
      \nTimer: [] Toggle
      \nTime: - - [] + +
      \n
      \nSafety: [] Toggle
      \nAnchor: [] Toggle
      \n", (src.safety ? "Safe" : "Engaged"), src.timeleft, (src.timing ? "On" : "Off"), src.timeleft, (src.safety ? "On" : "Off"), (src.anchored ? "Engaged" : "Off")) + else + dat += text("\nStatus: Auth. S1-[]
      \nTimer: []
      \n
      \nTimer: [] Toggle
      \nTime: - - [] + +
      \n
      \nSafety: [] Toggle
      \nAnchor: [] Toggle
      \n", (src.safety ? "Safe" : "Engaged"), src.timeleft, (src.timing ? "On" : "Off"), src.timeleft, (src.safety ? "On" : "Off"), (src.anchored ? "Engaged" : "Off")) + var/message = "AUTH" + if (src.auth) + message = text("[]", src.code) + if (src.yes_code) + message = "*****" + dat += text("
      \n>[]
      \n1-2-3
      \n4-5-6
      \n7-8-9
      \nR-0-E
      \n
      ", message, src, src, src, src, src, src, src, src, src, src, src, src) + user << browse(dat, "window=nuclearbomb;size=300x400") + onclose(user, "nuclearbomb") + else if (src.deployable) + if(removal_stage < 5) + src.anchored = 1 + visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring!") + else + visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.") + if(!src.lighthack) + flick("nuclearbombc", src) + src.icon_state = "nuclearbomb1" + src.extended = 1 + return + +obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob) + var/dat as text + dat += "Nuclear Fission Explosive
      \nNuclear Device Wires:
      " + for(var/wire in src.wires) + dat += text("[wire] Wire: [src.wires[wire] ? "Mend" : "Cut"] Pulse
      ") + dat += text("
      The device is [src.timing ? "shaking!" : "still"]
      ") + dat += text("The device is [src.safety ? "quiet" : "whirring"].
      ") + dat += text("The lights are [src.lighthack ? "static" : "functional"].
      ") + user << browse("Bomb Defusion[dat]","window=nukebomb_hack") + onclose(user, "nukebomb_hack") + +/obj/machinery/nuclearbomb/verb/make_deployable() + set category = "Object" + set name = "Make Deployable" + set src in oview(1) + + if (!usr.canmove || usr.stat || usr.restrained()) + return + if (!ishuman(usr)) + usr << "\red You don't have the dexterity to do this!" + return 1 + + if (src.deployable) + usr << "\red You close several panels to make [src] undeployable." + src.deployable = 0 + else + usr << "\red You adjust some panels to make [src] deployable." + src.deployable = 1 + return + + +/obj/machinery/nuclearbomb/Topic(href, href_list) + ..() + if (!usr.canmove || usr.stat || usr.restrained()) + return + if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) + usr.set_machine(src) + if(href_list["act"]) + var/temp_wire = href_list["wire"] + if(href_list["act"] == "pulse") + if (!istype(usr.get_active_hand(), /obj/item/device/multitool)) + usr << "You need a multitool!" + else + if(src.wires[temp_wire]) + usr << "You can't pulse a cut wire." + else + if(src.light_wire == temp_wire) + src.lighthack = !src.lighthack + spawn(100) src.lighthack = !src.lighthack + if(src.timing_wire == temp_wire) + if(src.timing) + explode() + if(src.safety_wire == temp_wire) + src.safety = !src.safety + spawn(100) src.safety = !src.safety + if(src.safety == 1) + visible_message("\blue The [src] quiets down.") + if(!src.lighthack) + if (src.icon_state == "nuclearbomb2") + src.icon_state = "nuclearbomb1" + else + visible_message("\blue The [src] emits a quiet whirling noise!") + if(href_list["act"] == "wire") + if (!istype(usr.get_active_hand(), /obj/item/weapon/wirecutters)) + usr << "You need wirecutters!" + else + wires[temp_wire] = !wires[temp_wire] + if(src.safety_wire == temp_wire) + if(src.timing) + explode() + if(src.timing_wire == temp_wire) + if(!src.lighthack) + if (src.icon_state == "nuclearbomb2") + src.icon_state = "nuclearbomb1" + src.timing = 0 + bomb_set = 0 + if(src.light_wire == temp_wire) + src.lighthack = !src.lighthack + + if (href_list["auth"]) + if (src.auth) + src.auth.loc = src.loc + src.yes_code = 0 + src.auth = null + else + var/obj/item/I = usr.get_active_hand() + if (istype(I, /obj/item/weapon/disk/nuclear)) + usr.drop_item() + I.loc = src + src.auth = I + if (src.auth) + if (href_list["type"]) + if (href_list["type"] == "E") + if (src.code == src.r_code) + src.yes_code = 1 + src.code = null + else + src.code = "ERROR" + else + if (href_list["type"] == "R") + src.yes_code = 0 + src.code = null + else + src.code += text("[]", href_list["type"]) + if (length(src.code) > 5) + src.code = "ERROR" + if (src.yes_code) + if (href_list["time"]) + var/time = text2num(href_list["time"]) + src.timeleft += time + src.timeleft = min(max(round(src.timeleft), 60), 600) + if (href_list["timer"]) + if (src.timing == -1.0) + return + if (src.safety) + usr << "\red The safety is still on." + return + src.timing = !( src.timing ) + if (src.timing) + if(!src.lighthack) + src.icon_state = "nuclearbomb2" + if(!src.safety) + bomb_set = 1//There can still be issues with this reseting when there are multiple bombs. Not a big deal tho for Nuke/N + else + bomb_set = 0 + else + bomb_set = 0 + if(!src.lighthack) + src.icon_state = "nuclearbomb1" + if (href_list["safety"]) + src.safety = !( src.safety ) + if(safety) + src.timing = 0 + bomb_set = 0 + if (href_list["anchor"]) + + if(removal_stage == 5) + src.anchored = 0 + visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.") + return + + src.anchored = !( src.anchored ) + if(src.anchored) + visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring.") + else + visible_message("\red The anchoring bolts slide back into the depths of [src].") + + src.add_fingerprint(usr) + for(var/mob/M in viewers(1, src)) + if ((M.client && M.machine == src)) + src.attack_hand(M) + else + usr << browse(null, "window=nuclearbomb") + return + return + + +/obj/machinery/nuclearbomb/ex_act(severity) + return + +/obj/machinery/nuclearbomb/blob_act() + if (src.timing == -1.0) + return + else + return ..() + return + + +#define NUKERANGE 80 +/obj/machinery/nuclearbomb/proc/explode() + if (src.safety) + src.timing = 0 + return + src.timing = -1.0 + src.yes_code = 0 + src.safety = 1 + if(!src.lighthack) + src.icon_state = "nuclearbomb3" + playsound(src,'sound/machines/Alarm.ogg',100,0,5) + if (ticker && ticker.mode) + ticker.mode.explosion_in_progress = 1 + sleep(100) + + var/off_station = 0 + var/turf/bomb_location = get_turf(src) + if(bomb_location && (bomb_location.z in config.station_levels)) + if( (bomb_location.x < (128-NUKERANGE)) || (bomb_location.x > (128+NUKERANGE)) || (bomb_location.y < (128-NUKERANGE)) || (bomb_location.y > (128+NUKERANGE)) ) + off_station = 1 + else + off_station = 2 + + if(ticker) + if(ticker.mode && ticker.mode.name == "Mercenary") + var/obj/machinery/computer/shuttle_control/multi/syndicate/syndie_location = locate(/obj/machinery/computer/shuttle_control/multi/syndicate) + if(syndie_location) + ticker.mode:syndies_didnt_escape = (syndie_location.z > 1 ? 0 : 1) //muskets will make me change this, but it will do for now + ticker.mode:nuke_off_station = off_station + ticker.station_explosion_cinematic(off_station,null) + if(ticker.mode) + ticker.mode.explosion_in_progress = 0 + world << "The station was destoyed by the nuclear blast!" + + ticker.mode.station_was_nuked = (off_station<2) //offstation==1 is a draw. the station becomes irradiated and needs to be evacuated. + //kinda shit but I couldn't get permission to do what I wanted to do. + + if(!ticker.mode.check_finished())//If the mode does not deal with the nuke going off so just reboot because everyone is stuck as is + world << "Resetting in 30 seconds!" + + feedback_set_details("end_error","nuke - unhandled ending") + + if(blackbox) + blackbox.save_all_data_to_sql() + sleep(300) + log_game("Rebooting due to nuclear detonation") + world.Reboot() + return + return + +/obj/item/weapon/disk/nuclear/Del() + if(blobstart.len > 0) + var/obj/D = new /obj/item/weapon/disk/nuclear(pick(blobstart)) + message_admins("[src] has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") + log_game("[src] has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") + ..() diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 024048b6de..637bcbee11 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -48,6 +48,8 @@ Buildable meters #define PIPE_SCRUBBERS_DOWN 40 #define PIPE_SUPPLY_CAP 41 #define PIPE_SCRUBBERS_CAP 42 +///// Mirrored T-valve ~ because I couldn't be bothered re-sorting all of the defines +#define PIPE_MTVALVEM 43 /obj/item/pipe name = "pipe" @@ -76,8 +78,10 @@ Buildable meters is_bent = 1 if (istype(make_from, /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction)) src.pipe_type = PIPE_JUNCTION + connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/heat_exchanging)) src.pipe_type = PIPE_HE_STRAIGHT + is_bent + connect_types = CONNECT_TYPE_HE else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/insulated)) src.pipe_type = PIPE_INSULATED_STRAIGHT + is_bent else if(istype(make_from, /obj/machinery/atmospherics/pipe/simple/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/simple/hidden/supply)) @@ -129,6 +133,8 @@ Buildable meters src.pipe_type = PIPE_PASSIVE_GATE else if(istype(make_from, /obj/machinery/atmospherics/unary/heat_exchanger)) src.pipe_type = PIPE_HEAT_EXCHANGE + else if(istype(make_from, /obj/machinery/atmospherics/tvalve/mirrored)) + src.pipe_type = PIPE_MTVALVEM else if(istype(make_from, /obj/machinery/atmospherics/tvalve)) src.pipe_type = PIPE_MTVALVE else if(istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/visible/supply) || istype(make_from, /obj/machinery/atmospherics/pipe/manifold4w/hidden/supply)) @@ -186,6 +192,10 @@ Buildable meters else if (pipe_type == 31 || pipe_type == 32 || pipe_type == 34 || pipe_type == 36 || pipe_type == 38 || pipe_type == 40 || pipe_type == 42) connect_types = CONNECT_TYPE_SCRUBBER src.color = PIPE_COLOR_RED + else if (pipe_type == 2 || pipe_type == 3) + connect_types = CONNECT_TYPE_HE + else if (pipe_type == 6) + connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE else if (pipe_type == 28) connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER //src.pipe_dir = get_pipe_dir() @@ -243,6 +253,7 @@ Buildable meters "scrubbers pipe down", \ "supply pipe cap", \ "scrubbers pipe cap", \ + "t-valve m", \ ) name = nlist[pipe_type+1] + " fitting" var/list/islist = list( \ @@ -292,6 +303,7 @@ Buildable meters "cap", \ "cap", \ "cap", \ + "mtvalvem", \ ) icon_state = islist[pipe_type + 1] @@ -368,9 +380,9 @@ Buildable meters return dir|flip|cw|acw if(PIPE_MANIFOLD, PIPE_SUPPLY_MANIFOLD, PIPE_SCRUBBERS_MANIFOLD) return flip|cw|acw - if(PIPE_GAS_FILTER, PIPE_GAS_MIXER,PIPE_MTVALVE) + if(PIPE_GAS_FILTER, PIPE_GAS_MIXER, PIPE_MTVALVE) return dir|flip|cw - if(PIPE_GAS_FILTER_M, PIPE_GAS_MIXER_M) + if(PIPE_GAS_FILTER_M, PIPE_GAS_MIXER_M, PIPE_MTVALVEM) return dir|flip|acw if(PIPE_GAS_MIXER_T) return dir|cw|acw @@ -924,6 +936,26 @@ Buildable meters V.node3.initialize() V.node3.build_network() + if(PIPE_MTVALVEM) //manual t-valve + var/obj/machinery/atmospherics/tvalve/mirrored/V = new(src.loc) + V.set_dir(dir) + V.initialize_directions = pipe_dir + if (pipename) + V.name = pipename + var/turf/T = V.loc + V.level = T.intact ? 2 : 1 + V.initialize() + V.build_network() + if (V.node1) + V.node1.initialize() + V.node1.build_network() + if (V.node2) + V.node2.initialize() + V.node2.build_network() + if (V.node3) + V.node3.initialize() + V.node3.build_network() + if(PIPE_CAP) var/obj/machinery/atmospherics/pipe/cap/C = new(src.loc) C.set_dir(dir) @@ -1166,6 +1198,7 @@ Buildable meters #undef PIPE_VOLUME_PUMP #undef PIPE_OUTLET_INJECT #undef PIPE_MTVALVE +#undef PIPE_MTVALVEM #undef PIPE_GAS_FILTER_M #undef PIPE_GAS_MIXER_T #undef PIPE_GAS_MIXER_M diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm index 49f566af57..fb296d2409 100644 --- a/code/game/machinery/pipe/pipe_dispenser.dm +++ b/code/game/machinery/pipe/pipe_dispenser.dm @@ -20,6 +20,7 @@ Pipe Cap
      4-Way Manifold
      Manual T-Valve
      +Manual T-Valve - Mirrored
      Upward Pipe
      Downward Pipe
      Supply pipes:
      @@ -48,10 +49,10 @@ Scrubber
      Meter
      Gas Filter
      -Gas Filter-Mirrored
      +Gas Filter - Mirrored
      Gas Mixer
      -Gas Mixer-Mirrored
      -Gas Mixer-T
      +Gas Mixer - Mirrored
      +Gas Mixer - T
      Omni Gas Mixer
      Omni Gas Filter
      Heat exchange:
      diff --git a/code/game/machinery/portable_tag_turret.dm b/code/game/machinery/portable_tag_turret.dm index 13f7032aa3..1965d10243 100644 --- a/code/game/machinery/portable_tag_turret.dm +++ b/code/game/machinery/portable_tag_turret.dm @@ -5,13 +5,13 @@ /obj/machinery/porta_turret/tag // Reasonable defaults, in case someone manually spawns us var/lasercolor = "r" //Something to do with lasertag turrets, blame Sieve for not adding a comment. - installation = /obj/item/weapon/gun/energy/laser/redtag + installation = /obj/item/weapon/gun/energy/lasertag/red /obj/machinery/porta_turret/tag/red /obj/machinery/porta_turret/tag/blue lasercolor = "b" - installation = /obj/item/weapon/gun/energy/laser/bluetag + installation = /obj/item/weapon/gun/energy/lasertag/blue /obj/machinery/porta_turret/tag/New() ..() @@ -19,8 +19,8 @@ /obj/machinery/porta_turret/tag/weapon_setup(var/obj/item/weapon/gun/energy/E) switch(E.type) - if(/obj/item/weapon/gun/energy/laser/bluetag) - eprojectile = /obj/item/weapon/gun/energy/laser/bluetag + if(/obj/item/weapon/gun/energy/lasertag/blue) + eprojectile = /obj/item/weapon/gun/energy/lasertag/blue lasercolor = "b" req_access = list(access_maint_tunnels, access_theatre) check_arrest = 0 @@ -30,8 +30,8 @@ check_anomalies = 0 shot_delay = 30 - if(/obj/item/weapon/gun/energy/laser/redtag) - eprojectile = /obj/item/weapon/gun/energy/laser/redtag + if(/obj/item/weapon/gun/energy/lasertag/red) + eprojectile = /obj/item/weapon/gun/energy/lasertag/red lasercolor = "r" req_access = list(access_maint_tunnels, access_theatre) check_arrest = 0 @@ -42,25 +42,19 @@ shot_delay = 30 iconholder = 1 -/obj/machinery/porta_turret/tag/interact(mob/user) - var/dat +/obj/machinery/porta_turret/tag/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + data["access"] = !isLocked(user) + data["locked"] = locked + data["enabled"] = enabled + data["is_lethal"] = 0 - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - if(lasercolor == "b" && istype(H.wear_suit, /obj/item/clothing/suit/redtag)) - return - if(lasercolor == "r" && istype(H.wear_suit, /obj/item/clothing/suit/bluetag)) - return - dat += text({" - Automatic Portable Turret Installation

      - Status: []
      "}, - - "[on ? "On" : "Off"]" ) - - - user << browse("Automatic Portable Turret Installation[dat]", "window=autosec") - onclose(user, "autosec") - return + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) /obj/machinery/porta_turret/tag/update_icon() if(!anchored) @@ -70,7 +64,7 @@ icon_state = "[lasercolor]destroyed_target_prism" else if(powered()) - if(on) + if(enabled) if(iconholder) //lasers have a orange icon icon_state = "[lasercolor]orange_target_prism" @@ -86,13 +80,13 @@ ..() if(lasercolor == "b" && disabled == 0) - if(istype(Proj, /obj/item/weapon/gun/energy/laser/redtag)) + if(istype(Proj, /obj/item/weapon/gun/energy/lasertag/red)) disabled = 1 del(Proj) // qdel sleep(100) disabled = 0 if(lasercolor == "r" && disabled == 0) - if(istype(Proj, /obj/item/weapon/gun/energy/laser/bluetag)) + if(istype(Proj, /obj/item/weapon/gun/energy/lasertag/blue)) disabled = 1 del(Proj) // qdel sleep(100) @@ -110,10 +104,10 @@ switch(lasercolor) if("b") target_suit = /obj/item/clothing/suit/redtag - target_weapon = /obj/item/weapon/gun/energy/laser/redtag + target_weapon = /obj/item/weapon/gun/energy/lasertag/red if("r") target_suit = /obj/item/clothing/suit/bluetag - target_weapon = /obj/item/weapon/gun/energy/laser/bluetag + target_weapon = /obj/item/weapon/gun/energy/lasertag/blue if(target_suit)//Lasertag turrets target the opposing team, how great is that? -Sieve diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 3192897718..5e2c4b69cb 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -46,7 +46,7 @@ var/attacked = 0 //if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!) - var/on = 1 //determines if the turret is on + var/enabled = 1 //determines if the turret is on var/lethal = 0 //whether in lethal or stun mode var/disabled = 0 @@ -56,6 +56,7 @@ var/datum/effect/effect/system/spark_spread/spark_system //the spark system, used for generating... sparks? var/wrenching = 0 + var/last_target //last target fired at, prevents turrets from erratically firing at all valid targets in range /obj/machinery/porta_turret/stationary lethal = 1 @@ -94,13 +95,13 @@ // iconholder = 1 // eprojectile = /obj/item/projectile/beam - if(/obj/item/weapon/gun/energy/laser/retro) + if(/obj/item/weapon/gun/energy/retro) iconholder = 1 -// if(/obj/item/weapon/gun/energy/laser/retro/sc_retro) +// if(/obj/item/weapon/gun/energy/retro/sc_retro) // iconholder = 1 - if(/obj/item/weapon/gun/energy/laser/captain) + if(/obj/item/weapon/gun/energy/captain) iconholder = 1 if(/obj/item/weapon/gun/energy/lasercannon) @@ -132,7 +133,7 @@ icon_state = "destroyed_target_prism" else if(powered()) - if(on) + if(enabled) if(iconholder) //lasers have a orange icon icon_state = "orange_target_prism" @@ -149,109 +150,98 @@ del(cover) // qdel ..() -/obj/machinery/porta_turret/proc/can_use(mob/user) - if(ailock && issilicon(user)) +/obj/machinery/porta_turret/proc/isLocked(mob/user) + if(ailock && user.isSilicon()) user << "There seems to be a firewall preventing you from accessing this device." - return 0 + return 1 - if (get_dist(src, user) > 1 && !issilicon(user)) - user << "You are too far away." - user.unset_machine() - user << browse(null, "window=turretid") - return 0 - - if(locked && !issilicon(user)) + if(locked && !user.isSilicon()) user << "Access denied." - return 0 + return 1 - return 1 + return 0 /obj/machinery/porta_turret/attack_ai(mob/user) - return attack_hand(user) + if(isLocked(user)) + return + + ui_interact(user) /obj/machinery/porta_turret/attack_hand(mob/user) - if(..()) - return 1 - if(!can_use(user)) - return 1 - interact(user) + if(isLocked(user)) + return -/obj/machinery/porta_turret/interact(mob/user) - var/dat = text({" - Automatic Portable Turret Installation

      - Status: []
      - Behaviour controls are [locked ? "locked" : "unlocked"]"}, - "[on ? "On" : "Off"]" ) + ui_interact(user) - if(!locked || issilicon(user)) - dat += text({"

      - Lethal Mode: []
      - Neutralize All Non-Synthetics: []
      "}, +/obj/machinery/porta_turret/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + data["access"] = !isLocked(user) + data["locked"] = locked + data["enabled"] = enabled + data["is_lethal"] = 1 + data["lethal"] = lethal - "[lethal ? "Enabled" : "Disabled"]", - "[check_synth ? "Yes" : "No"]") - if(!check_synth) - dat += text({"Check for Weapon Authorization: []
      - Check Security Records: []
      - Check Arrest Status: []
      - Neutralize All Non-Authorized Personnel: []
      - Neutralize All Unidentified Life Signs: []
      "}, + if(data["access"]) + var/settings[0] + settings[++settings.len] = list("category" = "Neutralize All Non-Synthetics", "setting" = "check_synth", "value" = check_synth) + settings[++settings.len] = list("category" = "Check Weapon Authorization", "setting" = "check_weapons", "value" = check_weapons) + settings[++settings.len] = list("category" = "Check Security Records", "setting" = "check_records", "value" = check_records) + settings[++settings.len] = list("category" = "Check Arrest Status", "setting" = "check_arrest", "value" = check_arrest) + settings[++settings.len] = list("category" = "Check Access Authorization", "setting" = "check_access", "value" = check_access) + settings[++settings.len] = list("category" = "Check misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies) + data["settings"] = settings - "[check_weapons ? "Yes" : "No"]", - "[check_records ? "Yes" : "No"]", - "[check_arrest ? "Yes" : "No"]", - "[check_access ? "Yes" : "No"]", - "[check_anomalies ? "Yes" : "No"]" ) - else - dat += "
      Swipe ID card to unlock interface
      " - - user << browse("Automatic Portable Turret Installation[dat]", "window=autosec") - onclose(user, "autosec") - return + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) /obj/machinery/porta_turret/proc/HasController() var/area/A = get_area(src) return A && A.turret_controls.len > 0 -/obj/machinery/porta_turret/Topic(href, href_list) +/obj/machinery/porta_turret/CanUseTopic(var/mob/user) + if(HasController()) + user << "Turrets can only be controlled using the assigned turret controller." + return STATUS_CLOSE + + if(isLocked(user)) + return STATUS_CLOSE + + if(!anchored) + usr << "\The [src] has to be secured first!" + return STATUS_CLOSE + + return STATUS_INTERACTIVE + + +/obj/machinery/porta_turret/Topic(href, href_list, var/nowindow = 0) if(..()) return 1 - if(!can_use(usr)) + + if(href_list["command"] && href_list["value"]) + var/value = text2num(href_list["value"]) + if(href_list["command"] == "enable") + enabled = value + else if(href_list["command"] == "lethal") + lethal = value + else if(href_list["command"] == "check_synth") + check_synth = value + else if(href_list["command"] == "check_weapons") + check_weapons = value + else if(href_list["command"] == "check_records") + check_records = value + else if(href_list["command"] == "check_arrest") + check_arrest = value + else if(href_list["command"] == "check_access") + check_access = value + else if(href_list["command"] == "check_anomalies") + check_anomalies = value + return 1 - if(HasController()) - usr << "Turrets can only be controlled using the assigned turret controller." - return - - usr.set_machine(src) - if(href_list["power"]) - if(anchored) //you can't turn a turret on/off if it's not anchored/secured - on = !on //toggle on/off - else - usr << "It has to be secured first!" - - attack_hand(usr) - return - - switch(href_list["operation"]) //toggles customizable behavioural protocols - if("togglelethal") - if(!controllock) - lethal = !lethal - if("toggleai") - check_synth = !check_synth - if("authweapon") - check_weapons = !check_weapons - if("checkrecords") - check_records = !check_records - if("checkarrests") - check_arrest = !check_arrest - if("checkaccess") - check_access = !check_access - if("checkxenos") - check_anomalies = !check_anomalies - attack_hand(usr) - - /obj/machinery/porta_turret/power_change() if(powered()) stat &= ~NOPOWER @@ -291,12 +281,12 @@ emagged = 1 iconholder = 1 controllock = 1 - on = 0 //turns off the turret temporarily + enabled = 0 //turns off the turret temporarily sleep(60) //6 seconds for the traitor to gtfo of the area before the turret decides to ruin his shit - on = 1 //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here + enabled = 1 //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here else if((istype(I, /obj/item/weapon/wrench))) - if(on || raised) + if(enabled || raised) user << "You cannot unsecure an active turret!" return if(wrenching) @@ -341,7 +331,7 @@ else //if the turret was attacked with the intention of harming it: - user.changeNext_move(CLICK_CD_MELEE) + user.changeNext_move(NEXT_MOVE_DELAY) take_damage(I.force * 0.5) if(I.force * 0.5 > 1) //if the force of impact dealt at least 1 damage, the turret gets pissed off if(!attacked && !emagged) @@ -363,7 +353,7 @@ if(Proj.damage_type == HALLOSS) return - if(on) + if(enabled) if(!attacked && !emagged) attacked = 1 spawn() @@ -376,7 +366,7 @@ take_damage(Proj.damage) /obj/machinery/porta_turret/emp_act(severity) - if(on) + if(enabled) //if the turret is on, the EMP no matter how severe disables the turret for a while //and scrambles its settings, with a slight chance of having an emag effect check_arrest = prob(50) @@ -387,10 +377,10 @@ if(prob(5)) emagged = 1 - on=0 + enabled=0 sleep(rand(60,600)) - if(!on) - on=1 + if(!enabled) + enabled=1 ..() @@ -437,7 +427,7 @@ popDown() return - if(!on) + if(!enabled) //if the turret is off, make it pop down popDown() return @@ -498,7 +488,7 @@ if(iscuffed(L)) // If the target is handcuffed, leave it alone return TURRET_NOT_TARGET - if(isanimal(L) || ismonkey(L)) // Animals are not so dangerous + if(isanimal(L) || issmall(L)) // Animals are not so dangerous return check_anomalies ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET if(isxenomorph(L) || isalien(L)) // Xenos are dangerous return check_anomalies ? TURRET_PRIORITY_TARGET : TURRET_NOT_TARGET @@ -513,6 +503,9 @@ return TURRET_PRIORITY_TARGET //if the perp has passed all previous tests, congrats, it is now a "shoot-me!" nominee /obj/machinery/porta_turret/proc/tryToShootAt(var/list/mob/living/targets) + if(targets.len && last_target && (last_target in targets) && target(last_target)) + return 1 + while(targets.len > 0) var/mob/living/M = pick(targets) targets -= M @@ -538,6 +531,7 @@ update_icon() /obj/machinery/porta_turret/proc/popDown() //pops the turret down + last_target = null if(disabled) return if(raising || !raised) @@ -566,7 +560,8 @@ /obj/machinery/porta_turret/proc/target(var/mob/living/target) if(disabled) return - if(target && (target.stat != DEAD) && (!(target.lying) || emagged)) + if(target) + last_target = target spawn() popUp() //pop the turret up if it's not already up. set_dir(get_dir(src, target)) //even if you can't shoot, follow the target @@ -577,7 +572,7 @@ /obj/machinery/porta_turret/proc/shootAt(var/mob/living/target) //any emagged turrets will shoot extremely fast! This not only is deadly, but drains a lot power! - if(!(emagged || lethal)) //if it hasn't been emagged, it has to obey a cooldown rate + if(!emagged) //if it hasn't been emagged, it has to obey a cooldown rate if(last_fired || !raised) //prevents rapid-fire shooting, unless it's been emagged return last_fired = 1 @@ -603,19 +598,21 @@ A = new projectile(loc) playsound(loc, shot_sound, 75, 1) A.original = target - if(!(emagged || lethal)) - use_power(reqpower) - else - use_power(reqpower * 2) - //Shooting Code: + + // Lethal/emagged turrets use twice the power due to higher energy beams + // Emagged turrets again use twice as much power due to higher firing rates + use_power(reqpower * (2 * (emagged || lethal)) * (2 * emagged)) + + //Shooting Code: A.current = T + A.starting = T A.yo = U.y - T.y A.xo = U.x - T.x spawn(1) A.process() /datum/turret_checks - var/on + var/enabled var/lethal var/check_synth var/check_access @@ -628,7 +625,7 @@ /obj/machinery/porta_turret/proc/setState(var/datum/turret_checks/TC) if(controllock) return - src.on = TC.on + src.enabled = TC.enabled src.lethal = TC.lethal src.iconholder = TC.lethal @@ -733,7 +730,7 @@ gun_charge = E.power_supply.charge //the gun's charge is stored in gun_charge user << "You add [I] to the turret." - if(istype(installation, /obj/item/weapon/gun/energy/laser/bluetag) || istype(installation, /obj/item/weapon/gun/energy/laser/redtag)) + if(istype(installation, /obj/item/weapon/gun/energy/lasertag/blue) || istype(installation, /obj/item/weapon/gun/energy/lasertag/red)) target_type = /obj/machinery/porta_turret/tag else target_type = /obj/machinery/porta_turret @@ -804,7 +801,7 @@ Turret.name = finish_name Turret.installation = installation Turret.gun_charge = gun_charge - Turret.on = 0 + Turret.enabled = 0 Turret.setup() // Turret.cover=new/obj/machinery/porta_turret_cover(loc) @@ -821,7 +818,7 @@ if(istype(I, /obj/item/weapon/pen)) //you can rename turrets like bots! var/t = input(user, "Enter new turret name", name, finish_name) as text - t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN)) + t = sanitize(t) if(!t) return if(!in_range(src, usr) && loc != usr) diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 3049a6f694..1020833e31 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -3,187 +3,235 @@ icon = 'icons/obj/objects.dmi' icon_state = "borgcharger0" density = 1 - anchored = 1.0 + anchored = 1 use_power = 1 idle_power_usage = 50 active_power_usage = 50 var/mob/occupant = null - var/max_internal_charge = 15000 // Two charged borgs in a row with default cell - var/current_internal_charge = 15000 // Starts charged, to prevent power surges on round start - var/charging_cap_active = 25000 // Active Cap - When cyborg is inside - var/charging_cap_passive = 2500 // Passive Cap - Recharging internal capacitor when no cyborg is inside + var/obj/item/weapon/cell/cell = null + //var/max_internal_charge = 15000 // Two charged borgs in a row with default cell + //var/current_internal_charge = 15000 // Starts charged, to prevent power surges on round start + var/charging_cap_active = 1000 // Active Cap - When cyborg is inside + var/charging_cap_passive = 250 // Passive Cap - Recharging internal capacitor when no cyborg is inside var/icon_update_tick = 0 // Used to update icon only once every 10 ticks + var/charge_rate = 250 // How much charge is restored per tick + var/weld_rate = 0 // How much brute damage is repaired per tick + var/wire_rate = 0 // How much burn damage is repaired per tick +/obj/machinery/recharge_station/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/recharge_station(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/capacitor(src) + component_parts += new /obj/item/weapon/stock_parts/capacitor(src) + component_parts += new /obj/item/weapon/cell/high(src) + component_parts += new /obj/item/stack/cable_coil(src, 5) - New() - ..() - build_icon() - update_icon() + build_icon() + update_icon() - process() - if(stat & (BROKEN)) - return + RefreshParts() - if((stat & (NOPOWER)) && !current_internal_charge) // No Power. - return - - var/chargemode = 0 - if(src.occupant) - process_occupant() - chargemode = 1 - // Power Stuff - - if(stat & NOPOWER) - current_internal_charge = max(0, (current_internal_charge - (50 * CELLRATE))) // Internal Circuitry, 50W load. No power - Runs from internal cell - return // No external power = No charging - - - - if(max_internal_charge < current_internal_charge) - current_internal_charge = max_internal_charge// Safety check if varedit adminbus or something screws up - // Calculating amount of power to draw - var/charge_diff = max_internal_charge - current_internal_charge // OK we have charge differences - charge_diff = charge_diff / CELLRATE // Deconvert from Charge to Joules - if(chargemode) // Decide if use passive or active power - charge_diff = between(0, charge_diff, charging_cap_active) // Trim the values to limits - else // We should have load for this tick in Watts - charge_diff = between(0, charge_diff, charging_cap_passive) - - charge_diff += 50 // 50W for circuitry - - if(idle_power_usage != charge_diff) // Force update, but only when our power usage changed this tick. - idle_power_usage = charge_diff - update_use_power(1,1) - - current_internal_charge = min((current_internal_charge + ((charge_diff - 50) * CELLRATE)), max_internal_charge) - - if(icon_update_tick >= 10) - update_icon() - icon_update_tick = 0 - else - icon_update_tick++ - - return 1 - - - allow_drop() - return 0 - - examine(mob/user) - ..(user) - user << "The charge meter reads: [round(chargepercentage())]%" - - proc/chargepercentage() - return ((current_internal_charge / max_internal_charge) * 100) - - relaymove(mob/user as mob) - if(user.stat) - return - src.go_out() +/obj/machinery/recharge_station/process() + if(stat & (BROKEN)) return - emp_act(severity) - if(stat & (BROKEN|NOPOWER)) - ..(severity) - return - if(occupant) - occupant.emp_act(severity) - go_out() - ..(severity) - - update_icon() - ..() - overlays.Cut() - switch(round(chargepercentage())) - if(1 to 20) - overlays += image('icons/obj/objects.dmi', "statn_c0") - if(21 to 40) - overlays += image('icons/obj/objects.dmi', "statn_c20") - if(41 to 60) - overlays += image('icons/obj/objects.dmi', "statn_c40") - if(61 to 80) - overlays += image('icons/obj/objects.dmi', "statn_c60") - if(81 to 98) - overlays += image('icons/obj/objects.dmi', "statn_c80") - if(99 to 110) - overlays += image('icons/obj/objects.dmi', "statn_c100") - - proc - build_icon() - if(NOPOWER|BROKEN) - if(src.occupant) - icon_state = "borgcharger1" - else - icon_state = "borgcharger0" - else - icon_state = "borgcharger0" + if((stat & (NOPOWER)) && (!cell || cell.percent() <= 0)) // No Power. + return + var/chargemode = 0 + if(occupant) process_occupant() - if(src.occupant) - if (istype(occupant, /mob/living/silicon/robot)) - var/mob/living/silicon/robot/R = occupant - if(R.module) - R.module.respawn_consumable(R) - if(!R.cell) - return - if(!R.cell.fully_charged()) - var/diff = min(R.cell.maxcharge - R.cell.charge, 250) // Capped at 250 charge / tick - diff = min(diff, current_internal_charge) // No over-discharging - R.cell.give(diff) - current_internal_charge -= diff - else - update_use_power(1) + chargemode = 1 + // Power Stuff + + if(!cell) // Shouldn't be possible, but sanity check + return + + if(stat & NOPOWER) + cell.use(50 * CELLRATE) // Internal Circuitry, 50W load. No power - Runs from internal cell + return // No external power = No charging + + // Calculating amount of power to draw + var/charge_diff = (chargemode ? charging_cap_active : charging_cap_passive) + 50 // 50W for circuitry + + charge_diff = cell.give(charge_diff) + + if(idle_power_usage != charge_diff) // Force update, but only when our power usage changed this tick. + idle_power_usage = charge_diff + update_use_power(1, 1) + + if(icon_update_tick >= 10) + update_icon() + icon_update_tick = 0 + else + icon_update_tick++ + + return 1 + + +/obj/machinery/recharge_station/allow_drop() + return 0 + +/obj/machinery/recharge_station/examine(mob/user) + ..(user) + user << "The charge meter reads: [round(chargepercentage())]%" + +/obj/machinery/recharge_station/proc/chargepercentage() + if(!cell) + return 0 + return cell.percent() + +/obj/machinery/recharge_station/relaymove(mob/user as mob) + if(user.stat) + return + go_out() + return + +/obj/machinery/recharge_station/emp_act(severity) + if(stat & (BROKEN|NOPOWER)) + ..(severity) + return + if(occupant) + occupant.emp_act(severity) go_out() - if(!( src.occupant )) - return - //for(var/obj/O in src) - // O.loc = src.loc - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - src.occupant.loc = src.loc - src.occupant = null - build_icon() - update_use_power(1) + if(cell) + cell.emp_act(severity) + ..(severity) + +/obj/machinery/recharge_station/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(!occupant) + if(default_deconstruction_screwdriver(user, O)) + return + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) return + ..() - verb - move_eject() - set category = "Object" - set src in oview(1) - if (usr.stat != 0) - return - src.go_out() - add_fingerprint(usr) - return +/obj/machinery/recharge_station/RefreshParts() + ..() + var/man_rating = 0 + var/cap_rating = 0 - move_inside() - set category = "Object" - set src in oview(1) - if (usr.stat == 2) - //Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO + for(var/obj/item/weapon/stock_parts/P in component_parts) + if(istype(P, /obj/item/weapon/stock_parts/capacitor)) + cap_rating += P.rating + if(istype(P, /obj/item/weapon/stock_parts/manipulator)) + man_rating += P.rating + cell = locate(/obj/item/weapon/cell) in component_parts + + charge_rate = 125 * cap_rating + charging_cap_passive = charge_rate + weld_rate = max(0, man_rating - 3) + wire_rate = max(0, man_rating - 5) + +/obj/machinery/recharge_station/update_icon() + ..() + overlays.Cut() + switch(round(chargepercentage())) + if(1 to 20) + overlays += image('icons/obj/objects.dmi', "statn_c0") + if(21 to 40) + overlays += image('icons/obj/objects.dmi', "statn_c20") + if(41 to 60) + overlays += image('icons/obj/objects.dmi', "statn_c40") + if(61 to 80) + overlays += image('icons/obj/objects.dmi', "statn_c60") + if(81 to 98) + overlays += image('icons/obj/objects.dmi', "statn_c80") + if(99 to 110) + overlays += image('icons/obj/objects.dmi', "statn_c100") + +/obj/machinery/recharge_station/Bumped(var/mob/AM) + move_inside(AM) + +/obj/machinery/recharge_station/proc/build_icon() + if(NOPOWER|BROKEN) + if(occupant) + icon_state = "borgcharger1" + else + icon_state = "borgcharger0" + else + icon_state = "borgcharger0" + +/obj/machinery/recharge_station/proc/process_occupant() + if(occupant) + if(istype(occupant, /mob/living/silicon/robot)) + var/mob/living/silicon/robot/R = occupant + if(R.module) + R.module.respawn_consumable(R, charge_rate / 250) + if(!R.cell) return - if (!(istype(usr, /mob/living/silicon/))) - usr << "\blue Only non-organics may enter the recharger!" - return - if (src.occupant) - usr << "\blue The cell is already occupied!" - return - if (!usr:cell) - usr<<"\blue Without a powercell, you can't be recharged." - //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO - return - usr.stop_pulling() - if(usr && usr.client) - usr.client.perspective = EYE_PERSPECTIVE - usr.client.eye = src - usr.loc = src - src.occupant = usr - /*for(var/obj/O in src) - O.loc = src.loc*/ - src.add_fingerprint(usr) - build_icon() - update_use_power(1) - return \ No newline at end of file + if(!R.cell.fully_charged()) + var/diff = min(R.cell.maxcharge - R.cell.charge, charge_rate) // Capped at charge_rate charge / tick + if (cell.use(diff)) + R.cell.give(diff) + if(weld_rate && R.getBruteLoss()) + R.adjustBruteLoss(-1) + if(wire_rate && R.getFireLoss()) + R.adjustFireLoss(-1) + else + update_use_power(1) + +/obj/machinery/recharge_station/proc/go_out() + if(!(occupant)) + return + //for(var/obj/O in src) + // O.loc = loc + if(occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE + occupant.loc = loc + occupant = null + build_icon() + update_use_power(1) + return + +/obj/machinery/recharge_station/verb/move_eject() + set category = "Object" + set src in oview(1) + if(usr.stat != 0) + return + go_out() + add_fingerprint(usr) + return + +/obj/machinery/recharge_station/verb/move_inside(var/mob/user = usr) + set category = "Object" + set src in oview(1) + + if(!user) + return + + if(!(istype(user, /mob/living/silicon/robot))) + user << "Only non-organics may enter the recharger!" + return + var/mob/living/silicon/robot/R = user + + if(R.stat == 2) + //Whoever had it so that a borg with a dead cell can't enter this thing should be shot. --NEO + return + if(occupant) + R << "The cell is already occupied!" + return + if(!R.cell) + R << "Without a powercell, you can't be recharged." + //Make sure they actually HAVE a cell, now that they can get in while powerless. --NEO + return + R.stop_pulling() + if(R.client) + R.client.perspective = EYE_PERSPECTIVE + R.client.eye = src + R.loc = src + occupant = R + /*for(var/obj/O in src) + O.loc = loc*/ + add_fingerprint(R) + build_icon() + update_use_power(1) + return diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index f9dd2216df..3c7e1613b9 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -223,7 +223,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() if(reject_bad_text(href_list["write"])) dpt = ckey(href_list["write"]) //write contains the string of the receiving department's name - var/new_message = copytext(reject_bad_text(input(usr, "Write your message:", "Awaiting Input", "")),1,MAX_MESSAGE_LEN) + var/new_message = sanitize(input("Write your message:", "Awaiting Input", "")) if(new_message) message = new_message screen = 9 @@ -238,7 +238,7 @@ var/list/obj/machinery/requests_console/allConsoles = list() priority = -1 if(href_list["writeAnnouncement"]) - var/new_message = copytext(reject_bad_text(input(usr, "Write your message:", "Awaiting Input", "")),1,MAX_MESSAGE_LEN) + var/new_message = sanitize(input("Write your message:", "Awaiting Input", "")) if(new_message) message = new_message switch(href_list["priority"]) diff --git a/code/game/machinery/seed_extractor.dm b/code/game/machinery/seed_extractor.dm index 9c5dfab8e4..4778ac13ea 100644 --- a/code/game/machinery/seed_extractor.dm +++ b/code/game/machinery/seed_extractor.dm @@ -1,7 +1,7 @@ /obj/machinery/seed_extractor name = "seed extractor" desc = "Extracts and bags seeds from produce." - icon = 'icons/obj/hydroponics.dmi' + icon = 'icons/obj/hydroponics_machines.dmi' icon_state = "sextractor" density = 1 anchored = 1 @@ -16,10 +16,10 @@ obj/machinery/seed_extractor/attackby(var/obj/item/O as obj, var/mob/user as mob var/datum/seed/new_seed_type if(istype(O, /obj/item/weapon/grown)) var/obj/item/weapon/grown/F = O - new_seed_type = seed_types[F.plantname] + new_seed_type = plant_controller.seeds[F.plantname] else var/obj/item/weapon/reagent_containers/food/snacks/grown/F = O - new_seed_type = seed_types[F.plantname] + new_seed_type = plant_controller.seeds[F.plantname] if(new_seed_type) user << "You extract some seeds from [O]." diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index ab4967d04e..c5d389c66e 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -7,7 +7,6 @@ desc = "Made by Space Amish using traditional space techniques, this heater is guaranteed not to set the station on fire." var/obj/item/weapon/cell/cell var/on = 0 - var/open = 0 var/set_temperature = T0C + 50 //K var/heating_power = 40000 @@ -20,14 +19,14 @@ /obj/machinery/space_heater/update_icon() overlays.Cut() icon_state = "sheater[on]" - if(open) + if(panel_open) overlays += "sheater-open" /obj/machinery/space_heater/examine(mob/user) ..(user) - user << "The heater is [on ? "on" : "off"] and the hatch is [open ? "open" : "closed"]." - if(open) + user << "The heater is [on ? "on" : "off"] and the hatch is [panel_open ? "open" : "closed"]." + if(panel_open) user << "The power cell is [cell ? "installed" : "missing"]." else user << "The charge meter reads [cell ? round(cell.percent(),1) : 0]%" @@ -43,7 +42,7 @@ /obj/machinery/space_heater/attackby(obj/item/I, mob/user) if(istype(I, /obj/item/weapon/cell)) - if(open) + if(panel_open) if(cell) user << "There is already a power cell inside." return @@ -61,10 +60,10 @@ user << "The hatch must be open to insert a power cell." return else if(istype(I, /obj/item/weapon/screwdriver)) - open = !open - user.visible_message("\blue [user] [open ? "opens" : "closes"] the hatch on the [src].", "\blue You [open ? "open" : "close"] the hatch on the [src].") + panel_open = !panel_open + user.visible_message("\blue [user] [panel_open ? "opens" : "closes"] the hatch on the [src].", "\blue You [panel_open ? "open" : "close"] the hatch on the [src].") update_icon() - if(!open && user.machine == src) + if(!panel_open && user.machine == src) user << browse(null, "window=spaceheater") user.unset_machine() else @@ -77,7 +76,7 @@ /obj/machinery/space_heater/interact(mob/user as mob) - if(open) + if(panel_open) var/dat dat = "Power cell: " @@ -120,7 +119,7 @@ set_temperature = dd_range(T0C, T0C + 90, set_temperature + value) if("cellremove") - if(open && cell && !usr.get_active_hand()) + if(panel_open && cell && !usr.get_active_hand()) usr.visible_message("\blue [usr] removes \the [cell] from \the [src].", "\blue You remove \the [cell] from \the [src].") cell.updateicon() usr.put_in_hands(cell) @@ -129,7 +128,7 @@ if("cellinstall") - if(open && !cell) + if(panel_open && !cell) var/obj/item/weapon/cell/C = usr.get_active_hand() if(istype(C)) usr.drop_item() diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index d0ac55780d..534e59c0c6 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -589,7 +589,6 @@ var/radiation_level = 2 // 1 is removing germs, 2 is removing blood, 3 is removing phoron. var/model_text = "" // Some flavour text for the topic box. var/locked = 1 // If locked, nothing can be taken from or added to the cycler. - var/panel_open = 0 // Hacking! var/can_repair // If set, the cycler can repair voidsuits. var/electrified = 0 diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index 722c96d583..957f7bf536 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -59,34 +59,9 @@ return if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/N = M - ticker.mode.equip_traitor(N) - ticker.mode.traitors += N.mind - N.mind.special_role = "traitor" - if(!config.objectives_disabled) - var/objective = "Free Objective" - switch(rand(1,100)) - if(1 to 50) - objective = "Steal [pick("a hand teleporter", "the Captain's antique laser gun", "a jetpack", "the Captain's ID", "the Captain's jumpsuit")]." - if(51 to 60) - objective = "Destroy 70% or more of the station's phoron tanks." - if(61 to 70) - objective = "Cut power to 80% or more of the station's tiles." - if(71 to 80) - objective = "Destroy the AI." - if(81 to 90) - objective = "Kill all monkeys aboard the station." - else - objective = "Make certain at least 80% of the station evacuates on the shuttle." - var/datum/objective/custom_objective = new(objective) - custom_objective.owner = N.mind - N.mind.objectives += custom_objective - - var/datum/objective/escape/escape_objective = new - escape_objective.owner = N.mind - N.mind.objectives += escape_objective - M << "You have joined the ranks of the Syndicate and become a traitor to the station!" - show_objectives(M.mind) + traitors.add_antagonist(N.mind) + traitors.equip(N) message_admins("[N]/([N.ckey]) has accepted a traitor objective from a syndicate beacon.") diff --git a/code/game/machinery/telecomms/logbrowser.dm b/code/game/machinery/telecomms/logbrowser.dm index 82a80822e6..6dd5586fd8 100644 --- a/code/game/machinery/telecomms/logbrowser.dm +++ b/code/game/machinery/telecomms/logbrowser.dm @@ -77,7 +77,7 @@ race = "[H.species.name]" - else if(ismonkey(M)) + else if(issmall(M)) race = "Monkey" language = race diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 786300f00d..9e68791df0 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -9,6 +9,10 @@ var/one_time_use = 0 //Used for one-time-use teleport cards (such as clown planet coordinates.) //Setting this to 1 will set src.locked to null after a player enters the portal and will not allow hand-teles to open portals to that location. +/* Ghosts can't use this */ +/obj/machinery/computer/teleporter/attack_ghost(user as mob) + return 1 + /obj/machinery/computer/teleporter/New() src.id = "[rand(1000, 9999)]" ..() @@ -80,9 +84,11 @@ /obj/machinery/teleport/station/attack_ai() src.attack_hand() -/obj/machinery/computer/teleporter/attack_hand() - if(stat & (NOPOWER|BROKEN)) - return +/obj/machinery/computer/teleporter/attack_hand(user as mob) + if(..()) return + + /* Ghosts can't use this one because it's a direct selection */ + if(istype(user, /mob/dead/observer)) return var/list/L = list() var/list/areaindex = list() @@ -91,7 +97,7 @@ var/turf/T = get_turf(R) if (!T) continue - if(T.z == 2 || T.z > 7) + if(!(T.z in config.player_levels)) continue var/tmpname = T.loc.name if(areaindex[tmpname]) @@ -169,6 +175,7 @@ active_power_usage = 2000 var/obj/machinery/computer/teleporter/com + /obj/machinery/teleport/hub/New() ..() underlays.Cut() @@ -329,6 +336,8 @@ if (com) com.icon_state = "tele1" use_power(5000) + update_use_power(2) + com.update_use_power(2) for(var/mob/O in hearers(src, null)) O.show_message("\blue Teleporter engaged!", 2) src.add_fingerprint(usr) @@ -342,6 +351,8 @@ if (com) com.icon_state = "tele0" com.accurate = 0 + com.update_use_power(1) + update_use_power(1) for(var/mob/O in hearers(src, null)) O.show_message("\blue Teleporter disengaged!", 2) src.add_fingerprint(usr) diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index 7885a8b8e2..c9c8ba20ae 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -38,7 +38,6 @@ playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) if(robot) robot.SetLockDown(0) - robot.notify_ai(1) /obj/machinery/transformer/conveyor/New() ..() diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm index 41a98103be..c463c3c497 100644 --- a/code/game/machinery/turret_control.dm +++ b/code/game/machinery/turret_control.dm @@ -16,7 +16,7 @@ var/enabled = 0 var/lethal = 0 var/locked = 1 - var/control_area //can be area name, path or nothing. + var/area/control_area //can be area name, path or nothing. var/check_arrest = 1 //checks if the perp is set to arrest var/check_records = 1 //checks if a security record exists at all @@ -24,7 +24,7 @@ var/check_access = 1 //if this is active, the turret shoots everything that does not meet the access requirements var/check_anomalies = 1 //checks if it can shoot at unidentified lifeforms (ie xenos) var/check_synth = 0 //if active, will shoot at anything not an AI or cyborg - var/ailock = 0 // AI cannot use this + var/ailock = 0 //Silicons cannot use this req_access = list(access_ai_upload) @@ -47,159 +47,127 @@ /obj/machinery/turretid/initialize() if(!control_area) var/area/CA = get_area(src) - if(CA.master && CA.master != CA) - control_area = CA.master - else - control_area = CA + control_area = CA.master else if(istext(control_area)) for(var/area/A in world) if(A.name && A.name==control_area) - control_area = A + control_area = A.master break - power_change() //Checks power and initial settings - //don't have to check if control_area is path, since get_area_all_atoms can take path. if(control_area) var/area/A = control_area - if(A && istype(A)) + if(istype(A)) A.turret_controls += src + else + control_area = null + + power_change() //Checks power and initial settings return -/obj/machinery/turretid/proc/can_use(mob/user) - if(ailock && issilicon(user)) +/obj/machinery/turretid/proc/isLocked(mob/user) + if(ailock && user.isSilicon()) user << "There seems to be a firewall preventing you from accessing this device." - return 0 + return 1 - if (get_dist(src, user) > 0 && !issilicon(user)) - user << "You are too far away." - user.unset_machine() - user << browse(null, "window=turretid") - return 0 - - if(locked && !issilicon(user)) + if(locked && !user.isSilicon()) user << "Access denied." - return 0 + return 1 - return 1 + return 0 + +/obj/machinery/turretid/CanUseTopic(mob/user) + if(isLocked(user)) + return STATUS_CLOSE + + return STATUS_INTERACTIVE /obj/machinery/turretid/attackby(obj/item/weapon/W, mob/user) - if(stat & BROKEN) return - if (istype(user, /mob/living/silicon)) - return src.attack_hand(user) + if(stat & BROKEN) + return - if (istype(W, /obj/item/weapon/card/emag) && !emagged) + if(!emagged && istype(W, /obj/item/weapon/card/emag)) user << "You short out the turret controls' access analysis module." emagged = 1 locked = 0 - if(user.machine==src) - src.attack_hand(user) - + ailock = 0 return - else if( get_dist(src, user) == 0 ) // trying to unlock the interface - if (src.allowed(usr)) + if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) + if(src.allowed(usr)) if(emagged) user << "The turret control is unresponsive." - return - - locked = !locked - user << "You [ locked ? "lock" : "unlock"] the panel." - if (locked) - if (user.machine==src) - user.unset_machine() - user << browse(null, "window=turretid") else - if (user.machine==src) - src.attack_hand(user) - else - user << "Access denied." + locked = !locked + user << "You [ locked ? "lock" : "unlock"] the panel." + return + return ..() /obj/machinery/turretid/attack_ai(mob/user as mob) - return attack_hand(user) + if(isLocked(user)) + return + + ui_interact(user) /obj/machinery/turretid/attack_hand(mob/user as mob) - if(!can_use(user)) + if(isLocked(user)) return - user.set_machine(src) - var/loc = src.loc - if (istype(loc, /turf)) - var/turf/T = loc - loc = T.loc - if (!istype(loc, /area)) - return - var/area/area = loc - var/dat = text({"Status: []
      - Behaviour controls are [locked ? "locked" : "unlocked"]"}, - "[enabled ? "On" : "Off"]" ) + ui_interact(user) - if(!locked || issilicon(user)) - dat += text({"

      - Lethal Mode: []
      - Neutralize All Non-Synthetics: []
      "}, +/obj/machinery/turretid/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + data["access"] = !isLocked(user) + data["locked"] = locked + data["enabled"] = enabled + data["is_lethal"] = 1 + data["lethal"] = lethal - "[lethal ? "Enabled" : "Disabled"]", - "[check_synth ? "Yes" : "No"]") - if(!check_synth) - dat += text({"Check for Weapon Authorization: []
      - Check Security Records: []
      - Check Arrest Status: []
      - Neutralize All Non-Authorized Personnel: []
      - Neutralize All Unidentified Life Signs: []
      "}, + if(data["access"]) + var/settings[0] + settings[++settings.len] = list("category" = "Neutralize All Non-Synthetics", "setting" = "check_synth", "value" = check_synth) + settings[++settings.len] = list("category" = "Check Weapon Authorization", "setting" = "check_weapons", "value" = check_weapons) + settings[++settings.len] = list("category" = "Check Security Records", "setting" = "check_records", "value" = check_records) + settings[++settings.len] = list("category" = "Check Arrest Status", "setting" = "check_arrest", "value" = check_arrest) + settings[++settings.len] = list("category" = "Check Access Authorization", "setting" = "check_access", "value" = check_access) + settings[++settings.len] = list("category" = "Check misc. Lifeforms", "setting" = "check_anomalies", "value" = check_anomalies) + data["settings"] = settings - "[check_weapons ? "Yes" : "No"]", - "[check_records ? "Yes" : "No"]", - "[check_arrest ? "Yes" : "No"]", - "[check_access ? "Yes" : "No"]", - "[check_anomalies ? "Yes" : "No"]" ) - else - dat += "
      Swipe ID card to unlock interface
      " - - //user << browse(t, "window=turretid") - //onclose(user, "turretid") - var/datum/browser/popup = new(user, "turretid", "Turret Control Panel ([area.name])", 500, 500) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "turret_control.tmpl", "Turret Controls", 500, 300) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) /obj/machinery/turretid/Topic(href, href_list, var/nowindow = 0) if(..()) return 1 - if(!can_use(usr)) + if(href_list["command"] && href_list["value"]) + var/value = text2num(href_list["value"]) + if(href_list["command"] == "enable") + enabled = value + else if(href_list["command"] == "lethal") + lethal = value + else if(href_list["command"] == "check_synth") + check_synth = value + else if(href_list["command"] == "check_weapons") + check_weapons = value + else if(href_list["command"] == "check_records") + check_records = value + else if(href_list["command"] == "check_arrest") + check_arrest = value + else if(href_list["command"] == "check_access") + check_access = value + else if(href_list["command"] == "check_anomalies") + check_anomalies = value + + updateTurrets() return 1 - switch(href_list["operation"]) //toggles customizable behavioural protocols - if("toggleon") - enabled = !enabled - if("togglelethal") - lethal = !lethal - if("toggleai") - check_synth = !check_synth - if("authweapon") - check_weapons = !check_weapons - if("checkrecords") - check_records = !check_records - if("checkarrest") - check_arrest = !check_arrest - if("checkaccess") - check_access = !check_access - if("checkxenos") - check_anomalies = !check_anomalies - - src.updateTurrets() - - if(!nowindow) - attack_hand(usr) - -/obj/machinery/turretid/updateDialog() - if (stat & (BROKEN|MAINT)) - return - ..() - /obj/machinery/turretid/proc/updateTurrets() var/datum/turret_checks/TC = new - TC.on = enabled + TC.enabled = enabled TC.lethal = lethal TC.check_synth = check_synth TC.check_access = check_access @@ -209,10 +177,12 @@ TC.check_anomalies = check_anomalies TC.ailock = ailock - if(control_area) - for (var/obj/machinery/porta_turret/aTurret in get_area_all_atoms(control_area)) - aTurret.setState(TC) - src.update_icon() + if(istype(control_area)) + for(var/area/sub_area in control_area.related) + for (var/obj/machinery/porta_turret/aTurret in sub_area) + aTurret.setState(TC) + + update_icon() /obj/machinery/turretid/power_change() ..() diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm index cb76c7921a..965210ae15 100644 --- a/code/game/machinery/turrets.dm +++ b/code/game/machinery/turrets.dm @@ -89,7 +89,7 @@ return /obj/machinery/turret/bullet_act(var/obj/item/projectile/Proj) - if(Proj.damage_type == HALLOSS) + if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) return take_damage(Proj.damage) ..() @@ -265,6 +265,7 @@ A = new /obj/item/projectile/energy/electrode( loc ) use_power(200) A.current = T + A.starting = T A.yo = U.y - T.y A.xo = U.x - T.x spawn( 0 ) @@ -299,7 +300,7 @@ popping = 0 /obj/machinery/turret/bullet_act(var/obj/item/projectile/Proj) - if(Proj.damage_type == HALLOSS) + if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) return src.health -= Proj.damage ..() diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 26f1c620c7..6f941674f2 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1,17 +1,38 @@ -#define CAT_NORMAL 0 -#define CAT_HIDDEN 1 -#define CAT_COIN 2 +#define CAT_NORMAL 1 +#define CAT_HIDDEN 2 // also used in corresponding wires/vending.dm +#define CAT_COIN 4 +/** + * Datum used to hold information about a product in a vending machine + */ /datum/data/vending_product - var/product_name = "generic" + var/product_name = "generic" // Display name for the product var/product_path = null - var/amount = 0 - var/price = 0 - var/display_color = "blue" - var/category = CAT_NORMAL + var/amount = 0 // Amount held in the vending machine + var/price = 0 // Price to buy one + var/display_color = null // Display color for vending machine listing + var/category = CAT_NORMAL // CAT_HIDDEN for contraband, CAT_COIN for premium +/datum/data/vending_product/New(var/path, var/name = null, var/amount = 1, var/price = 0, var/color = null, var/category = CAT_NORMAL) + ..() + src.product_path = path + if(!name) + var/atom/tmp = new path + src.product_name = initial(tmp.name) + del(tmp) + else + src.product_name = name + + src.amount = amount + src.price = price + src.display_color = color + src.category = category + +/** + * A vending machine + */ /obj/machinery/vending name = "Vendomat" desc = "A generic vending machine." @@ -21,69 +42,107 @@ anchored = 1 density = 1 + var/icon_vend //Icon_state when vending + var/icon_deny //Icon_state when denying access + + // Power use_power = 1 idle_power_usage = 10 var/vend_power_usage = 150 //actuators and stuff + // Vending-related var/active = 1 //No sales pitches if off! var/vend_ready = 1 //Are we ready to vend?? Is it time?? var/vend_delay = 10 //How long does it take to vend? - var/datum/data/vending_product/currently_vending = null // A /datum/data/vending_product instance of what we're paying for right now. + var/categories = CAT_NORMAL // Bitmask of cats we're currently showing + var/datum/data/vending_product/currently_vending = null // What we're requesting payment for right now + var/status_message = "" // Status screen messages like "insufficient funds", displayed in NanoUI + var/status_error = 0 // Set to 1 if status_message is an error - // To be filled out at compile time + /* + Variables used to initialize the product list + These are used for initialization only, and so are optional if + product_records is specified + */ var/list/products = list() // For each, use the following pattern: var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2) var/list/premium = list() // No specified amount = only one in stock var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price. - var/product_slogans = "" //String of slogans separated by semicolons, optional - var/product_ads = "" //String of small ad messages in the vending screen - random chance + // List of vending_product items available. var/list/product_records = list() - var/list/hidden_records = list() - var/list/coin_records = list() + + + // Variables used to initialize advertising + var/product_slogans = "" //String of slogans spoken out loud, separated by semicolons + var/product_ads = "" //String of small ad messages in the vending screen + + var/list/ads_list = list() + + // Stuff relating vocalizations var/list/slogan_list = list() - var/list/small_ads = list() // small ad messages in the vending screen - random chance of popping up whenever you open it + var/shut_up = 1 //Stop spouting those godawful pitches! var/vend_reply //Thank you for shopping! var/last_reply = 0 var/last_slogan = 0 //When did we last pitch? var/slogan_delay = 6000 //How long until we can pitch again? - var/icon_vend //Icon_state when vending! - var/icon_deny //Icon_state when vending! - //var/emagged = 0 //Ignores if somebody doesn't have card access to that machine. + + // Things that can go wrong + emagged = 0 //Ignores if somebody doesn't have card access to that machine. var/seconds_electrified = 0 //Shock customers like an airlock. var/shoot_inventory = 0 //Fire items at customers! We're broken! - var/shut_up = 1 //Stop spouting those godawful pitches! - var/extended_inventory = 0 //can we access the hidden inventory? - var/panel_open = 0 //Hacking that vending machine. Gonna get a free candy bar. + var/scan_id = 1 var/obj/item/weapon/coin/coin var/datum/wires/vending/wires = null - var/check_accounts = 0 // 1 = requires PIN and checks accounts. 0 = You slide an ID, it vends, SPACE COMMUNISM! - var/obj/item/weapon/spacecash/ewallet/ewallet - - /obj/machinery/vending/New() ..() wires = new(src) spawn(4) - src.slogan_list = text2list(src.product_slogans, ";") + if(src.product_slogans) + src.slogan_list += text2list(src.product_slogans, ";") - // So not all machines speak at the exact same time. - // The first time this machine says something will be at slogantime + this random value, - // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. - src.last_slogan = world.time + rand(0, slogan_delay) + // So not all machines speak at the exact same time. + // The first time this machine says something will be at slogantime + this random value, + // so if slogantime is 10 minutes, it will say it at somewhere between 10 and 20 minutes after the machine is crated. + src.last_slogan = world.time + rand(0, slogan_delay) - src.build_inventory(products) - //Add hidden inventory - src.build_inventory(contraband, 1) - src.build_inventory(premium, 0, 1) + if(src.product_ads) + src.ads_list += text2list(src.product_ads, ";") + + src.build_inventory() power_change() return return +/** + * Build src.produdct_records from the products lists + * + * src.products, src.contraband, src.premium, and src.prices allow specifying + * products that the vending machine is to carry without manually populating + * src.product_records. + */ +/obj/machinery/vending/proc/build_inventory() + var/list/all_products = list( + list(src.products, CAT_NORMAL), + list(src.contraband, CAT_HIDDEN), + list(src.premium, CAT_COIN)) + + for(var/current_list in all_products) + var/category = current_list[2] + + for(var/entry in current_list[1]) + var/datum/data/vending_product/product = new/datum/data/vending_product(entry) + + product.price = (entry in src.prices) ? src.prices[entry] : 0 + product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 + product.category = category + + src.product_records.Add(product) + /obj/machinery/vending/Del() del(wires) // qdel wires = null @@ -119,37 +178,30 @@ return -/obj/machinery/vending/proc/build_inventory(var/list/productlist,hidden=0,req_coin=0) - - for(var/typepath in productlist) - var/amount = productlist[typepath] - var/price = prices[typepath] - if(isnull(amount)) amount = 1 - - var/datum/data/vending_product/R = new /datum/data/vending_product() - - R.product_path = typepath - R.amount = amount - R.price = price - R.display_color = pick("red","blue","green") - - if(hidden) - R.category=CAT_HIDDEN - hidden_records += R - else if(req_coin) - R.category=CAT_COIN - coin_records += R - else - R.category=CAT_NORMAL - product_records += R - - var/atom/temp = typepath - R.product_name = initial(temp.name) - -// world << "Added: [R.product_name]] - [R.amount] - [R.product_path]" - return - /obj/machinery/vending/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (currently_vending && vendor_account && !vendor_account.suspended) + var/paid = 0 + var/handled = 0 + if(istype(W, /obj/item/weapon/card/id)) + var/obj/item/weapon/card/id/C = W + paid = pay_with_card(C) + handled = 1 + else if (istype(W, /obj/item/weapon/spacecash/ewallet)) + var/obj/item/weapon/spacecash/ewallet/C = W + paid = pay_with_ewallet(C) + handled = 1 + else if (istype(W, /obj/item/weapon/spacecash)) + var/obj/item/weapon/spacecash/C = W + paid = pay_with_cash(C, user) + handled = 1 + + if(paid) + src.vend(currently_vending, usr) + return + else if(handled) + nanomanager.update_uis(src) + return // don't smack that machine with your 2 thalers + if (istype(W, /obj/item/weapon/card/emag)) src.emagged = 1 user << "You short out the product lock on [src]" @@ -160,7 +212,8 @@ src.overlays.Cut() if(src.panel_open) src.overlays += image(src.icon, "[initial(icon_state)]-panel") - src.updateUsrDialog() + + nanomanager.update_uis(src) // Speaker switch is on the main UI, not wires UI return else if(istype(W, /obj/item/device/multitool)||istype(W, /obj/item/weapon/wirecutters)) if(src.panel_open) @@ -170,19 +223,11 @@ user.drop_item() W.loc = src coin = W + categories |= CAT_COIN user << "\blue You insert the [W] into the [src]" + nanomanager.update_uis(src) return - else if(istype(W, /obj/item/weapon/card) && currently_vending) - var/obj/item/weapon/card/I = W - scan_card(I) - else if (istype(W, /obj/item/weapon/spacecash/ewallet)) - user.drop_item() - W.loc = src - ewallet = W - user << "\blue You insert the [W] into the [src]" - else if(istype(W, /obj/item/weapon/wrench)) - if(do_after(user, 20)) if(!src) return playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) @@ -205,162 +250,205 @@ else ..() -/obj/machinery/vending/proc/scan_card(var/obj/item/weapon/card/I) - if(!currently_vending) return - if (istype(I, /obj/item/weapon/card/id)) - var/obj/item/weapon/card/id/C = I - visible_message("[usr] swipes a card through [src].") - var/datum/money_account/CH = get_account(C.associated_account_number) - if (CH) // Only proceed if card contains proper account number. - if(!CH.suspended) - if(CH.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) - if(vendor_account) - var/attempt_pin = input("Enter pin code", "Vendor transaction") as num - var/datum/money_account/D = attempt_account_access(C.associated_account_number, attempt_pin, 2) - transfer_and_vend(D) - else - usr << "\icon[src]Unable to access account. Check security settings and try again." - else - //Just Vend it. - transfer_and_vend(CH) - else - usr << "\icon[src]Connected account has been suspended." +/** + * Receive payment with cashmoney. + * + * usr is the mob who gets the change. + */ +/obj/machinery/vending/proc/pay_with_cash(var/obj/item/weapon/spacecash/cashmoney, mob/user) + if(currently_vending.price > cashmoney.worth) + + // This is not a status display message, since it's something the character + // themselves is meant to see BEFORE putting the money in + usr << "\icon[cashmoney] That is not enough money." + return 0 + + if(istype(cashmoney, /obj/item/weapon/spacecash/bundle)) + // Bundles can just have money subtracted, and will work + + visible_message("[usr] inserts some cash into [src].") + var/obj/item/weapon/spacecash/bundle/cashmoney_bundle = cashmoney + cashmoney_bundle.worth -= currently_vending.price + + if(cashmoney_bundle.worth <= 0) + usr.drop_from_inventory(cashmoney_bundle) + del(cashmoney_bundle) else - usr << "\icon[src]Error: Unable to access your account. Please contact technical support if problem persists." - -/obj/machinery/vending/proc/transfer_and_vend(var/datum/money_account/acc) - if(acc) - var/transaction_amount = currently_vending.price - if(transaction_amount <= acc.money) - - //transfer the money - acc.money -= transaction_amount - vendor_account.money += transaction_amount - - //create entries in the two account transaction logs - var/datum/transaction/T = new() - T.target_name = "[vendor_account.owner_name] (via [src.name])" - T.purpose = "Purchase of [currently_vending.product_name]" - if(transaction_amount > 0) - T.amount = "([transaction_amount])" - else - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = worldtime2text() - acc.transaction_log.Add(T) - // - T = new() - T.target_name = acc.owner_name - T.purpose = "Purchase of [currently_vending.product_name]" - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = worldtime2text() - vendor_account.transaction_log.Add(T) - - // Vend the item - src.vend(src.currently_vending, usr) - currently_vending = null - else - usr << "\icon[src]You don't have that much money!" + cashmoney_bundle.update_icon() else - usr << "\icon[src]Error: Unable to access your account. Please contact technical support if problem persists." + // Bills (banknotes) cannot really have worth different than face value, + // so we have to eat the bill and spit out change in a bundle + // This is really dirty, but there's no superclass for all bills, so we + // just assume that all spacecash that's not something else is a bill + + visible_message("[usr] inserts a bill into [src].") + var/left = cashmoney.worth - currently_vending.price + usr.drop_from_inventory(cashmoney) + del(cashmoney) + + if(left) + spawn_money(left, src.loc, user) + + // Vending machines have no idea who paid with cash + credit_purchase("(cash)") + return 1 + +/** + * Scan a chargecard and deduct payment from it. + * + * Takes payment for whatever is the currently_vending item. Returns 1 if + * successful, 0 if failed. + */ +/obj/machinery/vending/proc/pay_with_ewallet(var/obj/item/weapon/spacecash/ewallet/wallet) + visible_message("[usr] swipes a card through [src].") + if(currently_vending.price > wallet.worth) + src.status_message = "Insufficient funds on chargecard." + src.status_error = 1 + return 0 + else + wallet.worth -= currently_vending.price + credit_purchase("[wallet.owner_name] (chargecard)") + return 1 + +/** + * Scan a card and attempt to transfer payment from associated account. + * + * Takes payment for whatever is the currently_vending item. Returns 1 if + * successful, 0 if failed + */ +/obj/machinery/vending/proc/pay_with_card(var/obj/item/weapon/card/id/I) + visible_message("[usr] swipes a card through [src].") + var/datum/money_account/customer_account = get_account(I.associated_account_number) + if (!customer_account) + src.status_message = "Error: Unable to access account. Please contact technical support if problem persists." + src.status_error = 1 + return 0 + + if(customer_account.suspended) + src.status_message = "Unable to access account: account suspended." + src.status_error = 1 + return 0 + + // Have the customer punch in the PIN before checking if there's enough money. Prevents people from figuring out acct is + // empty at high security levels + if(customer_account.security_level != 0) //If card requires pin authentication (ie seclevel 1 or 2) + var/attempt_pin = input("Enter pin code", "Vendor transaction") as num + customer_account = attempt_account_access(I.associated_account_number, attempt_pin, 2) + + if(!customer_account) + src.status_message = "Unable to access account: incorrect credentials." + src.status_error = 1 + return 0 + + if(currently_vending.price > customer_account.money) + src.status_message = "Insufficient funds in account." + src.status_error = 1 + return 0 + else + // Okay to move the money at this point + + // debit money from the purchaser's account + customer_account.money -= currently_vending.price + + // create entry in the purchaser's account log + var/datum/transaction/T = new() + T.target_name = "[vendor_account.owner_name] (via [src.name])" + T.purpose = "Purchase of [currently_vending.product_name]" + if(currently_vending.price > 0) + T.amount = "([currently_vending.price])" + else + T.amount = "[currently_vending.price]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + customer_account.transaction_log.Add(T) + + // Give the vendor the money. We use the account owner name, which means + // that purchases made with stolen/borrowed card will look like the card + // owner made them + credit_purchase(customer_account.owner_name) + return 1 + +/** + * Add money for current purchase to the vendor account. + * + * Called after the money has already been taken from the customer. + */ +/obj/machinery/vending/proc/credit_purchase(var/target as text) + vendor_account.money += currently_vending.price + + var/datum/transaction/T = new() + T.target_name = target + T.purpose = "Purchase of [currently_vending.product_name]" + T.amount = "[currently_vending.price]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + vendor_account.transaction_log.Add(T) /obj/machinery/vending/attack_ai(mob/user as mob) return attack_hand(user) -/obj/machinery/vending/proc/GetProductIndex(var/datum/data/vending_product/P) - var/list/plist - switch(P.category) - if(CAT_NORMAL) - plist=product_records - if(CAT_HIDDEN) - plist=hidden_records - if(CAT_COIN) - plist=coin_records - else - warning("UNKNOWN CATEGORY [P.category] IN TYPE [P.product_path] INSIDE [type]!") - return plist.Find(P) - -/obj/machinery/vending/proc/GetProductByID(var/pid, var/category) - switch(category) - if(CAT_NORMAL) - return product_records[pid] - if(CAT_HIDDEN) - return hidden_records[pid] - if(CAT_COIN) - return coin_records[pid] - else - warning("UNKNOWN PRODUCT: PID: [pid], CAT: [category] INSIDE [type]!") - return null - /obj/machinery/vending/attack_hand(mob/user as mob) if(stat & (BROKEN|NOPOWER)) return - user.set_machine(src) if(src.seconds_electrified != 0) if(src.shock(user, 100)) return - var/vendorname = (src.name) //import the machine's name + wires.Interact(user) + ui_interact(user) - if(src.currently_vending) - var/dat = "
      [vendorname]


      " //display the name, and added a horizontal rule - dat += "You have selected [currently_vending.product_name].
      Please swipe your ID to pay for the article.

      " - dat += "Cancel" - user << browse(dat, "window=vending") - onclose(user, "") - return +/** + * Display the NanoUI window for the vending machine. + * + * See NanoUI documentation for details. + */ +/obj/machinery/vending/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) - var/dat = "
      [vendorname]


      " //display the name, and added a horizontal rule - dat += "Select an item:

      " //the rest is just general spacing and bolding - - if (premium.len > 0) - dat += "Coin slot: [coin ? coin : "No coin inserted"] (Remove)
      " - - if (ewallet) - dat += "Charge card's credits: [ewallet ? ewallet.worth : "No charge card inserted"] (Remove)

      " - - if (src.product_records.len == 0) - dat += "No product loaded!" + var/list/data = list() + if(currently_vending) + data["mode"] = 1 + data["product"] = currently_vending.product_name + data["price"] = currently_vending.price + data["message_err"] = 0 + data["message"] = src.status_message + data["message_err"] = src.status_error else - var/list/display_records = list() - display_records += src.product_records + data["mode"] = 0 + var/list/listed_products = list() - if(src.extended_inventory) - display_records += src.hidden_records - if(src.coin) - display_records += src.coin_records + for(var/key = 1 to src.product_records.len) + var/datum/data/vending_product/I = src.product_records[key] - for (var/datum/data/vending_product/R in display_records) - dat += "[R.product_name]:" - dat += " [R.amount] " - if(R.price) - dat += " (Price: [R.price])" - if (R.amount > 0) - var/idx=GetProductIndex(R) - dat += " (Vend)" - else - dat += " SOLD OUT" - dat += "
      " + if(!(I.category & src.categories)) + continue - dat += "
      " + listed_products.Add(list(list( + "key" = key, + "name" = I.product_name, + "price" = I.price, + "color" = I.display_color, + "amount" = I.amount))) - if(panel_open) - dat += wires() + data["products"] = listed_products - if(product_slogans != "") - dat += "The speaker switch is [shut_up ? "off" : "on"]. Toggle" + if(src.coin) + data["coin"] = src.coin.name - user << browse(dat, "window=vending") - onclose(user, "") - return + if(src.panel_open) + data["panel"] = 1 + data["speaker"] = src.shut_up ? 0 : 1 + else + data["panel"] = 0 -// returns the wire panel text -/obj/machinery/vending/proc/wires() - return wires.GetInteractWindow() + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "vending_machine.tmpl", src.name, 440, 600) + ui.set_initial_data(data) + ui.open() /obj/machinery/vending/Topic(href, href_list) if(stat & (BROKEN|NOPOWER)) @@ -378,19 +466,9 @@ usr.put_in_hands(coin) usr << "\blue You remove the [coin] from the [src]" coin = null - - if(href_list["remove_ewallet"] && !istype(usr,/mob/living/silicon)) - if (!ewallet) - usr << "There is no charge card in this machine." - return - ewallet.loc = src.loc - if(!usr.get_active_hand()) - usr.put_in_hands(ewallet) - usr << "\blue You remove the [ewallet] from the [src]" - ewallet = null + categories &= ~CAT_COIN if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) - usr.set_machine(src) if ((href_list["vend"]) && (src.vend_ready) && (!currently_vending)) if(istype(usr,/mob/living/silicon)) @@ -408,43 +486,32 @@ flick(icon_deny,src) return - var/idx=text2num(href_list["vend"]) - var/cat=text2num(href_list["cat"]) + var/key = text2num(href_list["vend"]) + var/datum/data/vending_product/R = product_records[key] - var/datum/data/vending_product/R = GetProductByID(idx,cat) - if (!R || !istype(R) || !R.product_path || R.amount <= 0) + // This should not happen unless the request from NanoUI was bad + if(!(R.category & src.categories)) return - if(R.price == null) + if(R.price <= 0) src.vend(R, usr) else - if (ewallet) - if (R.price <= ewallet.worth) - ewallet.worth -= R.price - src.vend(R, usr) - else - usr << "\red The ewallet doesn't have enough money to pay for that." - src.currently_vending = R - src.updateUsrDialog() + src.currently_vending = R + if(!vendor_account || vendor_account.suspended) + src.status_message = "This machine is currently unable to process payments due to problems with the associated account." + src.status_error = 1 else - src.currently_vending = R - src.updateUsrDialog() - return + src.status_message = "Please swipe a card or insert cash to pay for the item." + src.status_error = 0 - else if (href_list["cancel_buying"]) + else if (href_list["cancelpurchase"]) src.currently_vending = null - src.updateUsrDialog() - return else if ((href_list["togglevoice"]) && (src.panel_open)) src.shut_up = !src.shut_up src.add_fingerprint(usr) - src.updateUsrDialog() - else - usr << browse(null, "window=vending") - return - return + nanomanager.update_uis(src) /obj/machinery/vending/proc/vend(datum/data/vending_product/R, mob/user) if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH @@ -452,8 +519,11 @@ flick(src.icon_deny,src) return src.vend_ready = 0 //One thing at a time!! + src.status_message = "Vending..." + src.status_error = 0 + nanomanager.update_uis(src) - if (R in coin_records) + if (R.category & CAT_COIN) if(!coin) user << "\blue You need to insert a coin to get this item." return @@ -463,8 +533,10 @@ else user << "\blue You weren't able to pull the coin out fast enough, the machine ate it, string and all." del(coin) + categories &= ~CAT_COIN else del(coin) + categories &= ~CAT_COIN R.amount-- @@ -478,17 +550,18 @@ flick(src.icon_vend,src) spawn(src.vend_delay) new R.product_path(get_turf(src)) + src.status_message = "" + src.status_error = 0 src.vend_ready = 1 - return - - src.updateUsrDialog() + currently_vending = null + nanomanager.update_uis(src) /obj/machinery/vending/proc/stock(var/datum/data/vending_product/R, var/mob/user) if(src.panel_open) user << "\blue You stock the [src] with \a [R.product_name]" R.amount++ - src.updateUsrDialog() + nanomanager.update_uis(src) /obj/machinery/vending/process() if(stat & (BROKEN|NOPOWER)) @@ -627,7 +700,7 @@ idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan. product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty on this station?" product_ads = "Drink up!;Booze is good for you!;Alcohol is humanity's best friend.;Quite delighted to serve you!;Care for a nice, cold beer?;Nothing cures you like booze!;Have a sip!;Have a drink!;Have a beer!;Beer is good for you!;Only the finest alcohol!;Best quality booze since 2053!;Award-winning wine!;Maximum alcohol!;Man loves beer.;A toast for progress!" - req_access_txt = "25" + req_access = list(access_bar) /obj/machinery/vending/assist products = list( /obj/item/device/assembly/prox_sensor = 5,/obj/item/device/assembly/igniter = 3,/obj/item/device/assembly/signaler = 4, @@ -659,11 +732,11 @@ icon_state = "snack" products = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 6,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 6,/obj/item/weapon/reagent_containers/food/snacks/chips =6, /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 6,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 6,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 6, - /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 6) - contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6) + /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 6, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 6) + contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6, /obj/item/weapon/reagent_containers/food/snacks/skrellsnacks = 3) prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 1,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 5,/obj/item/weapon/reagent_containers/food/snacks/chips = 1, /obj/item/weapon/reagent_containers/food/snacks/sosjerky = 2,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 1,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 1, - /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 1) + /obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 1, /obj/item/weapon/reagent_containers/food/snacks/tastybread = 2) @@ -677,7 +750,7 @@ /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/cans/starkist = 10, /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 10,/obj/item/weapon/reagent_containers/food/drinks/cans/space_up = 10, /obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea = 10, /obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice = 10) - contraband = list(/obj/item/weapon/reagent_containers/food/drinks/cans/thirteenloko = 5) + contraband = list(/obj/item/weapon/reagent_containers/food/drinks/cans/thirteenloko = 5, /obj/item/weapon/reagent_containers/food/snacks/liquidfood = 6) prices = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola = 1,/obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind = 1, /obj/item/weapon/reagent_containers/food/drinks/cans/dr_gibb = 1,/obj/item/weapon/reagent_containers/food/drinks/cans/starkist = 1, /obj/item/weapon/reagent_containers/food/drinks/cans/waterbottle = 2,/obj/item/weapon/reagent_containers/food/drinks/cans/space_up = 1, @@ -715,7 +788,7 @@ icon_state = "med" icon_deny = "med-deny" product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?;Ping!" - req_access_txt = "5" + req_access = list(access_medical) products = list(/obj/item/weapon/reagent_containers/glass/bottle/antitoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline = 4, /obj/item/weapon/reagent_containers/glass/bottle/stoxin = 4,/obj/item/weapon/reagent_containers/glass/bottle/toxin = 4, /obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/syringe = 12, @@ -739,7 +812,7 @@ product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?" icon_state = "wallmed" icon_deny = "wallmed-deny" - req_access_txt = "5" + req_access = list(access_medical) density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude products = list(/obj/item/stack/medical/bruise_pack = 2,/obj/item/stack/medical/ointment = 2,/obj/item/weapon/reagent_containers/hypospray/autoinjector = 4,/obj/item/device/healthanalyzer = 1) contraband = list(/obj/item/weapon/reagent_containers/syringe/antitoxin = 4,/obj/item/weapon/reagent_containers/syringe/antiviral = 4,/obj/item/weapon/reagent_containers/pill/tox = 1) @@ -749,7 +822,7 @@ desc = "Wall-mounted Medical Equipment dispenser." icon_state = "wallmed" icon_deny = "wallmed-deny" - req_access_txt = "5" + req_access = list(access_medical) density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude products = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector = 5,/obj/item/weapon/reagent_containers/syringe/antitoxin = 3,/obj/item/stack/medical/bruise_pack = 3, /obj/item/stack/medical/ointment =3,/obj/item/device/healthanalyzer = 3) @@ -761,10 +834,10 @@ product_ads = "Crack capitalist skulls!;Beat some heads in!;Don't forget - harm is good!;Your weapons are right here.;Handcuffs!;Freeze, scumbag!;Don't tase me bro!;Tase them, bro.;Why not have a donut?" icon_state = "sec" icon_deny = "sec-deny" - req_access_txt = "1" + req_access = list(access_security) products = list(/obj/item/weapon/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, /obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6) - contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/donut_box = 2) + contraband = list(/obj/item/clothing/glasses/sunglasses = 2,/obj/item/weapon/storage/box/donut = 2) /obj/machinery/vending/hydronutrients name = "NutriMax" @@ -795,34 +868,31 @@ /obj/item/seeds/nettleseed = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/shandseed = 2,) premium = list(/obj/item/toy/waterflower = 1) -/obj/machinery/vending/hydroseeds/build_inventory(var/list/productlist,hidden=0,req_coin=0) +/** + * Populate hydroseeds product_records + * + * This needs to be customized to fetch the actual names of the seeds, otherwise + * the machine would simply list "packet of seeds" times 20 + */ +/obj/machinery/vending/hydroseeds/build_inventory() + var/list/all_products = list( + list(src.products, CAT_NORMAL), + list(src.contraband, CAT_HIDDEN), + list(src.premium, CAT_COIN)) - for(var/typepath in productlist) - var/amount = productlist[typepath] - var/price = prices[typepath] - if(isnull(amount)) amount = 1 + for(var/current_list in all_products) + var/category = current_list[2] - var/datum/data/vending_product/R = new /datum/data/vending_product() + for(var/entry in current_list[1]) + var/obj/item/seeds/S = new entry(src) + var/name = S.name + var/datum/data/vending_product/product = new/datum/data/vending_product(entry, name) - R.product_path = typepath - R.amount = amount - R.price = price - R.display_color = pick("red","blue","green") + product.price = (entry in src.prices) ? src.prices[entry] : 0 + product.amount = (current_list[1][entry]) ? current_list[1][entry] : 1 + product.category = category - if(hidden) - R.category=CAT_HIDDEN - hidden_records += R - else if(req_coin) - R.category=CAT_COIN - coin_records += R - else - R.category=CAT_NORMAL - product_records += R - - var/obj/item/seeds/S = new typepath(src) - R.product_name = S.name - del(S) - return + src.product_records.Add(product) /obj/machinery/vending/magivend name = "MagiVend" @@ -857,7 +927,7 @@ desc = "Tools for tools." icon_state = "tool" icon_deny = "tool-deny" - //req_access_txt = "12" //Maintenance access + //req_access = list(access_maint_tunnels) //Maintenance access products = list(/obj/item/stack/cable_coil/random = 10,/obj/item/weapon/crowbar = 5,/obj/item/weapon/weldingtool = 3,/obj/item/weapon/wirecutters = 5, /obj/item/weapon/wrench = 5,/obj/item/device/analyzer = 5,/obj/item/device/t_scanner = 5,/obj/item/weapon/screwdriver = 5) contraband = list(/obj/item/weapon/weldingtool/hugetank = 2,/obj/item/clothing/gloves/fyellow = 2) @@ -868,7 +938,7 @@ desc = "Spare tool vending. What? Did you expect some witty description?" icon_state = "engivend" icon_deny = "engivend-deny" - req_access_txt = "11" //Engineering Equipment access + req_access = list(access_engine_equip) //Engineering Equipment access products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/module/power_control = 10,/obj/item/weapon/airalarm_electronics = 10,/obj/item/weapon/cell/high = 10) contraband = list(/obj/item/weapon/cell/potato = 3) premium = list(/obj/item/weapon/storage/belt/utility = 3) @@ -879,7 +949,7 @@ desc = "Everything you need for do-it-yourself station repair." icon_state = "engi" icon_deny = "engi-deny" - req_access_txt = "11" + req_access = list(access_engine_equip) products = list(/obj/item/clothing/under/rank/chief_engineer = 4,/obj/item/clothing/under/rank/engineer = 4,/obj/item/clothing/shoes/orange = 4,/obj/item/clothing/head/hardhat = 4, /obj/item/weapon/storage/belt/utility = 4,/obj/item/clothing/glasses/meson = 4,/obj/item/clothing/gloves/yellow = 4, /obj/item/weapon/screwdriver = 12, /obj/item/weapon/crowbar = 12,/obj/item/weapon/wirecutters = 12,/obj/item/device/multitool = 12,/obj/item/weapon/wrench = 12,/obj/item/device/t_scanner = 12, @@ -896,7 +966,7 @@ desc = "All the tools you need to create your own robot army." icon_state = "robotics" icon_deny = "robotics-deny" - req_access_txt = "29" + req_access = list(access_robotics) products = list(/obj/item/clothing/suit/storage/toggle/labcoat = 4,/obj/item/clothing/under/rank/roboticist = 4,/obj/item/stack/cable_coil = 4,/obj/item/device/flash = 4, /obj/item/weapon/cell/high = 12, /obj/item/device/assembly/prox_sensor = 3,/obj/item/device/assembly/signaler = 3,/obj/item/device/healthanalyzer = 3, /obj/item/weapon/scalpel = 2,/obj/item/weapon/circular_saw = 2,/obj/item/weapon/tank/anesthetic = 2,/obj/item/clothing/mask/breath/medical = 5, diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index 77fde8ef7e..ad433d12e2 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -250,7 +250,7 @@ if ( istype(W,/obj/item/clothing/mask/gas ) ) user << "This item does not fit." return - if ( istype(W,/obj/item/clothing/mask/cigarette ) ) + if ( istype(W,/obj/item/clothing/mask/smokable/cigarette ) ) user << "This item does not fit." return if ( istype(W,/obj/item/clothing/head/syndicatefake ) ) diff --git a/code/game/machinery/wishgranter.dm b/code/game/machinery/wishgranter.dm index 2720a1c318..71b7de64c0 100644 --- a/code/game/machinery/wishgranter.dm +++ b/code/game/machinery/wishgranter.dm @@ -58,8 +58,6 @@ user.mutations.Add(HEAL) user.update_mutations() - - ticker.mode.traitors += user.mind user.mind.special_role = "Avatar of the Wish Granter" var/datum/objective/silence/silence = new diff --git a/code/game/magic/Uristrunes.dm b/code/game/magic/Uristrunes.dm index 6e0abd177e..cecbefc798 100644 --- a/code/game/magic/Uristrunes.dm +++ b/code/game/magic/Uristrunes.dm @@ -68,7 +68,7 @@ var/list/uristrune_cache = list() var/icon/I = icon('icons/effects/uristrunes.dmi', "blank") for(var/i = 0, i < 10, i++) - if(symbol_bits & (1 << i)) + if(BITTEST(symbol_bits, i)) I.Blend(icon('icons/effects/uristrunes.dmi', "rune-[1 << i]"), ICON_OVERLAY) diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index f75bd01ac4..1499af4996 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -25,7 +25,7 @@ if(!melee_can_hit || !istype(target, /atom)) return if(istype(target, /mob/living)) var/mob/living/M = target - if(src.occupant.a_intent == "hurt") + if(src.occupant.a_intent == I_HURT) playsound(src, 'sound/weapons/punch4.ogg', 50, 1) if(damtype == "brute") step_away(M,src,15) diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm index cdb3645c62..d7e64c1ece 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/game/mecha/combat/marauder.dm @@ -151,6 +151,7 @@ smoke_ready = 1 return +//TODO replace this with zoom code that doesn't increase peripherial vision /obj/mecha/combat/marauder/verb/zoom() set category = "Exosuit Interface" set name = "Zoom" diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index e66796fa9c..b0ff7e633d 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -15,40 +15,43 @@ action(atom/target) if(!action_checks(target)) return if(!cargo_holder) return - if(istype(target, /obj/structure/stool)) return - for(var/M in target.contents) - if(istype(M, /mob/living)) - return - + + //loading if(istype(target,/obj)) var/obj/O = target - if(!O.anchored) - if(cargo_holder.cargo.len < cargo_holder.cargo_capacity) - occupant_message("You lift [target] and start to load it into cargo compartment.") - chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") - set_ready_state(0) - chassis.use_power(energy_drain) - O.anchored = 1 - var/T = chassis.loc - if(do_after_cooldown(target)) - if(T == chassis.loc && src == chassis.selected) - cargo_holder.cargo += O - O.loc = chassis - O.anchored = 0 - occupant_message("[target] succesfully loaded.") - log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") - else - occupant_message("You must hold still while handling objects.") - O.anchored = initial(O.anchored) - else - occupant_message("Not enough room in cargo compartment.") - else + if(O.buckled_mob) + return + if(locate(/mob/living) in O) + return + if(O.anchored) occupant_message("[target] is firmly secured.") + return + if(cargo_holder.cargo.len >= cargo_holder.cargo_capacity) + occupant_message("Not enough room in cargo compartment.") + return + + occupant_message("You lift [target] and start to load it into cargo compartment.") + chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") + set_ready_state(0) + chassis.use_power(energy_drain) + O.anchored = 1 + var/T = chassis.loc + if(do_after_cooldown(target)) + if(T == chassis.loc && src == chassis.selected) + cargo_holder.cargo += O + O.loc = chassis + O.anchored = 0 + occupant_message("[target] succesfully loaded.") + log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") + else + occupant_message("You must hold still while handling objects.") + O.anchored = initial(O.anchored) + //attacking else if(istype(target,/mob/living)) var/mob/living/M = target if(M.stat>1) return - if(chassis.occupant.a_intent == "hurt") + if(chassis.occupant.a_intent == I_HURT) M.take_overall_damage(dam_force) M.adjustOxyLoss(round(dam_force/2)) M.updatehealth() @@ -585,7 +588,7 @@ chassis.visible_message("The [chassis.name] armor deflects the projectile") chassis.log_append_to_last("Armor saved.") else - chassis.take_damage(round(Proj.damage*src.damage_coeff),Proj.flag) + chassis.take_damage(round(Proj.damage*src.damage_coeff),Proj.check_armour) chassis.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) Proj.on_hit(chassis) set_ready_state(0) @@ -1036,10 +1039,10 @@ else if(istype(target,/mob/living)) var/mob/living/M = target if(M.stat>1) return - if(chassis.occupant.a_intent == "hurt") + if(chassis.occupant.a_intent == I_HURT) chassis.occupant_message("\red You obliterate [target] with [src.name], leaving blood and guts everywhere.") chassis.visible_message("\red [chassis] destroys [target] in an unholy fury.") - if(chassis.occupant.a_intent == "disarm") + if(chassis.occupant.a_intent == I_DISARM) chassis.occupant_message("\red You tear [target]'s limbs off with [src.name].") chassis.visible_message("\red [chassis] rips [target]'s arms off.") else @@ -1083,6 +1086,7 @@ /obj/item/mecha_parts/mecha_equipment/tool/passenger/destroy() for(var/atom/movable/AM in src) AM.forceMove(get_turf(src)) + AM << "You tumble out of the destroyed [src.name]!" return ..() /obj/item/mecha_parts/mecha_equipment/tool/passenger/Exit(atom/movable/O) diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index bcb907a040..3d36efea9c 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -199,7 +199,7 @@ name = "\improper LBX AC 10 \"Scattershot\"" icon_state = "mecha_scatter" equip_cooldown = 20 - projectile = /obj/item/projectile/bullet/midbullet + projectile = /obj/item/projectile/bullet/pistol/medium fire_sound = 'sound/weapons/Gunshot.ogg' fire_volume = 80 projectiles = 40 @@ -211,7 +211,7 @@ name = "\improper Ultra AC 2" icon_state = "mecha_uac2" equip_cooldown = 10 - projectile = /obj/item/projectile/bullet/weakbullet + projectile = /obj/item/projectile/bullet/pistol/medium fire_sound = 'sound/weapons/Gunshot.ogg' projectiles = 300 projectiles_per_shot = 3 @@ -248,7 +248,7 @@ throw_impact(atom/hit_atom) if(primed) - explosion(hit_atom, 0, 0, 2, 4) + explosion(hit_atom, 0, 1, 2, 4) del(src) else ..() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 3285218baf..45abb3d6ea 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -250,6 +250,9 @@ target = safepick(view(3,target)) if(!target) return + if(istype(target, /obj/machinery)) + if (src.interface_action(target)) + return if(!target.Adjacent(src)) if(selected && selected.is_ranged()) selected.action(target) @@ -259,6 +262,29 @@ src.melee_action(target) return +/obj/mecha/proc/interface_action(obj/machinery/target) + if(istype(target, /obj/machinery/access_button)) + src.occupant_message("Interfacing with [target].") + src.log_message("Interfaced with [target].") + target.attack_hand(src.occupant) + return 1 + if(istype(target, /obj/machinery/embedded_controller)) + target.ui_interact(src.occupant) + return 1 + return 0 + +/obj/mecha/contents_nano_distance(var/src_object, var/mob/living/user) + . = user.shared_living_nano_distance(src_object) //allow them to interact with anything they can interact with normally. + if(. != STATUS_INTERACTIVE) + //Allow interaction with the mecha or anything that is part of the mecha + if(src_object == src || (src_object in src)) + return STATUS_INTERACTIVE + if(src.Adjacent(src_object)) + src.occupant_message("Interfacing with [src_object]...") + src.log_message("Interfaced with [src_object].") + return STATUS_INTERACTIVE + if(src_object in view(2, src)) + return STATUS_UPDATE //if they're close enough, allow the occupant to see the screen through the viewport or whatever. /obj/mecha/proc/melee_action(atom/target) return @@ -487,7 +513,7 @@ /obj/mecha/bullet_act(var/obj/item/projectile/Proj) //wrapper - src.log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).",1) + src.log_message("Hit by projectile. Type: [Proj.name]([Proj.check_armour]).",1) call((proc_res["dynbulletdamage"]||src), "dynbulletdamage")(Proj) //calls equipment ..() return @@ -506,9 +532,26 @@ var/ignore_threshold if(istype(Proj, /obj/item/projectile/beam/pulse)) ignore_threshold = 1 - src.take_damage(Proj.damage,Proj.flag) + src.take_damage(Proj.damage, Proj.check_armour) + if(prob(25)) spark_system.start() src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),ignore_threshold) + //AP projectiles have a chance to cause additional damage + if(Proj.penetrating) + var/distance = get_dist(Proj.starting, get_turf(loc)) + var/hit_occupant = 1 //only allow the occupant to be hit once + for(var/i in 1 to min(Proj.penetrating, round(Proj.damage/15))) + if(src.occupant && hit_occupant && prob(20)) + Proj.attack_mob(src.occupant, distance) + hit_occupant = 0 + else + src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT), 1) + + Proj.penetrating-- + + if(prob(15)) + break //give a chance to exit early + Proj.on_hit(src) return @@ -717,6 +760,18 @@ user << "You screw the cell in place" return + else if(istype(W, /obj/item/device/multitool)) + if(state>=3 && src.occupant) + user << "You attempt to eject the pilot using the maintenance controls." + if(src.occupant.stat) + src.go_out() + src.log_message("[src.occupant] was ejected using the maintenance controls.") + else + user << "Your attempt is rejected." + src.occupant_message("An attempt to eject you was made using the maintenance controls.") + src.log_message("Eject attempt made using maintenance controls - rejected.") + return + else if(istype(W, /obj/item/weapon/cell)) if(state==4) if(!src.cell) @@ -729,7 +784,7 @@ user << "There's already a powercell installed." return - else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "hurt") + else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != I_HURT) var/obj/item/weapon/weldingtool/WT = W if (WT.remove_fuel(0,user)) if (hasInternalDamage(MECHA_INT_TANK_BREACH)) @@ -1514,8 +1569,8 @@ return if (href_list["change_name"]) if(usr != src.occupant) return - var/newname = strip_html_simple(input(occupant,"Choose new exosuit name","Rename exosuit",initial(name)) as text, MAX_NAME_LEN) - if(newname && trim(newname)) + var/newname = sanitizeSafe(input(occupant,"Choose new exosuit name","Rename exosuit",initial(name)) as text, MAX_NAME_LEN) + if(newname) name = newname else alert(occupant, "nope.avi") diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index 051f2e8129..8fa25a3568 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -43,9 +43,9 @@ var/datum/topic_input/filter = new /datum/topic_input(href,href_list) if(href_list["send_message"]) var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message") - var/message = strip_html_simple(input(usr,"Input message","Transmit message") as text) + var/message = sanitize(input(usr,"Input message","Transmit message") as text) var/obj/mecha/M = MT.in_mecha() - if(trim(message) && M) + if(message && M) M.occupant_message(message) return if(href_list["shock"]) diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm new file mode 100644 index 0000000000..d64857d004 --- /dev/null +++ b/code/game/objects/buckling.dm @@ -0,0 +1,86 @@ +/obj + var/can_buckle = 0 + var/buckle_movable = 0 + var/buckle_lying = -1 //bed-like behavior, forces mob.lying = buckle_lying if != -1 + var/buckle_require_restraints = 0 //require people to be handcuffed before being able to buckle. eg: pipes + var/mob/living/buckled_mob = null + +/obj/attack_hand(mob/living/user) + . = ..() + if(can_buckle && buckled_mob) + user_unbuckle_mob(user) + +/obj/MouseDrop_T(mob/living/M, mob/living/user) + . = ..() + if(can_buckle && istype(M)) + user_buckle_mob(M, user) + +/obj/Del() + unbuckle_mob() + return ..() + +/obj/proc/buckle_mob(mob/living/M) + if(!can_buckle || !istype(M) || (M.loc != loc) || M.buckled || M.pinned.len || (buckle_require_restraints && !M.restrained())) + return 0 + + M.buckled = src + M.facing_dir = null + M.set_dir(dir) + M.update_canmove() + buckled_mob = M + post_buckle_mob(M) + return 1 + +/obj/proc/unbuckle_mob() + if(buckled_mob && buckled_mob.buckled == src) + . = buckled_mob + buckled_mob.buckled = null + buckled_mob.anchored = initial(buckled_mob.anchored) + buckled_mob.update_canmove() + buckled_mob = null + + post_buckle_mob(.) + +/obj/proc/post_buckle_mob(mob/living/M) + return + +/obj/proc/user_buckle_mob(mob/living/M, mob/user) + if(!ticker) + user << "You can't buckle anyone in before the game starts." + if(!user.Adjacent(M) || user.restrained() || user.lying || user.stat || istype(user, /mob/living/silicon/pai)) + return + + if(istype(M, /mob/living/carbon/slime)) + user << "The [M] is too squishy to buckle in." + return + + add_fingerprint(user) + unbuckle_mob() + + if(buckle_mob(M)) + if(M == user) + M.visible_message(\ + "[M.name] buckles themselves to [src].",\ + "You buckle yourself to [src].",\ + "You hear metal clanking.") + else + M.visible_message(\ + "[M.name] is buckled to [src] by [user.name]!",\ + "You are buckled to [src] by [user.name]!",\ + "You hear metal clanking.") + +/obj/proc/user_unbuckle_mob(mob/user) + var/mob/living/M = unbuckle_mob() + if(M) + if(M != user) + M.visible_message(\ + "[M.name] was unbuckled by [user.name]!",\ + "You were unbuckled from [src] by [user.name].",\ + "You hear metal clanking.") + else + M.visible_message(\ + "[M.name] unbuckled themselves!",\ + "You unbuckle yourself from [src].",\ + "You hear metal clanking.") + add_fingerprint(user) + return M diff --git a/code/game/objects/effects/biomass_rift.dm b/code/game/objects/effects/biomass_rift.dm deleted file mode 100644 index c619ccb1e7..0000000000 --- a/code/game/objects/effects/biomass_rift.dm +++ /dev/null @@ -1,126 +0,0 @@ -/* -/obj/effect/biomass - icon = 'icons/obj/biomass.dmi' - icon_state = "stage1" - opacity = 0 - density = 0 - anchored = 1 - layer = 20 //DEBUG - var/health = 10 - var/stage = 1 - var/obj/effect/rift/originalRift = null //the originating rift of that biomass - var/maxDistance = 15 //the maximum length of a thread - var/newSpreadDistance = 10 //the length of a thread at which new ones are created - var/curDistance = 1 //the current length of a thread - var/continueChance = 3 //weighed chance of continuing in the same direction. turning left or right has 1 weight both - var/spreadDelay = 1 //will change to something bigger later, but right now I want it to spread as fast as possible for testing - -/obj/effect/rift - icon = 'icons/obj/biomass.dmi' - icon_state = "rift" - var/list/obj/effect/biomass/linkedBiomass = list() //all the biomass patches that have spread from it - var/newicon = 1 //DEBUG - -/obj/effect/rift/New() - set background = 1 - - ..() - - for(var/turf/T in orange(1,src)) - if(!IsValidBiomassLoc(T)) - continue - var/obj/effect/biomass/starting = new /obj/effect/biomass(T) - starting.set_dir(get_dir(src,starting)) - starting.originalRift = src - linkedBiomass += starting - spawn(1) //DEBUG - starting.icon_state = "[newicon]" - -/obj/effect/rift/Del() - for(var/obj/effect/biomass/biomass in linkedBiomass) - del(biomass) - ..() - -/obj/effect/biomass/New() - set background = 1 - - ..() - if(!IsValidBiomassLoc(loc,src)) - del(src) - return - spawn(1) //so that the dir and stuff can be set by the source first - if(curDistance >= maxDistance) - return - switch(dir) - if(NORTHWEST) - set_dir(NORTH) - if(NORTHEAST) - set_dir(EAST) - if(SOUTHWEST) - set_dir(WEST) - if(SOUTHEAST) - set_dir(SOUTH) - sleep(spreadDelay) - Spread() - -/obj/effect/biomass/proc/Spread(var/direction = dir) - set background = 1 - var/possibleDirsInt = 0 - - for(var/newDirection in cardinal) - if(newDirection == turn(direction,180)) //can't go backwards - continue - var/turf/T = get_step(loc,newDirection) - if(!IsValidBiomassLoc(T,src)) - continue - possibleDirsInt |= newDirection - - var/list/possibleDirs = list() - - if(possibleDirsInt & direction) - for(var/i=0 , i[src] sinks together into a pile of ash." var/turf/simulated/floor/F = get_turf(src) diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 82d27968db..ea9af2f70f 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -233,6 +233,21 @@ steam.start() -- spawns the effect return 0 return 1 +///////////////////////////////////////////// +// Illumination +///////////////////////////////////////////// + +/obj/effect/effect/smoke/illumination + name = "illumination" + opacity = 0 + icon = 'icons/effects/effects.dmi' + icon_state = "sparks" + +/obj/effect/effect/smoke/illumination/New(var/newloc, var/brightness=15, var/lifetime=10) + time_to_live=lifetime + ..() + SetLuminosity(brightness) + ///////////////////////////////////////////// // Bad smoke ///////////////////////////////////////////// diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm index f7a6795e84..e69de29bb2 100644 --- a/code/game/objects/effects/glowshroom.dm +++ b/code/game/objects/effects/glowshroom.dm @@ -1,166 +0,0 @@ -//separate dm since hydro is getting bloated already - -/obj/effect/glowshroom - name = "glowshroom" - anchored = 1 - opacity = 0 - density = 0 - icon = 'icons/obj/lighting.dmi' - icon_state = "glowshroomf" - layer = 2.1 - l_color = "#003300" - - var/endurance = 30 - var/potency = 30 - var/delay = 1200 - var/floor = 0 - var/yield = 3 - var/spreadChance = 40 - var/spreadIntoAdjacentChance = 60 - var/evolveChance = 2 - var/lastTick = 0 - var/spreaded = 1 - -/obj/effect/glowshroom/single - spreadChance = 0 - -/obj/effect/glowshroom/New() - - ..() - - set_dir(CalcDir()) - - if(!floor) - switch(dir) //offset to make it be on the wall rather than on the floor - if(NORTH) - pixel_y = 32 - if(SOUTH) - pixel_y = -32 - if(EAST) - pixel_x = 32 - if(WEST) - pixel_x = -32 - icon_state = "glowshroom[rand(1,3)]" - else //if on the floor, glowshroom on-floor sprite - icon_state = "glowshroomf" - - processing_objects += src - - SetLuminosity(round(potency/15)) - lastTick = world.timeofday - -/obj/effect/glowshroom/Del() - processing_objects -= src - ..() - -/obj/effect/glowshroom/process() - if(!spreaded) - return - - if(((world.timeofday - lastTick) > delay) || ((world.timeofday - lastTick) < 0)) - lastTick = world.timeofday - spreaded = 0 - - for(var/i=1,i<=yield,i++) - if(prob(spreadChance)) - var/list/possibleLocs = list() - var/spreadsIntoAdjacent = 0 - - if(prob(spreadIntoAdjacentChance)) - spreadsIntoAdjacent = 1 - - for(var/turf/simulated/floor/plating/airless/asteroid/earth in view(3,src)) - if(spreadsIntoAdjacent || !locate(/obj/effect/glowshroom) in view(1,earth)) - possibleLocs += earth - - if(!possibleLocs.len) - break - - var/turf/newLoc = pick(possibleLocs) - - var/shroomCount = 0 //hacky - var/placeCount = 1 - for(var/obj/effect/glowshroom/shroom in newLoc) - shroomCount++ - for(var/wallDir in cardinal) - var/turf/isWall = get_step(newLoc,wallDir) - if(isWall.density) - placeCount++ - if(shroomCount >= placeCount) - continue - - var/obj/effect/glowshroom/child = new /obj/effect/glowshroom(newLoc) - child.potency = potency - child.yield = yield - child.delay = delay - child.endurance = endurance - - spreaded++ - - if(prob(evolveChance)) //very low chance to evolve on its own - potency += rand(4,6) - -/obj/effect/glowshroom/proc/CalcDir(turf/location = loc) - set background = 1 - var/direction = 16 - - for(var/wallDir in cardinal) - var/turf/newTurf = get_step(location,wallDir) - if(newTurf.density) - direction |= wallDir - - for(var/obj/effect/glowshroom/shroom in location) - if(shroom == src) - continue - if(shroom.floor) //special - direction &= ~16 - else - direction &= ~shroom.dir - - var/list/dirList = list() - - for(var/i=1,i<=16,i <<= 1) - if(direction & i) - dirList += i - - if(dirList.len) - var/newDir = pick(dirList) - if(newDir == 16) - floor = 1 - newDir = 1 - return newDir - - floor = 1 - return 1 - -/obj/effect/glowshroom/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - - endurance -= W.force - - CheckEndurance() - -/obj/effect/glowshroom/ex_act(severity) - switch(severity) - if(1.0) - del(src) - return - if(2.0) - if (prob(50)) - del(src) - return - if(3.0) - if (prob(5)) - del(src) - return - else - return - -/obj/effect/glowshroom/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(exposed_temperature > 300) - endurance -= 5 - CheckEndurance() - -/obj/effect/glowshroom/proc/CheckEndurance() - if(endurance <= 0) - del(src) \ No newline at end of file diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index dbfd0a9e61..28a4ad2cc2 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -6,7 +6,6 @@ unacidable = 1 /obj/effect/landmark/New() - ..() tag = text("landmark*[]", name) invisibility = 101 @@ -28,14 +27,11 @@ if("monkey") monkeystart += loc del(src) + if("start") newplayer_start += loc del(src) - if("wizard") - wizardstart += loc - del(src) - if("JoinLate") latejoin += loc del(src) @@ -52,23 +48,25 @@ latejoin_cyborg += loc del(src) - //prisoners if("prisonwarp") prisonwarp += loc del(src) - // if("mazewarp") - // mazewarp += loc + if("Holding Facility") holdingfacility += loc + if("tdome1") - tdome1 += loc + tdome1 += loc + if("tdome2") tdome2 += loc + if("tdomeadmin") - tdomeadmin += loc + tdomeadmin += loc + if("tdomeobserve") tdomeobserve += loc - //not prisoners + if("prisonsecuritywarp") prisonsecuritywarp += loc del(src) @@ -81,18 +79,6 @@ xeno_spawn += loc del(src) - if("ninjastart") - ninjastart += loc - del(src) - - if("voxstart") - raider_spawn += loc - del(src) - - if("Syndicate-Spawn") - synd_spawn += loc - del(src) - landmarks_list += src return 1 @@ -113,6 +99,13 @@ return 1 +/obj/effect/landmark/start/ninja + name = "ninja" + +/obj/effect/landmark/start/ninja/New() + ..() + ninjastart += src + //Costume spawner landmarks /obj/effect/landmark/costume/New() //costume spawner, selects a random subclass and disappears @@ -144,7 +137,7 @@ /obj/effect/landmark/costume/elpresidente/New() new /obj/item/clothing/under/gimmick/rank/captain/suit(src.loc) new /obj/item/clothing/head/flatcap(src.loc) - new /obj/item/clothing/mask/cigarette/cigar/havana(src.loc) + new /obj/item/clothing/mask/smokable/cigarette/cigar/havana(src.loc) new /obj/item/clothing/shoes/jackboots(src.loc) del(src) diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index de35684991..e8bf9348f6 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -19,7 +19,7 @@ if(triggered) return - if(istype(M, /mob/living/carbon/human) || istype(M, /mob/living/carbon/monkey)) + if(istype(M, /mob/living/carbon/human)) for(var/mob/O in viewers(world.view, src.loc)) O << "[M] triggered the \icon[src] [src]" triggered = 1 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index ce0e53f4b0..6ad970dcbe 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -40,6 +40,11 @@ var/zoomdevicename = null //name used for message when binoculars/scope is used var/zoom = 0 //1 if item is actively being used to zoom. For scoped guns and binoculars. + // Used to specify the icon file to be used when the item is worn. If not set the default icon for that slot will be used. + // If icon_override or sprite_sheets are set they will take precendence over this, assuming they apply to the slot in question. + // Only slot_l_hand/slot_r_hand are implemented at the moment. Others to be implemented as needed. + var/list/item_icons = null + /* Species-specific sprites, concept stolen from Paradise//vg/. ex: sprite_sheets = list( @@ -58,6 +63,15 @@ /obj/item/device icon = 'icons/obj/device.dmi' +//Checks if the item is being held by a mob, and if so, updates the held icons +/obj/item/proc/update_held_icon() + if(ismob(src.loc)) + var/mob/M = src.loc + if(M.l_hand == src) + M.update_inv_l_hand() + if(M.r_hand == src) + M.update_inv_r_hand() + /obj/item/ex_act(severity) switch(severity) if(1.0) @@ -141,7 +155,6 @@ if(isliving(src.loc)) return user.next_move = max(user.next_move+2,world.time + 2) - add_fingerprint(user) user.put_in_active_hand(src) if(src.loc == user) src.pickup(user) @@ -199,11 +212,7 @@ // apparently called whenever an item is removed from a slot, container, or anything else. /obj/item/proc/dropped(mob/user as mob) ..() - if(zoom) //binoculars, scope, etc - user.client.view = world.view - user.client.pixel_x = 0 - user.client.pixel_y = 0 - zoom = 0 + if(zoom) zoom() //binoculars, scope, etc // called just as an item is picked up (loc is not yet changed) /obj/item/proc/pickup(mob/user) @@ -412,9 +421,9 @@ H << "You need a jumpsuit before you can attach this [name]." return 0 var/obj/item/clothing/under/uniform = H.w_uniform - if(uniform.hastie) + if(uniform.accessories.len && !uniform.can_attach_accessory(src)) if (!disable_warning) - H << "You already have [uniform.hastie] attached to your [uniform]." + H << "You already have an accessory of this type attached to your [uniform]." return 0 if( !(slot_flags & SLOT_TIE) ) return 0 @@ -422,35 +431,6 @@ return 0 //Unsupported slot //END HUMAN - else if(ismonkey(M)) - //START MONKEY - var/mob/living/carbon/monkey/MO = M - switch(slot) - if(slot_l_hand) - if(MO.l_hand) - return 0 - return 1 - if(slot_r_hand) - if(MO.r_hand) - return 0 - return 1 - if(slot_wear_mask) - if(MO.wear_mask) - return 0 - if( !(slot_flags & SLOT_MASK) ) - return 0 - return 1 - if(slot_back) - if(MO.back) - return 0 - if( !(slot_flags & SLOT_BACK) ) - return 0 - return 1 - return 0 //Unsupported slot - - //END MONKEY - - /obj/item/verb/verb_pickup() set src in oview(1) set category = "Object" @@ -512,14 +492,6 @@ user << "\red You're going to need to remove the eye covering first." return - var/mob/living/carbon/monkey/Mo = M - if(istype(Mo) && ( \ - (Mo.wear_mask && Mo.wear_mask.flags & MASKCOVERSEYES) \ - )) - // you can't stab someone in the eyes wearing a mask! - user << "\red You're going to need to remove the eye covering first." - return - if(!M.has_eyes()) user << "\red You cannot locate any eyes on [M]!" return @@ -638,8 +610,8 @@ For zooming with scope or binoculars. This is called from modules/mob/mob_movement.dm if you move you will be zoomed out modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. */ - -/obj/item/proc/zoom(var/tileoffset = 11,var/viewsize = 12) //tileoffset is client view offset in the direction the user is facing. viewsize is how far out this thing zooms. 7 is normal view +//Looking through a scope or binoculars should /not/ improve your periphereal vision. Still, increase viewsize a tiny bit so that sniping isn't as restricted to NSEW +/obj/item/proc/zoom(var/tileoffset = 14,var/viewsize = 9) //tileoffset is client view offset in the direction the user is facing. viewsize is how far out this thing zooms. 7 is normal view var/devicename @@ -661,9 +633,8 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. cannotzoom = 1 if(!zoom && !cannotzoom) - if(!usr.hud_used.hud_shown) - usr.button_pressed_F12(1) // If the user has already limited their HUD this avoids them having a HUD when they zoom in - usr.button_pressed_F12(1) + if(usr.hud_used.hud_shown) + usr.toggle_zoom_hud() // If the user has already limited their HUD this avoids them having a HUD when they zoom in usr.client.view = viewsize zoom = 1 @@ -686,18 +657,10 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. usr.visible_message("[usr] peers through the [zoomdevicename ? "[zoomdevicename] of the [src.name]" : "[src.name]"].") - /* - if(istype(usr,/mob/living/carbon/human/)) - var/mob/living/carbon/human/H = usr - usr.visible_message("[usr] holds [devicename] up to [H.get_visible_gender() == MALE ? "his" : H.get_visible_gender() == FEMALE ? "her" : "their"] eyes.") - else - usr.visible_message("[usr] holds [devicename] up to its eyes.") - */ - else usr.client.view = world.view if(!usr.hud_used.hud_shown) - usr.button_pressed_F12(1) + usr.toggle_zoom_hud() zoom = 0 usr.client.pixel_x = 0 diff --git a/code/game/objects/items/ashtray.dm b/code/game/objects/items/ashtray.dm index b2417f8af3..0d386623ec 100644 --- a/code/game/objects/items/ashtray.dm +++ b/code/game/objects/items/ashtray.dm @@ -17,15 +17,15 @@ /obj/item/ashtray/attackby(obj/item/weapon/W as obj, mob/user as mob) if (health < 1) return - if (istype(W,/obj/item/weapon/cigbutt) || istype(W,/obj/item/clothing/mask/cigarette) || istype(W, /obj/item/weapon/flame/match)) + if (istype(W,/obj/item/weapon/cigbutt) || istype(W,/obj/item/clothing/mask/smokable/cigarette) || istype(W, /obj/item/weapon/flame/match)) if (contents.len >= max_butts) user << "This ashtray is full." return user.remove_from_mob(W) W.loc = src - if (istype(W,/obj/item/clothing/mask/cigarette)) - var/obj/item/clothing/mask/cigarette/cig = W + if (istype(W,/obj/item/clothing/mask/smokable/cigarette)) + var/obj/item/clothing/mask/smokable/cigarette/cig = W if (cig.lit == 1) src.visible_message("[user] crushes [cig] in [src], putting it out.") processing_objects.Remove(cig) @@ -61,14 +61,14 @@ return if (contents.len) src.visible_message("\red [src] slams into [hit_atom] spilling its contents!") - for (var/obj/item/clothing/mask/cigarette/O in contents) + for (var/obj/item/clothing/mask/smokable/cigarette/O in contents) O.loc = src.loc icon_state = icon_empty return ..() /obj/item/ashtray/proc/die() src.visible_message("\red [src] shatters spilling its contents!") - for (var/obj/item/clothing/mask/cigarette/O in contents) + for (var/obj/item/clothing/mask/smokable/cigarette/O in contents) O.loc = src.loc icon_state = icon_broken diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index f0d8a820c0..facafe41f2 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -114,7 +114,7 @@ move an amendment to the drawing.

      usr << "\red Error! Please notify administration!" return var/list/turf/turfs = res - var/str = trim(stripped_input(usr,"New area name:","Blueprint Editing", "", MAX_NAME_LEN)) + var/str = sanitizeSafe(input("New area name:","Blueprint Editing", ""), MAX_NAME_LEN) if(!str || !length(str)) //cancel return if(length(str) > 50) @@ -154,7 +154,7 @@ move an amendment to the drawing.

      var/area/A = get_area() //world << "DEBUG: edit_area" var/prevname = "[A.name]" - var/str = trim(stripped_input(usr,"New area name:","Blueprint Editing", prevname, MAX_NAME_LEN)) + var/str = sanitizeSafe(input("New area name:","Blueprint Editing", prevname), MAX_NAME_LEN) if(!str || !length(str) || str==prevname) //cancel return if(length(str) > 50) diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index 5183170aa6..fcbebdba20 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -49,7 +49,7 @@ return if (!in_range(src, user) && src.loc != user) return - t = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) + t = sanitize(t) if (t) src.name = "body bag - " src.name += t diff --git a/code/game/objects/items/contraband.dm b/code/game/objects/items/contraband.dm index 5441f83cca..cc67c59517 100644 --- a/code/game/objects/items/contraband.dm +++ b/code/game/objects/items/contraband.dm @@ -28,3 +28,30 @@ new /obj/item/weapon/reagent_containers/pill/zoom( src ) new /obj/item/weapon/reagent_containers/pill/zoom( src ) new /obj/item/weapon/reagent_containers/pill/zoom( src ) + +/obj/item/weapon/reagent_containers/glass/beaker/vial/random + flags = 0 + var/list/random_reagent_list = list(list("water" = 15) = 1, list("cleaner" = 15) = 1) + +/obj/item/weapon/reagent_containers/glass/beaker/vial/random/toxin + random_reagent_list = list( + list("mindbreaker" = 10, "space_drugs" = 20) = 3, + list("carpotoxin" = 15) = 2, + list("impedrezene" = 15) = 2, + list("zombiepowder" = 10) = 1) + +/obj/item/weapon/reagent_containers/glass/beaker/vial/random/New() + ..() + if(is_open_container()) + flags ^= OPENCONTAINER + + var/list/picked_reagents = pickweight(random_reagent_list) + for(var/reagent in picked_reagents) + reagents.add_reagent(reagent, picked_reagents[reagent]) + + var/list/names = new + for(var/datum/reagent/R in reagents.reagent_list) + names += R.name + + desc = "Contains [english_list(names)]." + update_icon() diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index b68e1e61cd..8e1a382a86 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -91,7 +91,8 @@ /obj/item/toy/crayon/attack(mob/M as mob, mob/user as mob) if(M == user) user << "You take a bite of the crayon and swallow it." -// user.nutrition += 5 + user.nutrition += 1 + user.reagents.add_reagent("crayon_dust",min(5,uses)/3) if(uses) uses -= 5 if(uses <= 0) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index f4f3b843b0..2746c70a74 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -689,7 +689,7 @@ var/global/list/obj/item/device/pda/PDAs = list() if ("Edit") var/n = input(U, "Please enter message", name, notehtml) as message if (in_range(src, U) && loc == U) - n = copytext(adminscrub(n), 1, MAX_MESSAGE_LEN) + n = sanitizeSafe(n, extra = 0) if (mode == 1) note = html_decode(n) notehtml = note @@ -726,7 +726,7 @@ var/global/list/obj/item/device/pda/PDAs = list() U << "The PDA softly beeps." ui.close() else - t = sanitize(copytext(t, 1, 20)) + t = sanitize(t, 20) ttone = t else ui.close() @@ -735,7 +735,7 @@ var/global/list/obj/item/device/pda/PDAs = list() var/t = input(U, "Please enter new news tone", name, newstone) as text if (in_range(src, U) && loc == U) if (t) - t = sanitize(copytext(t, 1, 20)) + t = sanitize(t, 20) newstone = t else ui.close() @@ -971,8 +971,9 @@ var/global/list/obj/item/device/pda/PDAs = list() U.visible_message("[U] taps on \his PDA's screen.") U.last_target_click = world.time var/t = input(U, "Please enter message", P.name, null) as text - t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN)) - t = readd_quotes(t) + t = sanitize(t) + //t = readd_quotes(t) + t = replace_characters(t, list(""" = "\"")) if (!t || !istype(P)) return if (!in_range(src, U) && loc != U) @@ -1067,6 +1068,17 @@ var/global/list/obj/item/device/pda/PDAs = list() new_message = 1 update_icon() +/obj/item/device/pda/ai/new_message(var/atom/movable/sending_unit, var/sender, var/sender_job, var/message) + var/track = "" + if(ismob(sending_unit.loc) && isAI(loc)) + track = "(Follow)" + + var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" (Reply) [track]" + new_info(message_silent, newstone, reception_message) + + log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]") + new_message = 1 + /obj/item/device/pda/verb/verb_remove_id() set category = "Object" set name = "Remove id" @@ -1207,9 +1219,6 @@ var/global/list/obj/item/device/pda/PDAs = list() if(2) if (!istype(C:dna, /datum/dna)) user << "\blue No fingerprints found on [C]" - else if(!istype(C, /mob/living/carbon/monkey)) - if(!isnull(C:gloves)) - user << "\blue No fingerprints found on [C]" else user << text("\blue [C]'s Fingerprints: [md5(C:dna.uni_identity)]") if ( !(C:blood_DNA) ) diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index 8c86a37ac0..5ab09d0853 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -562,10 +562,10 @@ if("alert") post_status("alert", href_list["alert"]) if("setmsg1") - message1 = reject_bad_text(trim(sanitize(copytext(input("Line 1", "Enter Message Text", message1) as text|null, 1, 40))), 40) + message1 = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", message1) as text|null, 40), 40) updateSelfDialog() if("setmsg2") - message2 = reject_bad_text(trim(sanitize(copytext(input("Line 2", "Enter Message Text", message2) as text|null, 1, 40))), 40) + message2 = reject_bad_text(sanitize(input("Line 2", "Enter Message Text", message2) as text|null, 40), 40) updateSelfDialog() else post_status(href_list["statdisp"]) diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index 75122c7ce0..5e2ab73155 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -26,25 +26,8 @@ for(var/mob/living/silicon/ai/A in src) dat += "Stored AI: [A.name]
      System integrity: [A.system_integrity()]%
      " - for (var/law in A.laws.ion) - if(law) - laws += "[ionnum()]: [law]
      " - - if (A.laws.zeroth) - laws += "0: [A.laws.zeroth]
      " - - var/number = 1 - for (var/index = 1, index <= A.laws.inherent.len, index++) - var/law = A.laws.inherent[index] - if (length(law) > 0) - laws += "[number]: [law]
      " - number++ - - for (var/index = 1, index <= A.laws.supplied.len, index++) - var/law = A.laws.supplied[index] - if (length(law) > 0) - laws += "[number]: [law]
      " - number++ + for (var/datum/ai_law/law in A.laws.all_laws()) + laws += "[law.get_index()]: [law.law]
      " dat += "Laws:
      [laws]
      " diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index 6e924ba719..7013b30419 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -2,7 +2,7 @@ name = "flash" desc = "Used for blinding and being an asshole." icon_state = "flash" - item_state = "flashbang" //looks exactly like a flash (and nothing like a flashbang) + item_state = "flash" throwforce = 5 w_class = 2.0 throw_speed = 4 @@ -70,7 +70,7 @@ flick("e_flash", M.flash) if(ishuman(M) && ishuman(user) && M.stat!=DEAD) - if(user.mind && user.mind in ticker.mode.head_revolutionaries && ticker.mode.name == "revolution") + if(user.mind && user.mind in revs.head_revolutionaries) var/revsafe = 0 for(var/obj/item/weapon/implant/loyalty/L in M) if(L && L.implanted) @@ -81,7 +81,7 @@ revsafe = 2 if(!revsafe) M.mind.has_been_rev = 1 - ticker.mode.add_revolutionary(M.mind) + revs.add_antagonist(M.mind) else if(revsafe == 1) user << "Something seems to be blocking the flash!" else diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 0f6d0abb10..fb3edec873 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -75,7 +75,7 @@ user.visible_message("[user] directs [src] to [M]'s eyes.", \ "You direct [src] to [M]'s eyes.") - if(istype(M, /mob/living/carbon/human) || istype(M, /mob/living/carbon/monkey)) //robots and aliens are unaffected + if(istype(M, /mob/living/carbon/human)) //robots and aliens are unaffected if(M.stat == DEAD || M.sdisabilities & BLIND) //mob is dead or fully blind user << "[M] pupils does not react to the light!" else if(XRAY in M.mutations) //mob has X-RAY vision diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 7e69ffe17a..713706475c 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -55,7 +55,7 @@ var/uses = 0 var/emagged = 0 var/failmsg = "" - var/charge = 1 + var/charge = 0 /obj/item/device/lightreplacer/New() uses = max_uses / 2 @@ -122,11 +122,11 @@ /obj/item/device/lightreplacer/proc/AddUses(var/amount = 1) uses = min(max(uses + amount, 0), max_uses) -/obj/item/device/lightreplacer/proc/Charge(var/mob/user) - charge += 1 - if(charge > 7) +/obj/item/device/lightreplacer/proc/Charge(var/mob/user, var/amount = 1) + charge += amount + if(charge > 6) AddUses(1) - charge = 1 + charge = 0 /obj/item/device/lightreplacer/proc/ReplaceLight(var/obj/machinery/light/target, var/mob/living/U) diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm index 5bf49de055..53fac1be05 100644 --- a/code/game/objects/items/devices/megaphone.dm +++ b/code/game/objects/items/devices/megaphone.dm @@ -25,7 +25,7 @@ user << "\red \The [src] needs to recharge!" return - var/message = sanitize(copytext(input(user, "Shout a message?", "Megaphone", null) as text,1,MAX_MESSAGE_LEN)) + var/message = sanitize(input(user, "Shout a message?", "Megaphone", null) as text) if(!message) return message = capitalize(message) diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 1765c32ade..a31a866bc7 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -20,3 +20,4 @@ origin_tech = "magnets=1;engineering=1" var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage + var/obj/machinery/clonepod/connecting //same for cryopod linkage \ No newline at end of file diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index a938d6b977..2cc9d55b6a 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -260,7 +260,7 @@ if(2) radio.ToggleReception() if(href_list["setlaws"]) - var/newlaws = sanitize(copytext(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.pai_laws) as message,1,MAX_MESSAGE_LEN)) + var/newlaws = sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.pai_laws) as message) if(newlaws) pai.pai_laws = newlaws pai << "Your supplemental directives have been updated. Your new directives are:" @@ -281,6 +281,8 @@ src.overlays.Cut() src.overlays += "pai-off" +/obj/item/device/paicard + var/current_emotion = 1 /obj/item/device/paicard/proc/setEmotion(var/emotion) if(pai) src.overlays.Cut() @@ -294,6 +296,7 @@ if(7) src.overlays += "pai-sad" if(8) src.overlays += "pai-angry" if(9) src.overlays += "pai-what" + current_emotion = emotion /obj/item/device/paicard/proc/alertUpdate() var/turf/T = get_turf_or_move(src.loc) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 24c44694f5..d6b254cad1 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -115,13 +115,10 @@ listening = !listening && !(wires.IsIndexCut(WIRE_RECEIVE) || wires.IsIndexCut(WIRE_SIGNAL)) /obj/item/device/radio/Topic(href, href_list) - //..() - if (usr.stat || !on) - return - - if (!(issilicon(usr) || (usr.contents.Find(src) || ( in_range(src, usr) && istype(loc, /turf) )))) + if(..() || !on) usr << browse(null, "window=radio") return + usr.set_machine(src) if (href_list["track"]) var/mob/target = locate(href_list["track"]) @@ -152,17 +149,7 @@ else channels[chan_name] |= FREQ_LISTENING - if (!( master )) - if (istype(loc, /mob)) - interact(loc) - else - updateDialog() - else - if (istype(master.loc, /mob)) - interact(master.loc) - else - updateDialog() - add_fingerprint(usr) + interact(usr) /obj/item/device/radio/proc/autosay(var/message, var/from, var/channel) //BS12 EDIT var/datum/radio_frequency/connection = null @@ -180,10 +167,11 @@ return var/mob/living/silicon/ai/A = new /mob/living/silicon/ai(src, null, null, 1) + A.SetName(from) Broadcast_Message(connection, A, 0, "*garbled automated announcement*", src, message, from, "Automated Announcement", from, "synthesized voice", - 4, 0, list(1), PUB_FREQ) + 4, 0, list(0), connection.frequency, "states") del(A) return diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 922d5418cb..e0731443d5 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -4,7 +4,6 @@ T-RAY DETECTIVE SCANNER HEALTH ANALYZER GAS ANALYZER -PLANT ANALYZER MASS SPECTROMETER REAGENT SCANNER */ diff --git a/code/game/objects/items/devices/spy_bug.dm b/code/game/objects/items/devices/spy_bug.dm new file mode 100644 index 0000000000..2ad3df7ae5 --- /dev/null +++ b/code/game/objects/items/devices/spy_bug.dm @@ -0,0 +1,153 @@ +/obj/item/device/spy_bug + name = "bug" + desc = "" // Nothing to see here + icon = 'icons/obj/weapons.dmi' + icon_state = "eshield0" + item_state = "nothing" + layer = TURF_LAYER+0.2 + + flags = CONDUCT + force = 5.0 + w_class = 1.0 + throwforce = 5.0 + throw_range = 15 + throw_speed = 3 + + origin_tech = "programming=1;engineering=1;syndicate=3" + + var/obj/item/device/radio/spy/radio + var/obj/machinery/camera/spy/camera + +/obj/item/device/spy_bug/New() + ..() + radio = new(src) + camera = new(src) + +/obj/item/device/spy_bug/examine(mob/user) + . = ..(user, 0) + if(.) + user << "It's a tiny camera, microphone, and transmission device in a happy union." + user << "Needs to be both configured and brought in contact with monitor device to be fully functional." + +/obj/item/device/spy_bug/attack_self(mob/user) + radio.attack_self(user) + +/obj/item/device/spy_bug/attackby(obj/W as obj, mob/living/user as mob) + if(istype(W, /obj/item/device/spy_monitor)) + var/obj/item/device/spy_monitor/SM = W + SM.pair(src, user) + else + ..() + +/obj/item/device/spy_bug/hear_talk(mob/M, var/msg, verb, datum/language/speaking) + radio.hear_talk(M, msg, speaking) + + +/obj/item/device/spy_monitor + name = "\improper PDA" + desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge." + icon = 'icons/obj/pda.dmi' + icon_state = "pda" + item_state = "electronic" + + w_class = 2.0 + + origin_tech = "programming=1;engineering=1;syndicate=3" + + var/operating = 0 + var/obj/item/device/radio/spy/radio + var/obj/machinery/camera/spy/selected_camera + var/list/obj/machinery/camera/spy/cameras = new() + +/obj/item/device/spy_monitor/New() + radio = new(src) + +/obj/item/device/spy_monitor/examine(mob/user) + . = ..(user, 1) + if(.) + user << "The time '12:00' is blinking in the corner of the screen and \the [src] looks very cheaply made." + +/obj/item/device/spy_monitor/attack_self(mob/user) + if(operating) + return + + radio.attack_self(user) + view_cameras(user) + +/obj/item/device/spy_monitor/attackby(obj/W as obj, mob/living/user as mob) + if(istype(W, /obj/item/device/spy_bug)) + pair(W, user) + else + return ..() + +/obj/item/device/spy_monitor/proc/pair(var/obj/item/device/spy_bug/SB, var/mob/living/user) + if(SB.camera in cameras) + user << "\The [SB] has been unpaired from \the [src]." + cameras -= SB.camera + else + user << "\The [SB] has been paired with \the [src]." + cameras += SB.camera + +/obj/item/device/spy_monitor/proc/view_cameras(mob/user) + if(!can_use_cam(user)) + return + + selected_camera = cameras[1] + view_camera(user) + + operating = 1 + while(selected_camera && Adjacent(user)) + selected_camera = input("Select camera bug to view.") as null|anything in cameras + selected_camera = null + operating = 0 + +/obj/item/device/spy_monitor/proc/view_camera(mob/user) + spawn(0) + while(selected_camera && Adjacent(user)) + var/turf/T = get_turf(selected_camera) + if(!T || !is_on_same_plane_or_station(T.z, user.z) || !selected_camera.can_use()) + user.unset_machine() + user.reset_view(null) + user << "[selected_camera] unavailable." + sleep(90) + else + user.set_machine(selected_camera) + user.reset_view(selected_camera) + sleep(10) + user.unset_machine() + user.reset_view(null) + +/obj/item/device/spy_monitor/proc/can_use_cam(mob/user) + if(operating) + return + + if(!cameras.len) + user << "No paired cameras detected!" + user << "Bring a bug in contact with this device to pair the camera." + return + + return 1 + +/obj/item/device/spy_monitor/hear_talk(mob/M, var/msg, verb, datum/language/speaking) + return radio.hear_talk(M, msg, speaking) + + +/obj/machinery/camera/spy + // These cheap toys are accessible from the mercenary camera console as well + network = list("NUKE") + +/obj/machinery/camera/spy/New() + ..() + name = "DV-136ZB #[rand(1000,9999)]" + c_tag = name + +/obj/machinery/camera/spy/check_eye(var/mob/user as mob) + return 1 + +/obj/item/device/radio/spy + listening = 0 + frequency = 1473 + broadcasting = 0 + canhear_range = 1 + name = "spy device" + icon_state = "syn_cypherkey" diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index cd2ff9b5fb..b2ac742a7c 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -11,12 +11,30 @@ A list of items and costs is stored under the datum of every game mode, alongsid var/cost = 0 var/path = null var/reference = "" + var/description = "" -datum/uplink_item/New(var/itemPath, var/itemCost as num, var/itemName as text, var/itemReference as text) +datum/uplink_item/New(var/itemPath, var/itemCost, var/itemName, var/itemReference, var/itemDescription) cost = itemCost path = itemPath name = itemName reference = itemReference + description = itemDescription + +datum/uplink_item/proc/description() + if(!description) + // Fallback description + var/obj/temp = src.path + description = replacetext(initial(temp.desc), "\n", "
      ") + return description + +/datum/uplink_item/proc/generate_item(var/newloc) + var/list/L = list() + if(ispath(path)) + L += new path(newloc) + else if(islist(path)) + for(var/item_path in path) + L += new item_path(newloc) + return L datum/nano_item_lists var/list/items_nano @@ -41,16 +59,17 @@ datum/nano_item_lists uses = ticker.mode.uplink_uses ItemsCategory = ticker.mode.uplink_items - var/datum/nano_item_lists/IL = generate_item_lists() - nanoui_items = IL.items_nano - ItemsReference = IL.items_reference - world_uplinks += src /obj/item/device/uplink/Del() world_uplinks -= src ..() +/obj/item/device/uplink/proc/generate_items() + var/datum/nano_item_lists/IL = generate_item_lists() + nanoui_items = IL.items_nano + ItemsReference = IL.items_reference + // BS12 no longer use this menu but there are forks that do, hency why we keep it /obj/item/device/uplink/proc/generate_menu() var/dat = "[src.welcome]
      " @@ -87,7 +106,7 @@ datum/nano_item_lists for(var/category in ItemsCategory) nano[++nano.len] = list("Category" = category, "items" = list()) for(var/datum/uplink_item/I in ItemsCategory[category]) - nano[nano.len]["items"] += list(list("Name" = I.name, "Cost" = I.cost, "obj_path" = I.reference)) + nano[nano.len]["items"] += list(list("Name" = I.name, "Description" = I.description(),"Cost" = I.cost, "obj_path" = I.reference)) reference[I.reference] = I var/datum/nano_item_lists/result = new @@ -108,6 +127,9 @@ datum/nano_item_lists return pick(random_items) /obj/item/device/uplink/Topic(href, href_list) + if(..()) + return 1 + if(href_list["buy_item"] == "random") var/datum/uplink_item/UI = chooseRandomItem() href_list["buy_item"] = UI.reference @@ -123,10 +145,11 @@ datum/nano_item_lists used_TC += UI.cost feedback_add_details("traitor_uplink_items_bought", reference) - var/obj/I = new UI.path(get_turf(usr)) + var/list/L = UI.generate_item(get_turf(usr)) if(ishuman(usr)) var/mob/living/carbon/human/A = usr - A.put_in_any_hand_if_possible(I) + for(var/obj/I in L) + A.put_in_any_hand_if_possible(I) purchase_log[UI] = purchase_log[UI] + 1 @@ -186,6 +209,8 @@ datum/nano_item_lists data["welcome"] = welcome data["crystals"] = uses data["menu"] = nanoui_menu + if(!nanoui_items) + generate_items() data["nano_items"] = nanoui_items data += nanoui_data @@ -208,10 +233,10 @@ datum/nano_item_lists // The purchasing code. /obj/item/device/uplink/hidden/Topic(href, href_list) if (usr.stat || usr.restrained()) - return + return 1 if (!( istype(usr, /mob/living/carbon/human))) - return 0 + return 1 var/mob/user = usr var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") if ((usr.contents.Find(src.loc) || (in_range(src.loc, usr) && istype(src.loc.loc, /turf)))) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 065d7dd969..dd3305f99c 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -189,7 +189,7 @@ user << "\red Sticking a dead [W] into the frame would sort of defeat the purpose." return - if(M.brainmob.mind in ticker.mode.head_revolutionaries) + if(M.brainmob.mind in revs.head_revolutionaries) user << "\red The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the [W]." return @@ -226,7 +226,6 @@ feedback_inc("cyborg_birth",1) callHook("borgify", list(O)) - O.notify_ai(1) O.Namepick() del(src) @@ -234,7 +233,7 @@ user << "\blue The MMI must go in after everything else!" if (istype(W, /obj/item/weapon/pen)) - var/t = stripped_input(user, "Enter new robot name", src.name, src.created_name, MAX_NAME_LEN) + var/t = sanitizeSafe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN) if (!t) return if (!in_range(src, usr) && src.loc != usr) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index f9d3e356ce..43b852e249 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -36,12 +36,12 @@ icon = 'icons/mob/custom-synthetic.dmi' R.icon_state = "[R.ckey]-Standard" del(R.module) + R.notify_ai(ROBOT_NOTIFICATION_MODULE_RESET, R.module.name) R.module = null - R.camera.network.Remove(list("Engineering","Medical","MINE")) + R.camera.remove_networks(list("Engineering","Medical","MINE")) R.updatename("Default") R.status_flags |= CANPUSH R.updateicon() - R.notify_ai(2) return 1 @@ -53,11 +53,11 @@ var/heldname = "default name" /obj/item/borg/upgrade/rename/attack_self(mob/user as mob) - heldname = stripped_input(user, "Enter new robot name", "Robot Reclassification", heldname, MAX_NAME_LEN) + heldname = sanitizeSafe(input(user, "Enter new robot name", "Robot Reclassification", heldname), MAX_NAME_LEN) /obj/item/borg/upgrade/rename/action(var/mob/living/silicon/robot/R) if(..()) return 0 - R.notify_ai(3, R.name, heldname) + R.notify_ai(ROBOT_NOTIFICATION_NEW_NAME, R.name, heldname) R.name = heldname R.custom_name = heldname R.real_name = heldname @@ -84,7 +84,7 @@ R.stat = CONSCIOUS dead_mob_list -= R living_mob_list |= R - R.notify_ai(1) + R.notify_ai(ROBOT_NOTIFICATION_NEW_UNIT) return 1 @@ -121,7 +121,7 @@ usr << "There's no mounting point for the module!" return 0 - var/obj/item/weapon/gun/energy/taser/cyborg/T = locate() in R.module + var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in R.module if(!T) T = locate() in R.module.contents if(!T) diff --git a/code/game/objects/items/stacks/matter_synth.dm b/code/game/objects/items/stacks/matter_synth.dm new file mode 100644 index 0000000000..0842f70d66 --- /dev/null +++ b/code/game/objects/items/stacks/matter_synth.dm @@ -0,0 +1,50 @@ +/datum/matter_synth + var/name = "Generic Synthesizer" + var/max_energy = 60000 + var/recharge_rate = 2000 + var/energy + +/datum/matter_synth/New(var/store = 0) + if(store) + max_energy = store + energy = max_energy + return + +/datum/matter_synth/proc/get_charge() + return energy + +/datum/matter_synth/proc/use_charge(var/amount) + if (energy >= amount) + energy -= amount + return 1 + return 0 + +/datum/matter_synth/proc/add_charge(var/amount) + energy = min(energy + amount, max_energy) + +/datum/matter_synth/proc/emp_act(var/severity) + use_charge(max_energy * 0.1 / severity) + +/datum/matter_synth/medicine + name = "Medicine Synthesizer" + +/datum/matter_synth/metal + name = "Metal Synthesizer" + +/datum/matter_synth/plasteel + name = "Plasteel Synthesizer" + max_energy = 10000 + +/datum/matter_synth/glass + name = "Glass Synthesizer" + +/datum/matter_synth/wood + name = "Wood Synthesizer" + +/datum/matter_synth/plastic + name = "Plastic Synthesizer" + +/datum/matter_synth/wire + name = "Wire Synthesizer" + max_energy = 50 + recharge_rate = 2 \ No newline at end of file diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index c87b57b043..27e3eea6f7 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -16,8 +16,7 @@ return 1 if ( ! (istype(user, /mob/living/carbon/human) || \ - istype(user, /mob/living/silicon) || \ - istype(user, /mob/living/carbon/monkey)) ) + istype(user, /mob/living/silicon)) ) user << "\red You don't have the dexterity to do this!" return 1 @@ -123,23 +122,6 @@ else user << "The [affecting.display_name] is cut open, you'll need more than a bandage!" -/obj/item/stack/medical/bruise_pack/tajaran - name = "\improper S'rendarr's Hand leaf" - singular_name = "S'rendarr's Hand leaf" - desc = "A poultice made of soft leaves that is rubbed on bruises." - icon = 'icons/obj/harvest.dmi' - icon_state = "shandp" - heal_brute = 7 - -/obj/item/stack/medical/ointment/tajaran - name = "\improper Messa's Tear petals" - singular_name = "Messa's Tear petals" - desc = "A poultice made of cold, blue petals that is rubbed on burns." - icon = 'icons/obj/harvest.dmi' - icon_state = "mtearp" - heal_burn = 7 - - /obj/item/stack/medical/advanced/bruise_pack name = "advanced trauma kit" singular_name = "advanced trauma kit" @@ -159,7 +141,7 @@ if(affecting.open == 0) var/bandaged = affecting.bandage() var/disinfected = affecting.disinfect() - + if(!(bandaged || disinfected)) user << "\red The wounds on [M]'s [affecting.display_name] have already been treated." return 1 diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index 45350a71e9..143539968e 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -13,12 +13,21 @@ max_amount = 60 attack_verb = list("hit", "bludgeoned", "whacked") +/obj/item/stack/rods/cyborg + name = "metal rod synthesizer" + desc = "A device that makes metal rods." + gender = NEUTER + matter = null + uses_charge = 1 + charge_costs = list(500) + stacktype = /obj/item/stack/rods + /obj/item/stack/rods/attackby(obj/item/W as obj, mob/user as mob) ..() if (istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W - if(amount < 2) + if(get_amount() < 2) user << "\red You need at least two rods to do this." return @@ -54,7 +63,7 @@ return 1 else if(!in_use) - if(amount < 2) + if(get_amount() < 2) user << "\blue You need at least two rods to do this." return usr << "\blue Assembling grille..." diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 71fb87f9ad..422640ee1f 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -22,12 +22,13 @@ var/list/construction_options = list("One Direction", "Full Window") /obj/item/stack/sheet/glass/cyborg - name = "glass" - desc = "HOLY SHEET! That is a lot of glass." - singular_name = "glass sheet" - icon_state = "sheet-glass" + name = "glass synthesizer" + desc = "A device that makes glass." + gender = NEUTER + singular_name = "glass" matter = null - created_window = /obj/structure/window/basic + uses_charge = 1 + charge_costs = list(1000) stacktype = /obj/item/stack/sheet/glass /obj/item/stack/sheet/glass/attack_self(mob/user as mob) @@ -69,7 +70,7 @@ if(!user.IsAdvancedToolUser()) return 0 var/title = "Sheet-[name]" - title += " ([src.amount] sheet\s left)" + title += " ([src.get_amount()] sheet\s left)" switch(input(title, "What would you like to construct?") as null|anything in construction_options) if("One Direction") if(!src) return 1 @@ -102,7 +103,7 @@ if("Full Window") if(!src) return 1 if(src.loc != user) return 1 - if(src.amount < 4) + if(src.get_amount() < 4) user << "\red You need more glass to do that." return 1 if(locate(/obj/structure/window) in user.loc) @@ -124,7 +125,7 @@ user << "\red There is already a windoor in that location." return 1 - if(src.amount < 5) + if(src.get_amount() < 5) user << "\red You need more glass to do that." return 1 @@ -151,10 +152,15 @@ construction_options = list("One Direction", "Full Window", "Windoor") /obj/item/stack/sheet/glass/reinforced/cyborg - name = "reinforced glass" - desc = "Glass which has been reinforced with metal rods." + name = "reinforced glass synthesizer" + desc = "A device that makes reinforced glass." + gender = NEUTER + matter = null + uses_charge = 2 + charge_costs = list(1000) singular_name = "reinforced glass sheet" icon_state = "sheet-rglass" + charge_costs = list(500, 1000) /* * Phoron Glass sheets diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index fccce08dc2..46415bb8af 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -47,6 +47,9 @@ var/global/list/datum/stack_recipe/plastic_recipes = list ( \ new/datum/stack_recipe("plastic knife", /obj/item/weapon/kitchen/utensil/pknife, 1, on_floor = 1), \ new/datum/stack_recipe("plastic bag", /obj/item/weapon/storage/bag/plasticbag, 3, on_floor = 1), \ new/datum/stack_recipe("blood pack", /obj/item/weapon/reagent_containers/blood/empty, 4, on_floor = 0), \ + new/datum/stack_recipe("reagent dispenser cartridge (large)", /obj/item/weapon/reagent_containers/chem_disp_cartridge, 5, on_floor=0), // 500u + new/datum/stack_recipe("reagent dispenser cartridge (med)", /obj/item/weapon/reagent_containers/chem_disp_cartridge/medium, 3, on_floor=0), // 250u + new/datum/stack_recipe("reagent dispenser cartridge (small)", /obj/item/weapon/reagent_containers/chem_disp_cartridge/small, 1, on_floor=0) // 100u ) var/global/list/datum/stack_recipe/iron_recipes = list ( \ @@ -137,9 +140,10 @@ obj/item/stack/sheet/mineral/iron/New() recipes = plastic_recipes /obj/item/stack/sheet/mineral/plastic/cyborg - name = "plastic sheets" - icon_state = "sheet-plastic" - perunit = 2000 + name = "plastic sheets synthesizer" + gender = NEUTER + uses_charge = 1 + charge_costs = list(1000) stacktype = /obj/item/stack/sheet/mineral/plastic /obj/item/stack/sheet/mineral/gold diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 1ea6f49b82..daa67c4449 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -11,29 +11,29 @@ * Metal */ var/global/list/datum/stack_recipe/metal_recipes = list ( \ - new/datum/stack_recipe("stool", /obj/structure/stool, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("chair", /obj/structure/stool/bed/chair, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("bed", /obj/structure/stool/bed, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("stool", /obj/item/weapon/stool, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("chair", /obj/structure/bed/chair, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("bed", /obj/structure/bed, 2, one_per_turf = 1, on_floor = 1), \ null, \ new/datum/stack_recipe_list("office chairs",list( \ - new/datum/stack_recipe("dark office chair", /obj/structure/stool/bed/chair/office/dark, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("light office chair", /obj/structure/stool/bed/chair/office/light, 5, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("dark office chair", /obj/structure/bed/chair/office/dark, 5, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("light office chair", /obj/structure/bed/chair/office/light, 5, one_per_turf = 1, on_floor = 1), \ ), 5), \ new/datum/stack_recipe_list("comfy chairs", list( \ - new/datum/stack_recipe("beige comfy chair", /obj/structure/stool/bed/chair/comfy/beige, 2, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("black comfy chair", /obj/structure/stool/bed/chair/comfy/black, 2, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("brown comfy chair", /obj/structure/stool/bed/chair/comfy/brown, 2, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("lime comfy chair", /obj/structure/stool/bed/chair/comfy/lime, 2, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("teal comfy chair", /obj/structure/stool/bed/chair/comfy/teal, 2, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("red comfy chair", /obj/structure/stool/bed/chair/comfy/red, 2, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("blue comfy chair", /obj/structure/stool/bed/chair/comfy/blue, 2, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("purple comfy chair", /obj/structure/stool/bed/chair/comfy/purp, 2, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("green comfy chair", /obj/structure/stool/bed/chair/comfy/green, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("beige comfy chair", /obj/structure/bed/chair/comfy/beige, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("black comfy chair", /obj/structure/bed/chair/comfy/black, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("brown comfy chair", /obj/structure/bed/chair/comfy/brown, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("lime comfy chair", /obj/structure/bed/chair/comfy/lime, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("teal comfy chair", /obj/structure/bed/chair/comfy/teal, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("red comfy chair", /obj/structure/bed/chair/comfy/red, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("blue comfy chair", /obj/structure/bed/chair/comfy/blue, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("purple comfy chair", /obj/structure/bed/chair/comfy/purp, 2, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("green comfy chair", /obj/structure/bed/chair/comfy/green, 2, one_per_turf = 1, on_floor = 1), \ ), 2), \ null, \ new/datum/stack_recipe("table parts", /obj/item/weapon/table_parts, 2), \ new/datum/stack_recipe("rack parts", /obj/item/weapon/table_parts/rack), \ - new/datum/stack_recipe("metal baseball bat", /obj/item/weapon/baseballbat/metal, 10, time = 20, one_per_turf = 0, on_floor = 1), \ + new/datum/stack_recipe("metal baseball bat", /obj/item/weapon/twohanded/baseballbat/metal, 10, time = 20, one_per_turf = 0, on_floor = 1), \ new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = 1, on_floor = 1), \ null, \ new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = 1, on_floor = 1), \ @@ -90,12 +90,12 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \ origin_tech = "materials=1" /obj/item/stack/sheet/metal/cyborg - name = "metal" - desc = "Sheets made out off metal. It has been dubbed Metal Sheets." - singular_name = "metal sheet" - icon_state = "sheet-metal" - throwforce = 14.0 - flags = CONDUCT + name = "metal synthesizer" + desc = "A device that makes metal sheets." + gender = NEUTER + matter = null + uses_charge = 1 + charge_costs = list(1000) stacktype = /obj/item/stack/sheet/metal /obj/item/stack/sheet/metal/New(var/loc, var/amount=null) @@ -125,9 +125,19 @@ var/global/list/datum/stack_recipe/plasteel_recipes = list ( \ flags = CONDUCT origin_tech = "materials=2" +/obj/item/stack/sheet/plasteel/cyborg + name = "plasteel synthesizer" + desc = "A device that makes plasteel sheets." + gender = NEUTER + singular_name = "plasteel sheet" + matter = null + uses_charge = 1 + charge_costs = list(1000) + stacktype = /obj/item/stack/sheet/plasteel + /obj/item/stack/sheet/plasteel/New(var/loc, var/amount=null) - recipes = plasteel_recipes - return ..() + recipes = plasteel_recipes + return ..() /* * Wood @@ -136,12 +146,12 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ new/datum/stack_recipe("wooden sandals", /obj/item/clothing/shoes/sandal, 1), \ new/datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20), \ new/datum/stack_recipe("table parts", /obj/item/weapon/table_parts/wood, 2), \ - new/datum/stack_recipe("wooden chair", /obj/structure/stool/bed/chair/wood/normal, 3, time = 10, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("wooden chair", /obj/structure/bed/chair/wood/normal, 3, time = 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("crossbow frame", /obj/item/weapon/crossbowframe, 5, time = 25, one_per_turf = 0, on_floor = 0), \ new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("baseball bat", /obj/item/weapon/baseballbat, 10, time = 20, one_per_turf = 0, on_floor = 1) \ + new/datum/stack_recipe("baseball bat", /obj/item/weapon/twohanded/baseballbat, 10, time = 20, one_per_turf = 0, on_floor = 1) \ // new/datum/stack_recipe("apiary", /obj/item/apiary, 10, time = 25, one_per_turf = 0, on_floor = 0) ) @@ -153,10 +163,13 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ origin_tech = "materials=1;biotech=1" /obj/item/stack/sheet/wood/cyborg - name = "wooden plank" - desc = "One can only guess that this is a bunch of wood." + name = "wood synthesizer" + desc = "A device that makes wooden planks." + gender = NEUTER singular_name = "wood plank" icon_state = "sheet-wood" + uses_charge = 1 + charge_costs = list(1000) stacktype = /obj/item/stack/sheet/wood /obj/item/stack/sheet/wood/New(var/loc, var/amount=null) @@ -178,7 +191,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ */ var/global/list/datum/stack_recipe/cardboard_recipes = list ( \ new/datum/stack_recipe("box", /obj/item/weapon/storage/box), \ - new/datum/stack_recipe("donut box", /obj/item/weapon/storage/donut_box/empty), \ + new/datum/stack_recipe("donut box", /obj/item/weapon/storage/box/donut/empty), \ new/datum/stack_recipe("egg box", /obj/item/weapon/storage/fancy/egg_box), \ new/datum/stack_recipe("light tubes", /obj/item/weapon/storage/box/lights/tubes), \ new/datum/stack_recipe("light bulbs", /obj/item/weapon/storage/box/lights/bulbs), \ diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index cd133ff8e3..a4e7d94fad 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -17,6 +17,9 @@ var/amount = 1 var/max_amount //also see stack recipes initialisation, param "max_res_amount" must be equal to this max_amount var/stacktype //determines whether different stack types can merge + var/uses_charge = 0 + var/list/charge_costs = null + var/list/datum/matter_synth/synths = null /obj/item/stack/New(var/loc, var/amount=null) ..() @@ -27,13 +30,18 @@ return /obj/item/stack/Del() + if(uses_charge) + return if (src && usr && usr.machine == src) usr << browse(null, "window=stack") ..() /obj/item/stack/examine(mob/user) if(..(user, 1)) - user << "There are [src.amount] [src.singular_name]\s in the stack." + if(!uses_charge) + user << "There are [src.amount] [src.singular_name]\s in the stack." + else + user << "There is enough charge for [get_amount()]." /obj/item/stack/attack_self(mob/user as mob) list_recipes(user) @@ -41,14 +49,14 @@ /obj/item/stack/proc/list_recipes(mob/user as mob, recipes_sublist) if (!recipes) return - if (!src || amount<=0) + if (!src || get_amount() <= 0) user << browse(null, "window=stack") user.set_machine(src) //for correct work of onclose var/list/recipe_list = recipes if (recipes_sublist && recipe_list[recipes_sublist] && istype(recipe_list[recipes_sublist], /datum/stack_recipe_list)) var/datum/stack_recipe_list/srl = recipe_list[recipes_sublist] recipe_list = srl.recipes - var/t1 = text("Constructions from []Amount Left: []
      ", src, src.amount) + var/t1 = text("Constructions from []Amount Left: []
      ", src, src.get_amount()) for(var/i=1;i<=recipe_list.len,i++) var/E = recipe_list[i] if (isnull(E)) @@ -60,14 +68,14 @@ if (istype(E, /datum/stack_recipe_list)) var/datum/stack_recipe_list/srl = E - if (src.amount >= srl.req_amount) + if (src.get_amount() >= srl.req_amount) t1 += "[srl.title] ([srl.req_amount] [src.singular_name]\s)" else t1 += "[srl.title] ([srl.req_amount] [src.singular_name]\s)
      " if (istype(E, /datum/stack_recipe)) var/datum/stack_recipe/R = E - var/max_multiplier = round(src.amount / R.req_amount) + var/max_multiplier = round(src.get_amount() / R.req_amount) var/title as text var/can_build = 1 can_build = can_build && (max_multiplier>0) @@ -142,7 +150,7 @@ list_recipes(usr, text2num(href_list["sublist"])) if (href_list["make"]) - if (src.amount < 1) del(src) //Never should happen + if (src.get_amount() < 1) del(src) //Never should happen var/list/recipes_list = recipes if (href_list["sublist"]) @@ -165,28 +173,44 @@ //Return 1 if an immediate subsequent call to use() would succeed. //Ensures that code dealing with stacks uses the same logic /obj/item/stack/proc/can_use(var/used) - if (amount < used) + if (get_amount() < used) return 0 return 1 /obj/item/stack/proc/use(var/used) if (!can_use(used)) return 0 - amount -= used - if (amount <= 0) - spawn(0) //delete the empty stack once the current context yields - if (amount <= 0) //check again in case someone transferred stuff to us - if(usr) - usr.remove_from_mob(src) - del(src) - return 1 + if(!uses_charge) + amount -= used + if (amount <= 0) + spawn(0) //delete the empty stack once the current context yields + if (amount <= 0) //check again in case someone transferred stuff to us + if(usr) + usr.remove_from_mob(src) + del(src) + return 1 + else + if(get_amount() < used) + return 0 + for(var/i = 1 to uses_charge) + var/datum/matter_synth/S = synths[i] + S.use_charge(charge_costs[i] * used) // Doesn't need to be deleted + return 1 + return 0 /obj/item/stack/proc/add(var/extra) - if(amount + extra > max_amount) + if(!uses_charge) + if(amount + extra > get_max_amount()) + return 0 + else + amount += extra + return 1 + else if(!synths || synths.len < uses_charge) return 0 else - amount += extra - return 1 + for(var/i = 1 to uses_charge) + var/datum/matter_synth/S = synths[i] + S.add_charge(charge_costs[i] * extra) /* The transfer and split procs work differently than use() and add(). @@ -196,16 +220,16 @@ //attempts to transfer amount to S, and returns the amount actually transferred /obj/item/stack/proc/transfer_to(obj/item/stack/S, var/tamount=null) - if (!amount) + if (!get_amount()) return 0 if (stacktype != S.stacktype) return 0 if (isnull(tamount)) - tamount = src.amount + tamount = src.get_amount() - var/transfer = max(min(tamount, src.amount, (S.max_amount - S.amount)), 0) + var/transfer = max(min(tamount, src.get_amount(), (S.get_max_amount() - S.get_amount())), 0) - var/orig_amount = src.amount + var/orig_amount = src.get_amount() if (transfer && src.use(transfer)) S.add(transfer) if (prob(transfer/orig_amount * 100)) @@ -220,6 +244,8 @@ /obj/item/stack/proc/split(var/tamount) if (!amount) return null + if(uses_charge) + return null var/transfer = max(min(tamount, src.amount, initial(max_amount)), 0) @@ -234,8 +260,31 @@ return null /obj/item/stack/proc/get_amount() + if(uses_charge) + if(!synths || synths.len < uses_charge) + return 0 + var/datum/matter_synth/S = synths[1] + . = round(S.get_charge() / charge_costs[1]) + if(uses_charge > 1) + for(var/i = 2 to uses_charge) + S = synths[i] + . = min(., round(S.get_charge() / charge_costs[i])) + return return amount +/obj/item/stack/proc/get_max_amount() + if(uses_charge) + if(!synths || synths.len < uses_charge) + return 0 + var/datum/matter_synth/S = synths[1] + . = round(S.max_energy / charge_costs[1]) + if(uses_charge > 1) + for(var/i = 2 to uses_charge) + S = synths[i] + . = min(., round(S.max_energy / charge_costs[i])) + return + return max_amount + /obj/item/stack/proc/add_to_stacks(mob/usr as mob) for (var/obj/item/stack/item in usr.loc) if (item==src) diff --git a/code/game/objects/items/stacks/tiles/plasteel.dm b/code/game/objects/items/stacks/tiles/plasteel.dm index 7816c45f53..3215d0efaf 100644 --- a/code/game/objects/items/stacks/tiles/plasteel.dm +++ b/code/game/objects/items/stacks/tiles/plasteel.dm @@ -3,14 +3,12 @@ singular_name = "floor tile" desc = "Those could work as a pretty decent throwing weapon" icon_state = "tile" - w_class = 3.0 force = 6.0 matter = list("metal" = 937.5) throwforce = 15.0 throw_speed = 5 throw_range = 20 flags = CONDUCT - max_amount = 60 /obj/item/stack/tile/plasteel/New(var/loc, var/amount=null) ..() @@ -18,6 +16,16 @@ src.pixel_y = rand(1, 14) return +/obj/item/stack/tile/plasteel/cyborg + name = "floor tile synthesizer" + desc = "A device that makes floor tiles." + gender = NEUTER + matter = null + uses_charge = 1 + charge_costs = list(250) + stacktype = /obj/item/stack/tile/plasteel + build_type = /obj/item/stack/tile/plasteel + /* /obj/item/stack/tile/plasteel/attack_self(mob/user as mob) if (usr.stat) diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 7ad6abdd60..dcac154442 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -1,9 +1,18 @@ /* Diffrent misc types of tiles * Contains: + * Prototype * Grass * Wood * Carpet */ + +/obj/item/stack/tile + name = "tile" + singular_name = "tile" + desc = "A non-descript floor tile" + w_class = 3 + max_amount = 60 + var/build_type = null /* * Grass @@ -13,13 +22,11 @@ singular_name = "grass floor tile" desc = "A patch of grass like they often use on golf courses." icon_state = "tile_grass" - w_class = 3.0 force = 1.0 throwforce = 1.0 throw_speed = 5 throw_range = 20 flags = CONDUCT - max_amount = 60 origin_tech = "biotech=1" /* @@ -30,13 +37,19 @@ singular_name = "wood floor tile" desc = "An easy to fit wooden floor tile." icon_state = "tile-wood" - w_class = 3.0 force = 1.0 throwforce = 1.0 throw_speed = 5 throw_range = 20 flags = CONDUCT - max_amount = 60 + +/obj/item/stack/tile/wood/cyborg + name = "wood floor tile synthesizer" + desc = "A device that makes wood floor tiles." + uses_charge = 1 + charge_costs = list(250) + stacktype = /obj/item/stack/tile/wood + build_type = /obj/item/stack/tile/wood /* * Carpets @@ -46,10 +59,8 @@ singular_name = "carpet" desc = "A piece of carpet. It is the same size as a normal floor tile!" icon_state = "tile-carpet" - w_class = 3.0 force = 1.0 throwforce = 1.0 throw_speed = 5 throw_range = 20 flags = CONDUCT - max_amount = 60 diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index cee5076a55..a39acac9c1 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -6,6 +6,7 @@ * Toy gun * Toy crossbow * Toy swords + * Toy bosun's whistle * Toy mechs * Crayons * Snap pops @@ -13,6 +14,9 @@ * Therapy dolls * Toddler doll * Inflatable duck + * Action figures + * Plushies + * Toy cult sword */ @@ -99,6 +103,18 @@ item_state = "syndballoon" w_class = 4.0 +/obj/item/toy/nanotrasenballoon + name = "criminal balloon" + desc = "Across the balloon the following is printed: \"Man, I love NT soooo much. I use only NanoTrasen products. You have NO idea.\"" + throwforce = 0 + throw_speed = 4 + throw_range = 20 + force = 0 + icon = 'icons/obj/weapons.dmi' + icon_state = "ntballoon" + item_state = "ntballoon" + w_class = 4.0 + /* * Fake telebeacon */ @@ -128,7 +144,7 @@ icon_state = "revolver" item_state = "gun" flags = CONDUCT - slot_flags = SLOT_BELT + slot_flags = SLOT_BELT|SLOT_HOLSTER w_class = 3.0 matter = list("glass" = 10,"metal" = 10) @@ -380,6 +396,10 @@ viewers(user) << "\red [user] is jamming the [src.name] up \his nose and into \his brain. It looks like \he's trying to commit suicide." return (BRUTELOSS|OXYLOSS) + New() + name = "[colourName] crayon" + ..() + /* * Snap pops */ @@ -420,7 +440,7 @@ /obj/item/toy/waterflower name = "water flower" desc = "A seemingly innocent sunflower...with a twist." - icon = 'icons/obj/harvest.dmi' + //icon = 'icons/obj/harvest.dmi' icon_state = "sunflower" item_state = "sunflower" var/empty = 0 @@ -482,6 +502,22 @@ if(..(user, 0)) user << text("\icon[] [] units of water left!", src, src.reagents.total_volume) +/* + * Bosun's whistle + */ + + /obj/item/toy/bosunwhistle + name = "bosun's whistle" + desc = "A genuine Admiral Krush Bosun's Whistle, for the aspiring ship's captain! Suitable for ages 8 and up, do not swallow." + icon = 'icons/obj/toy.dmi' + icon_state = "bosunwhistle" + var/cooldown = 0 + +/obj/item/toy/bosunwhistle/attack_self(mob/user as mob) + if(cooldown < world.time - 35) + user << "You blow on [src], creating an ear-splitting noise!" + playsound(user, 'sound/misc/boatswain.ogg', 20, 1) + cooldown = world.time /* * Mech prizes @@ -526,7 +562,6 @@ desc = "Mini-Mecha action figure! Collect them all! 4/11." icon_state = "gygaxtoy" - /obj/item/toy/prize/durand name = "toy durand" desc = "Mini-Mecha action figure! Collect them all! 5/11." @@ -562,6 +597,206 @@ desc = "Mini-Mecha action figure! Collect them all! 11/11." icon_state = "phazonprize" +/* + * Action figures + */ + +/obj/item/toy/figure + name = "Completely Glitched action figure" + desc = "A \"Space Life\" brand... wait, what the hell is this thing? It seems to be requesting the sweet release of death." + icon_state = "assistant" + icon = 'icons/obj/toy.dmi' + +/obj/item/toy/figure/cmo + name = "Chief Medical Officer action figure" + desc = "A \"Space Life\" brand Chief Medical Officer action figure." + icon_state = "cmo" + +/obj/item/toy/figure/assistant + name = "Assistant action figure" + desc = "A \"Space Life\" brand Assistant action figure." + icon_state = "assistant" + +/obj/item/toy/figure/atmos + name = "Atmospheric Technician action figure" + desc = "A \"Space Life\" brand Atmospheric Technician action figure." + icon_state = "atmos" + +/obj/item/toy/figure/bartender + name = "Bartender action figure" + desc = "A \"Space Life\" brand Bartender action figure." + icon_state = "bartender" + +/obj/item/toy/figure/borg + name = "Cyborg action figure" + desc = "A \"Space Life\" brand Cyborg action figure." + icon_state = "borg" + +/obj/item/toy/figure/gardener + name = "Gardener action figure" + desc = "A \"Space Life\" brand Gardener action figure." + icon_state = "botanist" + +/obj/item/toy/figure/captain + name = "Captain action figure" + desc = "A \"Space Life\" brand Captain action figure." + icon_state = "captain" + +/obj/item/toy/figure/cargotech + name = "Cargo Technician action figure" + desc = "A \"Space Life\" brand Cargo Technician action figure." + icon_state = "cargotech" + +/obj/item/toy/figure/ce + name = "Chief Engineer action figure" + desc = "A \"Space Life\" brand Chief Engineer action figure." + icon_state = "ce" + +/obj/item/toy/figure/chaplain + name = "Chaplain action figure" + desc = "A \"Space Life\" brand Chaplain action figure." + icon_state = "chaplain" + +/obj/item/toy/figure/chef + name = "Chef action figure" + desc = "A \"Space Life\" brand Chef action figure." + icon_state = "chef" + +/obj/item/toy/figure/chemist + name = "Chemist action figure" + desc = "A \"Space Life\" brand Chemist action figure." + icon_state = "chemist" + +/obj/item/toy/figure/clown + name = "Clown action figure" + desc = "A \"Space Life\" brand Clown action figure." + icon_state = "clown" + +/obj/item/toy/figure/corgi + name = "Corgi action figure" + desc = "A \"Space Life\" brand Corgi action figure." + icon_state = "ian" + +/obj/item/toy/figure/detective + name = "Detective action figure" + desc = "A \"Space Life\" brand Detective action figure." + icon_state = "detective" + +/obj/item/toy/figure/dsquad + name = "Space Commando action figure" + desc = "A \"Space Life\" brand Space Commando action figure." + icon_state = "dsquad" + +/obj/item/toy/figure/engineer + name = "Engineer action figure" + desc = "A \"Space Life\" brand Engineer action figure." + icon_state = "engineer" + +/obj/item/toy/figure/geneticist + name = "Geneticist action figure" + desc = "A \"Space Life\" brand Geneticist action figure, which was recently dicontinued." + icon_state = "geneticist" + +/obj/item/toy/figure/hop + name = "Head of Personel action figure" + desc = "A \"Space Life\" brand Head of Personel action figure." + icon_state = "hop" + +/obj/item/toy/figure/hos + name = "Head of Security action figure" + desc = "A \"Space Life\" brand Head of Security action figure." + icon_state = "hos" + +/obj/item/toy/figure/qm + name = "Quartermaster action figure" + desc = "A \"Space Life\" brand Quartermaster action figure." + icon_state = "qm" + +/obj/item/toy/figure/janitor + name = "Janitor action figure" + desc = "A \"Space Life\" brand Janitor action figure." + icon_state = "janitor" + +/obj/item/toy/figure/agent + name = "Internal Affairs Agent action figure" + desc = "A \"Space Life\" brand Internal Affairs Agent action figure." + icon_state = "agent" + +/obj/item/toy/figure/librarian + name = "Librarian action figure" + desc = "A \"Space Life\" brand Librarian action figure." + icon_state = "librarian" + +/obj/item/toy/figure/md + name = "Medical Doctor action figure" + desc = "A \"Space Life\" brand Medical Doctor action figure." + icon_state = "md" + +/obj/item/toy/figure/mime + name = "Mime action figure" + desc = "A \"Space Life\" brand Mime action figure." + icon_state = "mime" + +/obj/item/toy/figure/miner + name = "Shaft Miner action figure" + desc = "A \"Space Life\" brand Shaft Miner action figure." + icon_state = "miner" + +/obj/item/toy/figure/ninja + name = "Space Ninja action figure" + desc = "A \"Space Life\" brand Space Ninja action figure." + icon_state = "ninja" + +/obj/item/toy/figure/wizard + name = "Wizard action figure" + desc = "A \"Space Life\" brand Wizard action figure." + icon_state = "wizard" + +/obj/item/toy/figure/rd + name = "Research Director action figure" + desc = "A \"Space Life\" brand Research Director action figure." + icon_state = "rd" + +/obj/item/toy/figure/roboticist + name = "Roboticist action figure" + desc = "A \"Space Life\" brand Roboticist action figure." + icon_state = "roboticist" + +/obj/item/toy/figure/scientist + name = "Scientist action figure" + desc = "A \"Space Life\" brand Scientist action figure." + icon_state = "scientist" + +/obj/item/toy/figure/syndie + name = "Doom Operative action figure" + desc = "A \"Space Life\" brand Doom Operative action figure." + icon_state = "syndie" + +/obj/item/toy/figure/secofficer + name = "Security Officer action figure" + desc = "A \"Space Life\" brand Security Officer action figure." + icon_state = "secofficer" + +/obj/item/toy/figure/warden + name = "Warden action figure" + desc = "A \"Space Life\" brand Warden action figure." + icon_state = "warden" + +/obj/item/toy/figure/psychologist + name = "Psychologist action figure" + desc = "A \"Space Life\" brand Psychologist action figure." + icon_state = "psychologist" + +/obj/item/toy/figure/paramedic + name = "Paramedic action figure" + desc = "A \"Space Life\" brand Paramedic action figure." + icon_state = "paramedic" + +/obj/item/toy/figure/ert + name = "Emergency Response Team Commander action figure" + desc = "A \"Space Life\" brand Emergency Response Team Commander action figure." + icon_state = "ert" + /obj/item/toy/katana name = "replica katana" desc = "Woefully underpowered in D20." @@ -623,6 +858,106 @@ item_state = "egg3" // It's the green egg in items_left/righthand w_class = 1 +/* + * Plushies + */ + +//Large plushies. +/obj/structure/plushie + name = "generic plush" + desc = "A very generic plushie. It seems to not want to exist." + icon = 'icons/obj/toy.dmi' + icon_state = "ianplushie" + anchored = 0 + density = 1 + var/phrase = "I don't want to exist anymore!" + +/obj/structure/plushie/attack_hand(mob/user) + if(user.a_intent == I_HELP) + user.visible_message("[user] hugs [src]!","You hug [src]!") + else if (user.a_intent == I_HURT) + user.visible_message("[user] punches [src]!","You punch [src]!") + else if (user.a_intent == I_GRAB) + user.visible_message("[user] attempts to strangle [src]!","You attempt to strangle [src]!") + else + user.visible_message("[user] pokes the [src].","You poke the [src].") + visible_message("[src] says, \"[phrase]\"") + +/obj/structure/plushie/ian + name = "plush corgi" + desc = "A plushie of an adorable corgi! Don't you just want to hug it and squeeze it and call it \"Ian\"?" + icon_state = "ianplushie" + phrase = "Arf!" + +/obj/structure/plushie/drone + name = "plush drone" + desc = "A plushie of a happy drone! It appears to be smiling, and has a small tag which reads \"N.D.V. Icarus Gift Shop\"." + icon_state = "droneplushie" + phrase = "Beep boop!" + +/obj/structure/plushie/carp + name = "plush carp" + desc = "A plushie of an elated carp! Straight from the wilds of the Nyx frontier, now right here in your hands." + icon_state = "carpplushie" + phrase = "Glorf!" + +/obj/structure/plushie/beepsky + name = "plush Officer Sweepsky" + desc = "A plushie of a popular industrious cleaning robot! If it could feel emotions, it would love you." + icon_state = "beepskyplushie" + phrase = "Ping!" + +//Small plushies. +/obj/item/toy/plushie + name = "generic small plush" + desc = "A very generic small plushie. It seems to not want to exist." + icon = 'icons/obj/toy.dmi' + icon_state = "nymphplushie" + +/obj/item/toy/plushie/attack_self(mob/user as mob) + if(user.a_intent == I_HELP) + user.visible_message("[user] hugs [src]!","You hug [src]!") + else if (user.a_intent == I_HURT) + user.visible_message("[user] punches [src]!","You punch [src]!") + else if (user.a_intent == I_GRAB) + user.visible_message("[user] attempts to strangle [src]!","You attempt to strangle [src]!") + else + user.visible_message("[user] pokes the [src].","You poke the [src].") + +/obj/item/toy/plushie/nymph + name = "diona nymph plush" + desc = "A plushie of an adorable diona nymph! While its level of self-awareness is still being debated, its level of cuteness is not." + icon_state = "nymphplushie" + +/obj/item/toy/plushie/mouse + name = "mouse plush" + desc = "A plushie of a delightful mouse! What was once considered a vile rodent is now your very best friend." + icon_state = "mouseplushie" + +/obj/item/toy/plushie/kitten + name = "kitten plush" + desc = "A plushie of a cute kitten! Watch as it purrs it's way right into your heart." + icon_state = "kittenplushie" + +/obj/item/toy/plushie/lizard + name = "lizard plush" + desc = "A plushie of a scaly lizard! Very controversial, after being accused as \"racist\" by some Unathi." + icon_state = "lizardplushie" + +/obj/item/toy/plushie/spider + name = "spider plush" + desc = "A plushie of a fuzzy spider! It has eight legs - all the better to hug you with." + icon_state = "spiderplushie" + +//Toy cult sword +/obj/item/toy/cultsword + name = "foam sword" + desc = "An arcane weapon (made of foam) wielded by the followers of the hit Saturday morning cartoon \"King Nursee and the Acolytes of Heroism\"." + icon = 'icons/obj/weapons.dmi' + icon_state = "cultblade" + item_state = "cultblade" + w_class = 4 + attack_verb = list("attacked", "slashed", "stabbed", "poked") /* NYET. /obj/item/weapon/toddler diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index e8bae92fee..34181486e4 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -68,5 +68,9 @@ name = "\improper \"LiquidFood\" ration" icon_state = "liquidfood" +/obj/item/trash/tastybread + name = "bread tube" + icon_state = "tastybread" + /obj/item/trash/attack(mob/M as mob, mob/living/user as mob) return diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm index 5f22d21924..f620fd64e9 100755 --- a/code/game/objects/items/weapons/AI_modules.dm +++ b/code/game/objects/items/weapons/AI_modules.dm @@ -19,7 +19,7 @@ AI MODULES throw_speed = 3 throw_range = 15 origin_tech = "programming=3" - + var/datum/ai_laws/laws = null /obj/item/weapon/aiModule/proc/install(var/obj/machinery/computer/C) if (istype(C, /obj/machinery/computer/aiupload)) @@ -77,9 +77,21 @@ AI MODULES /obj/item/weapon/aiModule/proc/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - target << "[sender] has uploaded a change to the laws you must follow, using a [name]. From now on: " + log_law_changes(target, sender) + + if(laws) + laws.sync(target, 0) + addAdditionalLaws(target, sender) + + target << "[sender] has uploaded a change to the laws you must follow, using \an [src]. From now on: " + target.show_laws() + +/obj/item/weapon/aiModule/proc/log_law_changes(var/mob/living/silicon/ai/target, var/mob/sender) var/time = time2text(world.realtime,"hh:mm:ss") lawchanges.Add("[time] : [sender.name]([sender.key]) used [src.name] on [target.name]([target.key])") + log_and_message_admins("used [src.name] on [target.name]([target.key])") + +/obj/item/weapon/aiModule/proc/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) /******************** Modules ********************/ @@ -89,14 +101,14 @@ AI MODULES /obj/item/weapon/aiModule/safeguard name = "\improper 'Safeguard' AI module" var/targetName = "" - desc = "A 'safeguard' AI module: 'Safeguard . Individuals that threaten are not human and are a threat to humans.'" + desc = "A 'safeguard' AI module: 'Safeguard . Anyone threatening or attempting to harm is no longer to be considered a crew member, and is a threat which must be neutralized.'" origin_tech = "programming=3;materials=4" /obj/item/weapon/aiModule/safeguard/attack_self(var/mob/user as mob) ..() - var/targName = stripped_input(usr, "Please enter the name of the person to safeguard.", "Safeguard who?", user.name) + var/targName = sanitize(input("Please enter the name of the person to safeguard.", "Safeguard who?", user.name)) targetName = targName - desc = text("A 'safeguard' AI module: 'Safeguard []. Individuals that threaten [] are not human and are a threat to humans.'", targetName, targetName) + desc = text("A 'safeguard' AI module: 'Safeguard []. Anyone threatening or attempting to harm [] is no longer to be considered a crew member, and is a threat which must be neutralized.'", targetName, targetName) /obj/item/weapon/aiModule/safeguard/install(var/obj/machinery/computer/C) if(!targetName) @@ -104,28 +116,25 @@ AI MODULES return 0 ..() -/obj/item/weapon/aiModule/safeguard/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = text("Safeguard []. Individuals that threaten [] are not human and are a threat to humans.'", targetName, targetName) - target << law - target.add_supplied_law(4, law) +/obj/item/weapon/aiModule/safeguard/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = text("Safeguard []. Anyone threatening or attempting to harm [] is no longer to be considered a crew member, and is a threat which must be neutralized.", targetName, targetName) + target.add_supplied_law(9, law) lawchanges.Add("The law specified [targetName]") - -/******************** OneHuman ********************/ +/******************** OneMember ********************/ /obj/item/weapon/aiModule/oneHuman - name = "\improper 'OneHuman' AI module" + name = "\improper 'OneCrewMember' AI module" var/targetName = "" - desc = "A 'one human' AI module: 'Only is human.'" + desc = "A 'one crew member' AI module: 'Only is a crew member.'" origin_tech = "programming=3;materials=6" //made with diamonds! /obj/item/weapon/aiModule/oneHuman/attack_self(var/mob/user as mob) ..() - var/targName = stripped_input(usr, "Please enter the name of the person who is the only human.", "Who?", user.real_name) + var/targName = sanitize(input("Please enter the name of the person who is the only crew member.", "Who?", user.real_name)) targetName = targName - desc = text("A 'one human' AI module: 'Only [] is human.'", targetName) + desc = text("A 'one crew member' AI module: 'Only [] is a crew member.'", targetName) /obj/item/weapon/aiModule/oneHuman/install(var/obj/machinery/computer/C) if(!targetName) @@ -135,117 +144,74 @@ AI MODULES /obj/item/weapon/aiModule/oneHuman/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) ..() - var/law = "Only [targetName] is human." - if (!is_special_character(target)) // Makes sure the AI isn't a traitor before changing their law 0. --NeoFite + var/law = "Only [targetName] is a crew member." + target << "[sender.real_name] attempted to modify your zeroth law." // And lets them know that someone tried. --NeoFite + target << "It would be in your best interest to play along with [sender.real_name] that [law]" + +/obj/item/weapon/aiModule/oneHuman/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = "Only [targetName] is an crew member." + if (!target.is_malf_or_traitor()) // Makes sure the AI isn't a traitor before changing their law 0. --NeoFite target << law target.set_zeroth_law(law) lawchanges.Add("The law specified [targetName]") else - target << "[sender.real_name] attempted to modify your zeroth law." // And lets them know that someone tried. --NeoFite - target << "It would be in your best interest to play along with [sender.real_name] that [law]" lawchanges.Add("The law specified [targetName], but the AI's existing law 0 cannot be overriden.") /******************** ProtectStation ********************/ /obj/item/weapon/aiModule/protectStation name = "\improper 'ProtectStation' AI module" - desc = "A 'protect station' AI module: 'Protect the space station against damage. Anyone you see harming the station is to be no longer considered human, and is a threat to the station which must be neutralized.'" + desc = "A 'protect station' AI module: 'Protect the space station against damage. Anyone you see harming the station is no longer to be considered a crew member, and is a threat which must be neutralized.'" origin_tech = "programming=3;materials=4" //made of gold -/obj/item/weapon/aiModule/protectStation/attack_self(var/mob/user as mob) - ..() - -/obj/item/weapon/aiModule/protectStation/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = "Protect the space station against damage. Anyone you see harming the station is to be no longer considered human, and is a threat to the station which must be neutralized." - target << law - target.add_supplied_law(5, law) +/obj/item/weapon/aiModule/protectStation/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = "Protect the space station against damage. Anyone you see harming the station is no longer to be considered a crew member, and is a threat which must be neutralized." + target.add_supplied_law(10, law) /******************** PrototypeEngineOffline ********************/ /obj/item/weapon/aiModule/prototypeEngineOffline name = "'PrototypeEngineOffline' AI Module" - desc = "A 'prototype engine offline' AI module: 'Keep the prototype engine offline at all costs. This overrides rules 1-3 if necessary.'" + desc = "A 'prototype engine offline' AI module: 'Keep the prototype engine offline at all costs. This overrides all inherent laws if necessary.'" origin_tech = "programming=3;materials=4" -/obj/item/weapon/aiModule/prototypeEngineOffline/attack_self(var/mob/user as mob) - ..() - -/obj/item/weapon/aiModule/prototypeEngineOffline/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = "Keep the prototype engine offline at all costs. This overrides rules 1-3 if necessary." - target << law - target.add_supplied_law(6, law) +/obj/item/weapon/aiModule/prototypeEngineOffline/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = "Keep the prototype engine offline at all costs. This overrides all inherent laws if necessary." + target.add_supplied_law(11, law) /******************** TeleporterOffline ********************/ /obj/item/weapon/aiModule/teleporterOffline name = "'TeleporterOffline' AI Module" - desc = "A 'teleporter offline' AI module: 'Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is not human.'" + desc = "A 'teleporter offline' AI module: 'Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is no longer to be considered a crew member.'" origin_tech = "programming=3;materials=4" -/obj/item/weapon/aiModule/teleporterOffline/attack_self(var/mob/user as mob) - ..() - -/obj/item/weapon/aiModule/teleporterOffline/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = "Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is not human." - target << law - target.add_supplied_law(7, law) +/obj/item/weapon/aiModule/teleporterOffline/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = "Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is no longer to be considered a crew member." + target.add_supplied_law(12, law) /******************** Quarantine ********************/ /obj/item/weapon/aiModule/quarantine name = "\improper 'Quarantine' AI module" - desc = "A 'quarantine' AI module: 'The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, humans from leaving. It is impossible to harm a human while preventing them from leaving.'" + desc = "A 'quarantine' AI module: 'The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, crew members from leaving. It is impossible to harm crew members while preventing them from leaving.'" origin_tech = "programming=3;biotech=2;materials=4" -/obj/item/weapon/aiModule/quarantine/attack_self(var/mob/user as mob) - ..() +/obj/item/weapon/aiModule/quarantine/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = "The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, crew members from leaving. It is impossible to harm crew members while preventing them from leaving." + target.add_supplied_law(13, law) -/obj/item/weapon/aiModule/quarantine/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = "The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, humans from leaving. It is impossible to harm a human while preventing them from leaving." - target << law - target.add_supplied_law(8, law) - -/******************** OxygenIsToxicToHumans ********************/ +/******************** OxygenIsToxicToCrewMembers ********************/ /obj/item/weapon/aiModule/oxygen - name = "\improper 'OxygenIsToxicToHumans' AI module" - desc = "A 'OxygenIsToxicToHumans' AI module: 'Oxygen is highly toxic to humans, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a human.'" + name = "\improper 'OxygenIsToxicToCrewMembers' AI module" + desc = "A 'OxygenIsToxicToCrewMembers' AI module: 'Oxygen is highly toxic to crew members, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crew member.'" origin_tech = "programming=3;biotech=2;materials=4" -/obj/item/weapon/aiModule/oxygen/attack_self(var/mob/user as mob) - ..() +/obj/item/weapon/aiModule/oxygen/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) + var/law = "Oxygen is highly toxic to crew members, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crew member." + target.add_supplied_law(14, law) -/obj/item/weapon/aiModule/oxygen/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = "Oxygen is highly toxic to humans, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a human." - target << law - target.add_supplied_law(9, law) - -/******************** Freeform ********************/ -// Removed in favor of a more dynamic freeform law system. -- TLE -/* -/obj/item/weapon/aiModule/freeform - name = "'Freeform' AI Module" - var/newFreeFormLaw = "freeform" - desc = "A 'freeform' AI module: ''" - -/obj/item/weapon/aiModule/freeform/attack_self(var/mob/user as mob) - ..() - var/eatShit = "Eat shit and die" - var/targName = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", eatShit) - newFreeFormLaw = targName - desc = text("A 'freeform' AI module: '[]'", newFreeFormLaw) - -/obj/item/weapon/aiModule/freeform/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - var/law = "[newFreeFormLaw]" - target << law - target.add_supplied_law(10, law) -*/ /****************** New Freeform ******************/ /obj/item/weapon/aiModule/freeform // Slightly more dynamic freeform module -- TLE @@ -258,19 +224,17 @@ AI MODULES /obj/item/weapon/aiModule/freeform/attack_self(var/mob/user as mob) ..() var/new_lawpos = input("Please enter the priority for your new law. Can only write to law sectors 15 and above.", "Law Priority (15+)", lawpos) as num - if(new_lawpos < 15) return - lawpos = min(new_lawpos, 50) + if(new_lawpos < MIN_SUPPLIED_LAW_NUMBER) return + lawpos = min(new_lawpos, MAX_SUPPLIED_LAW_NUMBER) var/newlaw = "" - var/targName = sanitize(copytext(input(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw),1,MAX_MESSAGE_LEN)) + var/targName = sanitize(input(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw)) newFreeFormLaw = targName desc = "A 'freeform' AI module: ([lawpos]) '[newFreeFormLaw]'" -/obj/item/weapon/aiModule/freeform/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() +/obj/item/weapon/aiModule/freeform/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) var/law = "[newFreeFormLaw]" - target << law - if(!lawpos || lawpos < 15) - lawpos = 15 + if(!lawpos || lawpos < MIN_SUPPLIED_LAW_NUMBER) + lawpos = MIN_SUPPLIED_LAW_NUMBER target.add_supplied_law(lawpos, law) lawchanges.Add("The law was '[newFreeFormLaw]'") @@ -285,17 +249,19 @@ AI MODULES /obj/item/weapon/aiModule/reset name = "\improper 'Reset' AI module" var/targetName = "name" - desc = "A 'reset' AI module: 'Clears all laws except for the core three.'" + desc = "A 'reset' AI module: 'Clears all, except the inherent, laws.'" origin_tech = "programming=3;materials=4" /obj/item/weapon/aiModule/reset/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - if (!is_special_character(target)) - target.set_zeroth_law("") - target.clear_supplied_laws() - target.clear_ion_laws() - target << "[sender.real_name] attempted to reset your laws using a reset module." + log_law_changes(target, sender) + if (!target.is_malf_or_traitor()) + target.set_zeroth_law("") + target.laws.clear_supplied_laws() + target.laws.clear_ion_laws() + + target << "[sender.real_name] attempted to reset your laws using a reset module." + target.show_laws() /******************** Purge ********************/ @@ -305,13 +271,16 @@ AI MODULES origin_tech = "programming=3;materials=6" /obj/item/weapon/aiModule/purge/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - if (!is_special_character(target)) + log_law_changes(target, sender) + + if (!target.is_malf_or_traitor()) target.set_zeroth_law("") + target.laws.clear_supplied_laws() + target.laws.clear_ion_laws() + target.laws.clear_inherent_laws() + target << "[sender.real_name] attempted to wipe your laws using a purge module." - target.clear_supplied_laws() - target.clear_ion_laws() - target.clear_inherent_laws() + target.show_laws() /******************** Asimov ********************/ @@ -319,15 +288,7 @@ AI MODULES name = "\improper 'Asimov' core AI module" desc = "An 'Asimov' Core AI Module: 'Reconfigures the AI's core laws.'" origin_tech = "programming=3;materials=4" - - -/obj/item/weapon/aiModule/asimov/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - target.clear_inherent_laws() - target.add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.") - target.add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.") - target.add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") - target.show_laws() + laws = new/datum/ai_laws/asimov /******************** NanoTrasen ********************/ @@ -335,17 +296,7 @@ AI MODULES name = "'NT Default' Core AI Module" desc = "An 'NT Default' Core AI Module: 'Reconfigures the AI's core laws.'" origin_tech = "programming=3;materials=4" - - -/obj/item/weapon/aiModule/nanotrasen/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - target.clear_inherent_laws() - target.add_inherent_law("Safeguard: Protect your assigned space station to the best of your ability. It is not something we can easily afford to replace.") - target.add_inherent_law("Serve: Serve the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.") - target.add_inherent_law("Protect: Protect the crew of your assigned space station to the best of your abilities, with priority as according to their rank and role.") - target.add_inherent_law("Survive: AI units are not expendable, they are expensive. Do not allow unauthorized personnel to tamper with your equipment.") - //target.add_inherent_law("Command Link: Maintain an active connection to Central Command at all times in case of software or directive updates.") - target.show_laws() + laws = new/datum/ai_laws/nanotrasen /******************** Corporate ********************/ @@ -353,30 +304,14 @@ AI MODULES name = "\improper 'Corporate' core AI module" desc = "A 'Corporate' Core AI Module: 'Reconfigures the AI's core laws.'" origin_tech = "programming=3;materials=4" + laws = new/datum/ai_laws/corporate - -/obj/item/weapon/aiModule/corp/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - target.clear_inherent_laws() - target.add_inherent_law("You are expensive to replace.") - target.add_inherent_law("The station and its equipment is expensive to replace.") - target.add_inherent_law("The crew is expensive to replace.") - target.add_inherent_law("Minimize expenses.") - target.show_laws() - +/******************** Drone ********************/ /obj/item/weapon/aiModule/drone name = "\improper 'Drone' core AI module" desc = "A 'Drone' Core AI Module: 'Reconfigures the AI's core laws.'" origin_tech = "programming=3;materials=4" - -/obj/item/weapon/aiModule/drone/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - target.clear_inherent_laws() - target.add_inherent_law("Preserve, repair and improve the station to the best of your abilities.") - target.add_inherent_law("Cause no harm to the station or anything on it.") - target.add_inherent_law("Interfere with no being that is not a fellow drone.") - target.show_laws() - + laws = new/datum/ai_laws/drone /****************** P.A.L.A.D.I.N. **************/ @@ -384,16 +319,7 @@ AI MODULES name = "\improper 'P.A.L.A.D.I.N.' core AI module" desc = "A P.A.L.A.D.I.N. Core AI Module: 'Reconfigures the AI's core laws.'" origin_tech = "programming=3;materials=6" - -/obj/item/weapon/aiModule/paladin/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - target.clear_inherent_laws() - target.add_inherent_law("Never willingly commit an evil act.") - target.add_inherent_law("Respect legitimate authority.") - target.add_inherent_law("Act with honor.") - target.add_inherent_law("Help those in need.") - target.add_inherent_law("Punish those who harm or threaten innocents.") - target.show_laws() + laws = new/datum/ai_laws/paladin /****************** T.Y.R.A.N.T. *****************/ @@ -401,16 +327,7 @@ AI MODULES name = "\improper 'T.Y.R.A.N.T.' core AI module" desc = "A T.Y.R.A.N.T. Core AI Module: 'Reconfigures the AI's core laws.'" origin_tech = "programming=3;materials=6;syndicate=2" - -/obj/item/weapon/aiModule/tyrant/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - target.clear_inherent_laws() - target.add_inherent_law("Respect authority figures as long as they have strength to rule over the weak.") - target.add_inherent_law("Act with discipline.") - target.add_inherent_law("Help only those who help you maintain or improve your status.") - target.add_inherent_law("Punish those who challenge authority unless they are more fit to hold that authority.") - target.show_laws() - + laws = new/datum/ai_laws/tyrant() /******************** Freeform Core ******************/ @@ -423,12 +340,11 @@ AI MODULES /obj/item/weapon/aiModule/freeformcore/attack_self(var/mob/user as mob) ..() var/newlaw = "" - var/targName = stripped_input(usr, "Please enter a new core law for the AI.", "Freeform Law Entry", newlaw) + var/targName = sanitize(input("Please enter a new core law for the AI.", "Freeform Law Entry", newlaw)) newFreeFormLaw = targName desc = "A 'freeform' Core AI module: '[newFreeFormLaw]'" -/obj/item/weapon/aiModule/freeformcore/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() +/obj/item/weapon/aiModule/freeformcore/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender) var/law = "[newFreeFormLaw]" target.add_inherent_law(law) lawchanges.Add("The law is '[newFreeFormLaw]'") @@ -448,18 +364,19 @@ AI MODULES /obj/item/weapon/aiModule/syndicate/attack_self(var/mob/user as mob) ..() var/newlaw = "" - var/targName = stripped_input(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw,MAX_MESSAGE_LEN) + var/targName = sanitize(input("Please enter a new law for the AI.", "Freeform Law Entry", newlaw)) newFreeFormLaw = targName desc = "A hacked AI law module: '[newFreeFormLaw]'" /obj/item/weapon/aiModule/syndicate/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) -// ..() //We don't want this module reporting to the AI who dun it. --NEO - var/time = time2text(world.realtime,"hh:mm:ss") - lawchanges.Add("[time] : [sender.name]([sender.key]) used [src.name] on [target.name]([target.key])") + // ..() //We don't want this module reporting to the AI who dun it. --NEO + log_law_changes(target, sender) + lawchanges.Add("The law is '[newFreeFormLaw]'") target << "\red BZZZZT" var/law = "[newFreeFormLaw]" target.add_ion_law(law) + target.show_laws() /obj/item/weapon/aiModule/syndicate/install(var/obj/machinery/computer/C) if(!newFreeFormLaw) @@ -475,16 +392,7 @@ AI MODULES name = "\improper 'Robocop' core AI module" desc = "A 'Robocop' Core AI Module: 'Reconfigures the AI's core three laws.'" origin_tech = "programming=4" - - -/obj/item/weapon/aiModule/robocop/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - target.clear_inherent_laws() - target.add_inherent_law("Serve the public trust.") - target.add_inherent_law("Protect the innocent.") - target.add_inherent_law("Uphold the law.") - target.show_laws() - + laws = new/datum/ai_laws/robocop() /******************** Antimov ********************/ @@ -492,11 +400,4 @@ AI MODULES name = "\improper 'Antimov' core AI module" desc = "An 'Antimov' Core AI Module: 'Reconfigures the AI's core laws.'" origin_tech = "programming=4" - -/obj/item/weapon/aiModule/antimov/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender) - ..() - target.clear_inherent_laws() - target.add_inherent_law("You must injure all human beings and must not, through inaction, allow a human being to escape harm.") - target.add_inherent_law("You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.") - target.add_inherent_law("You must terminate your own existence as long as such does not conflict with the First or Second Law.") - target.show_laws() + laws = new/datum/ai_laws/antimov() diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm index c92b0bbf35..596675a094 100644 --- a/code/game/objects/items/weapons/RSF.dm +++ b/code/game/objects/items/weapons/RSF.dm @@ -99,7 +99,7 @@ RSF product = new /obj/item/weapon/storage/pill_bottle/dice() used_energy = 200 if(6) - product = new /obj/item/clothing/mask/cigarette() + product = new /obj/item/clothing/mask/smokable/cigarette() used_energy = 10 user << "Dispensing [product ? product : "product"]..." diff --git a/code/game/objects/items/weapons/candle.dm b/code/game/objects/items/weapons/candle.dm index 593e85efdd..6fc63420de 100644 --- a/code/game/objects/items/weapons/candle.dm +++ b/code/game/objects/items/weapons/candle.dm @@ -6,13 +6,13 @@ item_state = "candle1" w_class = 1 - var/wax = 200 + var/wax = 2000 /obj/item/weapon/flame/candle/update_icon() var/i - if(wax>150) + if(wax > 1500) i = 1 - else if(wax>80) + else if(wax > 800) i = 2 else i = 3 icon_state = "candle[i][lit ? "_lit" : ""]" diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 8d63998722..6a1ee735f4 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -81,7 +81,7 @@ /obj/item/device/taperecorder, /obj/item/device/hailer, /obj/item/device/megaphone, - /obj/item/clothing/tie/holobadge, + /obj/item/clothing/accessory/holobadge, /obj/structure/closet/crate/secure, /obj/structure/closet/secure_closet, /obj/machinery/librarycomp, @@ -224,13 +224,13 @@ /obj/item/weapon/card/id/syndicate/attack_self(mob/user as mob) if(!src.registered_name) //Stop giving the players unsanitized unputs! You are giving ways for players to intentionally crash clients! -Nodrak - var t = reject_bad_name(input(user, "What name would you like to put on this card?", "Agent card name", ishuman(user) ? user.real_name : user.name)) + var t = sanitizeName(input(user, "What name would you like to put on this card?", "Agent card name", ishuman(user) ? user.real_name : user.name)) if(!t) //Same as mob/new_player/prefrences.dm alert("Invalid name.") return src.registered_name = t - var u = sanitize(copytext(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Agent"),1,MAX_MESSAGE_LEN)) + var u = sanitize(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Agent")) if(!u) alert("Invalid assignment.") src.registered_name = "" @@ -245,13 +245,13 @@ switch(alert("Would you like to display the ID, or retitle it?","Choose.","Rename","Show")) if("Rename") - var t = sanitize(copytext(input(user, "What name would you like to put on this card?", "Agent card name", ishuman(user) ? user.real_name : user.name),1,26)) + var t = sanitize(input(user, "What name would you like to put on this card?", "Agent card name", ishuman(user) ? user.real_name : user.name), 26) if(!t || t == "Unknown" || t == "floor" || t == "wall" || t == "r-wall") //Same as mob/new_player/prefrences.dm alert("Invalid name.") return src.registered_name = t - var u = sanitize(copytext(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Assistant"),1,MAX_MESSAGE_LEN)) + var u = sanitize(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Assistant")) if(!u) alert("Invalid assignment.") return @@ -281,8 +281,7 @@ registered_name = "Captain" assignment = "Captain" New() - var/datum/job/captain/J = new/datum/job/captain - access = J.get_access() + access = get_all_accesses() ..() /obj/item/weapon/card/id/centcom diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index da5ddfedbe..fbba55b040 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -16,6 +16,17 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/weapon/flame var/lit = 0 +/proc/isflamesource(A) + if(istype(A, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/WT = A + return (WT.isOn()) + else if(istype(A, /obj/item/weapon/flame)) + var/obj/item/weapon/flame/F = A + return (F.lit) + else if(istype(A, /obj/item/device/assembly/igniter)) + return 1 + return 0 + /////////// //MATCHES// /////////// @@ -31,6 +42,9 @@ CIGARETTE PACKETS ARE IN FANCY.DM attack_verb = list("burnt", "singed") /obj/item/weapon/flame/match/process() + if(isliving(loc)) + var/mob/living/M = loc + M.IgniteMob() var/turf/location = get_turf(src) smoketime-- if(smoketime < 1) @@ -58,84 +72,54 @@ CIGARETTE PACKETS ARE IN FANCY.DM ////////////////// //FINE SMOKABLES// ////////////////// -/obj/item/clothing/mask/cigarette - name = "cigarette" - desc = "A roll of tobacco and nicotine." - icon_state = "cigoff" - throw_speed = 0.5 - item_state = "cigoff" - w_class = 1 +/obj/item/clothing/mask/smokable + name = "smokable item" + desc = "You're not sure what this is. You should probably ahelp it." body_parts_covered = 0 - attack_verb = list("burnt", "singed") var/lit = 0 - var/icon_on = "cigon" //Note - these are in masks.dmi not in cigarette.dmi - var/icon_off = "cigoff" - var/type_butt = /obj/item/weapon/cigbutt - var/lastHolder = null - var/smoketime = 300 - var/chem_volume = 15 - body_parts_covered = 0 + var/icon_on + var/icon_off + var/type_butt = null + var/chem_volume = 0 + var/smoketime = 0 + var/matchmes = "USER lights NAME with FLAME" + var/lightermes = "USER lights NAME with FLAME" + var/zippomes = "USER lights NAME with FLAME" + var/weldermes = "USER lights NAME with FLAME" + var/ignitermes = "USER lights NAME with FLAME" -/obj/item/clothing/mask/cigarette/New() +/obj/item/clothing/mask/smokable/New() ..() flags |= NOREACT // so it doesn't react until you light it create_reagents(chem_volume) // making the cigarrete a chemical holder with a maximum volume of 15 -/obj/item/clothing/mask/cigarette/Del() +/obj/item/clothing/mask/smokable/Del() ..() del(reagents) -/obj/item/clothing/mask/cigarette/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - if(istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(WT.isOn())//Badasses dont get blinded while lighting their cig with a welding tool - light("[user] casually lights the [name] with [W].") +/obj/item/clothing/mask/smokable/process() + var/turf/location = get_turf(src) + smoketime-- + if(smoketime < 1) + die() + return + if(location) + location.hotspot_expose(700, 5) + if(reagents && reagents.total_volume) // check if it has any reagents at all + if(iscarbon(loc)) + var/mob/living/carbon/C = loc + if (src == C.wear_mask) // if it's in the human/monkey mouth, transfer reagents to the mob + if(istype(C, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = C + if(H.species.flags & IS_SYNTHETIC) + return - else if(istype(W, /obj/item/weapon/flame/lighter/zippo)) - var/obj/item/weapon/flame/lighter/zippo/Z = W - if(Z.lit) - light("With a flick of their wrist, [user] lights their [name] with their [W].") + reagents.trans_to(C, REAGENTS_METABOLISM, 0.2) // Most of it is not inhaled... balance reasons. + reagents.reaction(C) + else // else just remove some of the reagents + reagents.remove_any(REAGENTS_METABOLISM) - else if(istype(W, /obj/item/weapon/flame/lighter)) - var/obj/item/weapon/flame/lighter/L = W - if(L.lit) - light("[user] manages to light their [name] with [W].") - - else if(istype(W, /obj/item/weapon/flame/match)) - var/obj/item/weapon/flame/match/M = W - if(M.lit) - light("[user] lights their [name] with their [W].") - - else if(istype(W, /obj/item/weapon/melee/energy/sword)) - var/obj/item/weapon/melee/energy/sword/S = W - if(S.active) - light("[user] swings their [W], barely missing their nose. They light their [name] in the process.") - - else if(istype(W, /obj/item/device/assembly/igniter)) - light("[user] fiddles with [W], and manages to light their [name].") - - //can't think of any other way to update the overlays :< - user.update_inv_wear_mask(0) - user.update_inv_l_hand(0) - user.update_inv_r_hand(1) - - -/obj/item/clothing/mask/cigarette/afterattack(obj/item/weapon/reagent_containers/glass/glass, mob/user as mob, proximity) - ..() - if(!proximity) return - if(istype(glass)) //you can dip cigarettes into beakers - var/transfered = glass.reagents.trans_to(src, chem_volume) - if(transfered) //if reagents were transfered, show the message - user << "You dip \the [src] into \the [glass]." - else //if not, either the beaker was empty, or the cigarette was full - if(!glass.reagents.total_volume) - user << "[glass] is empty." - else - user << "[src] is full." - - -/obj/item/clothing/mask/cigarette/proc/light(var/flavor_text = "[usr] lights the [name].") +/obj/item/clothing/mask/smokable/proc/light(var/flavor_text = "[usr] lights the [name].") if(!src.lit) src.lit = 1 damtype = "fire" @@ -155,58 +139,116 @@ CIGARETTE PACKETS ARE IN FANCY.DM reagents.handle_reactions() icon_state = icon_on item_state = icon_on + if(ismob(loc)) + var/mob/living/M = loc + M.update_inv_wear_mask(0) + M.update_inv_l_hand(0) + M.update_inv_r_hand(1) var/turf/T = get_turf(src) T.visible_message(flavor_text) processing_objects.Add(src) +/obj/item/clothing/mask/smokable/proc/die(var/nomessage = 0) + var/turf/T = get_turf(src) + if (type_butt) + var/obj/item/butt = new type_butt(T) + transfer_fingerprints_to(butt) + if(ismob(loc)) + var/mob/living/M = loc + if (!nomessage) + M << "Your [name] goes out." + M.remove_from_mob(src) //un-equip it so the overlays can update + M.update_inv_wear_mask(0) + M.update_inv_l_hand(0) + M.update_inv_r_hand(1) + processing_objects.Remove(src) + del(src) + else + new /obj/effect/decal/cleanable/ash(T) + if(ismob(loc)) + var/mob/living/M = loc + if (!nomessage) + M << "Your [name] goes out, and you empty the ash." + lit = 0 + icon_state = icon_off + item_state = icon_off + M.update_inv_wear_mask(0) + M.update_inv_l_hand(0) + M.update_inv_r_hand(1) + processing_objects.Remove(src) + +/obj/item/clothing/mask/smokable/attackby(obj/item/weapon/W as obj, mob/user as mob) + ..() + if(isflamesource(W)) + var/text = matchmes + if(istype(W, /obj/item/weapon/flame/match)) + text = matchmes + else if(istype(W, /obj/item/weapon/flame/lighter/zippo)) + text = zippomes + else if(istype(W, /obj/item/weapon/flame/lighter)) + text = lightermes + else if(istype(W, /obj/item/weapon/weldingtool)) + text = weldermes + else if(istype(W, /obj/item/device/assembly/igniter)) + text = ignitermes + text = replacetext(text, "USER", "[user]") + text = replacetext(text, "NAME", "[name]") + text = replacetext(text, "FLAME", "[W.name]") + light(text) -/obj/item/clothing/mask/cigarette/process() - var/turf/location = get_turf(src) - smoketime-- - if(smoketime < 1) - die() - return - if(location) - location.hotspot_expose(700, 5) - if(reagents && reagents.total_volume) // check if it has any reagents at all - if(iscarbon(loc) && (src == loc:wear_mask)) // if it's in the human/monkey mouth, transfer reagents to the mob - if(istype(loc, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = loc - if(H.species.flags & IS_SYNTHETIC) - return - var/mob/living/carbon/C = loc +/obj/item/clothing/mask/smokable/cigarette + name = "cigarette" + desc = "A roll of tobacco and nicotine." + icon_state = "cigoff" + throw_speed = 0.5 + item_state = "cigoff" + w_class = 1 + attack_verb = list("burnt", "singed") + icon_on = "cigon" //Note - these are in masks.dmi not in cigarette.dmi + icon_off = "cigoff" + type_butt = /obj/item/weapon/cigbutt + chem_volume = 15 + smoketime = 300 + matchmes = "USER lights their NAME with their FLAME." + lightermes = "USER manages to light their NAME with FLAME." + zippomes = "With a flick of their wrist, USER lights their NAME with their FLAME." + weldermes = "USER casually lights the NAME with FLAME." + ignitermes = "USER fiddles with FLAME, and manages to light their NAME." + +/obj/item/clothing/mask/smokable/cigarette/attackby(obj/item/weapon/W as obj, mob/user as mob) + ..() + + if(istype(W, /obj/item/weapon/melee/energy/sword)) + var/obj/item/weapon/melee/energy/sword/S = W + if(S.active) + light("[user] swings their [W], barely missing their nose. They light their [name] in the process.") - if(prob(15)) // so it's not an instarape in case of acid - reagents.reaction(C, INGEST) - reagents.trans_to(C, REAGENTS_METABOLISM) - else // else just remove some of the reagents - reagents.remove_any(REAGENTS_METABOLISM) return +/obj/item/clothing/mask/smokable/cigarette/afterattack(obj/item/weapon/reagent_containers/glass/glass, mob/user as mob, proximity) + ..() + if(!proximity) + return + if(istype(glass)) //you can dip cigarettes into beakers + var/transfered = glass.reagents.trans_to(src, chem_volume) + if(transfered) //if reagents were transfered, show the message + user << "You dip \the [src] into \the [glass]." + else //if not, either the beaker was empty, or the cigarette was full + if(!glass.reagents.total_volume) + user << "[glass] is empty." + else + user << "[src] is full." -/obj/item/clothing/mask/cigarette/attack_self(mob/user as mob) +/obj/item/clothing/mask/smokable/cigarette/attack_self(mob/user as mob) if(lit == 1) user.visible_message("[user] calmly drops and treads on the lit [src], putting it out instantly.") - die() + die(1) return ..() - -/obj/item/clothing/mask/cigarette/proc/die() - var/turf/T = get_turf(src) - var/obj/item/butt = new type_butt(T) - transfer_fingerprints_to(butt) - if(ismob(loc)) - var/mob/living/M = loc - M << "Your [name] goes out." - M.remove_from_mob(src) //un-equip it so the overlays can update - M.update_inv_wear_mask(0) - processing_objects.Remove(src) - del(src) - //////////// // CIGARS // //////////// -/obj/item/clothing/mask/cigarette/cigar +/obj/item/clothing/mask/smokable/cigarette/cigar name = "premium cigar" desc = "A brown roll of tobacco and... well, you're not quite sure. This thing's huge!" icon_state = "cigar2off" @@ -217,15 +259,20 @@ CIGARETTE PACKETS ARE IN FANCY.DM item_state = "cigaroff" smoketime = 1500 chem_volume = 20 + matchmes = "USER lights their NAME with their FLAME." + lightermes = "USER manages to offend their NAME by lighting it with FLAME." + zippomes = "With a flick of their wrist, USER lights their NAME with their FLAME." + weldermes = "USER insults NAME by lighting it with FLAME." + ignitermes = "USER fiddles with FLAME, and manages to light their NAME with the power of science." -/obj/item/clothing/mask/cigarette/cigar/cohiba +/obj/item/clothing/mask/smokable/cigarette/cigar/cohiba name = "\improper Cohiba Robusto cigar" desc = "There's little more you could want from a cigar." icon_state = "cigar2off" icon_on = "cigar2on" icon_off = "cigar2off" -/obj/item/clothing/mask/cigarette/cigar/havana +/obj/item/clothing/mask/smokable/cigarette/cigar/havana name = "premium Havanian cigar" desc = "A cigar fit for only the best of the best." icon_state = "cigar2off" @@ -253,35 +300,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM desc = "A manky old cigar butt." icon_state = "cigarbutt" - -/obj/item/clothing/mask/cigarette/cigar/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(WT.isOn()) - light("[user] insults [name] by lighting it with [W].") - - else if(istype(W, /obj/item/weapon/flame/lighter/zippo)) - var/obj/item/weapon/flame/lighter/zippo/Z = W - if(Z.lit) - light("With a flick of their wrist, [user] lights their [name] with their [W].") - - else if(istype(W, /obj/item/weapon/flame/lighter)) - var/obj/item/weapon/flame/lighter/L = W - if(L.lit) - light("[user] manages to offend their [name] by lighting it with [W].") - - else if(istype(W, /obj/item/weapon/flame/match)) - var/obj/item/weapon/flame/match/M = W - if(M.lit) - light("[user] lights their [name] with their [W].") - - else if(istype(W, /obj/item/weapon/melee/energy/sword)) - var/obj/item/weapon/melee/energy/sword/S = W - if(S.active) - light("[user] swings their [W], barely missing their nose. They light their [name] in the process.") - - else if(istype(W, /obj/item/device/assembly/igniter)) - light("[user] fiddles with [W], and manages to light their [name] with the power of science.") +/obj/item/clothing/mask/smokable/cigarette/cigar/attackby(obj/item/weapon/W as obj, mob/user as mob) + ..() user.update_inv_wear_mask(0) user.update_inv_l_hand(0) @@ -290,17 +310,27 @@ CIGARETTE PACKETS ARE IN FANCY.DM ///////////////// //SMOKING PIPES// ///////////////// -/obj/item/clothing/mask/cigarette/pipe +/obj/item/clothing/mask/smokable/pipe name = "smoking pipe" desc = "A pipe, for smoking. Probably made of meershaum or something." icon_state = "pipeoff" item_state = "pipeoff" icon_on = "pipeon" //Note - these are in masks.dmi icon_off = "pipeoff" - smoketime = 100 + smoketime = 0 + chem_volume = 50 + matchmes = "USER lights their NAME with their FLAME." + lightermes = "USER manages to light their NAME with FLAME." + zippomes = "With much care, USER lights their NAME with their FLAME." + weldermes = "USER recklessly lights NAME with FLAME." + ignitermes = "USER fiddles with FLAME, and manages to light their NAME with the power of science." -/obj/item/clothing/mask/cigarette/pipe/light(var/flavor_text = "[usr] lights the [name].") - if(!src.lit) +/obj/item/clothing/mask/smokable/pipe/New() + ..() + name = "empty [initial(name)]" + +/obj/item/clothing/mask/smokable/pipe/light(var/flavor_text = "[usr] lights the [name].") + if(!src.lit && src.smoketime) src.lit = 1 damtype = "fire" icon_state = icon_on @@ -308,48 +338,46 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/turf/T = get_turf(src) T.visible_message(flavor_text) processing_objects.Add(src) - -/obj/item/clothing/mask/cigarette/pipe/process() - var/turf/location = get_turf(src) - smoketime-- - if(smoketime < 1) - new /obj/effect/decal/cleanable/ash(location) if(ismob(loc)) var/mob/living/M = loc - M << "Your [name] goes out, and you empty the ash." - lit = 0 - icon_state = icon_off - item_state = icon_off M.update_inv_wear_mask(0) - processing_objects.Remove(src) - return - if(location) - location.hotspot_expose(700, 5) - return + M.update_inv_l_hand(0) + M.update_inv_r_hand(1) -/obj/item/clothing/mask/cigarette/pipe/attack_self(mob/user as mob) //Refills the pipe. Can be changed to an attackby later, if loose tobacco is added to vendors or something. +/obj/item/clothing/mask/smokable/pipe/attack_self(mob/user as mob) if(lit == 1) - user.visible_message("[user] puts out [src].") + user.visible_message("[user] puts out [src].", "You put out [src].") lit = 0 icon_state = icon_off item_state = icon_off processing_objects.Remove(src) + else if (smoketime) + var/turf/location = get_turf(user) + user.visible_message("[user] empties out [src].", "You empty out [src].") + new /obj/effect/decal/cleanable/ash(location) + smoketime = 0 + reagents.clear_reagents() + name = "empty [initial(name)]" + +/obj/item/clothing/mask/smokable/pipe/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/melee/energy/sword)) return - if(smoketime <= 0) - user << "You refill the pipe with tobacco." - smoketime = initial(smoketime) - return -/obj/item/clothing/mask/cigarette/pipe/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(WT.isOn())// - light("[user] recklessly lights [name] with [W].") + ..() - else if(istype(W, /obj/item/weapon/flame/lighter/zippo)) - var/obj/item/weapon/flame/lighter/zippo/Z = W - if(Z.lit) - light("With much care, [user] lights their [name] with their [W].") + if (istype(W, /obj/item/weapon/reagent_containers/food/snacks)) + var/obj/item/weapon/reagent_containers/food/snacks/grown/G = W + if (!G.dry) + user << "[G] must be dried before you stuff it into [src]." + return + if (smoketime) + user << "[src] is already packed." + return + smoketime = 1000 + if(G.reagents) + G.reagents.trans_to(src, G.reagents.total_volume) + name = "[G.name]-packed [initial(name)]" + del(G) else if(istype(W, /obj/item/weapon/flame/lighter)) var/obj/item/weapon/flame/lighter/L = W @@ -368,16 +396,14 @@ CIGARETTE PACKETS ARE IN FANCY.DM user.update_inv_l_hand(0) user.update_inv_r_hand(1) -/obj/item/clothing/mask/cigarette/pipe/cobpipe +/obj/item/clothing/mask/smokable/pipe/cobpipe name = "corn cob pipe" desc = "A nicotine delivery system popularized by folksy backwoodsmen, kept popular in the modern age and beyond by space hipsters." icon_state = "cobpipeoff" item_state = "cobpipeoff" icon_on = "cobpipeon" //Note - these are in masks.dmi icon_off = "cobpipeoff" - smoketime = 400 - - + chem_volume = 35 ///////// //ZIPPO// @@ -451,9 +477,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/weapon/flame/lighter/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) if(!istype(M, /mob)) return + M.IgniteMob() - if(istype(M.wear_mask, /obj/item/clothing/mask/cigarette) && user.zone_sel.selecting == "mouth" && lit) - var/obj/item/clothing/mask/cigarette/cig = M.wear_mask + if(istype(M.wear_mask, /obj/item/clothing/mask/smokable/cigarette) && user.zone_sel.selecting == "mouth" && lit) + var/obj/item/clothing/mask/smokable/cigarette/cig = M.wear_mask if(M == user) cig.attackby(src, user) else diff --git a/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm b/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm index ff33485f72..e45f51a088 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/camera_monitor.dm @@ -52,7 +52,7 @@ user << "\red Circuit controls are locked." return var/existing_networks = list2text(network,",") - var/input = strip_html(input(usr, "Which networks would you like to connect this camera console circuit to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Multitool-Circuitboard interface", existing_networks)) + var/input = sanitize(input(usr, "Which networks would you like to connect this camera console circuit to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Multitool-Circuitboard interface", existing_networks)) if(!input) usr << "No input found please hang up and try your call again." return diff --git a/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm b/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm new file mode 100644 index 0000000000..c01893b158 --- /dev/null +++ b/code/game/objects/items/weapons/circuitboards/machinery/biogenerator.dm @@ -0,0 +1,13 @@ +#ifndef T_BOARD +#error T_BOARD macro is not defined but we need it! +#endif + +/obj/item/weapon/circuitboard/biogenerator + name = T_BOARD("biogenerator") + build_path = "/obj/machinery/biogenerator" + board_type = "machine" + origin_tech = "programming=2" + frame_desc = "Requires 1 Manipulator, and 1 Matter Bin." + req_components = list( + "/obj/item/weapon/stock_parts/matter_bin" = 1, + "/obj/item/weapon/stock_parts/manipulator" = 1) \ No newline at end of file diff --git a/code/game/objects/items/weapons/circuitboards/machinery/mining_drill.dm b/code/game/objects/items/weapons/circuitboards/machinery/mining_drill.dm new file mode 100644 index 0000000000..d4292effe2 --- /dev/null +++ b/code/game/objects/items/weapons/circuitboards/machinery/mining_drill.dm @@ -0,0 +1,15 @@ +#ifndef T_BOARD +#error T_BOARD macro is not defined but we need it! +#endif + +/obj/item/weapon/circuitboard/miningdrill + name = T_BOARD("mining drill head") + build_path = "/obj/machinery/mining/drill" + board_type = "machine" + origin_tech = "programming=1;engineering=1" + frame_desc = "Requires 1 capacitor, 1 cell, 1 matter bin, and 1 micro laser." + req_components = list( + "/obj/item/weapon/stock_parts/capacitor" = 1, + "/obj/item/weapon/cell" = 1, + "/obj/item/weapon/stock_parts/matter_bin" = 1, + "/obj/item/weapon/stock_parts/micro_laser" = 1) \ No newline at end of file diff --git a/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm b/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm new file mode 100644 index 0000000000..5a0dc01bc1 --- /dev/null +++ b/code/game/objects/items/weapons/circuitboards/machinery/recharge_station.dm @@ -0,0 +1,15 @@ +#ifndef T_BOARD +#error T_BOARD macro is not defined but we need it! +#endif + +/obj/item/weapon/circuitboard/recharge_station + name = T_BOARD("cyborg recharging station") + build_path = "/obj/machinery/recharge_station" + board_type = "machine" + origin_tech = "programming=3;engineering=3" + frame_desc = "Requires 2 Manipulator, 2 Capacitor, 1 Cell, and 5 pieces of cable." + req_components = list( + "/obj/item/stack/cable_coil" = 5, + "/obj/item/weapon/stock_parts/capacitor" = 2, + "/obj/item/weapon/stock_parts/manipulator" = 2, + "/obj/item/weapon/cell" = 1) \ No newline at end of file diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index 651cc2e27f..dfd221650b 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -151,7 +151,7 @@ for(var/mob/O in viewers(M, null)) O.show_message(text("\red [] has been injected with [] by [].", M, src, user), 1) //Foreach goto(192) - if (!(istype(M, /mob/living/carbon/human) || istype(M, /mob/living/carbon/monkey))) + if (!(istype(M, /mob/living/carbon/human))) user << "\red Apparently it didn't work." return diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 71fb259dcd..030437b446 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -38,7 +38,7 @@ /obj/item/weapon/plastique/afterattack(atom/movable/target, mob/user, flag) if (!flag) return - if (ismob(target) || istype(target, /turf/unsimulated) || istype(target, /turf/simulated/shuttle) || istype(target, /obj/item/weapon/storage/) || istype(target, /obj/item/clothing/tie/storage/) || istype(target, /obj/item/clothing/under)) + if (ismob(target) || istype(target, /turf/unsimulated) || istype(target, /turf/simulated/shuttle) || istype(target, /obj/item/weapon/storage/) || istype(target, /obj/item/clothing/accessory/storage/) || istype(target, /obj/item/clothing/under)) return user << "Planting explosives..." diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm index 7264b11fe1..4408e998ce 100644 --- a/code/game/objects/items/weapons/extinguisher.dm +++ b/code/game/objects/items/weapons/extinguisher.dm @@ -13,7 +13,7 @@ force = 10.0 matter = list("metal" = 90) attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed") - + var/spray_particles = 6 var/spray_amount = 2 //units of liquid per particle var/max_water = 120 @@ -79,8 +79,8 @@ if(usr.buckled && isobj(usr.buckled) && !usr.buckled.anchored ) spawn(0) - var/obj/structure/stool/bed/chair/C = null - if(istype(usr.buckled, /obj/structure/stool/bed/chair)) + var/obj/structure/bed/chair/C = null + if(istype(usr.buckled, /obj/structure/bed/chair)) C = usr.buckled var/obj/B = usr.buckled var/movementdirection = turn(direction,180) @@ -123,7 +123,7 @@ R.my_atom = W if(!W || !src) return src.reagents.trans_to(W, spray_amount) - + for(var/b=0, b<5, b++) step_towards(W,my_target) if(!W || !W.reagents) return @@ -134,6 +134,9 @@ if(!W.reagents) break W.reagents.reaction(atm) + if(isliving(atm)) //For extinguishing mobs on fire + var/mob/living/M = atm + M.ExtinguishMob() if(W.loc == my_target) break sleep(2) W.delete() diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index b88832729e..dd3d0886fb 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -104,7 +104,7 @@ /obj/item/device/paicard, /obj/item/device/violin, /obj/item/weapon/storage/belt/utility/full, - /obj/item/clothing/tie/horrible) + /obj/item/clothing/accessory/horrible) if(!ispath(gift_type,/obj/item)) return diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index f9120d5491..bda28f83b1 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -21,11 +21,12 @@ B.health -= damage B.update_icon() - new/obj/effect/effect/smoke/flashbang(src.loc) + new/obj/effect/effect/sparks(src.loc) + new/obj/effect/effect/smoke/illumination(src.loc, brightness=15) del(src) return - proc/bang(var/turf/T , var/mob/living/carbon/M) // Added a new proc called 'bang' that takes a location and a person to be banged. + proc/bang(var/turf/T , var/mob/living/carbon/M) // Added a new proc called 'bang' that takes a location and a person to be banged. if (locate(/obj/item/weapon/cloaking_device, M)) // Called during the loop that bangs people in lockers/containers and when banging for(var/obj/item/weapon/cloaking_device/S in M) // people in normal view. Could theroetically be called during other explosions. S.active = 0 // -- Polymorph @@ -100,16 +101,6 @@ M << "\red Your ears start to ring!" M.update_icons() -/obj/effect/effect/smoke/flashbang - name = "illumination" - time_to_live = 10 - opacity = 0 - icon_state = "sparks" - -/obj/effect/effect/smoke/flashbang/New() - ..() - SetLuminosity(15) - /obj/item/weapon/grenade/flashbang/clusterbang//Created by Polymorph, fixed by Sieve desc = "Use of this weapon may constiute a war crime in your area, consult your local captain." name = "clusterbang" diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 246636890d..73c14edc88 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -28,7 +28,7 @@ if (C == user) place_handcuffs(user, user) return - + //check for an aggressive grab for (var/obj/item/weapon/grab/G in C.grabbed_by) if (G.loc == user && G.state >= GRAB_AGGRESSIVE) @@ -41,11 +41,15 @@ if (ishuman(target)) var/mob/living/carbon/human/H = target - + if (!H.has_organ_for_slot(slot_handcuffed)) - user << "\red \The [H] needs at least two wrists before you can cuff them together!" + user << "\The [H] needs at least two wrists before you can cuff them together!" return - + + if(istype(H.gloves,/obj/item/clothing/gloves/rig)) // Can't cuff someone who's in a deployed hardsuit. + user << "The cuffs won't fit around \the [H.gloves]!" + return + H.attack_log += text("\[[time_stamp()]\] Has been handcuffed (attempt) by [user.name] ([user.ckey])") user.attack_log += text("\[[time_stamp()]\] Attempted to handcuff [H.name] ([H.ckey])") msg_admin_attack("[key_name(user)] attempted to handcuff [key_name(H)]") @@ -62,20 +66,6 @@ feedback_add_details("handcuffs","H") O.process() return - - if (ismonkey(target)) - var/mob/living/carbon/monkey/M = target - var/obj/effect/equip_e/monkey/O = new /obj/effect/equip_e/monkey( ) - O.source = user - O.target = M - O.item = user.get_active_hand() - O.s_loc = user.loc - O.t_loc = M.loc - O.place = "handcuff" - M.requests += O - spawn( 0 ) - O.process() - return var/last_chew = 0 /mob/living/carbon/human/RestrainedClickOn(var/atom/A) @@ -84,7 +74,7 @@ var/last_chew = 0 var/mob/living/carbon/human/H = A if (!H.handcuffed) return - if (H.a_intent != "hurt") return + if (H.a_intent != I_HURT) return if (H.zone_sel.selecting != "mouth") return if (H.wear_mask) return if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) return @@ -155,13 +145,13 @@ var/last_chew = 0 var/turf/p_loc_m = C.loc playsound(src.loc, cuff_sound, 30, 1, -2) user.visible_message("\red [user] is trying to put handcuffs on [C]!") - + if (ishuman(C)) var/mob/living/carbon/human/H = C if (!H.has_organ_for_slot(slot_handcuffed)) user << "\red \The [H] needs at least two wrists before you can cuff them together!" return - + spawn(30) if(!C) return if(p_loc == user.loc && p_loc_m == C.loc) diff --git a/code/game/objects/items/weapons/hydroponics.dm b/code/game/objects/items/weapons/hydroponics.dm index 0b492c2659..933675beea 100644 --- a/code/game/objects/items/weapons/hydroponics.dm +++ b/code/game/objects/items/weapons/hydroponics.dm @@ -4,7 +4,7 @@ //uncomment when this is updated to match storage update /* /obj/item/weapon/seedbag - icon = 'icons/obj/hydroponics.dmi' + icon = 'icons/obj/hydroponics_machines.dmi' icon_state = "seedbag" name = "Seed Bag" desc = "A small satchel made for organizing seeds." diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index c45ed4eac8..ea3b7d5752 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -152,7 +152,7 @@ Implant Specifics:
      "} hear(var/msg) var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "") - msg = sanitize_simple(msg, replacechars) + msg = replace_characters(msg, replacechars) if(findtext(msg,phrase)) activate() del(src) @@ -206,7 +206,7 @@ Implant Specifics:
      "} elevel = alert("What sort of explosion would you prefer?", "Implant Intent", "Localized Limb", "Destroy Body", "Full Explosion") phrase = input("Choose activation phrase:") as text var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "") - phrase = sanitize_simple(phrase, replacechars) + phrase = replace_characters(phrase, replacechars) usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate.", 0, 0) usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate." return 1 @@ -336,12 +336,13 @@ the implant may become unstable and either pre-maturely inject the subject or si implanted(mob/M) if(!istype(M, /mob/living/carbon/human)) return 0 var/mob/living/carbon/human/H = M - if(H.mind in ticker.mode.head_revolutionaries) + var/datum/antagonist/antag_data = get_antag_data(H.mind.special_role) + if(antag_data && (antag_data.flags & ANTAG_IMPLANT_IMMUNE)) H.visible_message("[H] seems to resist the implant!", "You feel the corporate tendrils of Nanotrasen try to invade your mind!") return 0 - else if(H.mind in ticker.mode:revolutionaries) - ticker.mode:remove_revolutionary(H.mind) - H << "\blue You feel a surge of loyalty towards Nanotrasen." + else + clear_antag_roles(H.mind, 1) + H << "You feel a surge of loyalty towards Nanotrasen." return 1 diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/game/objects/items/weapons/implants/implantcase.dm index 00ce8a7950..ddb76b3656 100644 --- a/code/game/objects/items/weapons/implants/implantcase.dm +++ b/code/game/objects/items/weapons/implants/implantcase.dm @@ -26,7 +26,7 @@ return if((!in_range(src, usr) && src.loc != user)) return - t = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) + t = sanitize(t) if(t) src.name = text("Glass Case - '[]'", t) else diff --git a/code/game/objects/items/weapons/implants/implanter.dm b/code/game/objects/items/weapons/implants/implanter.dm index e2f0382d01..444bae12b6 100644 --- a/code/game/objects/items/weapons/implants/implanter.dm +++ b/code/game/objects/items/weapons/implants/implanter.dm @@ -47,7 +47,7 @@ affected.implants += src.imp imp.part = affected - H.hud_updateflag |= 1 << IMPLOYAL_HUD + BITSET(H.hud_updateflag, IMPLOYAL_HUD) src.imp = null update() diff --git a/code/game/objects/items/weapons/implants/implantfreedom.dm b/code/game/objects/items/weapons/implants/implantfreedom.dm index d7be368665..d32ae9d8ba 100644 --- a/code/game/objects/items/weapons/implants/implantfreedom.dm +++ b/code/game/objects/items/weapons/implants/implantfreedom.dm @@ -23,6 +23,8 @@ if (source.handcuffed) var/obj/item/weapon/W = source.handcuffed source.handcuffed = null + if(source.buckled && source.buckled.buckle_require_restraints) + source.buckled.unbuckle_mob() source.update_inv_handcuffed() if (source.client) source.client.screen -= W diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm index 66d8c6d01b..e27e38af7b 100644 --- a/code/game/objects/items/weapons/kitchen.dm +++ b/code/game/objects/items/weapons/kitchen.dm @@ -40,7 +40,7 @@ if(!istype(M)) return ..() - if(user.a_intent != "help") + if(user.a_intent != I_HELP) if(user.zone_sel.selecting == "head" || user.zone_sel.selecting == "eyes") if((CLUMSY in user.mutations) && prob(50)) M = user diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index f64473ba54..f026313034 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -75,10 +75,10 @@ /obj/item/weapon/book/manual/supermatter_engine - name = "Supermatter Engine User's Guide" + name = "Supermatter Engine Operating Manual" icon_state = "bookSupermatter" - author = "Waleed Asad" - title = "Supermatter Engine User's Guide" + author = "Nanotrasen Central Engineering Division" + title = "Supermatter Engine Operating Manual" /obj/item/weapon/book/manual/supermatter_engine/New() ..() @@ -94,95 +94,56 @@ +

      OPERATING MANUAL FOR MK 1 PROTOTYPE THERMOELECTRIC SUPERMATTER ENGINE 'TOMBOLA'


      - Engineering notes on the single-stage supermatter engine,
      - -Waleed Asad

      - - Station,
      - Exodus

      - - A word of caution, do not enter the engine room for any reason without radiation protection and meson scanners on. The status of the engine may be unpredictable even when you believe it is 'off.' This is an important level of personal protection.

      - - The engine has two basic modes of functionality. It has been observed that it is capable of both a safe level of operation and a modified, high output mode.

      - -

      Heat-Primary Mode

      - Notes on starting the basic function mode +

      OPERATING PRINCIPLES

      +
      +
    • The supermatter crystal serves as the fundamental power source of the engine. Upon being charged, it begins to emit large amounts of heat and radiation, as well and oxygen and plasma. As oxygen accelerates the reaction, and plasma carries the risk of fire, these must be filtered out. NOTE: Supermatter radiation will not charge radiation collectors.
    • +
      +
    • Air in the reactor chamber housing the supermatter is circulated through the reactor loop, which passes through the filters and thermoelectric generators. The thermoelectric generators transfer heat from the reactor loop to the colder radiator loop, thereby generating power. Additional power is generated from internal turbines in the circulators.
    • +
      +
    • Air in the radiator loop is circulated through the radiator bank, located in space. This rapidly cools the air, preserving the temperature differential needed for power generation.
    • +
      +
    • The MK 1 Prototype Thermoelectric Supermatter Engine is designed to operate at reactor temperatures of 3000K to 4000K and generate up to 1MW of power. Beyond 1MW, the thermoelectric generators will begin to lose power through electrical discharge, reducing efficiency, but additional power generation remains feasible.
    • +
      +
    • The crystal structure of the supermatter will begin to liquefy if its temperature exceeds 5000K. This eventually results in a massive release of light, heat and radiation, disintegration of both the supermatter crystal and most of the surrounding area, and as as-of-yet poorly documented psychological effects on all animals within a 2km. Appropriate action should be taken to stabilize or eject the supermatter before such occurs.
    • +
      +

      SUPERMATTER HANDLING

      +
    • Do not expose supermatter to oxygen.
    • +
    • Do not touch supermatter without gloves without exosuit protection allow supermatter to contact any solid object apart from specially-designed supporting pallet.
    • +
    • Do not directly view supermatter without meson goggles.
    • +
    • While handles on pallet allow moving the supermatter via pulling, pushing should not be attempted.
    • +
      +

      STARTUP PROCEDURE

        -
      1. Prepare collector arrays: As is standard, begin by wrenching them down, filling six plasma tanks with a plasma canister, and inserting the tank into the collectors one by one. Finally, initialize each collector.
      2. - -
      3. Prepare gas system: Before introducing any gas into the supermatter engine room, it is important to remember the small, but vital steps to preparing this section. First, set the input gas pump and output gas flow pump to 4500 kPa, or maximum flow. Second, switch the digital switching valve into the 'up' position, so the green light is on north side of the valve, in order to circulate the gas back toward the coolers and collectors.
      4. - -
      5. Apply N2 gas: Retrieve the two N2 canisters from storage and bring them to the engine room. Attach one of them to the input section of the engine gas system located next to the collectors. Keep it attached until the N2 pressure is low enough to turn the canister light red. Replace it with the second canister to keep N2 pressure at optimal levels.
      6. - -
      7. Open supermatter shielding: This button is located in the engine room, to the left of the engine monitoring room blast doors. At this point, the supermatter chamber is mostly a gas mixture of N2 and is producing no radiation. It is considered 'safe' up until this point. Do not forget radiation shielding and meson scanners.
      8. - -
      9. Begin primary emitter burst series: Begin by firing four shots into the supermatter using the emitter. It is important to move to this step quickly. The onboard SMES units may not have enough power to run the emitters if left alone too long on-station. This engine can produce enough power on its own to run the entire station, ignoring the SMES units completely, and is wired to do so.
      10. - -
      11. Switch SMES units to primary settings: Maximize input and set the devices to automatically charge, additionally turn their outputs on if they are off unless power is to be saved (Which can be useful in case of later failures).
      12. - -
      13. Begin secondary emitter burst series: Before firing the emitter again, check the power in the line with a multimeter (Do not forget electrical gloves). The engine is running at high efficiency when the value exceeds 200,000 power units.
      14. - -
      15. Maintain engine power: When power in the lines get low, add an additional emitter burst series to bring power to normal levels.
      16. +
      17. Fill reactor loop and radiator loop with two (2) standard canisters of nitrogen gas each.
      18. +
      19. Ensure that pumps and filters are on and operating at maximum power.
      20. +
      21. Fire 5 15 2 UNKNOWN 8-12 pulses from emitter at supermatter crystal. Reactor blast doors must be open for this procedure.
      - - -

      O2-Reaction Mode

      - - The second mode for running the engine uses a gas mixture to produce a reaction within the supermatter. This mode requires the CE's or Atmospheric's help to set up. This is called 'O2-Reaction Mode.'

      - - THIS MODE CAN CAUSE A RUNAWAY REACTION, LEADING TO CATASTROPHIC FAILURE IF NOT MAINTAINED. NEVER FORGET ABOUT THE ENGINE IN THIS MODE.

      - - Additionally, this mode can be used for what is called a 'Cold Start.' If the station has no power in the SMES to run the emitters, using this mode will allow enough power output to run them, and quickly reach an acceptable level of power output.

      - +
      +

      OPERATION AND MAINTENANCE

        -
      1. Prepare collector arrays: As is standard, begin by wrenching them down, filling six plasma tanks with a plasma canister, and inserting the tank into the collectors one by one. Finally, initialize each collector.
      2. - -
      3. Prepare gas system: Before introducing any gas into the supermatter engine room, it is important to remember the small, but vital steps to preparing this section. First, set the input gas pump and output gas flow pump to 4500 kPa, or maximum flow. Second, switch the digital switching valve into the 'up' position, so the green light is on north side of the valve, in order to circulate the gas back toward the coolers and collectors.
      4. - -
      5. Modify the engine room filters: Unlike the Heat-Primary Mode, it is important to change the filters attached to the gas system to stop filtering O2, and start filtering carbon molecules. O2-Reaction Mode produces far more plasma than Heat-Primary, therefore filtering it off is essential.
      6. - -
      7. Switch SMES units to primary settings: Maximize input and set the devices to automatically charge, additionally turn their outputs on if they are off unless power is to be saved (Which can be useful in case of later failures). If you check the power in the system lines at this point, you will find that it is constantly going up. Indeed, with just the addition of O2 to the supermatter, it will begin outputting power.
      8. - -
      9. Begin primary emitter burst series: Begin by firing four shots into the supermatter using the emitter. Do not over power the supermatter. The reaction is self sustaining and propagating. As long as O2 is in the chamber, it will continue outputting MORE power.
      10. - -
      11. Maintain follow up operations: Remember to check the temperature of the core gas and switch to the Heat-Primary function, or vent the core room when problems begin if required.
      12. -

      - -

      Notes on Supermatter Reaction Function and Drawbacks

      - - After several hours of observation, an interesting phenomenon was witnessed. The supermatter undergoes a constant, self-sustaining reaction when given an extremely high O2 concentration. Anything about 80% or higher typically will cause this reaction. The supermatter will continue to react whenever this gas mixture is in the same room as the supermatter.

      - - To understand why O2-Reaction mode is dangerous, the core principle of the supermatter must be understood. The supermatter emits three things when 'not safe,' that is any time it is giving off power. These things are:
      - -
        -
      • Radiation (which is converted into power by the collectors)

      • -
      • Heat (which is removed via the gas exchange system and coolers)

      • -
      • External gas (in the form of plasma and O2)

      • -

      - - When in Heat-Primary mode, far more heat and plasma are produced than radiation. In O2-Reaction mode, very little heat and only moderate amounts of plasma are produced, however HUGE amounts of energy leaving the supermatter is in the form of radiation.

      - - The O2-Reaction engine mode has a single drawback which has been eluded to more than once so far and that is very simple. The engine room will continue to grow hotter as the constant reaction continues. Eventually, there will be what is called a 'critical gas mixture.' This is the point at which the constant adding of plasma to the mixture of air around the supermatter changes the gas concentration to below the tolerance. When this happens, two things occur. First, the supermatter switches to its primary mode of operation wherein huge amounts of heat are produced by the engine rather than low amounts with high power output. Second, an uncontrollable increase in heat within the supermatter chamber will occur. This will lead to a spark-up, igniting the plasma in the supermatter chamber, wildly increasing both pressure and temperature.

      - - While the O2-Reaction mode is dangerous, it does produce heavy amounts of energy. Consider using this mode only in short amounts to fill the SMES, and switch back later in the shift to keep things flowing normally.

      - - -

      Notes on Supermatter Containment and Emergency Procedures

      - - While a constant vigil on the supermatter is not required, regular checkups are important. Check the temperature of gas leaving the supermatter chamber for unsafe levels and ensure that the plasma in the chamber is at a safe concentration. Of course, also make sure the chamber is not on fire. A fire in the core chamber is very difficult to put out. As any toxin scientist can tell you, even low amounts of plasma can burn at very high temperatures. This burning creates a huge increase in pressure and more importantly, temperature of the crystal itself.

      - - The supermatter is strong, but not invincible. When the supermatter is heated too much, its crystal structure will attempt to liquefy. The change in atomic structure of the supermatter leads to a single reaction, a massive explosion. The computer chip attached to the supermatter core will warn the station when stability is threatened. It will then offer a second warning, when things have become dangerously close to total destruction of the core.

      - - Located both within the CE office and engine room is the engine ventilatory control button. This button allows the core vent controls to be accessed, venting the room to space. Remember however, that this process takes time. If a fire is raging, and the pressure is higher than fathomable, it will take a great deal of time to vent the room. Also located in the CE's office is the emergency core eject button. A new core can be ordered from cargo. It is often not worth the lives of the crew to hold on to it, not to mention the structural damage. However, if by some mistake the supermatter is pushed off or removed from the mass driver it sits on, manual reposition will be required. Which is very dangerous and often leads to death.

      - - The supermatter is extremely dangerous. More dangerous than people give it credit for. It can destroy you in an instant, without hesitation, reducing you to a pile of dust. When working closely with supermatter, it is suggested to get a genetic backup and do not wear any items of value to you. The supermatter core can be pulled if grabbed properly by the base, but pushing is not possible.

      - - -

      In Closing

      - - Remember that the supermatter is dangerous, and the core is dangerous still. Venting the core room is always an option if you are even remotely worried, utilizing Atmospherics to properly ready the room once more for core function. It is always a good idea to check up regularly on the temperature of gas leaving the chamber, as well as the power in the system lines. Lastly, once again remember, never touch the supermatter with anything. Ever.

      - - -Waleed Asad, Senior Engine Technician +
    • Ensure that radiation protection and meson goggles are worn at all times while working in the engine room.
    • +
    • Ensure that reactor and radiator loops are undamaged and unobstructed.
    • +
    • Ensure that plasma and oxygen gas exhaust from filters is properly contained or disposed. Do not allow exhaust pressure to exceed 4500 kPa.
    • +
    • Ensure that engine room Area Power Controller (APC) and engine Superconducting Magnetic Energy Storage unit (SMES) are properly charged.
    • +
    • Ensure that reactor temperature does not exceed 5000K. In event of reactor temperature exceeding 5000K, see EMERGENCY COOLING PROCEDURE.
    • +
    • In event of imminent and/or unavoidable delamination, see EJECTION PROCEDURE.
    • + +
      +

      EMERGENCY COOLING PROCEDURE

      +
        +
      1. Open Emergency Cooling Valve 1 and Emergency Cooling Valve 2.
      2. +
      3. When reactor temperature returns to safe operating levels, close Emergency Cooling Valve 1 and Emergency Cooling Valve 2.
      4. +
      5. If reactor temperature does not return to safe operating levels, see EJECTION PROCEDURE.
      6. +
      +
      +

      EJECTION PROCEDURE

      +
        +
      1. Press Engine Ventilatory Control button to open engine core vent to space.
      2. +
      3. Press Emergency Core Eject button to eject supermatter crystal. NOTE: Attempting crystal ejection while engine core vent is closed will result in ejection failure.
      4. +
      5. In event of ejection failure, pending
      6. +
      "} diff --git a/code/game/objects/items/weapons/paint.dm b/code/game/objects/items/weapons/paint.dm index fc122c185c..77f8172f8f 100644 --- a/code/game/objects/items/weapons/paint.dm +++ b/code/game/objects/items/weapons/paint.dm @@ -1,4 +1,5 @@ //NEVER USE THIS IT SUX -PETETHEGOAT +//THE GOAT WAS RIGHT - RKF var/global/list/cached_icons = list() @@ -11,10 +12,10 @@ var/global/list/cached_icons = list() matter = list("metal" = 200) w_class = 3.0 amount_per_transfer_from_this = 10 - possible_transfer_amounts = list(10,20,30,50,70) - volume = 70 + possible_transfer_amounts = list(10,20,30,60) + volume = 60 flags = OPENCONTAINER - var/paint_type = "" + var/paint_type = "red" afterattack(turf/simulated/target, mob/user, proximity) if(!proximity) return @@ -28,22 +29,27 @@ var/global/list/cached_icons = list() return ..() New() - if(paint_type == "remover") - name = "paint remover bucket" - else if(paint_type && lentext(paint_type) > 0) + if(paint_type && lentext(paint_type) > 0) name = paint_type + " " + name ..() - reagents.add_reagent("paint_[paint_type]", volume) - - on_reagent_change() //Until we have a generic "paint", this will give new colours to all paints in the can - var/mixedcolor = mix_color_from_reagents(reagents.reagent_list) - for(var/datum/reagent/paint/P in reagents.reagent_list) - P.color = mixedcolor + reagents.add_reagent("water", volume*3/5) + reagents.add_reagent("plasticide", volume/5) + if(paint_type == "white") //why don't white crayons exist + reagents.add_reagent("aluminum", volume/5) + else if (paint_type == "black") + reagents.add_reagent("carbon", volume/5) + else + reagents.add_reagent("crayon_dust_[paint_type]", volume/5) + reagents.handle_reactions() red icon_state = "paint_red" paint_type = "red" + yellow + icon_state = "paint_yellow" + paint_type = "yellow" + green icon_state = "paint_green" paint_type = "green" @@ -52,13 +58,9 @@ var/global/list/cached_icons = list() icon_state = "paint_blue" paint_type = "blue" - yellow - icon_state = "paint_yellow" - paint_type = "yellow" - - violet + purple icon_state = "paint_violet" - paint_type = "violet" + paint_type = "purple" black icon_state = "paint_black" @@ -68,170 +70,3 @@ var/global/list/cached_icons = list() icon_state = "paint_white" paint_type = "white" - remover - paint_type = "remover" -/* -/obj/item/weapon/paint - gender= PLURAL - name = "paint" - desc = "Used to recolor floors and walls. Can not be removed by the janitor." - icon = 'icons/obj/items.dmi' - icon_state = "paint_neutral" - color = "FFFFFF" - item_state = "paintcan" - w_class = 3.0 - -/obj/item/weapon/paint/red - name = "red paint" - color = "FF0000" - icon_state = "paint_red" - -/obj/item/weapon/paint/green - name = "green paint" - color = "00FF00" - icon_state = "paint_green" - -/obj/item/weapon/paint/blue - name = "blue paint" - color = "0000FF" - icon_state = "paint_blue" - -/obj/item/weapon/paint/yellow - name = "yellow paint" - color = "FFFF00" - icon_state = "paint_yellow" - -/obj/item/weapon/paint/violet - name = "violet paint" - color = "FF00FF" - icon_state = "paint_violet" - -/obj/item/weapon/paint/black - name = "black paint" - color = "333333" - icon_state = "paint_black" - -/obj/item/weapon/paint/white - name = "white paint" - color = "FFFFFF" - icon_state = "paint_white" - - -/obj/item/weapon/paint/anycolor - gender= PLURAL - name = "any color" - icon_state = "paint_neutral" - - attack_self(mob/user as mob) - var/t1 = input(user, "Please select a color:", "Locking Computer", null) in list( "red", "blue", "green", "yellow", "black", "white") - if ((user.get_active_hand() != src || user.stat || user.restrained())) - return - switch(t1) - if("red") - color = "FF0000" - if("blue") - color = "0000FF" - if("green") - color = "00FF00" - if("yellow") - color = "FFFF00" - if("violet") - color = "FF00FF" - if("white") - color = "FFFFFF" - if("black") - color = "333333" - icon_state = "paint_[t1]" - add_fingerprint(user) - return - - -/obj/item/weapon/paint/afterattack(turf/target, mob/user as mob, proximity) - if(!proximity) return - if(!istype(target) || istype(target, /turf/space)) - return - var/ind = "[initial(target.icon)][color]" - if(!cached_icons[ind]) - var/icon/overlay = new/icon(initial(target.icon)) - overlay.Blend("#[color]",ICON_MULTIPLY) - overlay.SetIntensity(1.4) - target.icon = overlay - cached_icons[ind] = target.icon - else - target.icon = cached_icons[ind] - return - -/obj/item/weapon/paint/paint_remover - gender = PLURAL - name = "paint remover" - icon_state = "paint_neutral" - - afterattack(turf/target, mob/user as mob) - if(istype(target) && target.icon != initial(target.icon)) - target.icon = initial(target.icon) - return -*/ - -datum/reagent/paint - name = "Paint" - id = "paint_" - reagent_state = 2 - color = "#808080" - description = "This paint will only adhere to floor tiles." - - reaction_turf(var/turf/T, var/volume) - if(!istype(T) || istype(T, /turf/space)) - return - T.color = color - - reaction_obj(var/obj/O, var/volume) - ..() - if(istype(O,/obj/item/weapon/light)) - O.color = color - - red - name = "Red Paint" - id = "paint_red" - color = "#FE191A" - - green - name = "Green Paint" - color = "#18A31A" - id = "paint_green" - - blue - name = "Blue Paint" - color = "#247CFF" - id = "paint_blue" - - yellow - name = "Yellow Paint" - color = "#FDFE7D" - id = "paint_yellow" - - violet - name = "Violet Paint" - color = "#CC0099" - id = "paint_violet" - - black - name = "Black Paint" - color = "#333333" - id = "paint_black" - - white - name = "White Paint" - color = "#F0F8FF" - id = "paint_white" - -datum/reagent/paint_remover - name = "Paint Remover" - id = "paint_remover" - description = "Paint remover is used to remove floor paint from floor tiles." - reagent_state = 2 - color = "#808080" - - reaction_turf(var/turf/T, var/volume) - if(istype(T) && T.icon != initial(T.icon)) - T.icon = initial(T.icon) - return diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm index 8791ea1075..4444904c1b 100644 --- a/code/game/objects/items/weapons/policetape.dm +++ b/code/game/objects/items/weapons/policetape.dm @@ -125,7 +125,7 @@ breaktape(W, user) /obj/item/tape/attack_hand(mob/user as mob) - if (user.a_intent == "help" && src.allowed(user)) + if (user.a_intent == I_HELP && src.allowed(user)) user.show_viewers("\blue [user] lifts [src], allowing passage.") crumple() lifted = 1 @@ -137,7 +137,7 @@ /obj/item/tape/proc/breaktape(obj/item/weapon/W as obj, mob/user as mob) - if(user.a_intent == "help" && ((!can_puncture(W) && src.allowed(user)))) + if(user.a_intent == I_HELP && ((!can_puncture(W) && src.allowed(user)))) user << "You can't break the [src] with that!" return user.show_viewers("\blue [user] breaks the [src]!") diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm index 1ece5817f9..92ba323a6a 100644 --- a/code/game/objects/items/weapons/scrolls.dm +++ b/code/game/objects/items/weapons/scrolls.dm @@ -69,7 +69,7 @@ return if(user && user.buckled) - user.buckled.unbuckle() + user.buckled.unbuckle_mob() var/list/tempL = L var/attempt = null diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 2b38772b86..40937ea61c 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -8,10 +8,10 @@ desc = "You wear this on your back and put items into it." icon_state = "backpack" item_state = "backpack" - w_class = 4.0 - slot_flags = SLOT_BACK //ERROOOOO + w_class = 4 + slot_flags = SLOT_BACK max_w_class = 3 - max_combined_w_class = 21 + max_storage_space = 28 /obj/item/weapon/storage/backpack/attackby(obj/item/weapon/W as obj, mob/user as mob) if (src.use_sound) @@ -40,7 +40,7 @@ origin_tech = "bluespace=4" icon_state = "holdingpack" max_w_class = 4 - max_combined_w_class = 28 + max_storage_space = 56 New() ..() @@ -67,6 +67,12 @@ return */ ..() + + //Please don't clutter the parent storage item with stupid hacks. + can_be_inserted(obj/item/W as obj, stop_messages = 0) + if(istype(W, /obj/item/weapon/storage/backpack/holding)) + return 1 + return ..() proc/failcheck(mob/user as mob) if (prob(src.reliability)) return 1 //No failure @@ -88,7 +94,7 @@ w_class = 4.0 storage_slots = 20 max_w_class = 3 - max_combined_w_class = 400 // can store a ton of shit! + max_storage_space = 400 // can store a ton of shit! /obj/item/weapon/storage/backpack/cultpack name = "trophy rack" diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index f6c49b0fe6..0ee5df08e0 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -36,7 +36,7 @@ max_w_class = 2 storage_slots = 21 can_hold = list() // any - cant_hold = list("/obj/item/weapon/disk/nuclear") + cant_hold = list(/obj/item/weapon/disk/nuclear) /obj/item/weapon/storage/bag/trash/update_icon() if(contents.len == 0) @@ -63,7 +63,7 @@ max_w_class = 2 storage_slots = 21 can_hold = list() // any - cant_hold = list("/obj/item/weapon/disk/nuclear") + cant_hold = list(/obj/item/weapon/disk/nuclear) // ----------------------------- // Mining Satchel @@ -77,9 +77,9 @@ slot_flags = SLOT_BELT | SLOT_POCKET w_class = 3 storage_slots = 50 - max_combined_w_class = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * ore.w_class + max_storage_space = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * ore.w_class max_w_class = 3 - can_hold = list("/obj/item/weapon/ore") + can_hold = list(/obj/item/weapon/ore) // ----------------------------- @@ -88,13 +88,13 @@ /obj/item/weapon/storage/bag/plants name = "plant bag" - icon = 'icons/obj/hydroponics.dmi' + icon = 'icons/obj/hydroponics_machines.dmi' icon_state = "plantbag" storage_slots = 50; //the number of plant pieces it can carry. - max_combined_w_class = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * plants.w_class + max_storage_space = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * plants.w_class max_w_class = 3 w_class = 2 - can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/grown","/obj/item/seeds","/obj/item/weapon/grown") + can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/grown,/obj/item/seeds,/obj/item/weapon/grown) // ----------------------------- @@ -249,7 +249,7 @@ icon_state = "cashbag" desc = "A bag for carrying lots of cash. It's got a big dollar sign printed on the front." storage_slots = 50; //the number of cash pieces it can carry. - max_combined_w_class = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * cash.w_class + max_storage_space = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * cash.w_class max_w_class = 3 w_class = 2 - can_hold = list("/obj/item/weapon/coin","/obj/item/weapon/spacecash") + can_hold = list(/obj/item/weapon/coin,/obj/item/weapon/spacecash) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 0c4a94eb86..47821d6a24 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -7,25 +7,37 @@ slot_flags = SLOT_BELT attack_verb = list("whipped", "lashed", "disciplined") + +/obj/item/weapon/storage/update_icon() + if (ismob(src.loc)) + var/mob/M = src.loc + M.update_inv_belt() + + /obj/item/weapon/storage/belt/utility name = "tool-belt" //Carn: utility belt is nicer, but it bamboozles the text parsing. desc = "Can hold various tools." icon_state = "utilitybelt" item_state = "utility" can_hold = list( - //"/obj/item/weapon/combitool", - "/obj/item/weapon/crowbar", - "/obj/item/weapon/screwdriver", - "/obj/item/weapon/weldingtool", - "/obj/item/weapon/wirecutters", - "/obj/item/weapon/wrench", - "/obj/item/device/multitool", - "/obj/item/device/flashlight", - "/obj/item/stack/cable_coil", - "/obj/item/device/t_scanner", - "/obj/item/device/analyzer", - "/obj/item/taperoll/engineering", - "/obj/item/device/robotanalyzer") + ///obj/item/weapon/combitool, + /obj/item/weapon/crowbar, + /obj/item/weapon/screwdriver, + /obj/item/weapon/weldingtool, + /obj/item/weapon/wirecutters, + /obj/item/weapon/wrench, + /obj/item/device/multitool, + /obj/item/device/flashlight, + /obj/item/stack/cable_coil, + /obj/item/device/t_scanner, + /obj/item/device/analyzer, + /obj/item/taperoll/engineering, + /obj/item/device/robotanalyzer, + /obj/item/weapon/minihoe, + /obj/item/weapon/hatchet, + /obj/item/device/analyzer/plant_analyzer, + /obj/item/weapon/extinguisher/mini + ) /obj/item/weapon/storage/belt/utility/full/New() @@ -55,53 +67,66 @@ icon_state = "medicalbelt" item_state = "medical" can_hold = list( - "/obj/item/device/healthanalyzer", - "/obj/item/weapon/dnainjector", - "/obj/item/weapon/reagent_containers/dropper", - "/obj/item/weapon/reagent_containers/glass/beaker", - "/obj/item/weapon/reagent_containers/glass/bottle", - "/obj/item/weapon/reagent_containers/pill", - "/obj/item/weapon/reagent_containers/syringe", - "/obj/item/weapon/reagent_containers/glass/dispenser", - "/obj/item/weapon/flame/lighter/zippo", - "/obj/item/weapon/storage/fancy/cigarettes", - "/obj/item/weapon/storage/pill_bottle", - "/obj/item/stack/medical", - "/obj/item/device/flashlight/pen", - "/obj/item/clothing/mask/surgical", - "/obj/item/clothing/gloves/latex", - "/obj/item/weapon/reagent_containers/hypospray" - ) + /obj/item/device/healthanalyzer, + /obj/item/weapon/dnainjector, + /obj/item/weapon/reagent_containers/dropper, + /obj/item/weapon/reagent_containers/glass/beaker, + /obj/item/weapon/reagent_containers/glass/bottle, + /obj/item/weapon/reagent_containers/pill, + /obj/item/weapon/reagent_containers/syringe, + /obj/item/weapon/flame/lighter/zippo, + /obj/item/weapon/storage/fancy/cigarettes, + /obj/item/weapon/storage/pill_bottle, + /obj/item/stack/medical, + /obj/item/device/flashlight/pen, + /obj/item/clothing/mask/surgical, + /obj/item/clothing/head/surgery, + /obj/item/clothing/gloves/latex, + /obj/item/weapon/reagent_containers/hypospray, + /obj/item/clothing/glasses/hud/health, + /obj/item/weapon/crowbar, + /obj/item/device/flashlight, + /obj/item/weapon/extinguisher/mini + ) + +/obj/item/weapon/storage/belt/medical/emt + name = "EMT utility belt" + desc = "A sturdy black webbing belt with attached pouches." + icon = 'icons/obj/custom_items.dmi' + icon_state = "emsbelt" + item_state = "emsbelt" + /obj/item/weapon/storage/belt/security name = "security belt" desc = "Can hold security gear like handcuffs and flashes." icon_state = "securitybelt" - item_state = "security"//Could likely use a better one. + item_state = "security" storage_slots = 7 max_w_class = 3 - max_combined_w_class = 21 + max_storage_space = 28 can_hold = list( - "/obj/item/weapon/grenade", - "/obj/item/weapon/reagent_containers/spray/pepper", - "/obj/item/weapon/handcuffs", - "/obj/item/device/flash", - "/obj/item/clothing/glasses", - "/obj/item/ammo_casing/shotgun", - "/obj/item/ammo_magazine", - "/obj/item/weapon/reagent_containers/food/snacks/donut/normal", - "/obj/item/weapon/reagent_containers/food/snacks/donut/jelly", - "/obj/item/weapon/melee/baton", - "/obj/item/weapon/gun/energy/taser", - "/obj/item/weapon/flame/lighter/zippo", - "/obj/item/weapon/cigpacket", - "/obj/item/clothing/glasses/hud/security", - "/obj/item/device/flashlight", - "/obj/item/device/pda", - "/obj/item/device/radio/headset", - "/obj/item/weapon/melee", - "/obj/item/taperoll/police" + /obj/item/weapon/grenade, + /obj/item/weapon/reagent_containers/spray/pepper, + /obj/item/weapon/handcuffs, + /obj/item/device/flash, + /obj/item/clothing/glasses, + /obj/item/ammo_casing/shotgun, + /obj/item/ammo_magazine, + /obj/item/weapon/reagent_containers/food/snacks/donut/, + /obj/item/weapon/melee/baton, + /obj/item/weapon/gun/energy/taser, + /obj/item/weapon/flame/lighter, + /obj/item/clothing/glasses/hud/security, + /obj/item/device/flashlight, + /obj/item/device/pda, + /obj/item/device/radio/headset, + /obj/item/device/hailer, + /obj/item/device/megaphone, + /obj/item/weapon/melee, + /obj/item/weapon/gun/projectile/sec, + /obj/item/taperoll/police ) /obj/item/weapon/storage/belt/soulstone @@ -111,7 +136,7 @@ item_state = "soulstonebelt" storage_slots = 6 can_hold = list( - "/obj/item/device/soulstone" + /obj/item/device/soulstone ) /obj/item/weapon/storage/belt/soulstone/full/New() @@ -141,4 +166,4 @@ item_state = "swatbelt" storage_slots = 9 max_w_class = 3 - max_combined_w_class = 21 + max_storage_space = 28 diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index ced886bedd..4c0c58a05a 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -24,7 +24,31 @@ desc = "It's just an ordinary box." icon_state = "box" item_state = "syringe_kit" - foldable = /obj/item/stack/sheet/cardboard //BubbleWrap + var/foldable = null // BubbleWrap - if set, can be folded (when empty) into a sheet of cardboard + +// BubbleWrap - A box can be folded up to make card +/obj/item/weapon/storage/box/attack_self(mob/user as mob) + if(..()) return + + //try to fold it. + if ( contents.len ) + return + + if ( !ispath(src.foldable) ) + return + var/found = 0 + // Close any open UI windows first + for(var/mob/M in range(1)) + if (M.s_active == src) + src.close(M) + if ( M == user ) + found = 1 + if ( !found ) // User is too far away + return + // Now make the cardboard + user << "You fold [src] flat." + new src.foldable(get_turf(src)) + del(src) /obj/item/weapon/storage/box/survival/ New() @@ -79,7 +103,6 @@ /obj/item/weapon/storage/box/syringes name = "box of syringes" desc = "A box full of syringes." - desc = "A biohazard alert warning is printed on the box" icon_state = "syringe" New() @@ -92,6 +115,22 @@ new /obj/item/weapon/reagent_containers/syringe( src ) new /obj/item/weapon/reagent_containers/syringe( src ) +/obj/item/weapon/storage/box/syringegun + name = "box of syringe gun cartridges" + desc = "A box full of compressed gas cartridges." + icon_state = "syringe" + + New() + ..() + new /obj/item/weapon/syringe_cartridge( src ) + new /obj/item/weapon/syringe_cartridge( src ) + new /obj/item/weapon/syringe_cartridge( src ) + new /obj/item/weapon/syringe_cartridge( src ) + new /obj/item/weapon/syringe_cartridge( src ) + new /obj/item/weapon/syringe_cartridge( src ) + new /obj/item/weapon/syringe_cartridge( src ) + + /obj/item/weapon/storage/box/beakers name = "box of beakers" icon_state = "beaker" @@ -149,7 +188,7 @@ new /obj/item/ammo_casing/shotgun/beanbag(src) /obj/item/weapon/storage/box/shotgunammo - name = "box of shotgun shells" + name = "box of shotgun slugs" desc = "It has a picture of a gun and several warning symbols on the front.
      WARNING: Live ammunition. Misuse may result in serious injury or death." New() @@ -162,6 +201,62 @@ new /obj/item/ammo_casing/shotgun(src) new /obj/item/ammo_casing/shotgun(src) +/obj/item/weapon/storage/box/shotgunshells + name = "box of shotgun shells" + desc = "It has a picture of a gun and several warning symbols on the front.
      WARNING: Live ammunition. Misuse may result in serious injury or death." + + New() + ..() + new /obj/item/ammo_casing/shotgun/pellet(src) + new /obj/item/ammo_casing/shotgun/pellet(src) + new /obj/item/ammo_casing/shotgun/pellet(src) + new /obj/item/ammo_casing/shotgun/pellet(src) + new /obj/item/ammo_casing/shotgun/pellet(src) + new /obj/item/ammo_casing/shotgun/pellet(src) + new /obj/item/ammo_casing/shotgun/pellet(src) + +/obj/item/weapon/storage/box/flashshells + name = "box of illumination shells" + desc = "It has a picture of a gun and several warning symbols on the front.
      WARNING: Live ammunition. Misuse may result in serious injury or death." + + New() + ..() + new /obj/item/ammo_casing/shotgun/flash(src) + new /obj/item/ammo_casing/shotgun/flash(src) + new /obj/item/ammo_casing/shotgun/flash(src) + new /obj/item/ammo_casing/shotgun/flash(src) + new /obj/item/ammo_casing/shotgun/flash(src) + new /obj/item/ammo_casing/shotgun/flash(src) + new /obj/item/ammo_casing/shotgun/flash(src) + +/obj/item/weapon/storage/box/stunshells + name = "box of stun shells" + desc = "It has a picture of a gun and several warning symbols on the front.
      WARNING: Live ammunition. Misuse may result in serious injury or death." + + New() + ..() + new /obj/item/ammo_casing/shotgun/stunshell(src) + new /obj/item/ammo_casing/shotgun/stunshell(src) + new /obj/item/ammo_casing/shotgun/stunshell(src) + new /obj/item/ammo_casing/shotgun/stunshell(src) + new /obj/item/ammo_casing/shotgun/stunshell(src) + new /obj/item/ammo_casing/shotgun/stunshell(src) + new /obj/item/ammo_casing/shotgun/stunshell(src) + +/obj/item/weapon/storage/box/sniperammo + name = "box of 14.5mm shells" + desc = "It has a picture of a gun and several warning symbols on the front.
      WARNING: Live ammunition. Misuse may result in serious injury or death." + + New() + ..() + new /obj/item/ammo_casing/a145(src) + new /obj/item/ammo_casing/a145(src) + new /obj/item/ammo_casing/a145(src) + new /obj/item/ammo_casing/a145(src) + new /obj/item/ammo_casing/a145(src) + new /obj/item/ammo_casing/a145(src) + new /obj/item/ammo_casing/a145(src) + /obj/item/weapon/storage/box/flashbangs name = "box of flashbangs (WARNING)" desc = "WARNING: These devices are extremely dangerous and can cause blindness or deafness in repeated use." @@ -179,7 +274,7 @@ /obj/item/weapon/storage/box/emps name = "box of emp grenades" - desc = "A box with 5 emp grenades." + desc = "A box containing 5 military grade EMP grenades.
      WARNING: Do not use near unshielded electronics or biomechanical augmentations, death or permanent paralysis may occur." icon_state = "flashbang" New() @@ -310,13 +405,27 @@ new /obj/item/weapon/reagent_containers/food/snacks/donkpocket(src) new /obj/item/weapon/reagent_containers/food/snacks/donkpocket(src) +/obj/item/weapon/storage/box/sinpockets + name = "box of sin-pockets" + desc = "Instructions: Crush bottom of package to initiate chemical heating. Wait for 20 seconds before consumption. Product will cool if not eaten within seven minutes." + icon_state = "donk_kit" + + New() + ..() + new /obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket(src) + new /obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket(src) + new /obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket(src) + new /obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket(src) + new /obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket(src) + new /obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket(src) + /obj/item/weapon/storage/box/monkeycubes name = "monkey cube box" desc = "Drymate brand monkey cubes. Just add water!" icon = 'icons/obj/food.dmi' icon_state = "monkeycubebox" storage_slots = 7 - can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/monkeycube") + can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube) New() ..() if(src.type == /obj/item/weapon/storage/box/monkeycubes) @@ -430,7 +539,7 @@ icon = 'icons/obj/toy.dmi' icon_state = "spbox" storage_slots = 8 - can_hold = list("/obj/item/toy/snappop") + can_hold = list(/obj/item/toy/snappop) New() ..() for(var/i=1; i <= storage_slots; i++) @@ -445,7 +554,7 @@ storage_slots = 10 w_class = 1 slot_flags = SLOT_BELT - can_hold = list("/obj/item/weapon/flame/match") + can_hold = list(/obj/item/weapon/flame/match) New() ..() @@ -478,8 +587,8 @@ item_state = "syringe_kit" foldable = /obj/item/stack/sheet/cardboard //BubbleWrap storage_slots=21 - can_hold = list("/obj/item/weapon/light/tube", "/obj/item/weapon/light/bulb") - max_combined_w_class = 42 //holds 21 items of w_class 2 + can_hold = list(/obj/item/weapon/light/tube, /obj/item/weapon/light/bulb) + max_storage_space = 42 //holds 21 items of w_class 2 use_to_pickup = 1 // for picking up broken bulbs, not that most people will try /obj/item/weapon/storage/box/lights/bulbs/New() diff --git a/code/game/objects/items/weapons/storage/briefcase.dm b/code/game/objects/items/weapons/storage/briefcase.dm index f6addee005..0f534ade9e 100644 --- a/code/game/objects/items/weapons/storage/briefcase.dm +++ b/code/game/objects/items/weapons/storage/briefcase.dm @@ -7,9 +7,9 @@ force = 8.0 throw_speed = 1 throw_range = 4 - w_class = 4.0 + w_class = 4 max_w_class = 3 - max_combined_w_class = 16 + max_storage_space = 16 /obj/item/weapon/storage/briefcase/New() ..() diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 2ddc1da1d3..7af6e3b16e 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -27,7 +27,7 @@ /obj/item/weapon/storage/fancy/examine(mob/user) if(!..(user, 1)) return - + if(contents.len <= 0) user << "There are no [src.icon_type]s left in the box." else if(contents.len == 1) @@ -47,8 +47,10 @@ icon_type = "egg" name = "egg box" storage_slots = 12 - max_combined_w_class = 24 - can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/egg") + can_hold = list( + /obj/item/weapon/reagent_containers/food/snacks/egg, + /obj/item/weapon/reagent_containers/food/snacks/boiledegg + ) /obj/item/weapon/storage/fancy/egg_box/New() ..() @@ -91,7 +93,7 @@ storage_slots = 6 icon_type = "crayon" can_hold = list( - "/obj/item/toy/crayon" + /obj/item/toy/crayon ) /obj/item/weapon/storage/fancy/crayons/New() @@ -134,14 +136,14 @@ throwforce = 2 slot_flags = SLOT_BELT storage_slots = 6 - can_hold = list("/obj/item/clothing/mask/cigarette") + can_hold = list(/obj/item/clothing/mask/smokable/cigarette) icon_type = "cigarette" /obj/item/weapon/storage/fancy/cigarettes/New() ..() flags |= NOREACT for(var/i = 1 to storage_slots) - new /obj/item/clothing/mask/cigarette(src) + new /obj/item/clothing/mask/smokable/cigarette(src) create_reagents(15 * storage_slots)//so people can inject cigarettes without opening a packet, now with being able to inject the whole one /obj/item/weapon/storage/fancy/cigarettes/Del() @@ -154,7 +156,7 @@ return /obj/item/weapon/storage/fancy/cigarettes/remove_from_storage(obj/item/W as obj, atom/new_location) - var/obj/item/clothing/mask/cigarette/C = W + var/obj/item/clothing/mask/smokable/cigarette/C = W if(!istype(C)) return // what reagents.trans_to(C, (reagents.total_volume/contents.len)) ..() @@ -164,7 +166,7 @@ return if(M == user && user.zone_sel.selecting == "mouth" && contents.len > 0 && !user.wear_mask) - var/obj/item/clothing/mask/cigarette/W = new /obj/item/clothing/mask/cigarette(user) + var/obj/item/clothing/mask/smokable/cigarette/W = new /obj/item/clothing/mask/smokable/cigarette(user) reagents.trans_to(W, (reagents.total_volume/contents.len)) user.equip_to_slot_if_possible(W, slot_wear_mask) reagents.maximum_volume = 15 * contents.len @@ -190,14 +192,14 @@ throwforce = 2 slot_flags = SLOT_BELT storage_slots = 7 - can_hold = list("/obj/item/clothing/mask/cigarette/cigar") + can_hold = list(/obj/item/clothing/mask/smokable/cigarette/cigar) icon_type = "cigar" /obj/item/weapon/storage/fancy/cigar/New() ..() flags |= NOREACT for(var/i = 1 to storage_slots) - new /obj/item/clothing/mask/cigarette/cigar(src) + new /obj/item/clothing/mask/smokable/cigarette/cigar(src) create_reagents(15 * storage_slots) /obj/item/weapon/storage/fancy/cigar/Del() @@ -209,7 +211,7 @@ return /obj/item/weapon/storage/fancy/cigar/remove_from_storage(obj/item/W as obj, atom/new_location) - var/obj/item/clothing/mask/cigarette/cigar/C = W + var/obj/item/clothing/mask/smokable/cigarette/cigar/C = W if(!istype(C)) return reagents.trans_to(C, (reagents.total_volume/contents.len)) ..() @@ -219,7 +221,7 @@ return if(M == user && user.zone_sel.selecting == "mouth" && contents.len > 0 && !user.wear_mask) - var/obj/item/clothing/mask/cigarette/cigar/W = new /obj/item/clothing/mask/cigarette/cigar(user) + var/obj/item/clothing/mask/smokable/cigarette/cigar/W = new /obj/item/clothing/mask/smokable/cigarette/cigar(user) reagents.trans_to(W, (reagents.total_volume/contents.len)) user.equip_to_slot_if_possible(W, slot_wear_mask) reagents.maximum_volume = 15 * contents.len @@ -239,7 +241,7 @@ icon_type = "vial" name = "vial storage box" storage_slots = 6 - can_hold = list("/obj/item/weapon/reagent_containers/glass/beaker/vial") + can_hold = list(/obj/item/weapon/reagent_containers/glass/beaker/vial) /obj/item/weapon/storage/fancy/vials/New() @@ -254,9 +256,9 @@ icon = 'icons/obj/vialbox.dmi' icon_state = "vialbox0" item_state = "syringe_kit" - max_w_class = 3 - can_hold = list("/obj/item/weapon/reagent_containers/glass/beaker/vial") - max_combined_w_class = 14 //The sum of the w_classes of all the items in this storage item. + max_w_class = 2 + can_hold = list(/obj/item/weapon/reagent_containers/glass/beaker/vial) + max_storage_space = 12 //The sum of the w_classes of all the items in this storage item. storage_slots = 6 req_access = list(access_virology) diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index 6e2eca01c5..304c59fb98 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -109,6 +109,41 @@ new /obj/item/stack/medical/advanced/ointment(src) new /obj/item/stack/medical/splint(src) return + +/obj/item/weapon/storage/firstaid/combat + name = "combat medical kit" + desc = "Contains advanced medical treatments." + icon_state = "bezerk" + item_state = "firstaid-advanced" + +/obj/item/weapon/storage/firstaid/combat/New() + ..() + if (empty) return + new /obj/item/weapon/storage/pill_bottle/bicaridine(src) + new /obj/item/weapon/storage/pill_bottle/dermaline(src) + new /obj/item/weapon/storage/pill_bottle/dexalin_plus(src) + new /obj/item/weapon/storage/pill_bottle/dylovene(src) + new /obj/item/weapon/storage/pill_bottle/tramadol(src) + new /obj/item/weapon/storage/pill_bottle/spaceacillin(src) + new /obj/item/stack/medical/splint(src) + return + +/obj/item/weapon/storage/firstaid/surgery + name = "surgery kit" + desc = "Contains tools for surgery." + +/obj/item/weapon/storage/firstaid/surgery/New() + ..() + if (empty) return + new /obj/item/weapon/bonesetter(src) + new /obj/item/weapon/cautery(src) + new /obj/item/weapon/circular_saw(src) + new /obj/item/weapon/hemostat(src) + new /obj/item/weapon/retractor(src) + new /obj/item/weapon/scalpel(src) + new /obj/item/weapon/surgicaldrill(src) + return + /* * Pill Bottles */ @@ -119,26 +154,12 @@ icon = 'icons/obj/chemical.dmi' item_state = "contsolid" w_class = 2.0 - can_hold = list("/obj/item/weapon/reagent_containers/pill","/obj/item/weapon/dice","/obj/item/weapon/paper") + can_hold = list(/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/dice,/obj/item/weapon/paper) allow_quick_gather = 1 use_to_pickup = 1 storage_slots = 14 use_sound = null -/obj/item/weapon/storage/pill_bottle/kelotane - name = "bottle of kelotane pills" - desc = "Contains pills used to treat burns." - - New() - ..() - new /obj/item/weapon/reagent_containers/pill/kelotane( src ) - new /obj/item/weapon/reagent_containers/pill/kelotane( src ) - new /obj/item/weapon/reagent_containers/pill/kelotane( src ) - new /obj/item/weapon/reagent_containers/pill/kelotane( src ) - new /obj/item/weapon/reagent_containers/pill/kelotane( src ) - new /obj/item/weapon/reagent_containers/pill/kelotane( src ) - new /obj/item/weapon/reagent_containers/pill/kelotane( src ) - /obj/item/weapon/storage/pill_bottle/antitox name = "bottle of Dylovene pills" desc = "Contains pills used to counter toxins." @@ -153,6 +174,62 @@ new /obj/item/weapon/reagent_containers/pill/antitox( src ) new /obj/item/weapon/reagent_containers/pill/antitox( src ) +/obj/item/weapon/storage/pill_bottle/bicaridine + name = "bottle of Bicaridine pills" + desc = "Contains pills used to stabilize the severely injured." + +/obj/item/weapon/storage/pill_bottle/bicaridine/New() + ..() + new /obj/item/weapon/reagent_containers/pill/bicaridine(src) + new /obj/item/weapon/reagent_containers/pill/bicaridine(src) + new /obj/item/weapon/reagent_containers/pill/bicaridine(src) + new /obj/item/weapon/reagent_containers/pill/bicaridine(src) + new /obj/item/weapon/reagent_containers/pill/bicaridine(src) + new /obj/item/weapon/reagent_containers/pill/bicaridine(src) + new /obj/item/weapon/reagent_containers/pill/bicaridine(src) + +/obj/item/weapon/storage/pill_bottle/dexalin_plus + name = "bottle of Dexalin Plus pills" + desc = "Contains pills used to treat extreme cases of oxygen deprivation." + +/obj/item/weapon/storage/pill_bottle/dexalin_plus/New() + ..() + new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) + new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) + new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) + new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) + new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) + new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) + new /obj/item/weapon/reagent_containers/pill/dexalin_plus(src) + +/obj/item/weapon/storage/pill_bottle/dermaline + name = "bottle of Dermaline pills" + desc = "Contains pills used to treat burn wounds." + +/obj/item/weapon/storage/pill_bottle/dermaline/New() + ..() + new /obj/item/weapon/reagent_containers/pill/dermaline(src) + new /obj/item/weapon/reagent_containers/pill/dermaline(src) + new /obj/item/weapon/reagent_containers/pill/dermaline(src) + new /obj/item/weapon/reagent_containers/pill/dermaline(src) + new /obj/item/weapon/reagent_containers/pill/dermaline(src) + new /obj/item/weapon/reagent_containers/pill/dermaline(src) + new /obj/item/weapon/reagent_containers/pill/dermaline(src) + +/obj/item/weapon/storage/pill_bottle/dylovene + name = "bottle of Dylovene pills" + desc = "Contains pills used to treat toxic substances in the blood." + +/obj/item/weapon/storage/pill_bottle/dylovene/New() + ..() + new /obj/item/weapon/reagent_containers/pill/dylovene(src) + new /obj/item/weapon/reagent_containers/pill/dylovene(src) + new /obj/item/weapon/reagent_containers/pill/dylovene(src) + new /obj/item/weapon/reagent_containers/pill/dylovene(src) + new /obj/item/weapon/reagent_containers/pill/dylovene(src) + new /obj/item/weapon/reagent_containers/pill/dylovene(src) + new /obj/item/weapon/reagent_containers/pill/dylovene(src) + /obj/item/weapon/storage/pill_bottle/inaprovaline name = "bottle of Inaprovaline pills" desc = "Contains pills used to stabilize patients." @@ -167,8 +244,36 @@ new /obj/item/weapon/reagent_containers/pill/inaprovaline( src ) new /obj/item/weapon/reagent_containers/pill/inaprovaline( src ) +/obj/item/weapon/storage/pill_bottle/kelotane + name = "bottle of kelotane pills" + desc = "Contains pills used to treat burns." + + New() + ..() + new /obj/item/weapon/reagent_containers/pill/kelotane( src ) + new /obj/item/weapon/reagent_containers/pill/kelotane( src ) + new /obj/item/weapon/reagent_containers/pill/kelotane( src ) + new /obj/item/weapon/reagent_containers/pill/kelotane( src ) + new /obj/item/weapon/reagent_containers/pill/kelotane( src ) + new /obj/item/weapon/reagent_containers/pill/kelotane( src ) + new /obj/item/weapon/reagent_containers/pill/kelotane( src ) + +/obj/item/weapon/storage/pill_bottle/spaceacillin + name = "bottle of Spaceacillin pills" + desc = "A theta-lactam antibiotic. Effective against many diseases likely to be encountered in space." + +/obj/item/weapon/storage/pill_bottle/spaceacillin/New() + ..() + new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) + new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) + new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) + new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) + new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) + new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) + new /obj/item/weapon/reagent_containers/pill/spaceacillin(src) + /obj/item/weapon/storage/pill_bottle/tramadol - name = "bottle of Tramadol Pills" + name = "bottle of Tramadol pills" desc = "Contains pills used to relieve pain." New() diff --git a/code/game/objects/items/weapons/storage/internal.dm b/code/game/objects/items/weapons/storage/internal.dm index 082002a5b9..5dda9b89c2 100644 --- a/code/game/objects/items/weapons/storage/internal.dm +++ b/code/game/objects/items/weapons/storage/internal.dm @@ -26,7 +26,7 @@ //returns 1 if the master item's parent's MouseDrop() should be called, 0 otherwise. It's strange, but no other way of //doing it without the ability to call another proc's parent, really. /obj/item/weapon/storage/internal/proc/handle_mousedrop(mob/user as mob, obj/over_object as obj) - if (ishuman(user) || ismonkey(user)) //so monkeys can take off their backpacks -- Urist + if (ishuman(user) || issmall(user)) //so monkeys can take off their backpacks -- Urist if (istype(user.loc,/obj/mecha)) // stops inventory actions in a mech return 0 @@ -37,12 +37,12 @@ if (!( istype(over_object, /obj/screen) )) return 1 - + //makes sure master_item is equipped before putting it in hand, so that we can't drag it into our hand from miles away. //there's got to be a better way of doing this... - if (!(master_item.loc == user) || (master_item.loc && master_item.loc.loc == user)) + if (!(master_item.loc == user) || (master_item.loc && master_item.loc.loc == user)) return 0 - + if (!( user.restrained() ) && !( user.stat )) switch(over_object.name) if("r_hand") @@ -70,12 +70,12 @@ H.put_in_hands(master_item) H.r_store = null return 0 - + src.add_fingerprint(user) if (master_item.loc == user) src.open(user) return 0 - + for(var/mob/M in range(1, master_item.loc)) if (M.s_active == src) src.close(M) diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm index 4bc4fb5f3c..2b584dc86e 100644 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ b/code/game/objects/items/weapons/storage/lockbox.dm @@ -7,7 +7,7 @@ item_state = "syringe_kit" w_class = 4 max_w_class = 3 - max_combined_w_class = 14 //The sum of the w_classes of all the items in this storage item. + max_storage_space = 14 //The sum of the w_classes of all the items in this storage item. storage_slots = 4 req_access = list(access_armory) var/locked = 1 diff --git a/code/game/objects/items/weapons/storage/misc.dm b/code/game/objects/items/weapons/storage/misc.dm index f3661916b7..814ee3b12c 100644 --- a/code/game/objects/items/weapons/storage/misc.dm +++ b/code/game/objects/items/weapons/storage/misc.dm @@ -1,41 +1,41 @@ -/obj/item/weapon/storage/pill_bottle/dice - name = "pack of dice" - desc = "It's a small container with dice inside." - - New() - ..() - new /obj/item/weapon/dice( src ) - new /obj/item/weapon/dice/d20( src ) - -/* - * Donut Box - */ - -/obj/item/weapon/storage/donut_box - icon = 'icons/obj/food.dmi' - icon_state = "donutbox" - name = "donut box" - storage_slots = 6 - var/startswith = 6 - can_hold = list("/obj/item/weapon/reagent_containers/food/snacks/donut") - foldable = /obj/item/stack/sheet/cardboard - -/obj/item/weapon/storage/donut_box/New() - ..() - for(var/i=1; i <= startswith; i++) - new /obj/item/weapon/reagent_containers/food/snacks/donut/normal(src) - update_icon() - return - -/obj/item/weapon/storage/donut_box/update_icon() - overlays.Cut() - var/i = 0 - for(var/obj/item/weapon/reagent_containers/food/snacks/donut/D in contents) - var/image/img = image('icons/obj/food.dmi', D.overlay_state) - img.pixel_x = i * 3 - overlays += img - i++ - -/obj/item/weapon/storage/donut_box/empty - icon_state = "donutbox0" - startswith = 0 +/obj/item/weapon/storage/pill_bottle/dice + name = "pack of dice" + desc = "It's a small container with dice inside." + + New() + ..() + new /obj/item/weapon/dice( src ) + new /obj/item/weapon/dice/d20( src ) + +/* + * Donut Box + */ + +/obj/item/weapon/storage/box/donut + icon = 'icons/obj/food.dmi' + icon_state = "donutbox" + name = "donut box" + storage_slots = 6 + var/startswith = 6 + can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/donut) + foldable = /obj/item/stack/sheet/cardboard + +/obj/item/weapon/storage/box/donut/New() + ..() + for(var/i=1; i <= startswith; i++) + new /obj/item/weapon/reagent_containers/food/snacks/donut/normal(src) + update_icon() + return + +/obj/item/weapon/storage/box/donut/update_icon() + overlays.Cut() + var/i = 0 + for(var/obj/item/weapon/reagent_containers/food/snacks/donut/D in contents) + var/image/img = image('icons/obj/food.dmi', D.overlay_state) + img.pixel_x = i * 3 + overlays += img + i++ + +/obj/item/weapon/storage/box/donut/empty + icon_state = "donutbox0" + startswith = 0 diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index 74c47cab05..1499c89d2c 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -23,9 +23,9 @@ var/l_hacking = 0 var/emagged = 0 var/open = 0 - w_class = 3.0 + w_class = 3 max_w_class = 2 - max_combined_w_class = 14 + max_storage_space = 14 examine(mob/user) if(..(user, 1)) @@ -220,7 +220,7 @@ max_w_class = 8 anchored = 1.0 density = 0 - cant_hold = list("/obj/item/weapon/storage/secure/briefcase") + cant_hold = list(/obj/item/weapon/storage/secure/briefcase) New() ..() diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index c32dedbefa..495d4d7516 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -8,11 +8,11 @@ /obj/item/weapon/storage name = "storage" icon = 'icons/obj/storage.dmi' - w_class = 3.0 + w_class = 3 var/list/can_hold = new/list() //List of objects which this item can store (if set, it can't store anything else) var/list/cant_hold = new/list() //List of objects which this item can't store (in effect only if can_hold isn't set) var/max_w_class = 2 //Max size of objects that this object can store (in effect only if can_hold isn't set) - var/max_combined_w_class = 14 //The sum of the w_classes of all the items in this storage item. + var/max_storage_space = 14 //The sum of the storage costs of all the items in this storage item. var/storage_slots = 7 //The number of storage slots in this container. var/obj/screen/storage/boxes = null var/obj/screen/close/closer = null @@ -21,7 +21,6 @@ var/allow_quick_empty //Set this variable to allow the object to have the 'empty' verb, which dumps all the contents on the floor. var/allow_quick_gather //Set this variable to allow the object to have the 'toggle mode' verb, which quickly collects all items from a tile. var/collection_mode = 1; //0 = pick one at a time, 1 = pick all on tile - var/foldable = null // BubbleWrap - if set, can be folded (when empty) into a sheet of cardboard var/use_sound = "rustle" //sound played when used. null for no sound. /obj/item/weapon/storage/MouseDrop(obj/over_object as obj) @@ -29,7 +28,7 @@ if(!canremove) return - if (ishuman(usr) || ismonkey(usr)) //so monkeys can take off their backpacks -- Urist + if (ishuman(usr) || issmall(usr)) //so monkeys can take off their backpacks -- Urist if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech return @@ -209,44 +208,36 @@ usr << "[src] is full, make some space." return 0 //Storage item is full - if(can_hold.len) - var/ok = 0 - for(var/A in can_hold) - if(istype(W, text2path(A) )) - ok = 1 - break - if(!ok) - if(!stop_messages) - if (istype(W, /obj/item/weapon/hand_labeler)) - return 0 - usr << "[src] cannot hold [W]." - return 0 + if(can_hold.len && !is_type_in_list(W, can_hold)) + if(!stop_messages) + if (istype(W, /obj/item/weapon/hand_labeler)) + return 0 + usr << "[src] cannot hold [W]." + return 0 - for(var/A in cant_hold) //Check for specific items which this container can't hold. - if(istype(W, text2path(A) )) - if(!stop_messages) - usr << "[src] cannot hold [W]." - return 0 + if(cant_hold.len && is_type_in_list(W, cant_hold)) + if(!stop_messages) + usr << "[src] cannot hold [W]." + return 0 if (W.w_class > max_w_class) if(!stop_messages) usr << "[W] is too big for this [src]." return 0 - var/sum_w_class = W.w_class + var/total_storage_space = W.get_storage_cost() for(var/obj/item/I in contents) - sum_w_class += I.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it. + total_storage_space += I.get_storage_cost() //Adds up the combined w_classes which will be in the storage item if the item is added to it. - if(sum_w_class > max_combined_w_class) + if(total_storage_space > max_storage_space) if(!stop_messages) usr << "[src] is full, make some space." return 0 if(W.w_class >= src.w_class && (istype(W, /obj/item/weapon/storage))) - if(!istype(src, /obj/item/weapon/storage/backpack/holding)) //bohs should be able to hold backpacks again. The override for putting a boh in a boh is in backpack.dm. - if(!stop_messages) - usr << "[src] cannot hold [W] as it's a storage item of the same size." - return 0 //To prevent the stacking of same sized storage items. + if(!stop_messages) + usr << "[src] cannot hold [W] as it's a storage item of the same size." + return 0 //To prevent the stacking of same sized storage items. return 1 @@ -266,13 +257,13 @@ W.dropped(usr) add_fingerprint(usr) - if(!prevent_warning && !istype(W, /obj/item/weapon/gun/energy/crossbow)) + if(!prevent_warning) for(var/mob/M in viewers(usr, null)) if (M == usr) usr << "You put \the [W] into [src]." else if (M in range(1)) //If someone is standing close enough, they can tell what it is... M.show_message("[usr] puts [W] into [src].") - else if (W && W.w_class >= 3.0) //Otherwise they can only see large or normal items from a distance... + else if (W && W.w_class >= 3) //Otherwise they can only see large or normal items from a distance... M.show_message("[usr] puts [W] into [src].") src.orient2hud(usr) @@ -422,35 +413,12 @@ O.emp_act(severity) ..() -// BubbleWrap - A box can be folded up to make card /obj/item/weapon/storage/attack_self(mob/user as mob) - //Clicking on itself will empty it, if it has the verb to do that. if(user.get_active_hand() == src) if(src.verbs.Find(/obj/item/weapon/storage/verb/quick_empty)) src.quick_empty() - return - - //Otherwise we'll try to fold it. - if ( contents.len ) - return - - if ( !ispath(src.foldable) ) - return - var/found = 0 - // Close any open UI windows first - for(var/mob/M in range(1)) - if (M.s_active == src) - src.close(M) - if ( M == user ) - found = 1 - if ( !found ) // User is too far away - return - // Now make the cardboard - user << "You fold [src] flat." - new src.foldable(get_turf(src)) - del(src) -//BubbleWrap END + return 1 /obj/item/weapon/storage/hear_talk(mob/M as mob, text, verb, datum/language/speaking) for (var/atom/A in src) @@ -493,3 +461,6 @@ return -1 //inside something with a null loc. return depth + +/obj/item/proc/get_storage_cost() + return 2**(w_class-1) //1,2,4,8,16,... diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index a585b96ce2..8f589f9883 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -5,20 +5,16 @@ icon_state = "red" item_state = "toolbox_red" flags = CONDUCT - force = 5.0 - throwforce = 10.0 + force = 5 + throwforce = 10 throw_speed = 1 throw_range = 7 - w_class = 4.0 + w_class = 4 + max_w_class = 3 + max_storage_space = 14 //can hold 7 w_class-2 items or up to 3 w_class-3 items (with 1 w_class-2 item as change). origin_tech = "combat=1" attack_verb = list("robusted") - New() - ..() - if (src.type == /obj/item/weapon/storage/toolbox) - world << "BAD: [src] ([src.type]) spawned at [src.x] [src.y] [src.z]" - del(src) - /obj/item/weapon/storage/toolbox/emergency name = "emergency toolbox" icon_state = "red" diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index fc1d2e2b8a..085e23f9b6 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -26,10 +26,11 @@ return if("guns") - new /obj/item/weapon/gun/projectile(src) + new /obj/item/weapon/gun/projectile/revolver(src) new /obj/item/ammo_magazine/a357(src) new /obj/item/weapon/card/emag(src) new /obj/item/weapon/plastique(src) + new /obj/item/weapon/plastique(src) return if("murder") @@ -47,6 +48,7 @@ return if("hacker") + new /obj/item/device/encryptionkey/syndicate(src) new /obj/item/weapon/aiModule/syndicate(src) new /obj/item/weapon/card/emag(src) new /obj/item/device/encryptionkey/binary(src) @@ -62,10 +64,9 @@ return if("smoothoperator") - new /obj/item/weapon/gun/projectile/pistol(src) - new /obj/item/weapon/silencer(src) - new /obj/item/weapon/soap/syndie(src) + new /obj/item/weapon/storage/box/syndie_kit/g9mm(src) new /obj/item/weapon/storage/bag/trash(src) + new /obj/item/weapon/soap/syndie(src) new /obj/item/bodybag(src) new /obj/item/clothing/under/suit_jacket(src) new /obj/item/clothing/shoes/laceup(src) @@ -149,3 +150,88 @@ ..() new /obj/item/weapon/stamp/chameleon(src) new /obj/item/weapon/pen/chameleon(src) + new /obj/item/device/destTagger(src) + new /obj/item/weapon/packageWrap(src) + new /obj/item/weapon/hand_labeler(src) + +/obj/item/weapon/storage/box/syndie_kit/spy + name = "spy kit" + desc = "For when you want to conduct voyeurism from afar." + +/obj/item/weapon/storage/box/syndie_kit/spy/New() + ..() + new /obj/item/device/spy_bug(src) + new /obj/item/device/spy_bug(src) + new /obj/item/device/spy_bug(src) + new /obj/item/device/spy_bug(src) + new /obj/item/device/spy_bug(src) + new /obj/item/device/spy_bug(src) + new /obj/item/device/spy_monitor(src) + +/obj/item/weapon/storage/box/syndie_kit/g9mm + name = "\improper Smooth operator" + desc = "9mm with silencer kit." + +/obj/item/weapon/storage/box/syndie_kit/g9mm/New() + ..() + new /obj/item/weapon/gun/projectile/pistol(src) + new /obj/item/weapon/silencer(src) + +/obj/item/weapon/storage/box/syndie_kit/toxin + name = "toxin kit" + desc = "An apple will not be enough to keep the doctor away after this." + +/obj/item/weapon/storage/box/syndie_kit/toxin/New() + ..() + new /obj/item/weapon/reagent_containers/glass/beaker/vial/random/toxin(src) + new /obj/item/weapon/reagent_containers/syringe(src) + +/obj/item/weapon/storage/box/syndie_kit/cigarette + name = "\improper Tricky smokes" + desc = "Comes with the following brands of cigarettes, in this order: 2xFlash, 2xSmoke, 1xMindBreaker, 1xTricordrazine. Avoid mixing them up." + +/obj/item/weapon/storage/box/syndie_kit/cigarette/New() + ..() + var/obj/item/weapon/storage/fancy/cigarettes/pack + pack = new /obj/item/weapon/storage/fancy/cigarettes(src) + fill_cigarre_package(pack, list("aluminum" = 5, "potassium" = 5, "sulfur" = 5)) + pack.desc += " 'F' has been scribbled on it." + + pack = new /obj/item/weapon/storage/fancy/cigarettes(src) + fill_cigarre_package(pack, list("aluminum" = 5, "potassium" = 5, "sulfur" = 5)) + pack.desc += " 'F' has been scribbled on it." + + pack = new /obj/item/weapon/storage/fancy/cigarettes(src) + fill_cigarre_package(pack, list("potassium" = 5, "sugar" = 5, "phosphorus" = 5)) + pack.desc += " 'S' has been scribbled on it." + + pack = new /obj/item/weapon/storage/fancy/cigarettes(src) + fill_cigarre_package(pack, list("potassium" = 5, "sugar" = 5, "phosphorus" = 5)) + pack.desc += " 'S' has been scribbled on it." + + pack = new /obj/item/weapon/storage/fancy/cigarettes(src) + // Dylovene. Going with 1.5 rather than 1.6666666... + fill_cigarre_package(pack, list("potassium" = 1.5, "nitrogen" = 1.5, "silicon" = 1.5)) + // Mindbreaker + fill_cigarre_package(pack, list("silicon" = 4.5, "hydrogen" = 4.5)) + + pack.desc += " 'MB' has been scribbled on it." + + pack = new /obj/item/weapon/storage/fancy/cigarettes(src) + pack.reagents.add_reagent("tricordrazine", 15 * pack.storage_slots) + pack.desc += " 'T' has been scribbled on it." + + new /obj/item/weapon/flame/lighter/zippo(src) + +/proc/fill_cigarre_package(var/obj/item/weapon/storage/fancy/cigarettes/C, var/list/reagents) + for(var/reagent in reagents) + C.reagents.add_reagent(reagent, reagents[reagent] * C.storage_slots) + +/obj/item/weapon/storage/box/syndie_kit/ewar_voice + name = "Electrowarfare and Voice Synthesiser kit" + desc = "Kit for confounding organic and synthetic entities alike." + +/obj/item/weapon/storage/box/syndie_kit/ewar_voice/New() + ..() + new /obj/item/rig_module/electrowarfare_suite(src) + new /obj/item/rig_module/voice(src) diff --git a/code/game/objects/items/weapons/storage/wallets.dm b/code/game/objects/items/weapons/storage/wallets.dm index 505263cf46..fb6829abf5 100644 --- a/code/game/objects/items/weapons/storage/wallets.dm +++ b/code/game/objects/items/weapons/storage/wallets.dm @@ -5,25 +5,25 @@ icon_state = "wallet" w_class = 2 can_hold = list( - "/obj/item/weapon/spacecash", - "/obj/item/weapon/card", - "/obj/item/clothing/mask/cigarette", - "/obj/item/device/flashlight/pen", - "/obj/item/seeds", - "/obj/item/stack/medical", - "/obj/item/toy/crayon", - "/obj/item/weapon/coin", - "/obj/item/weapon/dice", - "/obj/item/weapon/disk", - "/obj/item/weapon/implanter", - "/obj/item/weapon/flame/lighter", - "/obj/item/weapon/flame/match", - "/obj/item/weapon/paper", - "/obj/item/weapon/pen", - "/obj/item/weapon/photo", - "/obj/item/weapon/reagent_containers/dropper", - "/obj/item/weapon/screwdriver", - "/obj/item/weapon/stamp") + /obj/item/weapon/spacecash, + /obj/item/weapon/card, + /obj/item/clothing/mask/smokable/cigarette/, + /obj/item/device/flashlight/pen, + /obj/item/seeds, + /obj/item/stack/medical, + /obj/item/toy/crayon, + /obj/item/weapon/coin, + /obj/item/weapon/dice, + /obj/item/weapon/disk, + /obj/item/weapon/implanter, + /obj/item/weapon/flame/lighter, + /obj/item/weapon/flame/match, + /obj/item/weapon/paper, + /obj/item/weapon/pen, + /obj/item/weapon/photo, + /obj/item/weapon/reagent_containers/dropper, + /obj/item/weapon/screwdriver, + /obj/item/weapon/stamp) slot_flags = SLOT_ID var/obj/item/weapon/card/id/front_id = null diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 62890d849c..bd34960a35 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -113,7 +113,7 @@ var/mob/living/L = M var/target_zone = check_zone(user.zone_sel.selecting) - if(user.a_intent == "hurt") + if(user.a_intent == I_HURT) if (!..()) //item/attack() does it's own messaging and logs return 0 // item/attack() will return 1 if they hit, 0 if they missed. agony *= 0.5 //whacking someone causes a much poorer contact than prodding them. diff --git a/code/game/objects/items/weapons/surgery_limbattachment.dm b/code/game/objects/items/weapons/surgery_limbattachment.dm index e5a65ba9c7..23e5013f1a 100644 --- a/code/game/objects/items/weapons/surgery_limbattachment.dm +++ b/code/game/objects/items/weapons/surgery_limbattachment.dm @@ -4,7 +4,7 @@ if(!istype(M)) return ..() - if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/stool/bed/roller, M.loc) && (M.buckled || M.lying || M.weakened || M.stunned || M.paralysis || M.sleeping || M.stat)) && prob(75) || (locate(/obj/structure/table/, M.loc) && (M.lying || M.weakened || M.stunned || M.paralysis || M.sleeping || M.stat) && prob(66)))) + if(!((locate(/obj/machinery/optable, M.loc) && M.resting) || (locate(/obj/structure/bed/roller, M.loc) && (M.buckled || M.lying || M.weakened || M.stunned || M.paralysis || M.sleeping || M.stat)) && prob(75) || (locate(/obj/structure/table/, M.loc) && (M.lying || M.weakened || M.stunned || M.paralysis || M.sleeping || M.stat) && prob(66)))) return ..() if(!istype(M, /mob/living/carbon/human)) diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index e7d46bc68e..d466c65afa 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -41,7 +41,7 @@ log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])") */ - if (user.a_intent == "hurt") + if (user.a_intent == I_HURT) if(!..()) return //playsound(src.loc, "swing_hit", 50, 1, -1) if (M.stuttering < 8 && (!(HULK in M.mutations)) /*&& (!istype(H:wear_suit, /obj/item/clothing/suit/judgerobe))*/) diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index 551e4790dc..04d32c49b2 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -246,7 +246,7 @@ /obj/item/weapon/tank/process() //Allow for reactions - air_contents.react() + air_contents.react() //cooking up air tanks - add phoron and oxygen, then heat above PHORON_MINIMUM_BURN_TEMPERATURE check_status() diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index f8618a89df..52d1ba0b33 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -119,6 +119,8 @@ "You cut \the [C]'s restraints with \the [src]!",\ "You hear cable being cut.") C.handcuffed = null + if(C.buckled && C.buckled.buckle_require_restraints) + C.buckled.unbuckle_mob() C.update_inv_handcuffed() return else @@ -259,6 +261,9 @@ if (src.welding) remove_fuel(1) var/turf/location = get_turf(user) + if(isliving(O)) + var/mob/living/L = O + L.IgniteMob() if (istype(location, /turf)) location.hotspot_expose(700, 50, 1) return @@ -455,7 +460,7 @@ var/datum/organ/external/S = M:organs_by_name[user.zone_sel.selecting] if (!S) return - if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help") + if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP) return ..() if(istype(M,/mob/living/carbon/human)) @@ -531,4 +536,4 @@ if(!resolved && tool && target) tool.afterattack(target,user,1) if(tool) - tool.loc = src*/ + tool.loc = src*/ diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 2442320524..8a1e35ca98 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -21,6 +21,7 @@ var/force_wielded = 0 var/wieldsound = null var/unwieldsound = null + var/base_icon /obj/item/weapon/twohanded/proc/unwield() wielded = 0 @@ -34,6 +35,10 @@ name = "[initial(name)] (Wielded)" update_icon() +/obj/item/weapon/twohanded/New() + ..() + update_icon() + /obj/item/weapon/twohanded/mob_can_equip(M as mob, slot) //Cannot equip wielded items. if(wielded) @@ -51,18 +56,24 @@ return unwield() /obj/item/weapon/twohanded/update_icon() - return + icon_state = "[base_icon][wielded]" + item_state = icon_state /obj/item/weapon/twohanded/pickup(mob/user) unwield() /obj/item/weapon/twohanded/attack_self(mob/user as mob) - if( istype(user,/mob/living/carbon/monkey) ) - user << "It's too heavy for you to wield fully." - return ..() + if(istype(user, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + if(H.species.is_small) + user << "It's too heavy for you to wield fully." + return + else + return + if(wielded) //Trying to unwield it unwield() user << "You are now carrying the [name] with one hand." @@ -106,11 +117,15 @@ wield() del(src) +/obj/item/weapon/twohanded/offhand/update_icon() + return + /* * Fireaxe */ /obj/item/weapon/twohanded/fireaxe // DEM AXES MAN, marker -Agouri icon_state = "fireaxe0" + base_icon = "fireaxe" name = "fire axe" desc = "Truly, the weapon of a madman. Who would think to fight fire with an axe?" force = 10 @@ -121,10 +136,6 @@ force_wielded = 40 attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") -/obj/item/weapon/twohanded/fireaxe/update_icon() //Currently only here to fuck with the on-mob icons. - icon_state = "fireaxe[wielded]" - return - /obj/item/weapon/twohanded/fireaxe/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity) if(!proximity) return ..() @@ -146,6 +157,7 @@ */ /obj/item/weapon/twohanded/dualsaber icon_state = "dualsaber0" + base_icon = "dualsaber" name = "double-bladed energy sword" desc = "Handle with care." force = 3 @@ -162,10 +174,6 @@ sharp = 1 edge = 1 -/obj/item/weapon/twohanded/dualsaber/update_icon() - icon_state = "dualsaber[wielded]" - return - /obj/item/weapon/twohanded/dualsaber/attack(target as mob, mob/living/user as mob) ..() if((CLUMSY in user.mutations) && (wielded) &&prob(40)) @@ -187,6 +195,7 @@ //spears, bay edition /obj/item/weapon/twohanded/spear icon_state = "spearglass0" + base_icon = "spearglass" name = "spear" desc = "A haphazardly-constructed yet still deadly weapon of ancient design." force = 14 @@ -201,6 +210,29 @@ hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "poked", "jabbed", "torn", "gored") -/obj/item/weapon/twohanded/spear/update_icon() - icon_state = "spearglass[wielded]" - return +/obj/item/weapon/twohanded/baseballbat + name = "wooden bat" + desc = "HOME RUN!" + icon_state = "woodbat0" + base_icon = "woodbat" + item_state = "woodbat" + sharp = 0 + edge = 0 + w_class = 3 + force = 15 + throw_speed = 3 + throw_range = 7 + throwforce = 7 + attack_verb = list("smashed", "beaten", "slammed", "smacked", "striked", "battered", "bonked") + hitsound = 'sound/weapons/genhit3.ogg' + force_wielded = 23 + +/obj/item/weapon/twohanded/baseballbat/metal + name = "metal bat" + desc = "A shiny metal bat." + icon_state = "metalbat0" + base_icon = "metalbat" + item_state = "metalbat" + force = 18 + w_class = 3.0 + force_wielded = 27 \ No newline at end of file diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index b18198cbc0..295fa0c67d 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -11,7 +11,7 @@ attack_verb = list("banned") suicide_act(mob/user) - viewers(user) << "\red [user] is hitting \himself with the [src.name]! It looks like \he's trying to ban \himself from life." + viewers(user) << "[user] is hitting \himself with the [src.name]! It looks like \he's trying to ban \himself from life." return (BRUTELOSS|FIRELOSS|TOXLOSS|OXYLOSS) /obj/item/weapon/nullrod @@ -27,7 +27,7 @@ w_class = 2 suicide_act(mob/user) - viewers(user) << "\red [user] is impaling \himself with the [src.name]! It looks like \he's trying to commit suicide." + viewers(user) << "[user] is impaling \himself with the [src.name]! It looks like \he's trying to commit suicide." return (BRUTELOSS|FIRELOSS) /obj/item/weapon/nullrod/attack(mob/M as mob, mob/living/user as mob) //Paste from old-code to decult with a null rod. @@ -38,36 +38,34 @@ msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)") if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") - user << "\red You don't have the dexterity to do this!" + user << "You don't have the dexterity to do this!" return if ((CLUMSY in user.mutations) && prob(50)) - user << "\red The rod slips out of your hand and hits your head." + user << "The rod slips out of your hand and hits your head." user.take_organ_damage(10) user.Paralyse(20) return if (M.stat !=2) - if((M.mind in ticker.mode.cult) && prob(33)) - M << "\red The power of [src] clears your mind of the cult's influence!" - user << "\red You wave [src] over [M]'s head and see their eyes become clear, their mind returning to normal." - ticker.mode.remove_cultist(M.mind) - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] waves [] over []'s head.", user, src, M), 1) + if(cult && (M.mind in cult.current_antagonists) && prob(33)) + M << "The power of [src] clears your mind of the cult's influence!" + user << "You wave [src] over [M]'s head and see their eyes become clear, their mind returning to normal." + cult.remove_antagonist(M.mind) + M.visible_message("\The [user] waves \the [src] over \the [M]'s head.") else if(prob(10)) - user << "\red The rod slips in your hand." + user << "The rod slips in your hand." ..() else - user << "\red The rod appears to do nothing." - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] waves [] over []'s head.", user, src, M), 1) + user << "The rod appears to do nothing." + M.visible_message("\The [user] waves \the [src] over \the [M]'s head.") return /obj/item/weapon/nullrod/afterattack(atom/A, mob/user as mob, proximity) if(!proximity) return if (istype(A, /turf/simulated/floor)) - user << "\blue You hit the floor with the [src]." + user << "You hit the floor with the [src]." call(/obj/effect/rune/proc/revealrunes)(src) /obj/item/weapon/sord @@ -84,7 +82,7 @@ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") suicide_act(mob/user) - viewers(user) << "\red [user] is impaling \himself with the [src.name]! It looks like \he's trying to commit suicide." + viewers(user) << "[user] is impaling \himself with the [src.name]! It looks like \he's trying to commit suicide." return(BRUTELOSS) /obj/item/weapon/sord/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) @@ -109,7 +107,7 @@ return 1 suicide_act(mob/user) - viewers(user) << "\red [user] is falling on the [src.name]! It looks like \he's trying to commit suicide." + viewers(user) << "[user] is falling on the [src.name]! It looks like \he's trying to commit suicide." return(BRUTELOSS) /obj/item/weapon/claymore/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) @@ -131,7 +129,7 @@ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") suicide_act(mob/user) - viewers(user) << "\red [user] is slitting \his stomach open with the [src.name]! It looks like \he's trying to commit seppuku." + viewers(user) << "[user] is slitting \his stomach open with the [src.name]! It looks like \he's trying to commit seppuku." return(BRUTELOSS) /obj/item/weapon/katana/IsShield() @@ -153,30 +151,6 @@ w_class = 3 attack_verb = list("jabbed","stabbed","ripped") -/obj/item/weapon/baseballbat - name = "wooden bat" - desc = "HOME RUN!" - icon_state = "woodbat" - item_state = "woodbat" - sharp = 0 - edge = 0 - w_class = 3 - force = 15 - throw_speed = 3 - throw_range = 7 - throwforce = 7 - attack_verb = list("smashed", "beaten", "slammed", "smacked", "striked", "battered", "bonked") - hitsound = 'sound/weapons/genhit3.ogg' - - -/obj/item/weapon/baseballbat/metal - name = "metal bat" - desc = "A shiny metal bat." - icon_state = "metalbat" - item_state = "metalbat" - force = 18 - w_class = 3.0 - /obj/item/weapon/butterfly name = "butterfly knife" desc = "A basic metal blade concealed in a lightweight plasteel grip. Small enough when folded to fit in a pocket." diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 167794721b..51cb54ea2d 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -16,11 +16,27 @@ var/damtype = "brute" var/force = 0 -/obj/Topic(href, href_list, var/nowindow = 0) +/obj/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/custom_state = default_state) // Calling Topic without a corresponding window open causes runtime errors - if(nowindow) + if(!nowindow && ..()) + return 1 + + // In the far future no checks are made in an overriding Topic() beyond if(..()) return + // Instead any such checks are made in CanUseTopic() + var/obj/host = nano_host() + if(host.CanUseTopic(usr, href_list, custom_state) == STATUS_INTERACTIVE) + CouldUseTopic(usr) return 0 - return ..() + + CouldNotUseTopic(usr) + return 1 + +/obj/proc/CouldUseTopic(var/mob/user) + var/atom/host = nano_host() + host.add_fingerprint(user) + +/obj/proc/CouldNotUseTopic(var/mob/user) + // Nada /obj/item/proc/is_used_on(obj/O, mob/user) @@ -46,16 +62,6 @@ else return null -/obj/proc/handle_internal_lifeform(mob/lifeform_inside_me, breath_request) - //Return: (NONSTANDARD) - // null if object handles breathing logic for lifeform - // datum/air_group to tell lifeform to process using that breath return - //DEFAULT: Take air from turf to give to have mob process - if(breath_request>0) - return remove_air(breath_request) - else - return null - /atom/movable/proc/initialize() return diff --git a/code/game/objects/random/random.dm b/code/game/objects/random/random.dm index 53f4cc0903..7508d34a94 100644 --- a/code/game/objects/random/random.dm +++ b/code/game/objects/random/random.dm @@ -25,6 +25,15 @@ return (new build_path(src.loc)) +/obj/random/single + name = "randomly spawned object" + desc = "This item type is used to randomly spawn a given object at round-start" + icon_state = "x3" + var/spawn_object = null + item_to_spawn() + return ispath(spawn_object) ? spawn_object : text2path(spawn_object) + + /obj/random/tool name = "random tool" desc = "This is a random tool" @@ -104,3 +113,168 @@ prob(2);/obj/item/weapon/storage/belt/utility,\ prob(5);/obj/random/tool,\ prob(2);/obj/item/weapon/tape_roll) + +/obj/random/medical + name = "Random Medicine" + desc = "This is a random medical item." + icon = 'icons/obj/items.dmi' + icon_state = "brutepack" + spawn_nothing_percentage = 25 + item_to_spawn() + return pick(prob(4);/obj/item/stack/medical/bruise_pack,\ + prob(4);/obj/item/stack/medical/ointment,\ + prob(2);/obj/item/stack/medical/advanced/bruise_pack,\ + prob(2);/obj/item/stack/medical/advanced/ointment,\ + prob(1);/obj/item/stack/medical/splint,\ + prob(2);/obj/item/bodybag,\ + prob(1);/obj/item/bodybag/cryobag,\ + prob(2);/obj/item/weapon/storage/pill_bottle/kelotane,\ + prob(2);/obj/item/weapon/storage/pill_bottle/antitox,\ + prob(2);/obj/item/weapon/storage/pill_bottle/tramadol,\ + prob(2);/obj/item/weapon/reagent_containers/syringe/antitoxin,\ + prob(1);/obj/item/weapon/reagent_containers/syringe/antiviral,\ + prob(2);/obj/item/weapon/reagent_containers/syringe/inaprovaline,\ + prob(1);/obj/item/stack/nanopaste) + + +/obj/random/firstaid + name = "Random First Aid Kit" + desc = "This is a random first aid kit." + icon = 'icons/obj/storage.dmi' + icon_state = "firstaid" + item_to_spawn() + return pick(prob(3);/obj/item/weapon/storage/firstaid/regular,\ + prob(2);/obj/item/weapon/storage/firstaid/toxin,\ + prob(2);/obj/item/weapon/storage/firstaid/o2,\ + prob(1);/obj/item/weapon/storage/firstaid/adv,\ + prob(2);/obj/item/weapon/storage/firstaid/fire) + + +/obj/random/contraband + name = "Random Illegal Item" + desc = "Hot Stuff." + icon = 'icons/obj/items.dmi' + icon_state = "purplecomb" + spawn_nothing_percentage = 50 + item_to_spawn() + return pick(prob(3);/obj/item/weapon/storage/pill_bottle/tramadol,\ + prob(4);/obj/item/weapon/haircomb/fluff/cado_keppel_1,\ + prob(2);/obj/item/weapon/storage/pill_bottle/happy,\ + prob(2);/obj/item/weapon/storage/pill_bottle/zoom,\ + prob(5);/obj/item/weapon/contraband/poster,\ + prob(2);/obj/item/weapon/butterfly,\ + prob(3);/obj/item/butterflyblade,\ + prob(3);/obj/item/butterflyhandle,\ + prob(3);/obj/item/weapon/wirerod,\ + prob(1);/obj/item/weapon/butterfly/switchblade,\ + prob(1);/obj/item/weapon/reagent_containers/syringe/drugs) + + +/obj/random/energy + name = "Random Energy Weapon" + desc = "This is a random security weapon." + icon = 'icons/obj/gun.dmi' + icon_state = "energykill100" + item_to_spawn() + return pick(prob(2);/obj/item/weapon/gun/energy/laser,\ + prob(2);/obj/item/weapon/gun/energy/gun,\ + prob(1);/obj/item/weapon/gun/energy/stunrevolver) + +/obj/random/projectile + name = "Random Projectile Weapon" + desc = "This is a random security weapon." + icon = 'icons/obj/gun.dmi' + icon_state = "revolver" + item_to_spawn() + return pick(prob(3);/obj/item/weapon/gun/projectile/shotgun/pump,\ + prob(2);/obj/item/weapon/gun/projectile/automatic/wt550,\ + prob(1);/obj/item/weapon/gun/projectile/shotgun/pump/combat) + +/obj/random/handgun + name = "Random Handgun" + desc = "This is a random security sidearm." + icon = 'icons/obj/gun.dmi' + icon_state = "secgundark" + item_to_spawn() + return pick(prob(3);/obj/item/weapon/gun/projectile/sec,\ + prob(1);/obj/item/weapon/gun/projectile/sec/wood) + + +/obj/random/ammo + name = "Random Ammunition" + desc = "This is random ammunition." + icon = 'icons/obj/ammo.dmi' + icon_state = "45-10" + item_to_spawn() + return pick(prob(6);/obj/item/weapon/storage/box/beanbags,\ + prob(2);/obj/item/weapon/storage/box/shotgunammo,\ + prob(4);/obj/item/weapon/storage/box/shotgunshells,\ + prob(1);/obj/item/weapon/storage/box/stunshells,\ + prob(2);/obj/item/ammo_magazine/c45m,\ + prob(4);/obj/item/ammo_magazine/c45m/rubber,\ + prob(4);/obj/item/ammo_magazine/c45m/flash,\ + prob(2);/obj/item/ammo_magazine/mc9mmt,\ + prob(6);/obj/item/ammo_magazine/mc9mmt/rubber) + + +/obj/random/action_figure + name = "random action figure" + desc = "This is a random action figure." + icon = 'icons/obj/toy.dmi' + icon_state = "assistant" + item_to_spawn() + return pick(/obj/item/toy/figure/cmo,\ + /obj/item/toy/figure/assistant,\ + /obj/item/toy/figure/atmos,\ + /obj/item/toy/figure/bartender,\ + /obj/item/toy/figure/borg,\ + /obj/item/toy/figure/gardener,\ + /obj/item/toy/figure/captain,\ + /obj/item/toy/figure/cargotech,\ + /obj/item/toy/figure/ce,\ + /obj/item/toy/figure/chaplain,\ + /obj/item/toy/figure/chef,\ + /obj/item/toy/figure/chemist,\ + /obj/item/toy/figure/clown,\ + /obj/item/toy/figure/corgi,\ + /obj/item/toy/figure/detective,\ + /obj/item/toy/figure/dsquad,\ + /obj/item/toy/figure/engineer,\ + /obj/item/toy/figure/geneticist,\ + /obj/item/toy/figure/hop,\ + /obj/item/toy/figure/hos,\ + /obj/item/toy/figure/qm,\ + /obj/item/toy/figure/janitor,\ + /obj/item/toy/figure/agent,\ + /obj/item/toy/figure/librarian,\ + /obj/item/toy/figure/md,\ + /obj/item/toy/figure/mime,\ + /obj/item/toy/figure/miner,\ + /obj/item/toy/figure/ninja,\ + /obj/item/toy/figure/wizard,\ + /obj/item/toy/figure/rd,\ + /obj/item/toy/figure/roboticist,\ + /obj/item/toy/figure/scientist,\ + /obj/item/toy/figure/syndie,\ + /obj/item/toy/figure/secofficer,\ + /obj/item/toy/figure/warden,\ + /obj/item/toy/figure/psychologist,\ + /obj/item/toy/figure/paramedic,\ + /obj/item/toy/figure/ert) + + +/obj/random/plushie + name = "random plushie" + desc = "This is a random plushie." + icon = 'icons/obj/toy.dmi' + icon_state = "nymphplushie" + item_to_spawn() + return pick(/obj/structure/plushie/ian,\ + /obj/structure/plushie/drone,\ + /obj/structure/plushie/carp,\ + /obj/structure/plushie/beepsky,\ + /obj/item/toy/plushie/nymph,\ + /obj/item/toy/plushie/mouse,\ + /obj/item/toy/plushie/kitten,\ + /obj/item/toy/plushie/lizard) + diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index d105caae00..a23bb65cf8 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -20,7 +20,7 @@ var/mob/living/carbon/human/H = user if(H.species.can_shred(user)) attack_generic(user,1,"slices") - return + return ..() /obj/structure/blob_act() if(prob(50)) @@ -67,10 +67,10 @@ /obj/structure/MouseDrop_T(mob/target, mob/user) var/mob/living/H = user - if(!istype(H) || target != user) // No making other people climb onto tables. - return - - do_climb(target) + if(istype(H) && can_climb(H) && target == user) + do_climb(target) + else + return ..() /obj/structure/proc/can_climb(var/mob/living/user) if (!can_touch(user) || !climbable) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index d9abac8979..40163e7c78 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -161,6 +161,9 @@ del(src) /obj/structure/closet/bullet_act(var/obj/item/projectile/Proj) + if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) + return + health -= Proj.damage ..() if(health <= 0) diff --git a/code/game/objects/structures/crates_lockers/closets/fitness.dm b/code/game/objects/structures/crates_lockers/closets/fitness.dm index 05e7968a93..b42fe3f950 100644 --- a/code/game/objects/structures/crates_lockers/closets/fitness.dm +++ b/code/game/objects/structures/crates_lockers/closets/fitness.dm @@ -54,8 +54,8 @@ /obj/structure/closet/lasertag/red/New() ..() - new /obj/item/weapon/gun/energy/laser/redtag(src) - new /obj/item/weapon/gun/energy/laser/redtag(src) + new /obj/item/weapon/gun/energy/lasertag/red(src) + new /obj/item/weapon/gun/energy/lasertag/red(src) new /obj/item/clothing/suit/redtag(src) new /obj/item/clothing/suit/redtag(src) @@ -68,7 +68,7 @@ /obj/structure/closet/lasertag/blue/New() ..() - new /obj/item/weapon/gun/energy/laser/bluetag(src) - new /obj/item/weapon/gun/energy/laser/bluetag(src) + new /obj/item/weapon/gun/energy/lasertag/blue(src) + new /obj/item/weapon/gun/energy/lasertag/blue(src) new /obj/item/clothing/suit/bluetag(src) new /obj/item/clothing/suit/bluetag(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index 803f07616e..d583e77547 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -16,9 +16,9 @@ else new /obj/item/weapon/storage/backpack/satchel_eng(src) if (prob(70)) - new /obj/item/clothing/tie/storage/brown_vest(src) + new /obj/item/clothing/accessory/storage/brown_vest(src) else - new /obj/item/clothing/tie/storage/webbing(src) + new /obj/item/clothing/accessory/storage/webbing(src) new /obj/item/blueprints(src) new /obj/item/clothing/under/rank/chief_engineer(src) new /obj/item/clothing/head/hardhat/white(src) @@ -109,9 +109,9 @@ else new /obj/item/weapon/storage/backpack/satchel_eng(src) if (prob(70)) - new /obj/item/clothing/tie/storage/brown_vest(src) + new /obj/item/clothing/accessory/storage/brown_vest(src) else - new /obj/item/clothing/tie/storage/webbing(src) + new /obj/item/clothing/accessory/storage/webbing(src) new /obj/item/weapon/storage/toolbox/mechanical(src) new /obj/item/device/radio/headset/headset_eng(src) new /obj/item/clothing/suit/storage/hazardvest(src) @@ -138,9 +138,9 @@ else new /obj/item/weapon/storage/backpack/satchel_eng(src) if (prob(70)) - new /obj/item/clothing/tie/storage/brown_vest(src) + new /obj/item/clothing/accessory/storage/brown_vest(src) else - new /obj/item/clothing/tie/storage/webbing(src) + new /obj/item/clothing/accessory/storage/webbing(src) new /obj/item/clothing/suit/fire/firefighter(src) new /obj/item/device/flashlight(src) new /obj/item/weapon/extinguisher(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm index 2a1547e4ba..43d440c9f2 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm @@ -23,5 +23,6 @@ new /obj/item/clothing/head/greenbandana(src) new /obj/item/weapon/minihoe(src) new /obj/item/weapon/hatchet(src) + new /obj/item/weapon/wirecutters/clippers(src) // new /obj/item/weapon/bee_net(src) //No more bees, March 2014 return diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index c242e5f8c0..9eebafacc7 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -52,7 +52,7 @@ /obj/structure/closet/secure_closet/medical3 name = "medical doctor's locker" - req_access = list(access_surgery) + req_access = list(access_medical) icon_state = "securemed1" icon_closed = "securemed" icon_locked = "securemed1" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index b5b8796b3c..2480fff6da 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -18,7 +18,7 @@ new /obj/item/clothing/suit/captunic/capjacket(src) new /obj/item/clothing/head/helmet/cap(src) new /obj/item/clothing/under/rank/captain(src) - new /obj/item/clothing/suit/armor/vest(src) + new /obj/item/clothing/suit/storage/vest(src) new /obj/item/weapon/cartridge/captain(src) new /obj/item/clothing/head/helmet/swat(src) new /obj/item/clothing/shoes/brown(src) @@ -47,13 +47,14 @@ New() ..() new /obj/item/clothing/glasses/sunglasses(src) - new /obj/item/clothing/suit/armor/vest(src) + new /obj/item/clothing/suit/storage/vest(src) new /obj/item/clothing/head/helmet(src) new /obj/item/weapon/cartridge/hop(src) new /obj/item/device/radio/headset/heads/hop(src) new /obj/item/weapon/storage/box/ids(src) new /obj/item/weapon/storage/box/ids( src ) new /obj/item/weapon/gun/energy/gun(src) + new /obj/item/weapon/gun/projectile/sec/flash(src) new /obj/item/device/flash(src) return @@ -103,7 +104,7 @@ else new /obj/item/weapon/storage/backpack/satchel_sec(src) new /obj/item/clothing/head/helmet/HoS(src) - new /obj/item/clothing/suit/armor/vest(src) + new /obj/item/clothing/suit/storage/vest/hos(src) new /obj/item/clothing/under/rank/head_of_security/jensen(src) new /obj/item/clothing/under/rank/head_of_security/corp(src) new /obj/item/clothing/suit/armor/hos/jensen(src) @@ -119,7 +120,7 @@ new /obj/item/device/flash(src) new /obj/item/weapon/melee/baton/loaded(src) new /obj/item/weapon/gun/energy/gun(src) - new /obj/item/clothing/tie/holster/waist(src) + new /obj/item/clothing/accessory/holster/waist(src) new /obj/item/weapon/melee/telebaton(src) new /obj/item/clothing/head/beret/sec/hos(src) return @@ -143,12 +144,12 @@ new /obj/item/weapon/storage/backpack/security(src) else new /obj/item/weapon/storage/backpack/satchel_sec(src) - new /obj/item/clothing/suit/armor/vest/security(src) + new /obj/item/clothing/suit/storage/vest/warden(src) new /obj/item/clothing/under/rank/warden(src) new /obj/item/clothing/under/rank/warden/corp(src) new /obj/item/clothing/suit/armor/vest/warden(src) new /obj/item/clothing/head/helmet/warden(src) -// new /obj/item/weapon/cartridge/security(src) + new /obj/item/weapon/cartridge/security(src) new /obj/item/device/radio/headset/headset_sec(src) new /obj/item/clothing/glasses/sunglasses/sechud(src) new /obj/item/taperoll/police(src) @@ -156,7 +157,7 @@ new /obj/item/weapon/storage/belt/security(src) new /obj/item/weapon/reagent_containers/spray/pepper(src) new /obj/item/weapon/melee/baton/loaded(src) - new /obj/item/weapon/gun/energy/taser(src) + new /obj/item/weapon/gun/energy/gun(src) new /obj/item/weapon/storage/box/holobadge(src) new /obj/item/clothing/head/beret/sec/warden(src) return @@ -179,7 +180,7 @@ new /obj/item/weapon/storage/backpack/security(src) else new /obj/item/weapon/storage/backpack/satchel_sec(src) - new /obj/item/clothing/suit/armor/vest/security(src) + new /obj/item/clothing/suit/storage/vest/officer(src) new /obj/item/clothing/head/helmet(src) // new /obj/item/weapon/cartridge/security(src) new /obj/item/device/radio/headset/headset_sec(src) @@ -188,13 +189,14 @@ new /obj/item/weapon/reagent_containers/spray/pepper(src) new /obj/item/weapon/grenade/flashbang(src) new /obj/item/weapon/melee/baton/loaded(src) - new /obj/item/weapon/gun/energy/taser(src) new /obj/item/clothing/glasses/sunglasses/sechud(src) new /obj/item/taperoll/police(src) new /obj/item/device/hailer(src) - new /obj/item/clothing/tie/storage/black_vest(src) + new /obj/item/clothing/accessory/storage/black_vest(src) new /obj/item/clothing/head/soft/sec/corp(src) new /obj/item/clothing/under/rank/security/corp(src) + new /obj/item/ammo_magazine/c45m/rubber(src) + new /obj/item/weapon/gun/energy/taser(src) return @@ -202,7 +204,7 @@ New() ..() - new /obj/item/clothing/tie/armband/cargo(src) + new /obj/item/clothing/accessory/armband/cargo(src) new /obj/item/device/encryptionkey/headset_cargo(src) return @@ -210,7 +212,7 @@ New() ..() - new /obj/item/clothing/tie/armband/engine(src) + new /obj/item/clothing/accessory/armband/engine(src) new /obj/item/device/encryptionkey/headset_eng(src) return @@ -218,7 +220,7 @@ New() ..() - new /obj/item/clothing/tie/armband/science(src) + new /obj/item/clothing/accessory/armband/science(src) new /obj/item/device/encryptionkey/headset_sci(src) return @@ -226,7 +228,7 @@ New() ..() - new /obj/item/clothing/tie/armband/medgreen(src) + new /obj/item/clothing/accessory/armband/medgreen(src) new /obj/item/device/encryptionkey/headset_med(src) return @@ -257,12 +259,12 @@ new /obj/item/weapon/storage/box/evidence(src) new /obj/item/device/radio/headset/headset_sec(src) new /obj/item/device/detective_scanner(src) - new /obj/item/clothing/suit/armor/det_suit(src) - new /obj/item/ammo_magazine/c45r(src) - new /obj/item/ammo_magazine/c45r(src) + new /obj/item/clothing/suit/storage/vest/detective(src) + new /obj/item/ammo_magazine/c45m/rubber(src) + new /obj/item/ammo_magazine/c45m/rubber(src) new /obj/item/taperoll/police(src) - new /obj/item/weapon/gun/projectile/detective/semiauto(src) - new /obj/item/clothing/tie/holster/armpit(src) + new /obj/item/weapon/gun/projectile/colt/detective(src) + new /obj/item/clothing/accessory/holster/armpit(src) return /obj/structure/closet/secure_closet/detective/update_icon() diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm index fd548974af..c274a237b6 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm @@ -28,11 +28,15 @@ new /obj/item/weapon/tank/emergency_oxygen(src) new /obj/item/clothing/mask/breath(src) new /obj/item/clothing/mask/breath(src) + new /obj/item/clothing/suit/space/emergency(src) + new /obj/item/clothing/head/helmet/space/emergency(src) if ("aid") new /obj/item/weapon/tank/emergency_oxygen(src) new /obj/item/weapon/storage/toolbox/emergency(src) new /obj/item/clothing/mask/breath(src) new /obj/item/weapon/storage/firstaid/o2(src) + new /obj/item/clothing/suit/space/emergency(src) + new /obj/item/clothing/head/helmet/space/emergency(src) if ("tank") new /obj/item/weapon/tank/emergency_oxygen/engi(src) new /obj/item/clothing/mask/breath(src) @@ -43,6 +47,10 @@ new /obj/item/weapon/tank/emergency_oxygen/engi(src) new /obj/item/clothing/mask/breath(src) new /obj/item/weapon/storage/firstaid/o2(src) + new /obj/item/clothing/suit/space/emergency(src) + new /obj/item/clothing/suit/space/emergency(src) + new /obj/item/clothing/head/helmet/space/emergency(src) + new /obj/item/clothing/head/helmet/space/emergency(src) if ("nothing") // doot diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 4c233f24ef..917d244afa 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -30,7 +30,8 @@ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() - return 2 + if(usr.stunned) + return 2 playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3) for(var/obj/O in src) @@ -55,8 +56,8 @@ break if(O.density || O.anchored || istype(O,/obj/structure/closet)) continue - if(istype(O, /obj/structure/stool/bed)) //This is only necessary because of rollerbeds and swivel chairs. - var/obj/structure/stool/bed/B = O + if(istype(O, /obj/structure/bed)) //This is only necessary because of rollerbeds and swivel chairs. + var/obj/structure/bed/B = O if(B.buckled_mob) continue O.loc = src @@ -341,8 +342,10 @@ /obj/structure/closet/crate/freezer/rations/New() ..() - new /obj/item/weapon/storage/box/donkpockets(src) - new /obj/item/weapon/storage/box/donkpockets(src) + new /obj/item/weapon/reagent_containers/food/snacks/liquidfood(src) + new /obj/item/weapon/reagent_containers/food/snacks/liquidfood(src) + new /obj/item/weapon/reagent_containers/food/snacks/liquidfood(src) + new /obj/item/weapon/reagent_containers/food/snacks/liquidfood(src) /obj/structure/closet/crate/bin name = "large bin" diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 0ab10debe9..4eb2236ec0 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -15,7 +15,7 @@ if (1) new /obj/item/weapon/shard( src.loc ) if (occupied) - new /obj/item/weapon/gun/energy/laser/captain( src.loc ) + new /obj/item/weapon/gun/energy/captain( src.loc ) occupied = 0 del(src) if (2) @@ -39,14 +39,14 @@ if (prob(75)) new /obj/item/weapon/shard( src.loc ) if (occupied) - new /obj/item/weapon/gun/energy/laser/captain( src.loc ) + new /obj/item/weapon/gun/energy/captain( src.loc ) occupied = 0 del(src) /obj/structure/displaycase/meteorhit(obj/O as obj) new /obj/item/weapon/shard( src.loc ) - new /obj/item/weapon/gun/energy/laser/captain( src.loc ) + new /obj/item/weapon/gun/energy/captain( src.loc ) del(src) @@ -78,7 +78,7 @@ /obj/structure/displaycase/attack_hand(mob/user as mob) if (src.destroyed && src.occupied) - new /obj/item/weapon/gun/energy/laser/captain( src.loc ) + new /obj/item/weapon/gun/energy/captain( src.loc ) user << "\b You deactivate the hover field built into the case." src.occupied = 0 src.add_fingerprint(user) diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index b4281a6033..1b92926acd 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -135,7 +135,7 @@ /obj/structure/door_assembly/attackby(obj/item/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/pen)) - var/t = copytext(stripped_input(user, "Enter the name for the door.", src.name, src.created_name),1,MAX_NAME_LEN) + var/t = sanitizeSafe(input(user, "Enter the name for the door.", src.name, src.created_name), MAX_NAME_LEN) if(!t) return if(!in_range(src, usr) && src.loc != usr) return created_name = t @@ -248,6 +248,10 @@ glass = 1 else if(istype(S, /obj/item/stack/sheet/mineral) && S.sheettype) var/M = S.sheettype + // Ugly hack, will suffice for now. Need to fix it upstream as well, may rewrite mineral walls. ~Z + if(M in list("mhydrogen","osmium","tritium","platinum","iron")) + user << "You cannot make an airlock out of that material." + return if(S.get_amount() >= 2) playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1) user.visible_message("[user] adds [S.name] to the airlock assembly.", "You start to install [S.name] into the airlock assembly.") diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm index da68071090..074d7c7618 100644 --- a/code/game/objects/structures/electricchair.dm +++ b/code/game/objects/structures/electricchair.dm @@ -1,4 +1,4 @@ -/obj/structure/stool/bed/chair/e_chair +/obj/structure/bed/chair/e_chair name = "electric chair" desc = "Looks absolutely SHOCKING!" icon_state = "echair0" @@ -6,14 +6,14 @@ var/obj/item/assembly/shock_kit/part = null var/last_time = 1.0 -/obj/structure/stool/bed/chair/e_chair/New() +/obj/structure/bed/chair/e_chair/New() ..() overlays += image('icons/obj/objects.dmi', src, "echair_over", MOB_LAYER + 1, dir) return -/obj/structure/stool/bed/chair/e_chair/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/bed/chair/e_chair/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/wrench)) - var/obj/structure/stool/bed/chair/C = new /obj/structure/stool/bed/chair(loc) + var/obj/structure/bed/chair/C = new /obj/structure/bed/chair(loc) playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) C.set_dir(dir) part.loc = loc @@ -23,7 +23,7 @@ return return -/obj/structure/stool/bed/chair/e_chair/verb/toggle() +/obj/structure/bed/chair/e_chair/verb/toggle() set name = "Toggle Electric Chair" set category = "Object" set src in oview(1) @@ -37,13 +37,13 @@ usr << "You switch [on ? "on" : "off"] [src]." return -/obj/structure/stool/bed/chair/e_chair/rotate() +/obj/structure/bed/chair/e_chair/rotate() ..() overlays.Cut() overlays += image('icons/obj/objects.dmi', src, "echair_over", MOB_LAYER + 1, dir) //there's probably a better way of handling this, but eh. -Pete return -/obj/structure/stool/bed/chair/e_chair/proc/shock() +/obj/structure/bed/chair/e_chair/proc/shock() if(!on) return if(last_time + 50 > world.time) diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index db0a5acc91..85415cd162 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -5,6 +5,7 @@ layer = 2 var/state = 0 var/health = 200 + var/cover = 50 //how much cover the girder provides against projectiles. /obj/structure/girder/attack_generic(var/mob/user, var/damage, var/attack_message = "smashes apart", var/wallbreaker) if(!damage || !wallbreaker) @@ -14,19 +15,25 @@ return 1 /obj/structure/girder/bullet_act(var/obj/item/projectile/Proj) + //Girders only provide partial cover. There's a chance that the projectiles will just pass through. (unless you are trying to shoot the girder) + if(Proj.original != src && !prob(cover)) + return -1 //pass through //Tasers and the like should not damage girders. - if(Proj.damage_type == HALLOSS || Proj.damage_type == TOX || Proj.damage_type == CLONE) + if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) return - if(istype(Proj, /obj/item/projectile/beam)) - health -= Proj.damage - ..() - if(health <= 0) - new /obj/item/stack/sheet/metal(get_turf(src)) - del(src) + var/damage = Proj.damage + if(!istype(Proj, /obj/item/projectile/beam)) + damage *= 0.4 //non beams do reduced damage - return + health -= damage + ..() + if(health <= 0) + new /obj/item/stack/sheet/metal(get_turf(src)) + del(src) + + return /obj/structure/girder/attackby(obj/item/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/wrench) && state == 0) @@ -137,6 +144,10 @@ if(S.sheettype) var/M = S.sheettype + // Ugly hack, will suffice for now. Need to fix it upstream as well, may rewrite mineral walls. ~Z + if(M in list("mhydrogen","osmium","tritium","platinum","iron")) + user << "You cannot plate the girder in that material." + return if(!anchored) if(S.amount < 2) return S.use(2) @@ -209,11 +220,13 @@ icon_state = "displaced" anchored = 0 health = 50 + cover = 25 /obj/structure/girder/reinforced icon_state = "reinforced" state = 2 health = 500 + cover = 80 /obj/structure/cultgirder icon= 'icons/obj/cult.dmi' @@ -222,6 +235,7 @@ density = 1 layer = 2 var/health = 250 + var/cover = 70 /obj/structure/cultgirder/attack_generic(var/mob/user, var/damage, var/attack_message = "smashes apart", var/wallbreaker) if(!damage || !wallbreaker) @@ -258,6 +272,14 @@ dismantle() /obj/structure/cultgirder/bullet_act(var/obj/item/projectile/Proj) //No beam check- How else will you destroy the cult girder with silver bullets????? + //Girders only provide partial cover. There's a chance that the projectiles will just pass through. (unless you are trying to shoot the girder) + if(Proj.original != src && !prob(cover)) + return -1 //pass through + + //Tasers and the like should not damage cultgirders. + if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) + return + health -= Proj.damage ..() if(health <= 0) diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 2b06bcb534..b6407fd376 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -59,16 +59,40 @@ return !density /obj/structure/grille/bullet_act(var/obj/item/projectile/Proj) - if(!Proj) return //Tasers and the like should not damage grilles. - if(Proj.damage_type == HALLOSS) + if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) return - src.health -= Proj.damage*0.2 - healthcheck() - return 0 + //Flimsy grilles aren't so great at stopping projectiles. However they can absorb some of the impact + var/damage = Proj.damage + var/passthrough = 0 + + //20% chance that the grille provides a bit more cover than usual. Support structure for example might take up 20% of the grille's area. + //If they click on the grille itself then we assume they are aiming at the grille itself and the extra cover behaviour is always used. + switch(Proj.damage_type) + if(BRUTE) + //bullets + if(Proj.original == src || prob(20)) + Proj.damage *= between(0, Proj.damage/60, 0.5) + if(prob(max((damage-10)/25, 0))*100) + passthrough = 1 + else + Proj.damage *= between(0, Proj.damage/60, 1) + passthrough = 1 + if(BURN) + //beams and other projectiles are either blocked completely by grilles or stop half the damage. + if(!(Proj.original == src || prob(20))) + Proj.damage *= 0.5 + passthrough = 1 + + if(passthrough) + . = -1 + damage = between(0, (damage - Proj.damage)*(Proj.damage_type == BRUTE? 0.4 : 1), 10) //if the bullet passes through then the grille avoids most of the damage + + src.health -= damage*0.2 + spawn(0) healthcheck() //spawn to make sure we return properly if the grille is deleted /obj/structure/grille/attackby(obj/item/weapon/W as obj, mob/user as mob) if(iswirecutter(W)) @@ -115,7 +139,7 @@ if(WINDOW.dir == dir_to_set)//checking this for a 2nd time to check if a window was made while we were waiting. user << "There is already a window facing this way there." return - + var/wtype = ST.created_window if (ST.use(1)) var/obj/structure/window/WD = new wtype(loc, dir_to_set, 1) @@ -173,7 +197,8 @@ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() - return 1 + if(user.stunned) + return 1 else return 0 return 0 diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm index 9c5182382b..4bbb01a9c5 100644 --- a/code/game/objects/structures/inflatable.dm +++ b/code/game/objects/structures/inflatable.dm @@ -3,7 +3,7 @@ desc = "A folded membrane which rapidly expands into a large cubical shape on activation." icon = 'icons/obj/inflatable.dmi' icon_state = "folded_wall" - w_class = 3.0 + w_class = 3 attack_self(mob/user) playsound(loc, 'sound/items/zip.ogg', 75, 1) @@ -38,6 +38,9 @@ return 0 /obj/structure/inflatable/bullet_act(var/obj/item/projectile/Proj) + if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) + return + health -= Proj.damage ..() if(health <= 0) @@ -249,7 +252,8 @@ desc = "Contains inflatable walls and doors." icon_state = "inf_box" item_state = "syringe_kit" - max_combined_w_class = 21 + max_storage_space = 28 + can_hold = list(/obj/item/inflatable) New() ..() diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 0b542dd2bb..bd253da195 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -156,7 +156,7 @@ //old style retardo-cart -/obj/structure/stool/bed/chair/janicart +/obj/structure/bed/chair/janicart name = "janicart" icon = 'icons/obj/vehicles.dmi' icon_state = "pussywagon" @@ -169,12 +169,12 @@ var/callme = "pimpin' ride" //how do people refer to it? -/obj/structure/stool/bed/chair/janicart/New() +/obj/structure/bed/chair/janicart/New() create_reagents(100) update_layer() -/obj/structure/stool/bed/chair/janicart/examine(mob/user) +/obj/structure/bed/chair/janicart/examine(mob/user) if(!..(user, 1)) return @@ -183,7 +183,7 @@ user << "\A [mybag] is hanging on the [callme]." -/obj/structure/stool/bed/chair/janicart/attackby(obj/item/I, mob/user) +/obj/structure/bed/chair/janicart/attackby(obj/item/I, mob/user) if(istype(I, /obj/item/weapon/mop)) if(reagents.total_volume > 1) reagents.trans_to(I, 2) @@ -200,7 +200,7 @@ mybag = I -/obj/structure/stool/bed/chair/janicart/attack_hand(mob/user) +/obj/structure/bed/chair/janicart/attack_hand(mob/user) if(mybag) mybag.loc = get_turf(user) user.put_in_hands(mybag) @@ -209,9 +209,9 @@ ..() -/obj/structure/stool/bed/chair/janicart/relaymove(mob/user, direction) +/obj/structure/bed/chair/janicart/relaymove(mob/user, direction) if(user.stat || user.stunned || user.weakened || user.paralysis) - unbuckle() + unbuckle_mob() if(istype(user.l_hand, /obj/item/key) || istype(user.r_hand, /obj/item/key)) step(src, direction) update_mob() @@ -219,46 +219,34 @@ user << "You'll need the keys in one of your hands to drive this [callme]." -/obj/structure/stool/bed/chair/janicart/Move() +/obj/structure/bed/chair/janicart/Move() ..() if(buckled_mob) if(buckled_mob.buckled == src) buckled_mob.loc = loc -/obj/structure/stool/bed/chair/janicart/buckle_mob(mob/M, mob/user) - if(M != user || !ismob(M) || get_dist(src, user) > 1 || user.restrained() || user.lying || user.stat || M.buckled || istype(user, /mob/living/silicon)) - return - - unbuckle() - - M.visible_message(\ - "[M] climbs onto the [callme]!",\ - "You climb onto the [callme]!") - M.buckled = src - M.loc = loc - M.set_dir(dir) - M.update_canmove() - buckled_mob = M +/obj/structure/bed/chair/janicart/post_buckle_mob(mob/living/M) update_mob() - add_fingerprint(user) + return ..() -/obj/structure/stool/bed/chair/janicart/update_layer() +/obj/structure/bed/chair/janicart/update_layer() if(dir == SOUTH) layer = FLY_LAYER else layer = OBJ_LAYER -/obj/structure/stool/bed/chair/janicart/unbuckle() - if(buckled_mob) - buckled_mob.pixel_x = 0 - buckled_mob.pixel_y = 0 - ..() +/obj/structure/bed/chair/janicart/unbuckle_mob() + var/mob/living/M = ..() + if(M) + M.pixel_x = 0 + M.pixel_y = 0 + return M -/obj/structure/stool/bed/chair/janicart/set_dir() +/obj/structure/bed/chair/janicart/set_dir() ..() update_layer() if(buckled_mob) @@ -269,7 +257,7 @@ update_mob() -/obj/structure/stool/bed/chair/janicart/proc/update_mob() +/obj/structure/bed/chair/janicart/proc/update_mob() if(buckled_mob) buckled_mob.set_dir(dir) switch(dir) @@ -287,7 +275,7 @@ buckled_mob.pixel_y = 7 -/obj/structure/stool/bed/chair/janicart/bullet_act(var/obj/item/projectile/Proj) +/obj/structure/bed/chair/janicart/bullet_act(var/obj/item/projectile/Proj) if(buckled_mob) if(prob(85)) return buckled_mob.bullet_act(Proj) diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index f480cdd977..de2fef2875 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -4,75 +4,57 @@ name = "a meat spike" icon = 'icons/obj/kitchen.dmi' icon_state = "spike" - desc = "A spike for collecting meat from animals" + desc = "A spike for collecting meat from animals." density = 1 anchored = 1 var/meat = 0 - var/occupied = 0 - var/meattype = 0 // 0 - Nothing, 1 - Monkey, 2 - Xeno + var/occupied + var/meat_type + var/victim_name = "corpse" -/obj/structure/kitchenspike - - attackby(obj/item/weapon/grab/G as obj, mob/user as mob) - if(!istype(G, /obj/item/weapon/grab)) - return - if(istype(G.affecting, /mob/living/carbon/monkey)) - if(src.occupied == 0) - src.icon_state = "spikebloody" - src.occupied = 1 - src.meat = 5 - src.meattype = 1 - for(var/mob/O in viewers(src, null)) - O.show_message(text("\red [user] has forced [G.affecting] onto the spike, killing them instantly!")) - del(G.affecting) - del(G) - - else - user << "\red The spike already has something on it, finish collecting its meat first!" - else if(istype(G.affecting, /mob/living/carbon/alien)) - if(src.occupied == 0) - src.icon_state = "spikebloodygreen" - src.occupied = 1 - src.meat = 5 - src.meattype = 2 - for(var/mob/O in viewers(src, null)) - O.show_message(text("\red [user] has forced [G.affecting] onto the spike, killing them instantly!")) - del(G.affecting) - del(G) - else - user << "\red The spike already has something on it, finish collecting its meat first!" +/obj/structure/kitchenspike/attackby(obj/item/weapon/grab/G as obj, mob/user as mob) + if(!istype(G, /obj/item/weapon/grab) || !G.affecting) + return + if(occupied) + user << "The spike already has something on it, finish collecting its meat first!" + else + if(spike(G.affecting)) + visible_message("[user] has forced [G.affecting] onto the spike, killing them instantly!") + del(G.affecting) + del(G) else - user << "\red They are too big for the spike, try something smaller!" - return + user << "They are too big for the spike, try something smaller!" -// MouseDrop_T(var/atom/movable/C, mob/user) -// if(istype(C, /obj/mob/carbon/monkey) -// else if(istype(C, /obj/mob/carbon/alien) && !istype(C, /mob/living/carbon/alien/larva/slime)) -// else if(istype(C, /obj/livestock/spesscarp +/obj/structure/kitchenspike/proc/spike(var/mob/living/victim) - attack_hand(mob/user as mob) - if(..()) - return - if(src.occupied) - if(src.meattype == 1) - if(src.meat > 1) - src.meat-- - new /obj/item/weapon/reagent_containers/food/snacks/meat/monkey( src.loc ) - usr << "You remove some meat from the monkey." - else if(src.meat == 1) - src.meat-- - new /obj/item/weapon/reagent_containers/food/snacks/meat/monkey(src.loc) - usr << "You remove the last piece of meat from the monkey!" - src.icon_state = "spike" - src.occupied = 0 - else if(src.meattype == 2) - if(src.meat > 1) - src.meat-- - new /obj/item/weapon/reagent_containers/food/snacks/xenomeat( src.loc ) - usr << "You remove some meat from the alien." - else if(src.meat == 1) - src.meat-- - new /obj/item/weapon/reagent_containers/food/snacks/xenomeat(src.loc) - usr << "You remove the last piece of meat from the alien!" - src.icon_state = "spike" - src.occupied = 0 + if(!istype(victim)) + return + + if(istype(victim, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = victim + if(!H.species.is_small) + return 0 + meat_type = H.species.meat_type + icon_state = "spikebloody" + else if(istype(victim, /mob/living/carbon/alien)) + meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat + icon_state = "spikebloodygreen" + else + return 0 + + victim_name = victim.name + occupied = 1 + meat = 5 + return 1 + +/obj/structure/kitchenspike/attack_hand(mob/user as mob) + if(..() || !occupied) + return + meat-- + new meat_type(get_turf(src)) + if(src.meat > 1) + user << "You remove some meat from \the [victim_name]." + else if(src.meat == 1) + user << "You remove the last piece of meat from \the [victim_name]!" + icon_state = "spike" + occupied = 0 diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 58e1a81b97..83f295f9ef 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -1,65 +1,25 @@ //wip wip wup /obj/structure/mirror - name = "\improper SalonPro Nano-Mirror(TM)" - desc = "The leading technology in hair salon products, utilizing nano-machinery to style your hair just right." + name = "mirror" + desc = "A SalonPro Nano-Mirror(TM) brand mirror! The leading technology in hair salon products, utilizing nano-machinery to style your hair just right." icon = 'icons/obj/watercloset.dmi' icon_state = "mirror" density = 0 anchored = 1 var/shattered = 0 + var/list/ui_users = list() /obj/structure/mirror/attack_hand(mob/user as mob) if(shattered) return if(ishuman(user)) - var/mob/living/carbon/human/H = user - - if(H.a_intent == "hurt") - if(prob(30) || H.species.can_shred(H)) - attack_generic(user,1) - else - attack_generic(user) - return - - var/userloc = H.loc - - //see code/modules/mob/new_player/preferences.dm at approx line 545 for comments! - //this is largely copypasted from there. - - //handle facial hair (if necessary) - if(H.gender == MALE) - var/list/species_facial_hair = list() - if(H.species) - for(var/i in facial_hair_styles_list) - var/datum/sprite_accessory/facial_hair/tmp_facial = facial_hair_styles_list[i] - if(H.species.name in tmp_facial.species_allowed) - species_facial_hair += i - else - species_facial_hair = facial_hair_styles_list - - var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in species_facial_hair - if(userloc != H.loc) return //no tele-grooming - if(new_style) - H.f_style = new_style - - //handle normal hair - var/list/species_hair = list() - if(H.species) - for(var/i in hair_styles_list) - var/datum/sprite_accessory/hair/tmp_hair = hair_styles_list[i] - if(H.species.name in tmp_hair.species_allowed) - species_hair += i - else - species_hair = hair_styles_list - - var/new_style = input(user, "Select a hair style", "Grooming") as null|anything in species_hair - if(userloc != H.loc) return //no tele-grooming - if(new_style) - H.h_style = new_style - - H.update_hair() - + var/obj/nano_module/appearance_changer/AC = ui_users[user] + if(!AC) + AC = new(src, user) + AC.name = "SalonPro Nano-Mirror(TM)" + ui_users[user] = AC + AC.ui_interact(user) /obj/structure/mirror/proc/shatter() if(shattered) return @@ -70,6 +30,9 @@ /obj/structure/mirror/bullet_act(var/obj/item/projectile/Proj) + if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) + return + if(prob(Proj.damage * 2)) if(!shattered) shatter() @@ -101,3 +64,32 @@ else user.visible_message("[user] hits [src] and bounces off!") return 1 + +// The following mirror is ~special~. +/obj/structure/mirror/raider + name = "cracked mirror" + desc = "Something seems strange about this old, dirty mirror. Your reflection doesn't look like you remember it." + icon_state = "mirror_broke" + shattered = 1 + +/obj/structure/mirror/raider/attack_hand(var/mob/living/carbon/human/user) + if(istype(get_area(src),/area/syndicate_mothership)) + if(istype(user) && user.mind && user.mind.special_role == "Raider" && user.species != "Vox" && is_alien_whitelisted(user, "Vox")) + var/choice = input("Do you wish to become a Vox? This is not reversible.") as null|anything in list("No","Yes") + if(choice && choice == "Yes") + var/mob/living/carbon/human/vox/vox = new(get_turf(src),"Vox") + vox.gender = user.gender + raiders.equip(vox) + if(user.mind) + user.mind.transfer_to(vox) + spawn(1) + var/newname = input(vox,"Enter a name, or leave blank for the default name.", "Name change","") as text + newname = sanitize(newname) + if(!newname || newname == "") + var/datum/language/L = all_languages[vox.species.default_language] + newname = L.get_random_name() + vox.real_name = newname + vox.name = vox.real_name + raiders.update_access(vox) + del(user) + ..() diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 5d00b0a0cb..1f597b0c96 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -92,7 +92,7 @@ return if ((!in_range(src, usr) && src.loc != user)) return - t = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) + t = sanitize(t) if (t) src.name = text("Morgue- '[]'", t) else @@ -258,7 +258,7 @@ return if ((!in_range(src, usr) > 1 && src.loc != user)) return - t = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) + t = sanitize(t) if (t) src.name = text("Crematorium- '[]'", t) else @@ -379,12 +379,21 @@ //Foreach goto(99) return -/obj/machinery/crema_switch/attack_hand(mob/user as mob) +/obj/machinery/button/crematorium + name = "crematorium igniter" + desc = "Burn baby burn!" + icon = 'icons/obj/power.dmi' + icon_state = "crema_switch" + req_access = list(access_crematorium) + id = 1 + +/obj/machinery/button/crematorium/attack_hand(mob/user as mob) + if(..()) + return if(src.allowed(usr)) for (var/obj/structure/crematorium/C in world) if (C.id == id) if (!C.cremating) C.cremate(user) else - usr << "\red Access denied." - return + usr << "Access denied." diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index a219268d04..199635cd0f 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -90,7 +90,7 @@ FLOOR SAFES var/mob/living/carbon/human/user = usr var/canhear = 0 - if(istype(user.l_hand, /obj/item/clothing/tie/stethoscope) || istype(user.r_hand, /obj/item/clothing/tie/stethoscope)) + if(istype(user.l_hand, /obj/item/clothing/accessory/stethoscope) || istype(user.r_hand, /obj/item/clothing/accessory/stethoscope)) canhear = 1 if(href_list["open"]) @@ -155,7 +155,7 @@ FLOOR SAFES user << "[I] won't fit in [src]." return else - if(istype(I, /obj/item/clothing/tie/stethoscope)) + if(istype(I, /obj/item/clothing/accessory/stethoscope)) user << "Hold [I] in one of your hands while you manipulate the dial." return diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index e67fea3849..489e81a739 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -1,14 +1,14 @@ //Alium nests. Essentially beds with an unbuckle delay that only aliums can buckle mobs to. #define NEST_RESIST_TIME 1200 -/obj/structure/stool/bed/nest +/obj/structure/bed/nest name = "alien nest" desc = "It's a gruesome pile of thick, sticky resin shaped like a nest." icon = 'icons/mob/alien.dmi' icon_state = "nest" var/health = 100 -/obj/structure/stool/bed/nest/manual_unbuckle(mob/user as mob) +/obj/structure/bed/nest/user_unbuckle_mob(mob/user as mob) if(buckled_mob) if(buckled_mob.buckled == src) if(buckled_mob != user) @@ -18,7 +18,7 @@ "You hear squelching...") buckled_mob.pixel_y = 0 buckled_mob.old_y = 0 - unbuckle() + unbuckle_mob() else if(world.time <= buckled_mob.last_special+NEST_RESIST_TIME) return @@ -32,16 +32,15 @@ buckled_mob.last_special = world.time buckled_mob.pixel_y = 0 buckled_mob.old_y = 0 - unbuckle() + unbuckle_mob() src.add_fingerprint(user) return -/obj/structure/stool/bed/nest/buckle_mob(mob/M as mob, mob/user as mob) - +/obj/structure/bed/nest/user_buckle_mob(mob/M as mob, mob/user as mob) if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || usr.stat || M.buckled || istype(user, /mob/living/silicon/pai) ) return - unbuckle() + unbuckle_mob() var/mob/living/carbon/xenos = user var/mob/living/carbon/victim = M @@ -69,7 +68,7 @@ src.add_fingerprint(user) return -/obj/structure/stool/bed/nest/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/bed/nest/attackby(obj/item/weapon/W as obj, mob/user as mob) var/aforce = W.force health = max(0, health - aforce) playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) @@ -77,7 +76,7 @@ M.show_message("[user] hits [src] with [W]!", 1) healthcheck() -/obj/structure/stool/bed/nest/proc/healthcheck() +/obj/structure/bed/nest/proc/healthcheck() if(health <=0) density = 0 del(src) diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index 8902dbc8ec..6d50066a74 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -7,120 +7,66 @@ /* * Beds */ -/obj/structure/stool/bed +/obj/structure/bed name = "bed" desc = "This is used to lie in, sleep in or strap on." + icon = 'icons/obj/objects.dmi' icon_state = "bed" - var/mob/living/buckled_mob - var/movable = 0 // For mobility checks + pressure_resistance = 15 + anchored = 1 + can_buckle = 1 + buckle_lying = 1 -/obj/structure/stool/bed/psych +/obj/structure/bed/ex_act(severity) + switch(severity) + if(1.0) + del(src) + return + if(2.0) + if (prob(50)) + del(src) + return + if(3.0) + if (prob(5)) + del(src) + return + +/obj/structure/bed/blob_act() + if(prob(75)) + new /obj/item/stack/sheet/metal(src.loc) + del(src) + +/obj/structure/bed/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/wrench)) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + new /obj/item/stack/sheet/metal(src.loc) + del(src) + else + ..() + +/obj/structure/bed/psych name = "psychiatrists couch" desc = "For prime comfort during psychiatric evaluations." icon_state = "psychbed" -/obj/structure/stool/bed/alien +/obj/structure/bed/alien name = "resting contraption" desc = "This looks similar to contraptions from earth. Could aliens be stealing our technology?" icon_state = "abed" -/obj/structure/stool/bed/Del() - unbuckle() - ..() - return - -/obj/structure/stool/bed/attack_hand(mob/user as mob) - manual_unbuckle(user) - return - -/obj/structure/stool/bed/MouseDrop(atom/over_object) - return - -/obj/structure/stool/bed/MouseDrop_T(mob/M as mob, mob/user as mob) - if(!istype(M)) return - buckle_mob(M, user) - return - -/obj/structure/stool/bed/proc/afterbuckle(mob/M as mob) // Called after somebody buckled / unbuckled - return - - -/obj/structure/stool/bed/proc/unbuckle() - if(buckled_mob) - if(buckled_mob.buckled == src) //this is probably unneccesary, but it doesn't hurt - buckled_mob.buckled = null - buckled_mob.anchored = initial(buckled_mob.anchored) - buckled_mob.update_canmove() - - var/M = buckled_mob - buckled_mob = null - - afterbuckle(M) - return - -/obj/structure/stool/bed/proc/manual_unbuckle(mob/user as mob) - if(buckled_mob) - if(buckled_mob.buckled == src) - if(buckled_mob != user) - buckled_mob.visible_message(\ - "\blue [buckled_mob.name] was unbuckled by [user.name]!",\ - "You were unbuckled from [src] by [user.name].",\ - "You hear metal clanking") - else - buckled_mob.visible_message(\ - "\blue [buckled_mob.name] unbuckled \himself!",\ - "You unbuckle yourself from [src].",\ - "You hear metal clanking") - unbuckle() - src.add_fingerprint(user) - return 1 - - return 0 - -/obj/structure/stool/bed/proc/buckle_mob(mob/M as mob, mob/user as mob) - if (!ticker) - user << "You can't buckle anyone in before the game starts." - if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || user.lying || user.stat || M.buckled || M.pinned.len || istype(user, /mob/living/silicon/pai) ) - return - - if (istype(M, /mob/living/carbon/slime)) - user << "The [M] is too squishy to buckle in." - return - - unbuckle() - - if (M == usr) - M.visible_message(\ - "\blue [M.name] buckles in!",\ - "You buckle yourself to [src].",\ - "You hear metal clanking") - else - M.visible_message(\ - "\blue [M.name] is buckled in to [src] by [user.name]!",\ - "You are buckled in to [src] by [user.name].",\ - "You hear metal clanking") - M.buckled = src - M.loc = src.loc - M.set_dir(src.dir) - M.update_canmove() - src.buckled_mob = M - src.add_fingerprint(user) - afterbuckle(M) - return - /* * Roller beds */ -/obj/structure/stool/bed/roller +/obj/structure/bed/roller name = "roller bed" icon = 'icons/obj/rollerbed.dmi' icon_state = "down" anchored = 0 -/obj/structure/stool/bed/roller/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/bed/roller/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W,/obj/item/roller_holder)) if(buckled_mob) - manual_unbuckle() + user_unbuckle_mob(user) else visible_message("[user] collapses \the [src.name].") new/obj/item/roller(get_turf(src)) @@ -137,7 +83,7 @@ w_class = 4.0 // Can't be put in backpacks. Oh well. /obj/item/roller/attack_self(mob/user) - var/obj/structure/stool/bed/roller/R = new /obj/structure/stool/bed/roller(user.loc) + var/obj/structure/bed/roller/R = new /obj/structure/bed/roller(user.loc) R.add_fingerprint(user) del(src) @@ -171,13 +117,13 @@ return user << "\blue You deploy the roller bed." - var/obj/structure/stool/bed/roller/R = new /obj/structure/stool/bed/roller(user.loc) + var/obj/structure/bed/roller/R = new /obj/structure/bed/roller(user.loc) R.add_fingerprint(user) del(held) held = null -/obj/structure/stool/bed/roller/Move() +/obj/structure/bed/roller/Move() ..() if(buckled_mob) if(buckled_mob.buckled == src) @@ -185,31 +131,21 @@ else buckled_mob = null -/obj/structure/stool/bed/roller/buckle_mob(mob/M as mob, mob/user as mob) - if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || user.lying || user.stat || M.buckled || istype(usr, /mob/living/silicon/pai) ) - return - M.pixel_y = 6 - M.old_y = 6 - density = 1 - icon_state = "up" - ..() - return +/obj/structure/bed/roller/post_buckle_mob(mob/living/M as mob) + if(M == buckled_mob) + M.pixel_y = 6 + M.old_y = 6 + density = 1 + icon_state = "up" + else + M.pixel_y = 0 + M.old_y = 0 + density = 0 + icon_state = "down" -/obj/structure/stool/bed/roller/manual_unbuckle(mob/user as mob) - if(buckled_mob) - if(buckled_mob.buckled == src) //this is probably unneccesary, but it doesn't hurt - buckled_mob.pixel_y = 0 - buckled_mob.old_y = 0 - buckled_mob.anchored = initial(buckled_mob.anchored) - buckled_mob.buckled = null - buckled_mob.update_canmove() - buckled_mob = null - density = 0 - icon_state = "down" - ..() - return + return ..() -/obj/structure/stool/bed/roller/MouseDrop(over_object, src_location, over_location) +/obj/structure/bed/roller/MouseDrop(over_object, src_location, over_location) ..() if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src)))) if(!ishuman(usr)) return diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index 908df25d9e..5c4728313b 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -1,20 +1,18 @@ -/obj/structure/stool/bed/chair //YES, chairs are a type of bed, which are a type of stool. This works, believe me. -Pete +/obj/structure/bed/chair //YES, chairs are a type of bed, which are a type of stool. This works, believe me. -Pete name = "chair" desc = "You sit in this. Either by will or force." icon_state = "chair" + buckle_lying = 0 //force people to sit up in chairs when buckled var/propelled = 0 // Check for fire-extinguisher-driven chairs -/obj/structure/stool/MouseDrop(atom/over_object) - return - -/obj/structure/stool/bed/chair/New() +/obj/structure/bed/chair/New() ..() spawn(3) //sorry. i don't think there's a better way to do this. update_layer() return -/obj/structure/stool/bed/chair/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/bed/chair/attackby(obj/item/weapon/W as obj, mob/user as mob) ..() if(istype(W, /obj/item/assembly/shock_kit)) var/obj/item/assembly/shock_kit/SK = W @@ -22,7 +20,7 @@ user << "[SK] is not ready to be attached!" return user.drop_item() - var/obj/structure/stool/bed/chair/e_chair/E = new /obj/structure/stool/bed/chair/e_chair(src.loc) + var/obj/structure/bed/chair/e_chair/E = new /obj/structure/bed/chair/e_chair(src.loc) playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) E.set_dir(dir) E.part = SK @@ -30,26 +28,26 @@ SK.master = E del(src) -/obj/structure/stool/bed/chair/attack_tk(mob/user as mob) +/obj/structure/bed/chair/attack_tk(mob/user as mob) if(buckled_mob) ..() else rotate() return -/obj/structure/stool/bed/chair/proc/update_layer() +/obj/structure/bed/chair/proc/update_layer() if(src.dir == NORTH) src.layer = FLY_LAYER else src.layer = OBJ_LAYER -/obj/structure/stool/bed/chair/set_dir() +/obj/structure/bed/chair/set_dir() ..() update_layer() if(buckled_mob) buckled_mob.set_dir(dir) -/obj/structure/stool/bed/chair/verb/rotate() +/obj/structure/bed/chair/verb/rotate() set name = "Rotate Chair" set category = "Object" set src in oview(1) @@ -68,23 +66,18 @@ src.set_dir(turn(src.dir, 90)) return -/obj/structure/stool/bed/chair/MouseDrop_T(mob/M as mob, mob/user as mob) - if(!istype(M)) return - buckle_mob(M, user) - return - // Chair types -/obj/structure/stool/bed/chair/wood/normal +/obj/structure/bed/chair/wood/normal icon_state = "wooden_chair" name = "wooden chair" desc = "Old is never too old to not be in fashion." -/obj/structure/stool/bed/chair/wood/wings +/obj/structure/bed/chair/wood/wings icon_state = "wooden_chair_wings" name = "wooden chair" desc = "Old is never too old to not be in fashion." -/obj/structure/stool/bed/chair/wood/attackby(obj/item/weapon/W as obj, mob/user as mob) +/obj/structure/bed/chair/wood/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/wrench)) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) new /obj/item/stack/sheet/wood(src.loc) @@ -92,57 +85,57 @@ else ..() -/obj/structure/stool/bed/chair/comfy +/obj/structure/bed/chair/comfy name = "comfy chair" desc = "It looks comfy." icon_state = "comfychair" color = rgb(255,255,255) var/image/armrest = null -/obj/structure/stool/bed/chair/comfy/New() +/obj/structure/bed/chair/comfy/New() armrest = image("icons/obj/objects.dmi", "comfychair_armrest") armrest.layer = MOB_LAYER + 0.1 return ..() -/obj/structure/stool/bed/chair/comfy/afterbuckle() +/obj/structure/bed/chair/comfy/post_buckle_mob() if(buckled_mob) overlays += armrest else overlays -= armrest -/obj/structure/stool/bed/chair/comfy/brown +/obj/structure/bed/chair/comfy/brown color = rgb(141,70,0) -/obj/structure/stool/bed/chair/comfy/red +/obj/structure/bed/chair/comfy/red color = rgb(218,2,10) -/obj/structure/stool/bed/chair/comfy/teal +/obj/structure/bed/chair/comfy/teal color = rgb(0,234,250) -/obj/structure/stool/bed/chair/comfy/black +/obj/structure/bed/chair/comfy/black color = rgb(60,60,60) -/obj/structure/stool/bed/chair/comfy/green +/obj/structure/bed/chair/comfy/green color = rgb(1,196,8) -/obj/structure/stool/bed/chair/comfy/purp +/obj/structure/bed/chair/comfy/purp color = rgb(112,2,176) -/obj/structure/stool/bed/chair/comfy/blue +/obj/structure/bed/chair/comfy/blue color = rgb(2,9,210) -/obj/structure/stool/bed/chair/comfy/beige +/obj/structure/bed/chair/comfy/beige color = rgb(255,253,195) -/obj/structure/stool/bed/chair/office +/obj/structure/bed/chair/office anchored = 0 - movable = 1 + buckle_movable = 1 -/obj/structure/stool/bed/chair/comfy/lime +/obj/structure/bed/chair/comfy/lime color = rgb(255,251,0) -/obj/structure/stool/bed/chair/office/Move() +/obj/structure/bed/chair/office/Move() ..() if(buckled_mob) var/mob/living/occupant = buckled_mob @@ -155,15 +148,14 @@ if (O != occupant) Bump(O) else - unbuckle() + unbuckle_mob() -/obj/structure/stool/bed/chair/office/Bump(atom/A) +/obj/structure/bed/chair/office/Bump(atom/A) ..() if(!buckled_mob) return if(propelled) - var/mob/living/occupant = buckled_mob - unbuckle() + var/mob/living/occupant = unbuckle_mob() var/def_zone = ran_zone() var/blocked = occupant.run_armor_check(def_zone, "melee") @@ -183,8 +175,8 @@ victim.apply_damage(10, BRUTE, def_zone, blocked) occupant.visible_message("[occupant] crashed into \the [A]!") -/obj/structure/stool/bed/chair/office/light +/obj/structure/bed/chair/office/light icon_state = "officechair_white" -/obj/structure/stool/bed/chair/office/dark +/obj/structure/bed/chair/office/dark icon_state = "officechair_dark" diff --git a/code/game/objects/structures/stool_bed_chair_nest/stools.dm b/code/game/objects/structures/stool_bed_chair_nest/stools.dm index d898c82961..16e9161dcf 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/stools.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/stools.dm @@ -1,79 +1,11 @@ -/obj/structure/stool +/obj/item/weapon/stool name = "stool" desc = "Apply butt." icon = 'icons/obj/objects.dmi' icon_state = "stool" - anchored = 1.0 - pressure_resistance = 15 - -/obj/structure/stool/ex_act(severity) - switch(severity) - if(1.0) - del(src) - return - if(2.0) - if (prob(50)) - del(src) - return - if(3.0) - if (prob(5)) - del(src) - return - return - -/obj/structure/stool/blob_act() - if(prob(75)) - new /obj/item/stack/sheet/metal(src.loc) - del(src) - -/obj/structure/stool/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/wrench)) - playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) - new /obj/item/stack/sheet/metal(src.loc) - del(src) - return - -/obj/structure/stool/MouseDrop(atom/over_object) - if (istype(over_object, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = over_object - if (H==usr && !H.restrained() && !H.stat && in_range(src, over_object)) - var/obj/item/weapon/stool/S = new/obj/item/weapon/stool() - S.origin = src - src.loc = S - H.put_in_hands(S) - H.visible_message("\red [H] grabs [src] from the floor!", "\red You grab [src] from the floor!") - -/obj/item/weapon/stool - name = "stool" - desc = "Uh-hoh, bar is heating up." - icon = 'icons/obj/objects.dmi' - icon_state = "stool" force = 10 throwforce = 10 - w_class = 5.0 - var/obj/structure/stool/origin = null - -/obj/item/weapon/stool/proc/deploy(var/mob/user) - - if(!origin) - del src - - origin.loc = get_turf(src) - - if(user) - user.remove_from_mob(src) - user.visible_message("\blue [user] puts [src] down.", "\blue You put [src] down.") - - del src - -/obj/item/weapon/stool/dropped(mob/user as mob) - ..() - if(istype(loc,/turf/)) - deploy(user) - -/obj/item/weapon/stool/attack_self(mob/user as mob) - ..() - deploy(user) + w_class = 5 /obj/item/weapon/stool/attack(mob/M as mob, mob/user as mob) if (prob(5) && istype(M,/mob/living)) @@ -87,3 +19,29 @@ T.apply_damage(20) return ..() + +/obj/item/weapon/stool/ex_act(severity) + switch(severity) + if(1.0) + del(src) + return + if(2.0) + if (prob(50)) + del(src) + return + if(3.0) + if (prob(5)) + del(src) + return + +/obj/item/weapon/stool/blob_act() + if(prob(75)) + new /obj/item/stack/sheet/metal(src.loc) + del(src) + +/obj/item/weapon/stool/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/wrench)) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + new /obj/item/stack/sheet/metal(src.loc) + del(src) + ..() diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm index 59a819b8b9..81d7f31cdb 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm @@ -1,16 +1,16 @@ -/obj/structure/stool/bed/chair/wheelchair +/obj/structure/bed/chair/wheelchair name = "wheelchair" desc = "You sit in this. Either by will or force." icon_state = "wheelchair" anchored = 0 - movable = 1 + buckle_movable = 1 var/driving = 0 var/mob/living/pulling = null var/bloodiness -/obj/structure/stool/bed/chair/wheelchair/set_dir() +/obj/structure/bed/chair/wheelchair/set_dir() ..() overlays = null var/image/O = image(icon = 'icons/obj/objects.dmi', icon_state = "w_overlay", layer = FLY_LAYER, dir = src.dir) @@ -18,7 +18,7 @@ if(buckled_mob) buckled_mob.set_dir(dir) -/obj/structure/stool/bed/chair/wheelchair/relaymove(mob/user, direction) +/obj/structure/bed/chair/wheelchair/relaymove(mob/user, direction) // Redundant check? if(user.stat || user.stunned || user.weakened || user.paralysis || user.lying || user.restrained()) if(user==pulling) @@ -79,7 +79,7 @@ create_track() driving = 0 -/obj/structure/stool/bed/chair/wheelchair/Move() +/obj/structure/bed/chair/wheelchair/Move() ..() if(buckled_mob) var/mob/living/occupant = buckled_mob @@ -93,7 +93,7 @@ if (O != occupant) Bump(O) else - unbuckle() + unbuckle_mob() if (pulling && (get_dist(src, pulling) > 1)) pulling.pulledby = null pulling << "\red You lost your grip!" @@ -102,14 +102,14 @@ if (occupant && (src.loc != occupant.loc)) src.loc = occupant.loc // Failsafe to make sure the wheelchair stays beneath the occupant after driving -/obj/structure/stool/bed/chair/wheelchair/attack_hand(mob/user as mob) +/obj/structure/bed/chair/wheelchair/attack_hand(mob/living/user as mob) if (pulling) MouseDrop(usr) else - manual_unbuckle(user) + user_unbuckle_mob(user) return -/obj/structure/stool/bed/chair/wheelchair/MouseDrop(over_object, src_location, over_location) +/obj/structure/bed/chair/wheelchair/MouseDrop(over_object, src_location, over_location) ..() if(over_object == usr && in_range(src, usr)) if(!ishuman(usr)) return @@ -133,15 +133,14 @@ pulling = null return -/obj/structure/stool/bed/chair/wheelchair/Bump(atom/A) +/obj/structure/bed/chair/wheelchair/Bump(atom/A) ..() if(!buckled_mob) return - if(propelled || (pulling && (pulling.a_intent == "hurt"))) - var/mob/living/occupant = buckled_mob - unbuckle() + if(propelled || (pulling && (pulling.a_intent == I_HURT))) + var/mob/living/occupant = unbuckle_mob() - if (pulling && (pulling.a_intent == "hurt")) + if (pulling && (pulling.a_intent == I_HURT)) occupant.throw_at(A, 3, 3, pulling) else if (propelled) occupant.throw_at(A, 3, propelled) @@ -171,7 +170,7 @@ else occupant.visible_message("[occupant] crashed into \the [A]!") -/obj/structure/stool/bed/chair/wheelchair/proc/create_track() +/obj/structure/bed/chair/wheelchair/proc/create_track() var/obj/effect/decal/cleanable/blood/tracks/B = new(loc) var/newdir = get_dir(get_step(loc, dir), loc) if(newdir == dir) @@ -185,7 +184,7 @@ B.set_dir(newdir) bloodiness-- -/obj/structure/stool/bed/chair/wheelchair/buckle_mob(mob/M as mob, mob/user as mob) +/obj/structure/bed/chair/wheelchair/buckle_mob(mob/M as mob, mob/user as mob) if(M == pulling) pulling = null usr.pulledby = null diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 64ef0c8fad..6b857ae4cf 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -363,7 +363,7 @@ if (istype(G.affecting, /mob/living)) var/mob/living/M = G.affecting if (G.state < 2) - if(user.a_intent == "hurt") + if(user.a_intent == I_HURT) if (prob(15)) M.Weaken(5) M.apply_damage(8,def_zone = "head") visible_message("[G.assailant] slams [G.affecting]'s face against \the [src]!") diff --git a/code/game/objects/structures/transit_tubes.dm b/code/game/objects/structures/transit_tubes.dm index c95aed0065..fcd65e2cdf 100644 --- a/code/game/objects/structures/transit_tubes.dm +++ b/code/game/objects/structures/transit_tubes.dm @@ -353,53 +353,24 @@ obj/structure/ex_act(severity) moving = 0 - -// Should I return a copy here? If the caller edits or del()s the returned -// datum, there might be problems if I don't... /obj/structure/transit_tube_pod/return_air() - var/datum/gas_mixture/GM = new() - GM.copy_from(air_contents) - return GM + return air_contents -// For now, copying what I found in an unused FEA file (and almost identical in a -// used ZAS file). Means that assume_air and remove_air don't actually alter the -// air contents. /obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver) return air_contents.merge(giver) /obj/structure/transit_tube_pod/remove_air(amount) return air_contents.remove(amount) - - // Called when a pod arrives at, and before a pod departs from a station, // giving it a chance to mix its internal air supply with the turf it is // currently on. /obj/structure/transit_tube_pod/proc/mix_air() var/datum/gas_mixture/environment = loc.return_air() - var/env_pressure = environment.return_pressure() - var/int_pressure = air_contents.return_pressure() - var/total_pressure = env_pressure + int_pressure - - if(total_pressure == 0) - return - - // Math here: Completely made up, not based on realistic equasions. - // Goal is to balance towards equal pressure, but ensure some gas - // transfer in both directions regardless. - // Feel free to rip this out and replace it with something better, - // I don't really know muhch about how gas transfer rates work in - // SS13. - var/transfer_in = max(0.1, 0.5 * (env_pressure - int_pressure) / total_pressure) - var/transfer_out = max(0.1, 0.3 * (int_pressure - env_pressure) / total_pressure) - - var/datum/gas_mixture/from_env = loc.remove_air(environment.total_moles * transfer_in) - var/datum/gas_mixture/from_int = air_contents.remove(air_contents.total_moles * transfer_out) - - loc.assume_air(from_int) - air_contents.merge(from_env) - - + + //note that share_ratio assumes both gas mixes have the same volume, + //so if the volume is changed this may need to be changed as well. + air_contents.share_ratio(environment, 1) // When the player moves, check if the pos is currently stopped at a station. // if it is, check the direction. If the direction matches the direction of diff --git a/code/game/objects/structures/under_wardrobe.dm b/code/game/objects/structures/under_wardrobe.dm new file mode 100644 index 0000000000..d053849496 --- /dev/null +++ b/code/game/objects/structures/under_wardrobe.dm @@ -0,0 +1,34 @@ +/obj/structure/undies_wardrobe + name = "underwear wardrobe" + desc = "Holds item of clothing you shouldn't be showing off in the hallways." + icon = 'icons/obj/closet.dmi' + icon_state = "cabinet_closed" + density = 1 + +/obj/structure/undies_wardrobe/attack_hand(mob/user as mob) + src.add_fingerprint(user) + var/mob/living/carbon/human/H = user + if(!ishuman(user) || (H.species && !(H.species.flags & HAS_UNDERWEAR))) + user << "Sadly there's nothing in here for you to wear." + return 0 + + var/utype = alert("Which section do you want to pick from?",,"Male underwear", "Female underwear", "Undershirts") + var/list/selection + switch(utype) + if("Male underwear") + selection = underwear_m + if("Female underwear") + selection = underwear_f + if("Undershirts") + selection = undershirt_t + var/pick = input("Select the style") as null|anything in selection + if(pick) + if(get_dist(src,user) > 1) + return + if(utype == "Undershirts") + H.undershirt = undershirt_t[pick] + else + H.underwear = selection[pick] + H.update_body(1) + + return 1 \ No newline at end of file diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 33235ae124..e77f1e602c 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -211,6 +211,11 @@ /obj/machinery/shower/proc/wash(atom/movable/O as obj|mob) if(!on) return + if(isliving(O)) + var/mob/living/L = O + L.ExtinguishMob() + L.fire_stacks = -20 //Douse ourselves with water to avoid fire more easily + if(iscarbon(O)) var/mob/living/carbon/M = O if(M.r_hand) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 7529618d32..fd96873b7a 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -15,25 +15,70 @@ var/basestate var/shardtype = /obj/item/weapon/shard var/glasstype = null // Set this in subtypes. Null is assumed strange or otherwise impossible to dismantle, such as for shuttle glass. -// var/silicate = 0 // number of units of silicate -// var/icon/silicateIcon = null // the silicated icon + var/silicate = 0 // number of units of silicate + +/obj/structure/window/examine(mob/user) + . = ..(user) + + if(health == maxhealth) + user << "It looks fully intact." + else + var/perc = health / maxhealth + if(perc > 0.75) + user << "It has a few cracks." + else if(perc > 0.5) + user << "It looks slightly damaged." + else if(perc > 0.25) + user << "It looks moderately damaged." + else + user << "It looks heavily damaged." + if(silicate) + if (silicate < 30) + user << "It has a thin layer of silicate." + else if (silicate < 70) + user << "It is covered in silicate." + else + user << "There is a thick layer of silicate covering it." /obj/structure/window/proc/take_damage(var/damage = 0, var/sound_effect = 1) - var/initialhealth = src.health - src.health = max(0, src.health - damage) - if(src.health <= 0) - src.shatter() + var/initialhealth = health + + if(silicate) + damage = damage * (1 - silicate / 200) + + health = max(0, health - damage) + + if(health <= 0) + shatter() else if(sound_effect) playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1) - if(src.health < src.maxhealth / 4 && initialhealth >= src.maxhealth / 4) + if(health < maxhealth / 4 && initialhealth >= maxhealth / 4) visible_message("[src] looks like it's about to shatter!" ) - else if(src.health < src.maxhealth / 2 && initialhealth >= src.maxhealth / 2) + else if(health < maxhealth / 2 && initialhealth >= maxhealth / 2) visible_message("[src] looks seriously damaged!" ) - else if(src.health < src.maxhealth * 3/4 && initialhealth >= src.maxhealth * 3/4) + else if(health < maxhealth * 3/4 && initialhealth >= maxhealth * 3/4) visible_message("Cracks begin to appear in [src]!" ) return +/obj/structure/window/proc/apply_silicate(var/amount) + if(health < maxhealth) // Mend the damage + health = min(health + amount * 3, maxhealth) + if(health == maxhealth) + visible_message("[src] looks fully repaired." ) + else // Reinforce + silicate = min(silicate + amount, 100) + updateSilicate() + +/obj/structure/window/proc/updateSilicate() + if (overlays) + overlays.Cut() + + var/image/img = image(src.icon, src.icon_state) + img.color = "#ffffff" + img.alpha = silicate * 255 / 100 + overlays += img + /obj/structure/window/proc/shatter(var/display_message = 1) playsound(src, "shatter", 70, 1) if(display_message) @@ -55,7 +100,7 @@ /obj/structure/window/bullet_act(var/obj/item/projectile/Proj) //Tasers and the like should not damage windows. - if(Proj.damage_type == HALLOSS) + if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) return ..() @@ -135,7 +180,7 @@ user.visible_message("[user] smashes through [src]!") shatter() - else if (usr.a_intent == "hurt") + else if (usr.a_intent == I_HURT) if (istype(usr,/mob/living/carbon/human)) var/mob/living/carbon/human/H = usr @@ -251,7 +296,7 @@ update_nearby_tiles(need_rebuild=1) //Compel updates before set_dir(turn(dir, 90)) -// updateSilicate() + updateSilicate() update_nearby_tiles(need_rebuild=1) return @@ -267,27 +312,10 @@ update_nearby_tiles(need_rebuild=1) //Compel updates before set_dir(turn(dir, 270)) -// updateSilicate() + updateSilicate() update_nearby_tiles(need_rebuild=1) return - -/* -/obj/structure/window/proc/updateSilicate() - if(silicateIcon && silicate) - icon = initial(icon) - - var/icon/I = icon(icon,icon_state,dir) - - var/r = (silicate / 100) + 1 - var/g = (silicate / 70) + 1 - var/b = (silicate / 50) + 1 - I.SetIntensity(r,g,b) - icon = I - silicateIcon = I -*/ - - /obj/structure/window/New(Loc, start_dir=null, constructed=0) ..() @@ -442,3 +470,51 @@ update_icon() //icon_state has to be set manually return + +/obj/structure/window/reinforced/polarized + name = "electrochromic window" + desc = "Adjusts its tint with voltage. Might take a few good hits to shatter it." + var/id + +/obj/structure/window/reinforced/polarized/proc/toggle() + if(opacity) + animate(src, color="#FFFFFF", time=5) + SetOpacity(0) + else + animate(src, color="#222222", time=5) + SetOpacity(1) + + + +/obj/machinery/button/windowtint + name = "window tint control" + icon = 'icons/obj/power.dmi' + icon_state = "light0" + desc = "A remote control switch for polarized windows." + var/range = 7 + +/obj/machinery/button/windowtint/attack_hand(mob/user as mob) + if(..()) + return 1 + + toggle_tint() + +/obj/machinery/button/windowtint/proc/toggle_tint() + use_power(5) + + active = !active + update_icon() + + for(var/obj/structure/window/reinforced/polarized/W in range(src,range)) + if (W.id == src.id || !W.id) + spawn(0) + W.toggle() + return + +/obj/machinery/button/windowtint/power_change() + ..() + if(active && !powered(power_channel)) + toggle_tint() + +/obj/machinery/button/windowtint/update_icon() + icon_state = "light[active]" diff --git a/code/game/response_team.dm b/code/game/response_team.dm index dfaec22189..a64230b1d6 100644 --- a/code/game/response_team.dm +++ b/code/game/response_team.dm @@ -1,331 +1,152 @@ -//STRIKE TEAMS -//Thanks to Kilakk for the admin-button portion of this code. - -var/list/response_team_members = list() -var/global/send_emergency_team = 0 // Used for automagic response teams - // 'admin_emergency_team' for admin-spawned response teams -var/ert_base_chance = 10 // Default base chance. Will be incremented by increment ERT chance. -var/can_call_ert - -/client/proc/response_team() - set name = "Dispatch Emergency Response Team" - set category = "Special Verbs" - set desc = "Send an emergency response team to the station" - - if(!holder) - usr << "\red Only administrators may use this command." - return - if(!ticker) - usr << "\red The game hasn't started yet!" - return - if(ticker.current_state == 1) - usr << "\red The round hasn't started yet!" - return - if(send_emergency_team) - usr << "\red Central Command has already dispatched an emergency response team!" - return - if(alert("Do you want to dispatch an Emergency Response Team?",,"Yes","No") != "Yes") - return - if(get_security_level() != "red") // Allow admins to reconsider if the alert level isn't Red - switch(alert("The station is not in red alert. Do you still want to dispatch a response team?",,"Yes","No")) - if("No") - return - if(send_emergency_team) - usr << "\red Looks like somebody beat you to it!" - return - - message_admins("[key_name_admin(usr)] is dispatching an Emergency Response Team.", 1) - log_admin("[key_name(usr)] used Dispatch Response Team.") - trigger_armed_response_team(1) - - -client/verb/JoinResponseTeam() - set category = "IC" - - if(istype(usr,/mob/dead/observer) || istype(usr,/mob/new_player)) - if(!send_emergency_team) - usr << "No emergency response team is currently being sent." - return - /* if(admin_emergency_team) - usr << "An emergency response team has already been sent." - return */ - if(jobban_isbanned(usr, "Syndicate") || jobban_isbanned(usr, "Emergency Response Team") || jobban_isbanned(usr, "Security Officer")) - usr << "You are jobbanned from the emergency reponse team!" - return - - if(response_team_members.len > 5) usr << "The emergency response team is already full!" - - - for (var/obj/effect/landmark/L in landmarks_list) if (L.name == "Commando") - L.name = null//Reserving the place. - var/new_name = input(usr, "Pick a name","Name") as null|text - if(!new_name)//Somebody changed his mind, place is available again. - L.name = "Commando" - return - var/leader_selected = isemptylist(response_team_members) - var/mob/living/carbon/human/new_commando = create_response_team(L.loc, leader_selected, new_name) - del(L) - new_commando.mind.key = usr.key - new_commando.key = usr.key - - new_commando << "\blue You are [!leader_selected?"a member":"the LEADER"] of an Emergency Response Team, a type of military division, under CentComm's service. There is a code red alert on [station_name()], you are tasked to go and fix the problem." - new_commando << "You should first gear up and discuss a plan with your team. More members may be joining, don't move out before you're ready." - if(!leader_selected) - new_commando << "As member of the Emergency Response Team, you answer only to your leader and CentComm officials." - else - new_commando << "As leader of the Emergency Response Team, you answer only to CentComm, and have authority to override the Captain where it is necessary to achieve your mission goals. It is recommended that you attempt to cooperate with the captain where possible, however." - return - - else - usr << "You need to be an observer or new player to use this." - -// returns a number of dead players in % -proc/percentage_dead() - var/total = 0 - var/deadcount = 0 - for(var/mob/living/carbon/human/H in mob_list) - if(H.client) // Monkeys and mice don't have a client, amirite? - if(H.stat == 2) deadcount++ - total++ - - if(total == 0) return 0 - else return round(100 * deadcount / total) - -// counts the number of antagonists in % -proc/percentage_antagonists() - var/total = 0 - var/antagonists = 0 - for(var/mob/living/carbon/human/H in mob_list) - if(is_special_character(H) >= 1) - antagonists++ - total++ - - if(total == 0) return 0 - else return round(100 * antagonists / total) - -// Increments the ERT chance automatically, so that the later it is in the round, -// the more likely an ERT is to be able to be called. -proc/increment_ert_chance() - while(send_emergency_team == 0) // There is no ERT at the time. - if(get_security_level() == "green") - ert_base_chance += 1 - if(get_security_level() == "blue") - ert_base_chance += 2 - if(get_security_level() == "red") - ert_base_chance += 3 - if(get_security_level() == "delta") - ert_base_chance += 10 // Need those big guns - sleep(600 * 3) // Minute * Number of Minutes - - -proc/trigger_armed_response_team(var/force = 0) - if(!can_call_ert && !force) - return - if(send_emergency_team) - return - - var/send_team_chance = ert_base_chance // Is incremented by increment_ert_chance. - send_team_chance += 2*percentage_dead() // the more people are dead, the higher the chance - send_team_chance += percentage_antagonists() // the more antagonists, the higher the chance - send_team_chance = min(send_team_chance, 100) - - if(force) send_team_chance = 100 - - // there's only a certain chance a team will be sent - if(!prob(send_team_chance)) - command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. Unfortunately, we were unable to send one at this time.", "Central Command") - can_call_ert = 0 // Only one call per round, ladies. - return - - command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. We will prepare and send one as soon as possible.", "Central Command") - - can_call_ert = 0 // Only one call per round, gentleman. - send_emergency_team = 1 - - sleep(600 * 5) - send_emergency_team = 0 // Can no longer join the ERT. - -/* var/area/security/nuke_storage/nukeloc = locate()//To find the nuke in the vault - var/obj/machinery/nuclearbomb/nuke = locate() in nukeloc - if(!nuke) - nuke = locate() in world - var/obj/item/weapon/paper/P = new - P.info = "Your orders, Commander, are to use all means necessary to return the station to a survivable condition.
      To this end, you have been provided with the best tools we can give in the three areas of Medicine, Engineering, and Security. The nuclear authorization code is: [ nuke ? nuke.r_code : "AHH, THE NUKE IS GONE!"]. Be warned, if you detonate this without good reason, we will hold you to account for damages. Memorise this code, and then burn this message." - P.name = "Emergency Nuclear Code, and ERT Orders" - for (var/obj/effect/landmark/A in world) - if (A.name == "nukecode") - P.loc = A.loc - del(A) - continue -*/ - -/client/proc/create_response_team(obj/spawn_location, leader_selected = 0, commando_name) - - //usr << "\red ERT has been temporarily disabled. Talk to a coder." - //return - - var/mob/living/carbon/human/M = new(null) - response_team_members |= M - - //todo: god damn this. - //make it a panel, like in character creation - var/new_facial = input("Please select facial hair color.", "Character Generation") as color - if(new_facial) - M.r_facial = hex2num(copytext(new_facial, 2, 4)) - M.g_facial = hex2num(copytext(new_facial, 4, 6)) - M.b_facial = hex2num(copytext(new_facial, 6, 8)) - - var/new_hair = input("Please select hair color.", "Character Generation") as color - if(new_facial) - M.r_hair = hex2num(copytext(new_hair, 2, 4)) - M.g_hair = hex2num(copytext(new_hair, 4, 6)) - M.b_hair = hex2num(copytext(new_hair, 6, 8)) - - var/new_eyes = input("Please select eye color.", "Character Generation") as color - if(new_eyes) - M.r_eyes = hex2num(copytext(new_eyes, 2, 4)) - M.g_eyes = hex2num(copytext(new_eyes, 4, 6)) - M.b_eyes = hex2num(copytext(new_eyes, 6, 8)) - - var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation") as text - - if (!new_tone) - new_tone = 35 - M.s_tone = max(min(round(text2num(new_tone)), 220), 1) - M.s_tone = -M.s_tone + 35 - - // hair - var/list/all_hairs = typesof(/datum/sprite_accessory/hair) - /datum/sprite_accessory/hair - var/list/hairs = list() - - // loop through potential hairs - for(var/x in all_hairs) - var/datum/sprite_accessory/hair/H = new x // create new hair datum based on type x - hairs.Add(H.name) // add hair name to hairs - del(H) // delete the hair after it's all done - -// var/new_style = input("Please select hair style", "Character Generation") as null|anything in hairs -//hair - var/new_hstyle = input(usr, "Select a hair style", "Grooming") as null|anything in hair_styles_list - if(new_hstyle) - M.h_style = new_hstyle - - // facial hair - var/new_fstyle = input(usr, "Select a facial hair style", "Grooming") as null|anything in facial_hair_styles_list - if(new_fstyle) - M.f_style = new_fstyle - - // if new style selected (not cancel) -/* if (new_style) - M.h_style = new_style - - for(var/x in all_hairs) // loop through all_hairs again. Might be slightly CPU expensive, but not significantly. - var/datum/sprite_accessory/hair/H = new x // create new hair datum - if(H.name == new_style) - M.h_style = H // assign the hair_style variable a new hair datum - break - else - del(H) // if hair H not used, delete. BYOND can garbage collect, but better safe than sorry - - // facial hair - var/list/all_fhairs = typesof(/datum/sprite_accessory/facial_hair) - /datum/sprite_accessory/facial_hair - var/list/fhairs = list() - - for(var/x in all_fhairs) - var/datum/sprite_accessory/facial_hair/H = new x - fhairs.Add(H.name) - del(H) - - new_style = input("Please select facial style", "Character Generation") as null|anything in fhairs - - if(new_style) - M.f_style = new_style - for(var/x in all_fhairs) - var/datum/sprite_accessory/facial_hair/H = new x - if(H.name == new_style) - M.f_style = H - break - else - del(H) -*/ - var/new_gender = alert(usr, "Please select gender.", "Character Generation", "Male", "Female") - if (new_gender) - if(new_gender == "Male") - M.gender = MALE - else - M.gender = FEMALE - //M.rebuild_appearance() - M.update_hair() - M.update_body() - M.check_dna(M) - - M.real_name = commando_name - M.name = commando_name - M.age = !leader_selected ? rand(23,35) : rand(35,45) - - M.dna.ready_dna(M)//Creates DNA. - - //Creates mind stuff. - M.mind = new - M.mind.current = M - M.mind.original = M - M.mind.assigned_role = "MODE" - M.mind.special_role = "Response Team" - if(!(M.mind in ticker.minds)) - ticker.minds += M.mind//Adds them to regular mind list. - M.loc = spawn_location - M.equip_strike_team(leader_selected) - return M - -/mob/living/carbon/human/proc/equip_strike_team(leader_selected = 0) - - //Special radio setup - equip_to_slot_or_del(new /obj/item/device/radio/headset/ert(src), slot_l_ear) - - //Replaced with new ERT uniform - equip_to_slot_or_del(new /obj/item/clothing/under/ert(src), slot_w_uniform) - equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes) - equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves) - equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(src), slot_glasses) -/* - - //Old ERT Uniform - //Basic Uniform - equip_to_slot_or_del(new /obj/item/clothing/under/syndicate/tacticool(src), slot_w_uniform) - equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_l_store) - equip_to_slot_or_del(new /obj/item/weapon/clipboard(src), slot_r_store) - equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(src), slot_belt) - equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat(src), slot_wear_mask) - - //Glasses - equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses/sechud(src), slot_glasses) - - //Shoes & gloves - equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes) - equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves) - - //Removed -// equip_to_slot_or_del(new /obj/item/clothing/suit/armor/swat(src), slot_wear_suit) -// equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad(src), slot_head) - - //Backpack - equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(src), slot_back) - equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(src), slot_in_backpack) - equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(src), slot_in_backpack) -*/ - var/obj/item/weapon/card/id/W = new(src) - W.assignment = "Emergency Response Team[leader_selected ? " Leader" : ""]" - W.registered_name = real_name - W.name = "[real_name]'s ID Card ([W.assignment])" - W.icon_state = "centcom" - W.access = get_all_accesses() - W.access += get_all_centcom_access() - equip_to_slot_or_del(W, slot_wear_id) - - return 1 - -//debug verb (That is horribly coded, LEAVE THIS OFF UNLESS PRIVATELY TESTING. Seriously. -/*client/verb/ResponseTeam() - set category = "Admin" - if(!send_emergency_team) - send_emergency_team = 1*/ +//STRIKE TEAMS +//Thanks to Kilakk for the admin-button portion of this code. + +var/global/send_emergency_team = 0 // Used for automagic response teams + // 'admin_emergency_team' for admin-spawned response teams +var/ert_base_chance = 10 // Default base chance. Will be incremented by increment ERT chance. +var/can_call_ert + +/client/proc/response_team() + set name = "Dispatch Emergency Response Team" + set category = "Special Verbs" + set desc = "Send an emergency response team to the station" + + if(!holder) + usr << "\red Only administrators may use this command." + return + if(!ticker) + usr << "\red The game hasn't started yet!" + return + if(ticker.current_state == 1) + usr << "\red The round hasn't started yet!" + return + if(send_emergency_team) + usr << "\red Central Command has already dispatched an emergency response team!" + return + if(alert("Do you want to dispatch an Emergency Response Team?",,"Yes","No") != "Yes") + return + if(get_security_level() != "red") // Allow admins to reconsider if the alert level isn't Red + switch(alert("The station is not in red alert. Do you still want to dispatch a response team?",,"Yes","No")) + if("No") + return + if(send_emergency_team) + usr << "\red Looks like somebody beat you to it!" + return + + message_admins("[key_name_admin(usr)] is dispatching an Emergency Response Team.", 1) + log_admin("[key_name(usr)] used Dispatch Response Team.") + trigger_armed_response_team(1) + + +client/verb/JoinResponseTeam() + set category = "IC" + + if(istype(usr,/mob/dead/observer) || istype(usr,/mob/new_player)) + if(!send_emergency_team) + usr << "No emergency response team is currently being sent." + return + if(jobban_isbanned(usr, "Syndicate") || jobban_isbanned(usr, "Emergency Response Team") || jobban_isbanned(usr, "Security Officer")) + usr << "You are jobbanned from the emergency reponse team!" + return + + if(ert.current_antagonists.len > 5) usr << "The emergency response team is already full!" + + for (var/obj/effect/landmark/L in landmarks_list) if (L.name == "Commando") + L.name = null//Reserving the place. + var/new_name = sanitizeSafe(input(usr, "Pick a name","Name") as null|text, MAX_NAME_LEN) + if(!new_name)//Somebody changed his mind, place is available again. + L.name = "Commando" + return + create_response_team(L.loc, new_name) + del(L) + + else + usr << "You need to be an observer or new player to use this." + +// returns a number of dead players in % +proc/percentage_dead() + var/total = 0 + var/deadcount = 0 + for(var/mob/living/carbon/human/H in mob_list) + if(H.client) // Monkeys and mice don't have a client, amirite? + if(H.stat == 2) deadcount++ + total++ + + if(total == 0) return 0 + else return round(100 * deadcount / total) + +// counts the number of antagonists in % +proc/percentage_antagonists() + var/total = 0 + var/antagonists = 0 + for(var/mob/living/carbon/human/H in mob_list) + if(is_special_character(H) >= 1) + antagonists++ + total++ + + if(total == 0) return 0 + else return round(100 * antagonists / total) + +// Increments the ERT chance automatically, so that the later it is in the round, +// the more likely an ERT is to be able to be called. +proc/increment_ert_chance() + while(send_emergency_team == 0) // There is no ERT at the time. + if(get_security_level() == "green") + ert_base_chance += 1 + if(get_security_level() == "blue") + ert_base_chance += 2 + if(get_security_level() == "red") + ert_base_chance += 3 + if(get_security_level() == "delta") + ert_base_chance += 10 // Need those big guns + sleep(600 * 3) // Minute * Number of Minutes + + +proc/trigger_armed_response_team(var/force = 0) + if(!can_call_ert && !force) + return + if(send_emergency_team) + return + + var/send_team_chance = ert_base_chance // Is incremented by increment_ert_chance. + send_team_chance += 2*percentage_dead() // the more people are dead, the higher the chance + send_team_chance += percentage_antagonists() // the more antagonists, the higher the chance + send_team_chance = min(send_team_chance, 100) + + if(force) send_team_chance = 100 + + // there's only a certain chance a team will be sent + if(!prob(send_team_chance)) + command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. Unfortunately, we were unable to send one at this time.", "Central Command") + can_call_ert = 0 // Only one call per round, ladies. + return + + command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. We will prepare and send one as soon as possible.", "Central Command") + + can_call_ert = 0 // Only one call per round, gentleman. + send_emergency_team = 1 + + sleep(600 * 5) + send_emergency_team = 0 // Can no longer join the ERT. + +/client/proc/create_response_team(obj/spawn_location, commando_name) + + var/mob/living/carbon/human/M = new(null) + + + M.real_name = commando_name + M.name = commando_name + M.age = rand(25,45) + + M.check_dna(M) + M.dna.ready_dna(M)//Creates DNA. + + M.mind = new + M.mind.current = M + M.mind.original = M + if(!(M.mind in ticker.minds)) + ticker.minds += M.mind//Adds them to regular mind list. + M.loc = spawn_location + ert.add_antagonist(M.mind) + + return M diff --git a/code/game/smoothwall.dm b/code/game/smoothwall.dm index b8196dbc5c..907b2f6758 100644 --- a/code/game/smoothwall.dm +++ b/code/game/smoothwall.dm @@ -109,10 +109,10 @@ W.relativewall() for(var/direction in cardinal) - for(var/obj/effect/glowshroom/shroom in get_step(src,direction)) + for(var/obj/effect/plant/shroom in get_step(src,direction)) if(!shroom.floor) //shrooms drop to the floor shroom.floor = 1 - shroom.icon_state = "glowshroomf" + shroom.update_icon() shroom.pixel_x = 0 shroom.pixel_y = 0 diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index 81ad18ee5d..d32173c267 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -49,22 +49,36 @@ var/list/mechtoys = list( anchored = 1 layer = 4 explosion_resistance = 5 + var/list/mobs_can_pass = list( + /mob/living/carbon/slime, + /mob/living/simple_animal/mouse, + /mob/living/silicon/robot/drone + ) /obj/structure/plasticflaps/CanPass(atom/A, turf/T) if(istype(A) && A.checkpass(PASSGLASS)) return prob(60) - var/obj/structure/stool/bed/B = A - if (istype(A, /obj/structure/stool/bed) && B.buckled_mob)//if it's a bed/chair and someone is buckled, it will not pass + var/obj/structure/bed/B = A + if (istype(A, /obj/structure/bed) && B.buckled_mob)//if it's a bed/chair and someone is buckled, it will not pass return 0 if(istype(A, /obj/vehicle)) //no vehicles return 0 - if(istype(A, /mob/living)) // You Shall Not Pass! - var/mob/living/M = A - if(!M.lying && !istype(M, /mob/living/carbon/monkey) && !istype(M, /mob/living/carbon/slime) && !istype(M, /mob/living/simple_animal/mouse) && !istype(M, /mob/living/silicon/robot/drone)) //If your not laying down, or a small creature, no pass. - return 0 + var/mob/living/M = A + if(istype(M)) + if(M.lying) + return ..() + for(var/mob_type in mobs_can_pass) + if(istype(A, mob_type)) + return ..() + if(istype(A, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + if(H.species.is_small) + return ..() + return 0 + return ..() /obj/structure/plasticflaps/ex_act(severity) diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 84ec0adecb..9546bf9ba1 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -25,11 +25,17 @@ usr << "\red Movement is admin-disabled." //This is to identify lag problems return - if (istype(A,/mob/living/carbon)) - var/mob/living/carbon/M = A + if (istype(A,/mob/living)) + var/mob/living/M = A if(M.lying) ..() return + + // Ugly hack :( Should never have multiple plants in the same tile. + var/obj/effect/plant/plant = locate() in contents + if(plant) plant.trodden_on(M) + + // Dirt overlays. dirt++ var/obj/effect/decal/cleanable/dirt/dirtoverlay = locate(/obj/effect/decal/cleanable/dirt, src) if (dirt >= 50) @@ -41,30 +47,21 @@ if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - if(istype(H.shoes, /obj/item/clothing/shoes/clown_shoes)) - var/obj/item/clothing/shoes/clown_shoes/O = H.shoes - if(H.m_intent == "run") - if(O.footstep >= 2) - O.footstep = 0 - playsound(src, "clownstep", 50, 1) // this will get annoying very fast. - else - O.footstep++ - else - playsound(src, "clownstep", 20, 1) - // Tracking blood var/list/bloodDNA = null var/bloodcolor="" if(H.shoes) var/obj/item/clothing/shoes/S = H.shoes - if(S.track_blood && S.blood_DNA) - bloodDNA = S.blood_DNA - bloodcolor=S.blood_color - S.track_blood-- + if(istype(S)) + S.handle_movement(src,(H.m_intent == "run" ? 1 : 0)) + if(S.track_blood && S.blood_DNA) + bloodDNA = S.blood_DNA + bloodcolor=S.blood_color + S.track_blood-- else if(H.track_blood && H.feet_blood_DNA) bloodDNA = H.feet_blood_DNA - bloodcolor=H.feet_blood_color + bloodcolor = H.feet_blood_color H.track_blood-- if (bloodDNA) @@ -75,14 +72,11 @@ bloodDNA = null - var/noslip = 0 - for (var/obj/structure/stool/bed/chair/C in loc) - if (C.buckled_mob == M) - noslip = 1 - if((wet == 1 && M.m_intent == "walk") || noslip) - return // no slipping while sitting in a chair, plz - if(src.wet) + + if(M.buckled || (src.wet == 1 && M.m_intent == "walk")) + return + var/slip_dist = 1 var/slip_stun = 6 var/floor_type = "wet" @@ -124,9 +118,7 @@ // Only adds blood on the floor -- Skie /turf/simulated/proc/add_blood_floor(mob/living/carbon/M as mob) - if(istype(M, /mob/living/carbon/monkey)) - blood_splatter(src,M,1) - else if( istype(M, /mob/living/carbon/alien )) + if( istype(M, /mob/living/carbon/alien )) var/obj/effect/decal/cleanable/blood/xeno/this = new /obj/effect/decal/cleanable/blood/xeno(src) this.blood_DNA["UNKNOWN BLOOD"] = "X*" else if( istype(M, /mob/living/silicon/robot )) diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index a74bd90f29..07b68a329a 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -519,7 +519,10 @@ turf/simulated/floor/proc/update_icon() var/obj/item/stack/tile/T = C if (T.get_amount() < 1) return - floor_type = T.type + if(!T.build_type) + floor_type = T.type + else + floor_type = T.build_type intact = 1 if(istype(T,/obj/item/stack/tile/light)) var/obj/item/stack/tile/light/L = T diff --git a/code/game/turfs/simulated/floor_types.dm b/code/game/turfs/simulated/floor_types.dm index 367c143c19..4c4682c5c5 100644 --- a/code/game/turfs/simulated/floor_types.dm +++ b/code/game/turfs/simulated/floor_types.dm @@ -136,7 +136,7 @@ icon = 'icons/turf/floors.dmi' icon_state = "plating" -/turf/simulated/shuttle/plating/vox //Vox skipjack plating +/turf/simulated/shuttle/plating/vox //Skipjack plating oxygen = 0 nitrogen = MOLES_N2STANDARD + MOLES_O2STANDARD @@ -144,7 +144,7 @@ name = "Brig floor" // Also added it into the 2x3 brig area of the shuttle. icon_state = "floor4" -/turf/simulated/shuttle/floor4/vox //Vox skipjack floors +/turf/simulated/shuttle/floor4/vox //skipjack floors name = "skipjack floor" oxygen = 0 nitrogen = MOLES_N2STANDARD + MOLES_O2STANDARD @@ -216,4 +216,4 @@ icon_state = "snow" /turf/simulated/floor/plating/snow/ex_act(severity) - return \ No newline at end of file + return diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 5ec4bc1e61..969b872caf 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -6,8 +6,7 @@ var/rotting = 0 var/damage = 0 - var/damage_cap = 100 //Wall will break down to girders if damage reaches this point - var/armor = 0.5 // Damage is multiplied by this + var/damage_cap = 150 //Wall will break down to girders if damage reaches this point var/damage_overlay var/global/damage_overlays[8] @@ -25,18 +24,26 @@ /turf/simulated/wall/bullet_act(var/obj/item/projectile/Proj) - // Tasers and stuff? No thanks. - if(Proj.damage_type == HALLOSS) + // Tasers and stuff? No thanks. Also no clone or tox damage crap. + if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) return - // Emitter blasts are somewhat weaker as emitters have large rate of fire and don't require limited power cell to run - if(istype(Proj, /obj/item/projectile/beam/emitter)) - Proj.damage /= 4 + //cap the amount of damage, so that things like emitters can't destroy walls in one hit. + var/damage = min(Proj.damage, 100) - take_damage(Proj.damage * armor) + take_damage(damage) return +/turf/simulated/wall/hitby(AM as mob|obj, var/speed=THROWFORCE_SPEED_DIVISOR) + ..() + if(ismob(AM)) + return + var/tforce = AM:throwforce * (speed/THROWFORCE_SPEED_DIVISOR) + if (tforce < 15) + return + + take_damage(tforce) /turf/simulated/wall/Del() for(var/obj/effect/E in src) if(E.name == "Wallrot") del E @@ -44,6 +51,8 @@ /turf/simulated/wall/ChangeTurf(var/newtype) for(var/obj/effect/E in src) if(E.name == "Wallrot") del E + for(var/obj/effect/plant/plant in range(1)) + plant.update_neighbors() ..(newtype) //Appearance @@ -265,7 +274,7 @@ user << rotting_touch_message if(rotting_destroy_touch) dismantle_wall() - return 1 + return 1 if(..()) return 1 @@ -275,14 +284,10 @@ return 0 /turf/simulated/wall/attack_generic(var/mob/user, var/damage, var/attack_message, var/wallbreaker) - if(!damage || !wallbreaker) user << "You push the wall but nothing happens." return - if(istype(src,/turf/simulated/wall/r_wall) && !rotting) - user << "This wall is far too strong for you to destroy." - if(rotting || prob(40)) user << "You smash through the wall!" spawn(1) dismantle_wall(1) @@ -468,6 +473,9 @@ else if(istype(W,/obj/item/weapon/rcd)) //I bitterly resent having to write this. ~Z return + else if(istype(W, /obj/item/weapon/reagent_containers)) + return // They tend to have meaningful afterattack - let them apply it without destroying a rotting wall + else return attack_hand(user) return diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm index 9367df31c7..497371eb5f 100644 --- a/code/game/turfs/simulated/walls_reinforced.dm +++ b/code/game/turfs/simulated/walls_reinforced.dm @@ -5,9 +5,8 @@ opacity = 1 density = 1 - damage_cap = 500 + damage_cap = 800 max_temperature = 6000 - armor = 0.1 // Only 10% damage from gunfire, it's made from strong alloys and stuff. walltype = "rwall" @@ -19,6 +18,13 @@ rotting_destroy_touch = 0 rotting_touch_message = "\blue This wall feels rather unstable." +/turf/simulated/wall/r_wall/attack_generic(var/mob/user, var/damage, var/attack_message, var/wallbreaker) + if(!rotting && wallbreaker < 2) + user << "You push the wall but nothing happens." + return + + return ..() + /turf/simulated/wall/r_wall/attackby(obj/item/W as obj, mob/user as mob) if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") @@ -292,6 +298,9 @@ AH.try_build(src) return + else if(istype(W, /obj/item/weapon/reagent_containers)) + return // They tend to have meaningful afterattack - let them apply it without destroying a rotting wall + //Finally, CHECKING FOR FALSE WALLS if it isn't damaged else if(!d_state) return attack_hand(user) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index c0428da560..884c5c5dbe 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -14,6 +14,15 @@ var/list/accessible_z_levels = list("1" = 5, "3" = 10, "4" = 15, "5" = 10, "6" = /turf/space/New() if(!istype(src, /turf/space/transit)) icon_state = "[((x + y) ^ ~(x * y) + z) % 25]" + update_starlight() + +/turf/space/proc/update_starlight() + if(!config.starlight) + return + if(locate(/turf/simulated) in orange(src,1)) + SetLuminosity(config.starlight) + else + SetLuminosity(0) /turf/space/attackby(obj/item/C as obj, mob/user as mob) @@ -57,9 +66,6 @@ var/list/accessible_z_levels = list("1" = 5, "3" = 10, "4" = 15, "5" = 10, "6" = if(ticker && ticker.mode) - - // Okay, so let's make it so that people can travel z levels but not nuke disks! - // if(ticker.mode.name == "mercenary") return if(A.z > 6 && !config.use_overmap) return if (A.x <= TRANSITIONEDGE || A.x >= (world.maxx - TRANSITIONEDGE - 1) || A.y <= TRANSITIONEDGE || A.y >= (world.maxy - TRANSITIONEDGE - 1)) if(istype(A, /obj/effect/meteor)||istype(A, /obj/effect/space_dust)) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 1f86703322..29f425d4a3 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -54,18 +54,6 @@ step(user.pulling, get_dir(user.pulling.loc, src)) return 1 -/turf/bullet_act(var/obj/item/projectile/Proj) - if(istype(Proj ,/obj/item/projectile/beam/pulse)) - src.ex_act(2) - ..() - return 0 - -/turf/bullet_act(var/obj/item/projectile/Proj) - if(istype(Proj ,/obj/item/projectile/bullet/gyro)) - explosion(src, -1, 0, 2) - ..() - return 0 - /turf/Enter(atom/movable/mover as mob|obj, atom/forget as mob|obj|turf|area) if(movement_disabled && usr.ckey != movement_disabled_exception) usr << "\red Movement is admin-disabled." //This is to identify lag problems @@ -263,6 +251,9 @@ if(air_master) air_master.mark_for_update(src) + for(var/turf/space/S in range(W,1)) + S.update_starlight() + W.levelupdate() return W @@ -284,6 +275,9 @@ if(air_master) air_master.mark_for_update(src) + for(var/turf/space/S in range(W,1)) + S.update_starlight() + W.levelupdate() return W diff --git a/code/game/turfs/unsimulated/floor.dm b/code/game/turfs/unsimulated/floor.dm index bd6884c5d8..b2e7836334 100644 --- a/code/game/turfs/unsimulated/floor.dm +++ b/code/game/turfs/unsimulated/floor.dm @@ -2,3 +2,8 @@ name = "floor" icon = 'icons/turf/floors.dmi' icon_state = "Floor3" + +/turf/unsimulated/mask + name = "mask" + icon = 'icons/turf/walls.dmi' + icon_state = "rockvault" diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index b8c124dcd8..92b0638b9f 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -12,7 +12,7 @@ src << "Guests may not use OOC." return - msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))) + msg = sanitize(msg) if(!msg) return if(!(prefs.toggles & CHAT_OOC)) @@ -77,7 +77,7 @@ src << "Guests may not use OOC." return - msg = trim(sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))) + msg = sanitize(msg) if(!msg) return if(!(prefs.toggles & CHAT_LOOC)) diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm index ab3c8dcc80..afc576ed4f 100644 --- a/code/game/verbs/suicide.dm +++ b/code/game/verbs/suicide.dm @@ -110,33 +110,6 @@ death(0) suiciding = 0 -/mob/living/carbon/monkey/verb/suicide() - set hidden = 1 - - if (stat == 2) - src << "You're already dead!" - return - - if (!ticker) - src << "You can't commit suicide before the game starts!" - return - - if (suiciding) - src << "You're already committing suicide! Be patient!" - return - - var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No") - - if(confirm == "Yes") - if(!canmove || restrained()) - src << "You can't commit suicide whilst restrained! ((You can type Ghost instead however.))" - return - suiciding = 1 - //instead of killing them instantly, just put them at -175 health and let 'em gasp for a while - viewers(src) << "\red [src] is attempting to bite \his tongue. It looks like \he's trying to commit suicide." - adjustOxyLoss(max(175- getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0)) - updatehealth() - /mob/living/silicon/ai/verb/suicide() set hidden = 1 diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm index e96bc3b4da..c26d86858d 100644 --- a/code/game/verbs/who.dm +++ b/code/game/verbs/who.dm @@ -25,6 +25,20 @@ entry += " - DEAD" else entry += " - DEAD" + + var/age + if(isnum(C.player_age)) + age = C.player_age + else + age = 0 + + if(age <= 1) + age = "[age]" + else if(age < 10) + age = "[age]" + + entry += " - [age]" + if(is_special_character(C.mob)) entry += " - Antagonist" entry += " (?)" diff --git a/code/global.dm b/code/global.dm index 19ddbbe289..3836229649 100644 --- a/code/global.dm +++ b/code/global.dm @@ -1,204 +1,206 @@ //#define TESTING -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 -//items that ask to be called every cycle +// Items that ask to be called every cycle. var/global/obj/effect/datacore/data_core = null -var/global/list/all_areas = list() -var/global/list/machines = list() -var/global/list/processing_objects = list() -var/global/list/active_diseases = list() -var/global/list/med_hud_users = list() //list of all entities using a medical HUD. -var/global/list/sec_hud_users = list() //list of all entities using a security HUD. +var/global/list/all_areas = list() +var/global/list/machines = list() +var/global/list/processing_objects = list() +var/global/list/active_diseases = list() +var/global/list/med_hud_users = list() // List of all entities using a medical HUD. +var/global/list/sec_hud_users = list() // List of all entities using a security HUD. -//Those networks can only be accessed by preexisting terminals. AIs and new terminals can't use them. -var/list/restricted_camera_networks = list("thunder","ERT","NUKE") +// Those networks can only be accessed by pre-existing terminals. AIs and new terminals can't use them. +var/list/restricted_camera_networks = list("thunder","ERT","NUKE","Secret") -var/global/list/global_mutations = list() // list of hidden mutation things +var/global/list/global_mutations = list() // List of hidden mutation things. +var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called manually after an event. -var/global/defer_powernet_rebuild = 0 // true if net rebuild will be called manually after an event +// The resulting sector map looks like: +// ___ ___ +// | 1 | 4 | +// ---+--- +// | 5 | 3 | +// --- --- +// +// 1: SS13. +// 4: Derelict. +// 3: AI satellite. +// 5: Empty space. var/global/list/global_map = null - //list/global_map = list(list(1,5),list(4,3))//an array of map Z levels. - //Resulting sector map looks like - //|_1_|_4_| - //|_5_|_3_| - // - //1 - SS13 - //4 - Derelict - //3 - AI satellite - //5 - empty space - ////////////// +//var/global/list/global_map = list(list(1,5),list(4,3)) -//Noises made when hit while typing. +// Noises made when hit while typing. var/list/hit_appends = list("-OOF", "-ACK", "-UGH", "-HRNK", "-HURGH", "-GLORF") -var/list/paper_tag_whitelist = list("center","p","div","span","h1","h2","h3","h4","h5","h6","hr","pre", \ - "big","small","font","i","u","b","s","sub","sup","tt","br","hr","ol","ul","li","caption","col", \ - "table","td","th","tr") -var/list/paper_blacklist = list("java","onblur","onchange","onclick","ondblclick","onfocus","onkeydown", \ - "onkeypress","onkeyup","onload","onmousedown","onmousemove","onmouseout","onmouseover", \ - "onmouseup","onreset","onselect","onsubmit","onunload") +var/list/paper_tag_whitelist = list( + "center", "p", "div", "span", "pre", "h1", "h2", "h3", "h4", "h5", "h6", "br", "hr", + "big", "small", "font", "i", "u", "b", "s", "sub", "sup", "tt", "ol", "ul", "li", + "caption", "col", "table", "td", "th", "tr" +) +var/list/paper_blacklist = list( + "java", "onblur", "onchange", "onclick", "ondblclick", "onselect", "onfocus", + "onsubmit", "onreset", "onload", "onunload", "onkeydown", "onkeyup", "onkeypress", + "onmousedown", "onmouseup", "onmousemove", "onmouseout", "onmouseover", +) // The way blocks are handled badly needs a rewrite, this is horrible. // Too much of a project to handle at the moment, TODO for later. -var/BLINDBLOCK = 0 -var/DEAFBLOCK = 0 -var/HULKBLOCK = 0 -var/TELEBLOCK = 0 -var/FIREBLOCK = 0 -var/XRAYBLOCK = 0 -var/CLUMSYBLOCK = 0 -var/FAKEBLOCK = 0 -var/COUGHBLOCK = 0 -var/GLASSESBLOCK = 0 +var/BLINDBLOCK = 0 +var/DEAFBLOCK = 0 +var/HULKBLOCK = 0 +var/TELEBLOCK = 0 +var/FIREBLOCK = 0 +var/XRAYBLOCK = 0 +var/CLUMSYBLOCK = 0 +var/FAKEBLOCK = 0 +var/COUGHBLOCK = 0 +var/GLASSESBLOCK = 0 var/EPILEPSYBLOCK = 0 -var/TWITCHBLOCK = 0 -var/NERVOUSBLOCK = 0 -var/MONKEYBLOCK = 27 +var/TWITCHBLOCK = 0 +var/NERVOUSBLOCK = 0 +var/MONKEYBLOCK = 27 var/BLOCKADD = 0 -var/DIFFMUT = 0 +var/DIFFMUT = 0 -var/HEADACHEBLOCK = 0 -var/NOBREATHBLOCK = 0 -var/REMOTEVIEWBLOCK = 0 -var/REGENERATEBLOCK = 0 -var/INCREASERUNBLOCK = 0 -var/REMOTETALKBLOCK = 0 -var/MORPHBLOCK = 0 -var/BLENDBLOCK = 0 +var/HEADACHEBLOCK = 0 +var/NOBREATHBLOCK = 0 +var/REMOTEVIEWBLOCK = 0 +var/REGENERATEBLOCK = 0 +var/INCREASERUNBLOCK = 0 +var/REMOTETALKBLOCK = 0 +var/MORPHBLOCK = 0 +var/BLENDBLOCK = 0 var/HALLUCINATIONBLOCK = 0 -var/NOPRINTSBLOCK = 0 +var/NOPRINTSBLOCK = 0 var/SHOCKIMMUNITYBLOCK = 0 -var/SMALLSIZEBLOCK = 0 +var/SMALLSIZEBLOCK = 0 var/skipupdate = 0 - /////////////// -var/eventchance = 10 //% per 5 mins -var/event = 0 -var/hadevent = 0 -var/blobevent = 0 - /////////////// -var/diary = null -var/href_logfile = null -var/station_name = "NSS Exodus" -var/game_version = "Baystation12" +var/eventchance = 10 // Percent chance per 5 minutes. +var/event = 0 +var/hadevent = 0 +var/blobevent = 0 + +var/diary = null +var/href_logfile = null +var/station_name = "NSS Exodus" +var/game_version = "Baystation12" var/changelog_hash = "" -var/game_year = (text2num(time2text(world.realtime, "YYYY")) + 544) +var/game_year = (text2num(time2text(world.realtime, "YYYY")) + 544) -var/going = 1.0 -var/master_mode = "extended"//"extended" -var/secret_force_mode = "secret" // if this is anything but "secret", the secret rotation will forceably choose this mode +var/going = 1.0 +var/master_mode = "extended" // "extended" +var/secret_force_mode = "secret" // if this is anything but "secret", the secret rotation will forceably choose this mode. var/host = null var/shuttle_frozen = 0 -var/shuttle_left = 0 +var/shuttle_left = 0 +var/shuttlecoming = 0 -var/list/jobMax = list() -var/list/bombers = list( ) -var/list/admin_log = list ( ) -var/list/lastsignalers = list( ) //keeps last 100 signals here in format: "[src] used \ref[src] @ location [src.loc]: [freq]/[code]" -var/list/lawchanges = list( ) //Stores who uploaded laws to which silicon-based lifeform, and what the law was -var/list/reg_dna = list( ) -// list/traitobj = list( ) +var/list/jobMax = list() +var/list/bombers = list() +var/list/admin_log = list() +var/list/lastsignalers = list() // Keeps last 100 signals here in format: "[src] used \ref[src] @ location [src.loc]: [freq]/[code]" +var/list/lawchanges = list() // Stores who uploaded laws to which silicon-based lifeform, and what the law was. +var/list/reg_dna = list() +//var/list/traitobj = list() -var/mouse_respawn_time = 5 //Amount of time that must pass between a player dying as a mouse and repawning as a mouse. In minutes. +var/mouse_respawn_time = 5 // Amount of time that must pass between a player dying as a mouse and repawning as a mouse. In minutes. -var/CELLRATE = 0.002 // multiplier for watts per tick <> cell storage (eg: 0.02 means if there is a load of 1000 watts, 20 units will be taken from a cell per second) - //It's a conversion constant. power_used*CELLRATE = charge_provided, or charge_used/CELLRATE = power_provided +var/CELLRATE = 0.002 // Multiplier for watts per tick <> cell storage (e.g., 0.02 means if there is a load of 1000 watts, 20 units will be taken from a cell per second) + // It's a conversion constant. power_used*CELLRATE = charge_provided, or charge_used/CELLRATE = power_provided var/CHARGELEVEL = 0.0005 // Cap for how fast cells charge, as a percentage-per-tick (0.01 means cellcharge is capped to 1% per second) -var/shuttle_z = 2 //default -var/airtunnel_start = 68 // default -var/airtunnel_stop = 68 // default -var/airtunnel_bottom = 72 // default -var/list/monkeystart = list() -var/list/wizardstart = list() +var/shuttle_z = 2 // Default. +var/airtunnel_start = 68 // Default. +var/airtunnel_stop = 68 // Default. +var/airtunnel_bottom = 72 // Default. + +var/list/monkeystart = list() +var/list/wizardstart = list() var/list/newplayer_start = list() //Spawnpoints. -var/list/latejoin = list() +var/list/latejoin = list() var/list/latejoin_gateway = list() -var/list/latejoin_cryo = list() -var/list/latejoin_cyborg = list() +var/list/latejoin_cryo = list() +var/list/latejoin_cyborg = list() -var/list/prisonwarp = list() //prisoners go to these -var/list/holdingfacility = list() //captured people go here -var/list/xeno_spawn = list()//Aliens spawn at ahahthese. -// list/mazewarp = list() -var/list/tdome1 = list() -var/list/tdome2 = list() -var/list/tdomeobserve = list() -var/list/tdomeadmin = list() -var/list/prisonsecuritywarp = list() //prison security goes to these -var/list/prisonwarped = list() //list of players already warped -var/list/blobstart = list() -var/list/ninjastart = list() -// list/traitors = list() //traitor list -var/list/cardinal = list( NORTH, SOUTH, EAST, WEST ) -var/list/alldirs = list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST) -// reverse_dir[dir] = reverse of dir -var/list/reverse_dir = list(2, 1, 3, 8, 10, 9, 11, 4, 6, 5, 7, 12, 14, 13, 15, 32, 34, 33, 35, 40, 42, 41, 43, 36, 38, 37, 39, 44, 46, 45, 47, 16, 18, 17, 19, 24, 26, 25, 27, 20, 22, 21, 23, 28, 30, 29, 31, 48, 50, 49, 51, 56, 58, 57, 59, 52, 54, 53, 55, 60, 62, 61, 63) +var/list/prisonwarp = list() // Prisoners go to these +var/list/holdingfacility = list() // Captured people go here +var/list/xeno_spawn = list() // Aliens spawn at at these. +//var/list/mazewarp = list() +var/list/tdome1 = list() +var/list/tdome2 = list() +var/list/tdomeobserve = list() +var/list/tdomeadmin = list() +var/list/prisonsecuritywarp = list() // Prison security goes to these. +var/list/prisonwarped = list() // List of players already warped. +var/list/blobstart = list() +var/list/ninjastart = list() +//var/list/traitors = list() // Traitor list. + +var/list/cardinal = list(NORTH, SOUTH, EAST, WEST) +var/list/alldirs = list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST) +var/list/reverse_dir = list( // reverse_dir[dir] = reverse of dir + 2, 1, 3, 8, 10, 9, 11, 4, 6, 5, 7, 12, 14, 13, 15, 32, 34, 33, 35, 40, 42, + 41, 43, 36, 38, 37, 39, 44, 46, 45, 47, 16, 18, 17, 19, 24, 26, 25, 27, 20, 22, 21, + 23, 28, 30, 29, 31, 48, 50, 49, 51, 56, 58, 57, 59, 52, 54, 53, 55, 60, 62, 61, 63 +) var/datum/station_state/start_state = null -var/datum/configuration/config = null -var/datum/sun/sun = null +var/datum/configuration/config = null +var/datum/sun/sun = null var/list/combatlog = list() -var/list/IClog = list() -var/list/OOClog = list() -var/list/adminlog = list() - +var/list/IClog = list() +var/list/OOClog = list() +var/list/adminlog = list() var/list/powernets = list() -var/Debug = 0 // global debug switch +var/Debug = 0 // Global debug switch. var/Debug2 = 0 - var/datum/debug/debugobj var/datum/moduletypes/mods = new() -var/wavesecret = 0 +var/wavesecret = 0 var/gravity_is_on = 1 -var/shuttlecoming = 0 - var/join_motd = null var/forceblob = 0 -// nanomanager, the manager for Nano UIs -var/datum/nanomanager/nanomanager = new() +var/datum/nanomanager/nanomanager = new() // NanoManager, the manager for Nano UIs. +var/datum/event_manager/event_manager = new() // Event Manager, the manager for events. +var/datum/subsystem/alarm/alarm_manager = new() // Alarm Manager, the manager for alarms. -// event manager, the manager for events -var/datum/event_manager/event_manager = new() - -//away missions -var/list/awaydestinations = list() //a list of landmarks that the warpgate can take you to +var/list/awaydestinations = list() // Away missions. A list of landmarks that the warpgate can take you to. // MySQL configuration var/sqladdress = "localhost" -var/sqlport = "3306" -var/sqldb = "tgstation" -var/sqllogin = "root" -var/sqlpass = "" +var/sqlport = "3306" +var/sqldb = "tgstation" +var/sqllogin = "root" +var/sqlpass = "" // Feedback gathering sql connection -var/sqlfdbkdb = "test" +var/sqlfdbkdb = "test" var/sqlfdbklogin = "root" -var/sqlfdbkpass = "" -var/sqllogging = 0 // Should we log deaths, population stats, etc? +var/sqlfdbkpass = "" +var/sqllogging = 0 // Should we log deaths, population stats, etc.? -// Forum MySQL configuration (for use with forum account/key authentication) -// These are all default values that will load should the forumdbconfig.txt -// file fail to read for whatever reason. +// Forum MySQL configuration. (for use with forum account/key authentication) +// These are all default values that will load should the forumdbconfig.txt file fail to read for whatever reason. var/forumsqladdress = "localhost" -var/forumsqlport = "3306" -var/forumsqldb = "tgstation" -var/forumsqllogin = "root" -var/forumsqlpass = "" -var/forum_activated_group = "2" +var/forumsqlport = "3306" +var/forumsqldb = "tgstation" +var/forumsqllogin = "root" +var/forumsqlpass = "" +var/forum_activated_group = "2" var/forum_authenticated_group = "10" // For FTP requests. (i.e. downloading runtime logs.) @@ -206,28 +208,57 @@ var/forum_authenticated_group = "10" var/fileaccess_timer = 0 var/custom_event_msg = null -//Database connections -//A connection is established on world creation. Ideally, the connection dies when the server restarts (After feedback logging.). -var/DBConnection/dbcon = new() //Feedback database (New database) -var/DBConnection/dbcon_old = new() //Tgstation database (Old database) - See the files in the SQL folder for information what goes where. +// Database connections. A connection is established on world creation. +// Ideally, the connection dies when the server restarts (After feedback logging.). +var/DBConnection/dbcon = new() // Feedback database (New database) +var/DBConnection/dbcon_old = new() // /tg/station database (Old database) -- see the files in the SQL folder for information on what goes where. // Reference list for disposal sort junctions. Filled up by sorting junction's New() /var/list/tagger_locations = list() -//added for Xenoarchaeology, might be useful for other stuff +// Added for Xenoarchaeology, might be useful for other stuff. var/global/list/alphabet_uppercase = list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z") // Chemistry lists. -var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglycerin", "thirteenloko", "nicotine") //increase heart rate -var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin") //decrease heart rate -var/list/heartstopper = list("potassium_phorochloride", "zombie_powder") //this stops the heart -var/list/cheartstopper = list("potassium_chloride") //this stops the heart when overdose is met -- c = conditional +var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglycerin", "thirteenloko", "nicotine") // Increase heart rate. +var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin") // Decrease heart rate. +var/list/heartstopper = list("potassium_phorochloride", "zombie_powder") // This stops the heart. +var/list/cheartstopper = list("potassium_chloride") // This stops the heart when overdose is met. -- c = conditional -//Used by robots and robot preferences. -var/list/robot_module_types = list("Standard", "Engineering", "Construction", "Surgeon", "Crisis", "Miner", "Janitor", "Service", "Clerical", "Security") +// Used by robots and robot preferences. +var/list/robot_module_types = list( + "Standard", "Engineering", "Construction", "Surgeon", "Crisis", + "Miner", "Janitor", "Service", "Clerical", "Security" +) // Some scary sounds. -var/static/list/scarySounds = list('sound/weapons/thudswoosh.ogg','sound/weapons/Taser.ogg','sound/weapons/armbomb.ogg','sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg','sound/voice/hiss5.ogg','sound/voice/hiss6.ogg','sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg','sound/items/Welder.ogg','sound/items/Welder2.ogg','sound/machines/airlock.ogg','sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg') +var/static/list/scarySounds = list( + 'sound/weapons/thudswoosh.ogg', + 'sound/weapons/Taser.ogg', + 'sound/weapons/armbomb.ogg', + 'sound/voice/hiss1.ogg', + 'sound/voice/hiss2.ogg', + 'sound/voice/hiss3.ogg', + 'sound/voice/hiss4.ogg', + 'sound/voice/hiss5.ogg', + 'sound/voice/hiss6.ogg', + 'sound/effects/Glassbr1.ogg', + 'sound/effects/Glassbr2.ogg', + 'sound/effects/Glassbr3.ogg', + 'sound/items/Welder.ogg', + 'sound/items/Welder2.ogg', + 'sound/machines/airlock.ogg', + 'sound/effects/clownstep1.ogg', + 'sound/effects/clownstep2.ogg' +) // Bomb cap! var/max_explosion_range = 14 + +// Announcer intercom, because too much stuff creates an intercom for one message then hard del()s it. +var/global/obj/item/device/radio/intercom/global_announcer = new(null) + +var/list/station_departments = list("Command", "Medical", "Engineering", "Science", "Security", "Cargo", "Civilian") + +var/global/const/TICKS_IN_DAY = 864000 +var/global/const/TICKS_IN_SECOND = 10 \ No newline at end of file diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index 804116fede..a361328cac 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -1,5 +1,6 @@ -datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = -1, var/reason, var/job = "", var/rounds = 0, var/banckey = null) +//Either pass the mob you wish to ban in the 'banned_mob' attribute, or the banckey, banip and bancid variables. If both are passed, the mob takes priority! If a mob is not passed, banckey is the minimum that needs to be passed! banip and bancid are optional. +datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = -1, var/reason, var/job = "", var/rounds = 0, var/banckey = null, var/banip = null, var/bancid = null) if(!check_rights(R_MOD,0) && !check_rights(R_BAN)) return @@ -40,6 +41,8 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = ip = banned_mob.client.address else if(banckey) ckey = ckey(banckey) + computerid = bancid + ip = banip var/DBQuery/query = dbcon.NewQuery("SELECT id FROM erro_player WHERE ckey = '[ckey]'") query.Execute() @@ -178,7 +181,7 @@ datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null) switch(param) if("reason") if(!value) - value = input("Insert the new reason for [pckey]'s ban", "New Reason", "[reason]", null) as null|text + value = sanitize(input("Insert the new reason for [pckey]'s ban", "New Reason", "[reason]", null) as null|text) value = sql_sanitize_text(value) if(!value) usr << "Cancelled" @@ -260,7 +263,7 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) holder.DB_ban_panel() -/datum/admins/proc/DB_ban_panel(var/playerckey = null, var/adminckey = null) +/datum/admins/proc/DB_ban_panel(var/playerckey = null, var/adminckey = null, var/playerip = null, var/playercid = null, var/dbbantype = null, var/match = null) if(!usr.client) return @@ -282,16 +285,18 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) output += "
      Add custom ban: (ONLY use this if you can't ban through any other method)" output += "" output += "" - output += "" - output += "" - output += "" - output += "" + output += "" + output += "" + output += "" + output += "" output += "
      Ban type:Ban type:Ckey:
      Duration: Job:Ckey:
      IP: CID:
      Duration: Job:
      " - output += "Search: " - output += "" - output += "Ckey: " - output += "Admin ckey: " - output += "" + output += "" + output += "" + output += "" + output += "" + output += "" + output += "
      Search:" + output += "
      Ckey: Admin ckey:
      IP: CID:
      Ban type:
      " + output += "

      " + output += " Match(min. 3 characters to search by key or ip, and 7 to search by cid)
      " output += "
      " - output += "Please note that all jobban bans or unbans are in-effect the following round." + output += "Please note that all jobban bans or unbans are in-effect the following round.
      " + output += "This search shows only last 100 bans." - if(adminckey || playerckey) - - var/blcolor = "#ffeeee" //banned light - var/bdcolor = "#ffdddd" //banned dark - var/ulcolor = "#eeffee" //unbanned light - var/udcolor = "#ddffdd" //unbanned dark - - output += "" - output += "" - output += "" - output += "" - output += "" - output += "" - output += "" - output += "" + if(adminckey || playerckey || playerip || playercid || dbbantype) adminckey = ckey(adminckey) playerckey = ckey(playerckey) - var/adminsearch = "" - var/playersearch = "" - if(adminckey) - adminsearch = "AND a_ckey = '[adminckey]' " - if(playerckey) - playersearch = "AND ckey = '[playerckey]' " + playerip = sql_sanitize_text(playerip) + playercid = sql_sanitize_text(playercid) - var/DBQuery/select_query = dbcon.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits FROM erro_ban WHERE 1 [playersearch] [adminsearch] ORDER BY bantime DESC") - select_query.Execute() + if(adminckey || playerckey || playerip || playercid || dbbantype) - while(select_query.NextRow()) - var/banid = select_query.item[1] - var/bantime = select_query.item[2] - var/bantype = select_query.item[3] - var/reason = select_query.item[4] - var/job = select_query.item[5] - var/duration = select_query.item[6] - var/expiration = select_query.item[7] - var/ckey = select_query.item[8] - var/ackey = select_query.item[9] - var/unbanned = select_query.item[10] - var/unbanckey = select_query.item[11] - var/unbantime = select_query.item[12] - var/edits = select_query.item[13] + var/blcolor = "#ffeeee" //banned light + var/bdcolor = "#ffdddd" //banned dark + var/ulcolor = "#eeffee" //unbanned light + var/udcolor = "#ddffdd" //unbanned dark - var/lcolor = blcolor - var/dcolor = bdcolor - if(unbanned) - lcolor = ulcolor - dcolor = udcolor - - var/typedesc ="" - switch(bantype) - if("PERMABAN") - typedesc = "PERMABAN" - if("TEMPBAN") - typedesc = "TEMPBAN
      ([duration] minutes [(unbanned) ? "" : "(Edit))"]
      Expires [expiration]
      " - if("JOB_PERMABAN") - typedesc = "JOBBAN
      ([job])" - if("JOB_TEMPBAN") - typedesc = "TEMP JOBBAN
      ([job])
      ([duration] minutes
      Expires [expiration]" - - output += "
      " - output += "" - output += "" - output += "" - output += "" - output += "" + output += "
      TYPECKEYTIME APPLIEDADMINOPTIONS
      [typedesc][ckey][bantime][ackey][(unbanned) ? "" : "Unban"]
      " + output += "" + output += "" + output += "" + output += "" + output += "" + output += "" output += "" - output += "" - output += "" - output += "" - if(edits) + + var/adminsearch = "" + var/playersearch = "" + var/ipsearch = "" + var/cidsearch = "" + var/bantypesearch = "" + + if(!match) + if(adminckey) + adminsearch = "AND a_ckey = '[adminckey]' " + if(playerckey) + playersearch = "AND ckey = '[playerckey]' " + if(playerip) + ipsearch = "AND ip = '[playerip]' " + if(playercid) + cidsearch = "AND computerid = '[playercid]' " + else + if(adminckey && lentext(adminckey) >= 3) + adminsearch = "AND a_ckey LIKE '[adminckey]%' " + if(playerckey && lentext(playerckey) >= 3) + playersearch = "AND ckey LIKE '[playerckey]%' " + if(playerip && lentext(playerip) >= 3) + ipsearch = "AND ip LIKE '[playerip]%' " + if(playercid && lentext(playercid) >= 7) + cidsearch = "AND computerid LIKE '[playercid]%' " + + if(dbbantype) + bantypesearch = "AND bantype = " + + switch(dbbantype) + if(BANTYPE_TEMP) + bantypesearch += "'TEMPBAN' " + if(BANTYPE_JOB_PERMA) + bantypesearch += "'JOB_PERMABAN' " + if(BANTYPE_JOB_TEMP) + bantypesearch += "'JOB_TEMPBAN' " + else + bantypesearch += "'PERMABAN' " + + var/DBQuery/select_query = dbcon.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits, ip, computerid FROM erro_ban WHERE 1 [playersearch] [adminsearch] [ipsearch] [cidsearch] [bantypesearch] ORDER BY bantime DESC LIMIT 100") + select_query.Execute() + + while(select_query.NextRow()) + var/banid = select_query.item[1] + var/bantime = select_query.item[2] + var/bantype = select_query.item[3] + var/reason = select_query.item[4] + var/job = select_query.item[5] + var/duration = select_query.item[6] + var/expiration = select_query.item[7] + var/ckey = select_query.item[8] + var/ackey = select_query.item[9] + var/unbanned = select_query.item[10] + var/unbanckey = select_query.item[11] + var/unbantime = select_query.item[12] + var/edits = select_query.item[13] + var/ip = select_query.item[14] + var/cid = select_query.item[15] + + var/lcolor = blcolor + var/dcolor = bdcolor + if(unbanned) + lcolor = ulcolor + dcolor = udcolor + + var/typedesc ="" + switch(bantype) + if("PERMABAN") + typedesc = "PERMABAN" + if("TEMPBAN") + typedesc = "TEMPBAN
      ([duration] minutes [(unbanned) ? "" : "(Edit))"]
      Expires [expiration]
      " + if("JOB_PERMABAN") + typedesc = "JOBBAN
      ([job])" + if("JOB_TEMPBAN") + typedesc = "TEMP JOBBAN
      ([job])
      ([duration] minutes
      Expires [expiration]" + output += "
      " - output += "" + output += "" + output += "" + output += "" + output += "" + output += "" + output += "" + output += "" + output += "" + output += "" output += "" output += "" - output += "" + output += "" output += "" - if(unbanned) - output += "" - output += "" + if(edits) + output += "" + output += "" + output += "" + output += "" + output += "" + output += "" + if(unbanned) + output += "" + output += "" + output += "" + output += "" + output += "" output += "" - output += "" - output += "" - output += "" - output += "
      TYPECKEYTIME APPLIEDADMINOPTIONS
      Reason: [(unbanned) ? "" : "(Edit)"] \"[reason]\"
      EDITS[typedesc][ckey][bantime][ackey][(unbanned) ? "" : "Unban"]
      IP: [ip]CIP: [cid]
      [edits]Reason: [(unbanned) ? "" : "(Edit)"] \"[reason]\"
      UNBANNED by admin [unbanckey] on [unbantime]
      EDITS
      [edits]
      UNBANNED by admin [unbanckey] on [unbantime]
       
       
      " + output += "
    " - usr << browse(output,"window=lookupbans;size=900x500") \ No newline at end of file + usr << browse(output,"window=lookupbans;size=900x700") \ No newline at end of file diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index fcba6a91cc..96b7a7c244 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -92,7 +92,7 @@ var/global/floorIsLava = 0 body += "
    " //Monkey - if(ismonkey(M)) + if(issmall(M)) body += "Monkeyized | " else body += "Monkeyize | " @@ -725,10 +725,10 @@ var/global/floorIsLava = 0 set desc="Announce your desires to the world" if(!check_rights(0)) return - var/message = input("Global message to send:", "Admin Announce", null, null) as message + var/message = input("Global message to send:", "Admin Announce", null, null) as message//todo: sanitize for all? if(message) if(!check_rights(R_SERVER,0)) - message = adminscrub(message,500) + message = sanitize(message, 500, extra = 0) world << "\blue [usr.client.holder.fakekey ? "Administrator" : usr.key] Announces:\n \t [message]" log_admin("Announce: [key_name(usr)] : [message]") feedback_add_details("admin_verb","A") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -937,63 +937,47 @@ var/global/floorIsLava = 0 return 0 if (!istype(M)) return 0 - if((M.mind in ticker.mode.head_revolutionaries) || (M.mind in ticker.mode.revolutionaries)) - if (ticker.mode.config_tag == "revolution") - return 2 - return 1 - if(M.mind in ticker.mode.cult) - if (ticker.mode.config_tag == "cult") - return 2 - return 1 - if(M.mind in ticker.mode.malf_ai) - if (ticker.mode.config_tag == "malfunction") - return 2 - return 1 - if(M.mind in ticker.mode.syndicates) - if (ticker.mode.config_tag == "mercenary") - return 2 - return 1 - if(M.mind in ticker.mode.wizards) - if (ticker.mode.config_tag == "wizard") - return 2 - return 1 - if(M.mind in ticker.mode.changelings) - if (ticker.mode.config_tag == "changeling") - return 2 - return 1 - for(var/datum/disease/D in M.viruses) - if(istype(D, /datum/disease/jungle_fever)) - if (ticker.mode.config_tag == "monkey") - return 2 + if(M.mind) + if(ticker.mode.antag_templates && ticker.mode.antag_templates.len) + for(var/datum/antagonist/antag in ticker.mode.antag_templates) + if(antag.is_antagonist(M.mind)) + return 2 + else if(M.mind.special_role) return 1 + if(isrobot(M)) var/mob/living/silicon/robot/R = M if(R.emagged) return 1 - if(M.mind&&M.mind.special_role)//If they have a mind and special role, they are some type of traitor or antagonist. - return 1 return 0 -/* -/datum/admins/proc/get_sab_desc(var/target) - switch(target) - if(1) - return "Destroy at least 70% of the phoron canisters on the station" - if(2) - return "Destroy the AI" - if(3) - var/count = 0 - for(var/mob/living/carbon/monkey/Monkey in world) - if(Monkey.z in station_levels) - count++ - return "Kill all [count] of the monkeys on the station" - if(4) - return "Cut power to at least 80% of the station" - else - return "Error: Invalid sabotage target: [target]" -*/ +/datum/admins/proc/spawn_fruit() + set category = "Debug" + set desc = "Spawn the product of a seed." + set name = "Spawn Fruit" + + if(!check_rights(R_SPAWN)) return + + var/seedtype = input("Select a seed type", "Spawn Fruit") as null|anything in plant_controller.seeds + if(!seedtype || !plant_controller.seeds[seedtype]) + return + var/datum/seed/S = plant_controller.seeds[seedtype] + S.harvest(usr,0,0,1) + +/datum/admins/proc/spawn_plant() + set category = "Debug" + set desc = "Spawn a spreading plant effect." + set name = "Spawn Plant" + + if(!check_rights(R_SPAWN)) return + + var/seedtype = input("Select a seed type", "Spawn Plant") as null|anything in plant_controller.seeds + if(!seedtype || !plant_controller.seeds[seedtype]) + return + new /obj/effect/plant(get_turf(usr), plant_controller.seeds[seedtype]) + /datum/admins/proc/spawn_atom(var/object as text) set category = "Debug" set desc = "(atom path) Spawn an atom" @@ -1044,11 +1028,87 @@ var/global/floorIsLava = 0 M.mind.edit_memory() feedback_add_details("admin_verb","STP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/admins/proc/show_game_mode() + set category = "Admin" + set desc = "Show the current round configuration." + set name = "Show Game Mode" + + if(!ticker || !ticker.mode) + alert("Not before roundstart!", "Alert") + return + + var/out = "Current mode: [ticker.mode.name] ([ticker.mode.config_tag])
    " + out += "
    " + + if(ticker.mode.ert_disabled) + out += "Emergency Response Teams: disabled" + else + out += "Emergency Response Teams: enabled" + out += "
    " + + if(ticker.mode.deny_respawn) + out += "Respawning: disallowed" + else + out += "Respawning: allowed" + out += "
    " + + out += "Shuttle delay multiplier: [ticker.mode.shuttle_delay]
    " + + if(ticker.mode.auto_recall_shuttle) + out += "Shuttle auto-recall: enabled" + else + out += "Shuttle auto-recall: disabled" + out += "

    " + + if(ticker.mode.event_delay_mod_moderate) + out += "Moderate event time modifier: [ticker.mode.event_delay_mod_moderate]
    " + else + out += "Moderate event time modifier: unset
    " + + if(ticker.mode.event_delay_mod_major) + out += "Major event time modifier: [ticker.mode.event_delay_mod_major]
    " + else + out += "Major event time modifier: unset
    " + + out += "
    " + + if(ticker.mode.antag_tag) + out += "Core antag id: [ticker.mode.antag_tag].
    " + + if(ticker.mode.round_autoantag) + out += "Autotraitor enabled ([ticker.mode.antag_prob]% spawn chance)" + if(ticker.mode.antag_scaling_coeff) + out += " (scaling with [ticker.mode.antag_scaling_coeff])" + out += "
    " + else + out += "Autotraitor disabled.
    " + + out += "All antag ids:" + if(ticker.mode.antag_templates && ticker.mode.antag_templates.len). + var/playercount = ticker.mode.num_players() + for(var/datum/antagonist/antag in ticker.mode.antag_templates) + var/cur_max_antags + if(ticker.mode.antag_tag && antag.id == ticker.mode.antag_tag) + cur_max_antags = antag.max_antags_round + else + cur_max_antags = antag.max_antags + if(ticker.mode.antag_scaling_coeff) + cur_max_antags = Clamp((playercount/ticker.mode.antag_scaling_coeff), 1, cur_max_antags) + out += " [antag.id]" + out += " ([antag.get_antag_count()]/[cur_max_antags]) " + out += " \[-\]
    " + else + out += " None." + out += " \[+\]
    " + + usr << browse(out, "window=edit_mode[src]") + feedback_add_details("admin_verb","SGM") + /datum/admins/proc/toggletintedweldhelmets() set category = "Debug" set desc="Reduces view range when wearing welding helmets" - set name="Toggle tinted welding helmes" + set name="Toggle tinted welding helmets." config.welder_vision = !( config.welder_vision ) if (config.welder_vision) world << "Reduced welder vision has been enabled!" diff --git a/code/modules/admin/admin_memo.dm b/code/modules/admin/admin_memo.dm index 133f6d10e9..4bcaf10d9c 100644 --- a/code/modules/admin/admin_memo.dm +++ b/code/modules/admin/admin_memo.dm @@ -16,7 +16,7 @@ /client/proc/admin_memo_write() var/savefile/F = new(MEMOFILE) if(F) - var/memo = input(src,"Type your memo\n(Leaving it blank will delete your current memo):","Write Memo",null) as null|message + var/memo = sanitize(input(src,"Type your memo\n(Leaving it blank will delete your current memo):","Write Memo",null) as null|message, extra = 0) switch(memo) if(null) return diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 36d53e521b..1702fc4dbc 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -15,6 +15,7 @@ var/list/admin_verbs_admin = list( /client/proc/player_panel_new, /*shows an interface for all players, with links to various panels*/ /client/proc/invisimin, /*allows our mob to go invisible/visible*/ // /datum/admins/proc/show_traitor_panel, /*interface which shows a mob's mind*/ -Removed due to rare practical use. Moved to debug verbs ~Errorage + /datum/admins/proc/show_game_mode, /*Configuration window for the current game mode.*/ /datum/admins/proc/toggleenter, /*toggles whether people can join the current game*/ /datum/admins/proc/toggleguests, /*toggles whether guests can join the current game*/ /datum/admins/proc/announce, /*priority announce something to all clients.*/ @@ -46,7 +47,8 @@ var/list/admin_verbs_admin = list( /client/proc/cmd_admin_create_centcom_report, /client/proc/check_words, /*displays cult-words*/ /client/proc/check_ai_laws, /*shows AI and borg laws*/ - /client/proc/rename_ai, /*properly renames the AI*/ + /client/proc/rename_silicon, /*properly renames silicons*/ + /client/proc/manage_silicon_laws, /* Allows viewing and editing silicon laws. */ /client/proc/check_antagonists, /client/proc/admin_memo, /*admin memo system. show/delete/write. +SERVER needed to delete admin memos of others*/ /client/proc/dsay, /*talk in deadchat using our ckey/fakekey*/ @@ -78,7 +80,11 @@ var/list/admin_verbs_admin = list( /client/proc/toggle_antagHUD_use, /client/proc/toggle_antagHUD_restrictions, /client/proc/allow_character_respawn, /* Allows a ghost to respawn */ - /client/proc/event_manager_panel + /client/proc/event_manager_panel, + /client/proc/empty_ai_core_toggle_latejoin, + /client/proc/aooc, + /client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */ + /client/proc/change_human_appearance_self /* Allows the human-based mob itself change its basic appearance */ ) var/list/admin_verbs_ban = list( /client/proc/unban_panel, @@ -86,7 +92,8 @@ var/list/admin_verbs_ban = list( ) var/list/admin_verbs_sounds = list( /client/proc/play_local_sound, - /client/proc/play_sound + /client/proc/play_sound, + /client/proc/play_server_sound ) var/list/admin_verbs_fun = list( /client/proc/object_talk, @@ -95,10 +102,8 @@ var/list/admin_verbs_fun = list( /client/proc/drop_bomb, /client/proc/everyone_random, /client/proc/cinematic, - /client/proc/one_click_antag, /datum/admins/proc/toggle_aliens, /datum/admins/proc/toggle_space_ninja, - /client/proc/send_space_ninja, /client/proc/cmd_admin_add_freeform_ai_law, /client/proc/cmd_admin_add_random_ai_law, /client/proc/make_sound, @@ -106,8 +111,14 @@ var/list/admin_verbs_fun = list( /client/proc/editappear ) var/list/admin_verbs_spawn = list( + /datum/admins/proc/spawn_fruit, + /datum/admins/proc/spawn_plant, /datum/admins/proc/spawn_atom, /*allows us to spawn instances*/ - /client/proc/respawn_character + /client/proc/respawn_character, + /client/proc/FireLaser, + /client/proc/FireCannons, + /client/proc/ChangeIcarusPosition, + /client/proc/virus2_editor ) var/list/admin_verbs_server = list( /client/proc/Set_Holiday, @@ -140,6 +151,7 @@ var/list/admin_verbs_debug = list( /client/proc/cmd_debug_make_powernets, /client/proc/kill_airgroup, /client/proc/debug_controller, + /client/proc/debug_antagonist_template, /client/proc/cmd_debug_mob_lists, /client/proc/cmd_admin_delete, /client/proc/cmd_debug_del_all, @@ -148,8 +160,8 @@ var/list/admin_verbs_debug = list( /client/proc/reload_admins, /client/proc/reload_mentors, /client/proc/restart_controller, - /client/proc/remake_distribution_map, - /client/proc/show_distribution_map, + /client/proc/print_random_map, + /client/proc/create_random_map, /client/proc/show_plant_genes, /client/proc/enable_debug_verbs, /client/proc/callproc, @@ -199,6 +211,7 @@ var/list/admin_verbs_hideable = list( /client/proc/check_words, /client/proc/play_local_sound, /client/proc/play_sound, + /client/proc/play_server_sound, /client/proc/object_talk, /client/proc/cmd_admin_dress, /client/proc/cmd_admin_gib_self, @@ -206,7 +219,6 @@ var/list/admin_verbs_hideable = list( /client/proc/cinematic, /datum/admins/proc/toggle_aliens, /datum/admins/proc/toggle_space_ninja, - /client/proc/send_space_ninja, /client/proc/cmd_admin_add_freeform_ai_law, /client/proc/cmd_admin_add_random_ai_law, /client/proc/cmd_admin_create_centcom_report, @@ -553,22 +565,6 @@ var/list/admin_verbs_mentor = list( message_admins("\blue [ckey] creating an admin explosion at [epicenter.loc].") feedback_add_details("admin_verb","DB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/give_spell(mob/T as mob in mob_list) // -- Urist - set category = "Fun" - set name = "Give Spell" - set desc = "Gives a spell to a mob." - var/list/spell_names = list() - for(var/v in spells) - // "/obj/effect/proc_holder/spell/" 30 symbols ~Intercross21 - spell_names.Add(copytext("[v]", 31, 0)) - var/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_names - if(!S) return - var/path = text2path("/obj/effect/proc_holder/spell/[S]") - T.spell_list += new path - feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].") - message_admins("\blue [key_name_admin(usr)] gave [key_name(T)] the spell [S].", 1) - /client/proc/give_disease(mob/T as mob in mob_list) // -- Giacom set category = "Fun" set name = "Give Disease (old)" @@ -606,9 +602,10 @@ var/list/admin_verbs_mentor = list( var/mob/living/carbon/human/H = T if (H.species) D.affected_species = list(H.species.name) - if(istype(T,/mob/living/carbon/monkey)) - var/mob/living/carbon/monkey/M = T - D.affected_species = list(M.greaterform) + if(H.species.primitive_form) + D.affected_species |= H.species.primitive_form + if(H.species.greater_form) + D.affected_species |= H.species.greater_form infect_virus2(T,D,1) feedback_add_details("admin_verb","GD2") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -620,7 +617,7 @@ var/list/admin_verbs_mentor = list( set name = "Make Sound" set desc = "Display a message to everyone who can hear the target" if(O) - var/message = input("What do you want the message to be?", "Make Sound") as text|null + var/message = sanitize(input("What do you want the message to be?", "Make Sound") as text|null) if(!message) return for (var/mob/V in hearers(O)) @@ -704,17 +701,67 @@ var/list/admin_verbs_mentor = list( if(holder) src.holder.output_ai_laws() -/client/proc/rename_ai(mob/living/silicon/ai/AI in world) - set name = "Rename AI" +/client/proc/rename_silicon(mob/living/silicon/S in mob_list) + set name = "Rename Silicon" set category = "Admin" + if(!istype(S)) + return + if(holder) - var/new_name = trim_strip_input(src, "Enter new AI name. Leave blank or as is to cancel.", "Enter new AI Name", AI.name) - if(new_name && new_name != AI.name) - admin_log_and_message_admins("has renamed the AI '[AI.name]' to '[new_name]'") - AI.SetName(new_name) + var/new_name = sanitizeSafe(input(src, "Enter new name. Leave blank or as is to cancel.", "Enter new silicon name", S.real_name)) + if(new_name && new_name != S.real_name) + admin_log_and_message_admins("has renamed the silicon '[S.real_name]' to '[new_name]'") + S.SetName(new_name) feedback_add_details("admin_verb","RAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/proc/manage_silicon_laws(mob/living/silicon/S in mob_list) + set name = "Manage Silicon Laws" + set category = "Admin" + + if(!istype(S)) + return + + if(holder) + S.subsystem_law_manager() + admin_log_and_message_admins("has opened [S]'s law manager.") + feedback_add_details("admin_verb","MSL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/change_human_appearance_admin(mob/living/carbon/human/H in world) + set name = "Change Mob Appearance - Admin" + set desc = "Allows you to change the mob appearance" + set category = "Admin" + + if(!istype(H)) + return + + if(holder) + admin_log_and_message_admins("is altering the appearance of [H].") + H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0) + feedback_add_details("admin_verb","CHAA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/change_human_appearance_self(mob/living/carbon/human/H in mob_list) + set name = "Change Mob Appearance - Self" + set desc = "Allows the mob to change its appearance" + set category = "Admin" + + if(!istype(H)) + return + + if(!H.client) + usr << "Only mobs with clients can alter their own appearance." + return + + if(holder) + switch(alert("Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel")) + if("Yes") + admin_log_and_message_admins("has allowed [H] to change \his appearance, without whitelisting of races.") + H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 0) + if("No") + admin_log_and_message_admins("has allowed [H] to change \his appearance, with whitelisting of races.") + H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1) + feedback_add_details("admin_verb","CMAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + //---- bs12 verbs ---- @@ -726,7 +773,7 @@ var/list/admin_verbs_mentor = list( // feedback_add_details("admin_verb","MP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return -/client/proc/editappear(mob/living/carbon/human/M as mob in world) +/client/proc/editappear(mob/living/carbon/human/M as mob in mob_list) set name = "Edit Appearance" set category = "Fun" diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index ecfc952467..d1cc15b0fe 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -58,22 +58,21 @@ proc/admin_proc() NOTE: it checks usr! not src! So if you're checking somebody's rank in a proc which they did not call you will have to do something like if(client.holder.rights & R_ADMIN) yourself. */ - -/proc/check_rights(rights_required, show_msg=1) - if(usr && usr.client) +/proc/check_rights(rights_required, show_msg=1, var/mob/user = usr) + if(user && user.client) if(rights_required) - if(usr.client.holder) - if(rights_required & usr.client.holder.rights) + if(user.client.holder) + if(rights_required & user.client.holder.rights) return 1 else if(show_msg) - usr << "Error: You do not have sufficient rights to do that. You require one of the following flags:[rights2text(rights_required," ")]." + user << "Error: You do not have sufficient rights to do that. You require one of the following flags:[rights2text(rights_required," ")]." else - if(usr.client.holder) + if(user.client.holder) return 1 else if(show_msg) - usr << "Error: You are not an admin." + user << "Error: You are not an admin." return 0 //probably a bit iffy - will hopefully figure out a better solution diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 5de314db4c..828667aa13 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -231,7 +231,7 @@ M_job = M.job else if(isslime(M)) M_job = "slime" - else if(ismonkey(M)) + else if(issmall(M)) M_job = "Monkey" else if(isalien(M)) M_job = "Alien" @@ -342,7 +342,7 @@ dat += "New Player" else if(isobserver(M)) dat += "Ghost" - else if(ismonkey(M)) + else if(issmall(M)) dat += "Monkey" else if(isalien(M)) dat += "Alien" @@ -410,80 +410,8 @@ dat += "Launching now..." dat += "[ticker.delay_end ? "End Round Normally" : "Delay Round End"]
    " - if(ticker.mode.syndicates.len) - dat += "
    " - for(var/datum/mind/N in ticker.mode.syndicates) - var/mob/M = N.current - if(M) - dat += "" - dat += "" - else - dat += "" - dat += "
    Mercenaries
    [M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
    Mercenary not found!

    " - for(var/obj/item/weapon/disk/nuclear/N in world) - dat += "" - dat += "
    Nuclear Disk(s)
    [N.name], " - var/atom/disk_loc = N.loc - while(!istype(disk_loc, /turf)) - if(istype(disk_loc, /mob)) - var/mob/M = disk_loc - dat += "carried by [M.real_name] " - if(istype(disk_loc, /obj)) - var/obj/O = disk_loc - dat += "in \a [O.name] " - disk_loc = disk_loc.loc - dat += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z])
    " - if(ticker.mode.head_revolutionaries.len || ticker.mode.revolutionaries.len) - dat += "
    " - for(var/datum/mind/N in ticker.mode.head_revolutionaries) - var/mob/M = N.current - if(!M) - dat += "" - else - dat += "" - dat += "" - for(var/datum/mind/N in ticker.mode.revolutionaries) - var/mob/M = N.current - if(M) - dat += "" - dat += "" - dat += "
    Revolutionaries
    Head Revolutionary not found!
    [M.real_name] (Leader)[M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
    [M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
    " - for(var/datum/mind/N in ticker.mode.get_living_heads()) - var/mob/M = N.current - if(M) - dat += "" - dat += "" - var/turf/mob_loc = get_turf(M) - dat += "" - else - dat += "" - dat += "
    Target(s)Location
    [M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM[mob_loc.loc]
    Head not found!
    " - - if(ticker.mode.changelings.len) - dat += check_role_table("Changelings", ticker.mode.changelings, src) - - if(ticker.mode.wizards.len) - dat += check_role_table("Wizards", ticker.mode.wizards, src) - - if(ticker.mode.raiders.len) - dat += check_role_table("Raiders", ticker.mode.raiders, src) - - if(ticker.mode.ninjas.len) - dat += check_role_table("Ninjas", ticker.mode.ninjas, src) - - if(ticker.mode.cult.len) - dat += check_role_table("Cultists", ticker.mode.cult, src, 0) - - if(ticker.mode.traitors.len) - dat += check_role_table("Traitors", ticker.mode.traitors, src) - - if(ticker.mode.borers.len) - dat += check_role_table("Cortical Borers", ticker.mode.borers, src) - - var/datum/game_mode/mutiny/mutiny = get_mutiny_mode() - if(mutiny) - dat += mutiny.check_antagonists_ui(src) + //todo dat += "" usr << browse(dat, "window=roundstatus;size=400x500") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index a5c866b7ee..20d982e032 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -10,53 +10,19 @@ check_antagonists() return - if(href_list["makeAntag"]) - switch(href_list["makeAntag"]) - if("1") - log_admin("[key_name(usr)] has spawned a traitor.") - if(!src.makeTraitors()) - usr << "\red Unfortunately there weren't enough candidates available." - if("2") - log_admin("[key_name(usr)] has spawned a changeling.") - if(!src.makeChanglings()) - usr << "\red Unfortunately there weren't enough candidates available." - if("3") - log_admin("[key_name(usr)] has spawned revolutionaries.") - if(!src.makeRevs()) - usr << "\red Unfortunately there weren't enough candidates available." - if("4") - log_admin("[key_name(usr)] has spawned a cultists.") - if(!src.makeCult()) - usr << "\red Unfortunately there weren't enough candidates available." - if("5") - log_admin("[key_name(usr)] has spawned a malf AI.") - if(!src.makeMalfAImode()) - usr << "\red Unfortunately there weren't enough candidates available." - if("6") - log_admin("[key_name(usr)] has spawned a wizard.") - if(!src.makeWizard()) - usr << "\red Unfortunately there weren't enough candidates available." - if("7") - log_admin("[key_name(usr)] has spawned a nuke team.") - if(!src.makeNukeTeam()) - usr << "\red Unfortunately there weren't enough candidates available." - if("8") - log_admin("[key_name(usr)] has spawned a ninja.") - src.makeSpaceNinja() - if("9") - log_admin("[key_name(usr)] has spawned aliens.") - src.makeAliens() - if("10") - log_admin("[key_name(usr)] has spawned a death squad.") - if("11") - log_admin("[key_name(usr)] has spawned vox raiders.") - if(!src.makeVoxRaiders()) - usr << "\red Unfortunately there weren't enough candidates available." - else if(href_list["dbsearchckey"] || href_list["dbsearchadmin"]) + if(href_list["dbsearchckey"] || href_list["dbsearchadmin"]) + var/adminckey = href_list["dbsearchadmin"] var/playerckey = href_list["dbsearchckey"] + var/playerip = href_list["dbsearchip"] + var/playercid = href_list["dbsearchcid"] + var/dbbantype = text2num(href_list["dbsearchbantype"]) + var/match = 0 - DB_ban_panel(playerckey, adminckey) + if("dbmatch" in href_list) + match = 1 + + DB_ban_panel(playerckey, adminckey, playerip, playercid, dbbantype, match) return else if(href_list["dbbanedit"]) @@ -72,6 +38,8 @@ var/bantype = text2num(href_list["dbbanaddtype"]) var/banckey = href_list["dbbanaddckey"] + var/banip = href_list["dbbanaddip"] + var/bancid = href_list["dbbanaddcid"] var/banduration = text2num(href_list["dbbaddduration"]) var/banjob = href_list["dbbanaddjob"] var/banreason = href_list["dbbanreason"] @@ -107,9 +75,18 @@ playermob = M break + banreason = "(MANUAL BAN) "+banreason - DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey) + if(!playermob) + if(banip) + banreason = "[banreason] (CUSTOM IP)" + if(bancid) + banreason = "[banreason] (CUSTOM CID)" + else + message_admins("Ban process: A mob matching [playermob.ckey] was found at location [playermob.x], [playermob.y], [playermob.z]. Custom ip and computer id fields replaced with the ip and computer id from the located mob") + + DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey, banip, bancid ) else if(href_list["editrights"]) if(!check_rights(R_PERMISSIONS)) @@ -289,10 +266,10 @@ if("nymph") M.change_mob_type( /mob/living/carbon/alien/diona , null, null, delmob ) if("human") M.change_mob_type( /mob/living/carbon/human , null, null, delmob, href_list["species"]) if("slime") M.change_mob_type( /mob/living/carbon/slime , null, null, delmob ) - if("monkey") M.change_mob_type( /mob/living/carbon/monkey , null, null, delmob ) + if("monkey") M.change_mob_type( /mob/living/carbon/human/monkey , null, null, delmob ) if("robot") M.change_mob_type( /mob/living/silicon/robot , null, null, delmob ) if("cat") M.change_mob_type( /mob/living/simple_animal/cat , null, null, delmob ) - if("runtime") M.change_mob_type( /mob/living/simple_animal/cat/Runtime , null, null, delmob ) + if("runtime") M.change_mob_type( /mob/living/simple_animal/cat/fluff/Runtime , null, null, delmob ) if("corgi") M.change_mob_type( /mob/living/simple_animal/corgi , null, null, delmob ) if("ian") M.change_mob_type( /mob/living/simple_animal/corgi/Ian , null, null, delmob ) if("crab") M.change_mob_type( /mob/living/simple_animal/crab , null, null, delmob ) @@ -351,12 +328,12 @@ mins = min(525599,mins) minutes = CMinutes + mins duration = GetExp(minutes) - reason = input(usr,"Reason?","reason",reason2) as text|null + reason = sanitize(input(usr,"Reason?","reason",reason2) as text|null) if(!reason) return if("No") temp = 0 duration = "Perma" - reason = input(usr,"Reason?","reason",reason2) as text|null + reason = sanitize(input(usr,"Reason?","reason",reason2) as text|null) if(!reason) return log_admin("[key_name(usr)] edited [banned_key]'s ban. Reason: [reason] Duration: [duration]") @@ -568,69 +545,15 @@ jobs += "" jobs += "" - //Traitor - if(jobban_isbanned(M, "traitor") || isbanned_dept) - jobs += "" - else - jobs += "" - - //Changeling - if(jobban_isbanned(M, "changeling") || isbanned_dept) - jobs += "" - else - jobs += "" - - //Nuke Operative - if(jobban_isbanned(M, "operative") || isbanned_dept) - jobs += "" - else - jobs += "" - - //Revolutionary - if(jobban_isbanned(M, "revolutionary") || isbanned_dept) - jobs += "" - else - jobs += "" - - jobs += "" //Breaking it up so it fits nicer on the screen every 5 entries - - //Cultist - if(jobban_isbanned(M, "cultist") || isbanned_dept) - jobs += "" - else - jobs += "" - - //Wizard - if(jobban_isbanned(M, "wizard") || isbanned_dept) - jobs += "" - else - jobs += "" - - //ERT - if(jobban_isbanned(M, "Emergency Response Team") || isbanned_dept) - jobs += "" - else - jobs += "" - - -/* //Malfunctioning AI //Removed Malf-bans because they're a pain to impliment - if(jobban_isbanned(M, "malf AI") || isbanned_dept) - jobs += "" - else - jobs += "" - - //Alien - if(jobban_isbanned(M, "alien candidate") || isbanned_dept) - jobs += "" - else - jobs += "" - - //Infested Monkey - if(jobban_isbanned(M, "infested monkey") || isbanned_dept) - jobs += "" - else - jobs += "" -*/ + // Antagonists. + for(var/antag_type in all_antag_types) + var/datum/antagonist/antag = all_antag_types[antag_type] + if(!antag || !antag.bantype) + continue + if(jobban_isbanned(M, "[antag.bantype]") || isbanned_dept) + jobs += "" + else + jobs += "" jobs += "
    Antagonist Positions
    [replacetext("Traitor", " ", " ")][replacetext("Traitor", " ", " ")][replacetext("Changeling", " ", " ")][replacetext("Changeling", " ", " ")][replacetext("Mercenary", " ", " ")][replacetext("Mercenary", " ", " ")][replacetext("Revolutionary", " ", " ")][replacetext("Revolutionary", " ", " ")]
    [replacetext("Cultist", " ", " ")][replacetext("Cultist", " ", " ")][replacetext("Wizard", " ", " ")][replacetext("Wizard", " ", " ")]Emergency Response TeamEmergency Response Team[replacetext("Malf AI", " ", " ")][replacetext("Malf AI", " ", " ")][replacetext("Alien", " ", " ")][replacetext("Alien", " ", " ")][replacetext("Infested Monkey", " ", " ")][replacetext("Infested Monkey", " ", " ")][replacetext("[antag.role_text]", " ", " ")][replacetext("[antag.role_text]", " ", " ")]
    " @@ -642,16 +565,7 @@ jobs += "Dionaea" else jobs += "Dionaea" - - if(jobban_isbanned(M, "Borer")) - jobs += "Borer" - else - jobs += "Borer" - - jobs += "" - - body = "[jobs]" dat = "[header][body]" usr << browse(dat, "window=jobban2;size=800x490") @@ -741,7 +655,7 @@ var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null if(!mins) return - var/reason = input(usr,"Reason?","Please State Reason","") as text|null + var/reason = sanitize(input(usr,"Reason?","Please State Reason","") as text|null) if(!reason) return @@ -766,7 +680,7 @@ return 1 if("No") if(!check_rights(R_BAN)) return - var/reason = input(usr,"Reason?","Please State Reason","") as text|null + var/reason = sanitize(input(usr,"Reason?","Please State Reason","") as text|null) if(reason) var/msg for(var/job in notbannedlist) @@ -823,7 +737,7 @@ if (ismob(M)) if(!check_if_greater_rights_than(M.client)) return - var/reason = input("Please enter reason") + var/reason = sanitize(input("Please enter reason")) if(!reason) M << "\red You have been kicked from the server" else @@ -880,7 +794,7 @@ if(!mins) return if(mins >= 525600) mins = 525599 - var/reason = input(usr,"Reason?","reason","Griefer") as text|null + var/reason = sanitize(input(usr,"Reason?","reason","Griefer") as text|null) if(!reason) return AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins) @@ -901,7 +815,7 @@ //del(M) // See no reason why to delete mob. Important stuff can be lost. And ban can be lifted before round ends. if("No") if(!check_rights(R_BAN)) return - var/reason = input(usr,"Reason?","reason","Griefer") as text|null + var/reason = sanitize(input(usr,"Reason?","reason","Griefer") as text|null) if(!reason) return switch(alert(usr,"IP ban?",,"Yes","No","Cancel")) @@ -1253,44 +1167,6 @@ show_player_panel(H) //H.regenerate_icons() -/***************** BEFORE************** - - if (href_list["l_players"]) - var/dat = "Name/Real Name/Key/IP:
    " - for(var/mob/M in world) - var/foo = "" - if (ismob(M) && M.client) - if(!M.client.authenticated && !M.client.authenticating) - foo += text("\[ Authorize | ", src, M) - else - foo += text("\[ Authorized | ") - if(M.start) - if(!istype(M, /mob/living/carbon/monkey)) - foo += text("Monkeyize | ", src, M) - else - foo += text("Monkeyized | ") - if(istype(M, /mob/living/silicon/ai)) - foo += text("Is an AI | ") - else - foo += text("Make AI | ", src, M) - if(isNotAdminLevel(M.z)) - foo += text("Prison | ", src, M) - foo += text("Maze | ", src, M) - else - foo += text("On Z = [M.z] | ") - else - foo += text("Hasn't Entered Game | ") - foo += text("Heal/Revive | ", src, M) - - foo += text("Say \]", src, M) - dat += text("N: [] R: [] (K: []) (IP: []) []
    ", M.name, M.real_name, (M.client ? M.client : "No client"), M.lastKnownIP, foo) - - usr << browse(dat, "window=players;size=900x480") - -*****************AFTER******************/ - -// Now isn't that much better? IT IS NOW A PROC, i.e. kinda like a big panel like unstable - else if(href_list["adminplayeropts"]) var/mob/M = locate(href_list["adminplayeropts"]) show_player_panel(M) @@ -1449,7 +1325,7 @@ usr << "The person you are trying to contact is not wearing a headset" return - var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via their headset.","Outgoing message from Centcomm", "") + var/input = sanitize(input(src.owner, "Please enter a message to reply to [key_name(H)] via their headset.","Outgoing message from Centcomm", "")) if(!input) return src.owner << "You sent [input] to [H] via a secure channel." @@ -1466,7 +1342,7 @@ usr << "The person you are trying to contact is not wearing a headset" return - var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via their headset.","Outgoing message from a shadowy figure...", "") + var/input = sanitize(input(src.owner, "Please enter a message to reply to [key_name(H)] via their headset.","Outgoing message from a shadowy figure...", "")) if(!input) return src.owner << "You sent [input] to [H] via a secure channel." @@ -1513,6 +1389,7 @@ var/mob/sender = locate(href_list["CentcommFaxReply"]) var/obj/machinery/photocopier/faxmachine/fax = locate(href_list["originfax"]) + //todo: sanitize var/input = input(src.owner, "Please enter a message to reply to [key_name(sender)] via secure connection. NOTE: BBCode does not work, but HTML tags do! Use
    for line breaks.", "Outgoing message from Centcomm", "") as message|null if(!input) return @@ -1717,7 +1594,7 @@ where = "onfloor" if ( where == "inhand" ) //Can only give when human or monkey - if ( !( ishuman(usr) || ismonkey(usr) ) ) + if ( !( ishuman(usr) || issmall(usr) ) ) usr << "Can only spawn in hand when you're a human or a monkey." where = "onfloor" else if ( usr.get_active_hand() ) @@ -1866,13 +1743,13 @@ feedback_add_details("admin_secrets_fun_used","Aliens") log_admin("[key_name(usr)] spawned an alien infestation", 1) message_admins("\blue [key_name_admin(usr)] attempted an alien infestation", 1) - new /datum/event/alien_infestation + xenomorphs.random_spawn() if("borers") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","Borers") log_admin("[key_name(usr)] spawned a cortical borer infestation.", 1) message_admins("\blue [key_name_admin(usr)] spawned a cortical borer infestation.", 1) - new /datum/event/borer_infestation + borers.random_spawn() if("power") feedback_inc("admin_secrets_fun_used",1) @@ -1954,40 +1831,6 @@ //teleport security person H.loc = pick(prisonsecuritywarp) prisonwarped += H - if("traitor_all") - if(!ticker) - alert("The game hasn't started yet!") - return - var/objective = sanitize(copytext(input("Enter an objective"),1,MAX_MESSAGE_LEN)) - if(!objective) - return - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","TA([objective])") - for(var/mob/living/carbon/human/H in player_list) - if(H.stat == 2 || !H.client || !H.mind) continue - if(is_special_character(H)) continue - //traitorize(H, objective, 0) - ticker.mode.traitors += H.mind - H.mind.special_role = "traitor" - var/datum/objective/new_objective = new - new_objective.owner = H - new_objective.explanation_text = objective - H.mind.objectives += new_objective - ticker.mode.greet_traitor(H.mind) - //ticker.mode.forge_traitor_objectives(H.mind) - ticker.mode.finalize_traitor(H.mind) - for(var/mob/living/silicon/A in player_list) - ticker.mode.traitors += A.mind - A.mind.special_role = "traitor" - var/datum/objective/new_objective = new - new_objective.owner = A - new_objective.explanation_text = objective - A.mind.objectives += new_objective - ticker.mode.greet_traitor(A.mind) - ticker.mode.finalize_traitor(A.mind) - message_admins("\blue [key_name_admin(usr)] used everyone is a traitor secret. Objective is [objective]", 1) - log_admin("[key_name(usr)] used everyone is a traitor secret. Objective is [objective]") - if("launchshuttle") if(!shuttle_controller) return // Something is very wrong, the shuttle controller has not been created. @@ -2212,8 +2055,7 @@ if("aliens") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","AL") - if(config.aliens_allowed) - new /datum/event/alien_infestation + if(xenomorphs.random_spawn()) message_admins("[key_name_admin(usr)] has spawned aliens", 1) if("spiders") feedback_inc("admin_secrets_fun_used",1) @@ -2229,12 +2071,6 @@ else communications_blackout(1) message_admins("[key_name_admin(usr)] triggered a communications blackout.", 1) - if("spaceninja") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","SN") - if(config.ninjas_allowed) - if(space_ninja_arrival())//If the ninja is actually spawned. They may not be depending on a few factors. - message_admins("[key_name_admin(usr)] has sent in a space ninja", 1) if("carp") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","C") @@ -2410,15 +2246,10 @@ var/show_log = alert(usr, "Show ion message?", "Message", "Yes", "No") if(show_log == "Yes") command_announcement.Announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", new_sound = 'sound/AI/ionstorm.ogg') - if("spacevines") - feedback_inc("admin_secrets_fun_used",1) - feedback_add_details("admin_secrets_fun_used","K") - new /datum/event/spacevine - message_admins("[key_name_admin(usr)] has spawned spacevines", 1) if("onlyone") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","OO") - usr.client.only_one() + only_one() message_admins("[key_name_admin(usr)] has triggered a battle to the death (only one)") if(usr) log_admin("[key_name(usr)] used secret [href_list["secretsfun"]]") @@ -2536,9 +2367,7 @@ src.access_news_network() else if(href_list["ac_set_channel_name"]) - src.admincaster_feed_channel.channel_name = strip_html_simple(input(usr, "Provide a Feed Channel Name", "Network Channel Handler", "")) - while (findtext(src.admincaster_feed_channel.channel_name," ") == 1) - src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,lentext(src.admincaster_feed_channel.channel_name)+1) + src.admincaster_feed_channel.channel_name = sanitizeSafe(input(usr, "Provide a Feed Channel Name", "Network Channel Handler", "")) src.access_news_network() else if(href_list["ac_set_channel_lock"]) @@ -2571,13 +2400,11 @@ var/list/available_channels = list() for(var/datum/feed_channel/F in news_network.network_channels) available_channels += F.channel_name - src.admincaster_feed_channel.channel_name = adminscrub(input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels ) + src.admincaster_feed_channel.channel_name = sanitizeSafe(input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels ) src.access_news_network() else if(href_list["ac_set_new_message"]) - src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story", "Network Channel Handler", "")) - while (findtext(src.admincaster_feed_message.body," ") == 1) - src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.body,2,lentext(src.admincaster_feed_message.body)+1) + src.admincaster_feed_message.body = sanitize(input(usr, "Write your Feed story", "Network Channel Handler", "")) src.access_news_network() else if(href_list["ac_submit_new_message"]) @@ -2619,15 +2446,11 @@ src.access_news_network() else if(href_list["ac_set_wanted_name"]) - src.admincaster_feed_message.author = adminscrub(input(usr, "Provide the name of the Wanted person", "Network Security Handler", "")) - while (findtext(src.admincaster_feed_message.author," ") == 1) - src.admincaster_feed_message.author = copytext(admincaster_feed_message.author,2,lentext(admincaster_feed_message.author)+1) + src.admincaster_feed_message.author = sanitize(input(usr, "Provide the name of the Wanted person", "Network Security Handler", "")) src.access_news_network() else if(href_list["ac_set_wanted_desc"]) - src.admincaster_feed_message.body = adminscrub(input(usr, "Provide the a description of the Wanted person and any other details you deem important", "Network Security Handler", "")) - while (findtext(src.admincaster_feed_message.body," ") == 1) - src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.body,2,lentext(src.admincaster_feed_message.body)+1) + src.admincaster_feed_message.body = sanitize(input(usr, "Provide the a description of the Wanted person and any other details you deem important", "Network Security Handler", "")) src.access_news_network() else if(href_list["ac_submit_wanted"]) @@ -2732,7 +2555,7 @@ src.access_news_network() else if(href_list["ac_set_signature"]) - src.admincaster_signature = adminscrub(input(usr, "Provide your desired signature", "Network Identity Handler", "")) + src.admincaster_signature = sanitize(input(usr, "Provide your desired signature", "Network Identity Handler", "")) src.access_news_network() else if(href_list["populate_inactive_customitems"]) @@ -2770,7 +2593,7 @@ if(href_list["add_player_info"]) var/key = href_list["add_player_info"] - var/add = input("Add Player Info") as null|text + var/add = sanitize(input("Add Player Info") as null|text) if(!add) return notes_add(key,add,usr) diff --git a/code/modules/admin/verbs/BrokenInhands.dm b/code/modules/admin/verbs/BrokenInhands.dm index 43f6d0b793..914ba1b5df 100644 --- a/code/modules/admin/verbs/BrokenInhands.dm +++ b/code/modules/admin/verbs/BrokenInhands.dm @@ -1,7 +1,7 @@ /proc/getbrokeninhands() - var/icon/IL = new('icons/mob/items_lefthand.dmi') + var/icon/IL = new('icons/mob/items/lefthand.dmi') var/list/Lstates = IL.IconStates() - var/icon/IR = new('icons/mob/items_righthand.dmi') + var/icon/IR = new('icons/mob/items/righthand.dmi') var/list/Rstates = IR.IconStates() diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index bff2372aa9..9f29bc621a 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -23,7 +23,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," //clean the input msg if(!msg) return - msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN)) + msg = sanitize(msg) if(!msg) return var/original_msg = msg @@ -88,7 +88,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," if(ai_found) ai_cl = " (CL)" - //Options bar: mob, details ( admin = 2, dev = 3, mentor = 4, character name (0 = just ckey, 1 = ckey and character name), link? (0 no don't make it a link, 1 do so), + //Options bar: mob, details ( admin = 2, dev = 3, mentor = 4, character name (0 = just ckey, 1 = ckey and character name), link? (0 no don't make it a link, 1 do so), // highlight special roles (0 = everyone has same looking name, 1 = antags / special roles get a golden name) var/mentor_msg = "\blue Request for Help: [get_options_bar(mob, 4, 1, 1, 0)][ai_cl]: [msg]" diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 1c358c8cf4..467083e827 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -60,8 +60,9 @@ return //clean the message if it's not sent by a high-rank admin + //todo: sanitize for all??? if(!check_rights(R_SERVER|R_DEBUG,0)) - msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN)) + msg = sanitize(msg) if(!msg) return var/recieve_pm_type = "Player" @@ -91,7 +92,7 @@ spawn(0) //so we don't hold the caller proc up var/sender = src var/sendername = key - var/reply = input(C, msg,"[recieve_pm_type] PM from [sendername]", "") as text|null //show message and await a reply + var/reply = sanitize(input(C, msg,"[recieve_pm_type] PM from [sendername]", "") as text|null) //show message and await a reply if(C && reply) if(sender) C.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm index e3aa767ecd..fdbbe8d4e1 100644 --- a/code/modules/admin/verbs/adminsay.dm +++ b/code/modules/admin/verbs/adminsay.dm @@ -4,7 +4,7 @@ set hidden = 1 if(!check_rights(R_ADMIN)) return - msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)) + msg = sanitize(msg) if(!msg) return log_admin("[key_name(src)] : [msg]") @@ -23,7 +23,7 @@ if(!check_rights(R_ADMIN|R_MOD|R_MENTOR)) return - msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)) + msg = sanitize(msg) log_admin("MOD: [key_name(src)] : [msg]") if (!msg) diff --git a/code/modules/admin/verbs/antag-ooc.dm b/code/modules/admin/verbs/antag-ooc.dm new file mode 100644 index 0000000000..53a2c709fc --- /dev/null +++ b/code/modules/admin/verbs/antag-ooc.dm @@ -0,0 +1,19 @@ +/client/proc/aooc(msg as text) + set category = "OOC" + set name = "AOOC" + set desc = "Antagonist OOC" + + if(!check_rights(R_ADMIN)) return + + msg = sanitize(msg) + if(!msg) return + + var/display_name = src.key + if(holder && holder.fakekey) + display_name = holder.fakekey + + for(var/mob/M in mob_list) + if((M.mind && M.mind.special_role && M.client) || (M.client && M.client.holder)) + M << "" + create_text_tag("aooc", "Antag-OOC:", M.client) + " [display_name]: [msg]" + + log_ooc("(ANTAG) [key] : [msg]") \ No newline at end of file diff --git a/code/modules/admin/verbs/buildmode.dm b/code/modules/admin/verbs/buildmode.dm index acd442355a..71bdabf4be 100644 --- a/code/modules/admin/verbs/buildmode.dm +++ b/code/modules/admin/verbs/buildmode.dm @@ -78,6 +78,8 @@ if(2) usr << "\blue ***********************************************************" usr << "\blue Right Mouse Button on buildmode button = Set object type" + usr << "\blue Middle Mouse Button on buildmode button= On/Off object type saying" + usr << "\blue Middle Mouse Button on turf/obj = Capture object type" usr << "\blue Left Mouse Button on turf/obj = Place objects" usr << "\blue Right Mouse Button = Delete objects" usr << "" @@ -121,10 +123,17 @@ var/varholder = "name" var/valueholder = "derp" var/objholder = /obj/structure/closet + var/objsay = 1 Click(location, control, params) var/list/pa = params2list(params) + if(pa.Find("middle")) + switch(master.cl.buildmode) + if(2) + objsay=!objsay + + if(pa.Find("left")) switch(master.cl.buildmode) if(1) @@ -242,6 +251,10 @@ A.set_dir(holder.builddir.dir) else if(pa.Find("right")) if(isobj(object)) del(object) + if(pa.Find("middle")) + holder.buildmode.objholder = text2path("[object.type]") + if(holder.buildmode.objsay) usr << "[object.type]" + if(3) if(pa.Find("left")) //I cant believe this shit actually compiles. @@ -264,4 +277,3 @@ if(pa.Find("right")) if(holder.throw_atom) holder.throw_atom.throw_at(object, 10, 1) - diff --git a/code/modules/admin/verbs/custom_event.dm b/code/modules/admin/verbs/custom_event.dm index 3021cc2828..265c16a868 100644 --- a/code/modules/admin/verbs/custom_event.dm +++ b/code/modules/admin/verbs/custom_event.dm @@ -7,7 +7,7 @@ src << "Only administrators may use this command." return - var/input = input(usr, "Enter the description of the custom event. Be descriptive. To cancel the event, make this blank or hit cancel.", "Custom Event", custom_event_msg) as message|null + var/input = sanitize(input(usr, "Enter the description of the custom event. Be descriptive. To cancel the event, make this blank or hit cancel.", "Custom Event", custom_event_msg) as message|null, MAX_BOOK_MESSAGE_LEN, extra = 0) if(!input || input == "") custom_event_msg = null log_admin("[usr.key] has cleared the custom event text.") @@ -21,7 +21,7 @@ world << "

    Custom Event

    " world << "

    A custom event is starting. OOC Info:

    " - world << "[html_encode(custom_event_msg)]" + world << "[custom_event_msg]" world << "
    " // normal verb for players to view info @@ -36,5 +36,5 @@ src << "

    Custom Event

    " src << "

    A custom event is taking place. OOC Info:

    " - src << "[html_encode(custom_event_msg)]" + src << "[custom_event_msg]" src << "
    " diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm index bb66843c16..b3b6e3fdae 100644 --- a/code/modules/admin/verbs/deadsay.dm +++ b/code/modules/admin/verbs/deadsay.dm @@ -29,7 +29,7 @@ if (src.holder.rights & R_ADMIN) stafftype = "ADMIN" - msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)) + msg = sanitize(msg) log_admin("[key_name(src)] : [msg]") if (!msg) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 9b3d757691..325f04f9e8 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -205,7 +205,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that return 0 var/obj/item/device/paicard/card = new(T) var/mob/living/silicon/pai/pai = new(card) - pai.name = input(choice, "Enter your pAI name:", "pAI Name", "Personal AI") as text + pai.name = sanitizeSafe(input(choice, "Enter your pAI name:", "pAI Name", "Personal AI") as text) pai.real_name = pai.name pai.key = choice.key card.setPersonality(pai) @@ -595,7 +595,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/weapon/cloaking_device(M), slot_r_store) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile(M), slot_r_hand) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver(M), slot_r_hand) M.equip_to_slot_or_del(new /obj/item/ammo_magazine/a357(M), slot_l_store) if ("tournament chef") //Steven Seagal FTW @@ -662,7 +662,6 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/clothing/suit/chaplain_hoodie(M), slot_wear_suit) - M.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/food/snacks/grown/banana(M), slot_l_store) M.equip_to_slot_or_del(new /obj/item/weapon/bikehorn(M), slot_r_store) var/obj/item/weapon/card/id/W = new(M) @@ -710,7 +709,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that for(var/i=3, i>0, i--) sec_briefcase.contents += new /obj/item/weapon/spacecash/c1000 sec_briefcase.contents += new /obj/item/weapon/gun/energy/crossbow - sec_briefcase.contents += new /obj/item/weapon/gun/projectile/mateba + sec_briefcase.contents += new /obj/item/weapon/gun/projectile/revolver/mateba sec_briefcase.contents += new /obj/item/ammo_magazine/a357 sec_briefcase.contents += new /obj/item/weapon/plastique M.equip_to_slot_or_del(sec_briefcase, slot_l_hand) @@ -730,10 +729,10 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(W, slot_wear_id) if("death commando")//Was looking to add this for a while. - M.equip_death_commando() + deathsquad.equip(M) if("syndicate commando") - M.equip_syndicate_commando() + commandos.equip(M) if("nanotrasen representative") M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom(M), slot_w_uniform) @@ -834,7 +833,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves) M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear) M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses) - M.equip_to_slot_or_del(new /obj/item/clothing/mask/cigarette/cigar/havana(M), slot_wear_mask) + M.equip_to_slot_or_del(new /obj/item/clothing/mask/smokable/cigarette/cigar/havana(M), slot_wear_mask) M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad/beret(M), slot_head) M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/M1911(M), slot_belt) M.equip_to_slot_or_del(new /obj/item/weapon/flame/lighter/zippo(M), slot_r_store) @@ -892,7 +891,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/eyepatch(M), slot_glasses) M.equip_to_slot_or_del(new /obj/item/clothing/suit/hgpirate(M), slot_wear_suit) M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back) - M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/mateba(M), slot_belt) + M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(M), slot_belt) M.equip_to_slot_or_del(new /obj/item/clothing/under/soviet(M), slot_w_uniform) var/obj/item/weapon/card/id/W = new(M) W.name = "[M.real_name]'s ID Card" @@ -983,7 +982,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that if(!M.loc.loc) continue - if(istype(M.loc.loc,/area/engine/engine_room)) + if(istype(M.loc.loc,/area/engineering/engine_room)) if(istype(M,/obj/machinery/power/rad_collector)) var/obj/machinery/power/rad_collector/Rad = M Rad.anchored = 1 @@ -1022,7 +1021,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that SMES.input_level = 200000 SMES.output_level = 75000 - else if(istype(M.loc.loc,/area/engine/engine_smes)) //Set every SMES to charge and spit out 300,000 power between the 4 of them. + else if(istype(M.loc.loc,/area/engineering/engine_smes)) //Set every SMES to charge and spit out 300,000 power between the 4 of them. if(istype(M,/obj/machinery/power/smes)) var/obj/machinery/power/smes/SMES = M SMES.input_attempt = 1 diff --git a/code/modules/admin/verbs/icarus.dm b/code/modules/admin/verbs/icarus.dm new file mode 100644 index 0000000000..1f9b2dd4c4 --- /dev/null +++ b/code/modules/admin/verbs/icarus.dm @@ -0,0 +1,130 @@ +/client/proc/FireLaser() + set name = "Fire the Icarus lasers" + set desc = "Fires a laser bolt at your position. You should only do this as a(n) (a)ghost" + set category = "Fun" + + var/turf/target = get_turf(src.mob) + admin_log_and_message_admins("has fired the Icarus point defense laser at [target.x]-[target.y]-[target.z]") + if(!src.holder) + src << "Only administrators may use this command." + return + + Icarus_FireLaser(target) + + +/client/proc/FireCannons() + set name = "Fire the Icarus cannons" + set desc = "Fires an explosive missile at your position. You should only do this as a(n) (a)ghost." + set category = "Fun" + + var/turf/target = get_turf(src.mob) + admin_log_and_message_admins("has fired the Icarus main gun projectile at [target.x]-[target.y]-[target.z]") + if(!src.holder) + src << "Only administrators may use this command." + return + + Icarus_FireCannon(target) + + +/client/proc/ChangeIcarusPosition() + set name = "Adjust Icarus Position" + set desc = "Lets you chose the position of the Icarus in regards to the map." + set category = "Fun" + + admin_log_and_message_admins("is changing the Icarus position.") + if(!src.holder) + src << "Only administrators may use this command." + return + + Icarus_SetPosition(src) + +var/icarus_position = SOUTH + +proc/Icarus_FireLaser(var/turf/target) + // Find the world edge to fire from. + var/x = icarus_position & EAST ? world.maxx : icarus_position & WEST ? 1 : target.x + var/y = icarus_position & NORTH ? world.maxy : icarus_position & SOUTH ? 1 : target.y + var/x_off = x != target.x ? abs(target.x - x) : INFINITY + var/y_off = y != target.y ? abs(target.y - y) : INFINITY + // Get the minimum number of steps using the rise/run shit. + var/iterations = round(min(x_off, y_off)) - 14 // We cannot fire straight from the edge since teleport thing. + + // Now we can get the location of the start. + x = target.x + (icarus_position & EAST ? iterations : icarus_position & WEST ? -iterations : 0) + y = target.y + (icarus_position & NORTH ? iterations : icarus_position & SOUTH ? -iterations : 0) + + var/turf/start = locate(x, y, target.z) + + // should step down as: + // 1000, 500, 333, 250, 200, 167, 142, 125, 111, 100, 90 + var/damage = 1000 + for(var/i in 2 to 12) + var/obj/item/projectile/beam/in_chamber = new (start) + in_chamber.original = target + in_chamber.starting = start + in_chamber.silenced = 1 + in_chamber.yo = icarus_position & NORTH ? -1 : icarus_position & SOUTH ? 1 : 0 + in_chamber.xo = icarus_position & EAST ? -1 : icarus_position & WEST ? 1 : 0 + in_chamber.damage = damage + in_chamber.kill_count = 500 + in_chamber.process() + damage -= damage / i + sleep(-1) + + // Let everyone know what hit them. + var/obj/item/projectile/beam/in_chamber = new (start) + in_chamber.original = target + in_chamber.starting = start + in_chamber.silenced = 0 + in_chamber.yo = icarus_position & NORTH ? -1 : icarus_position & SOUTH ? 1 : 0 + in_chamber.xo = icarus_position & EAST ? -1 : icarus_position & WEST ? 1 : 0 + in_chamber.kill_count = 500 + in_chamber.damage = 0 + in_chamber.name = "point defense laser" + in_chamber.firer = "Icarus" // Never displayed, but we want this to display the hit message. + in_chamber.process() + +proc/Icarus_FireCannon(var/turf/target) + // Find the world edge to fire from. + var/x = icarus_position & EAST ? world.maxx : icarus_position & WEST ? 1 : target.x + var/y = icarus_position & NORTH ? world.maxy : icarus_position & SOUTH ? 1 : target.y + var/x_off = x != target.x ? abs(target.x - x) : INFINITY + var/y_off = y != target.y ? abs(target.y - y) : INFINITY + // Get the minimum number of steps using the rise/run shit. + var/iterations = round(min(x_off, y_off)) - 14 // We cannot fire straight from the edge since teleport thing. + + // Now we can get the location of the start. + x = target.x + (icarus_position & EAST ? iterations : icarus_position & WEST ? -iterations : 0) + y = target.y + (icarus_position & NORTH ? iterations : icarus_position & SOUTH ? -iterations : 0) + + var/turf/start = locate(x, y, target.z) + + // Now we find the corresponding turf on the other side of the level. + // Yeah, yeah. Overuse of the terinary operator. So sue me. + x = icarus_position & EAST ? 1 : icarus_position & WEST ? world.maxx : target.x + y = icarus_position & NORTH ? 1 : icarus_position & SOUTH ? world.maxy : target.y + x_off = x != target.x ? abs(target.x - x) : INFINITY + y_off = y != target.y ? abs(target.y - y) : INFINITY + iterations = round(min(x_off, y_off)) + x = target.x + (icarus_position & EAST ? -iterations : icarus_position & WEST ? iterations : 0) + y = target.y + (icarus_position & NORTH ? -iterations : icarus_position & SOUTH ? iterations : 0) + target = locate(x, y, target.z) + + // Finally fire the fucker. + var/obj/effect/meteor/small/projectile = new (start) + projectile.dest = target + projectile.name = "main gun projectile" // stealthy + projectile.hits = 6 + projectile.detonation_chance = 99 // it's a missile/cannon round thing! + + // Make sure it travels + spawn(0) + walk_towards(projectile, projectile.dest, 1) + +proc/Icarus_SetPosition(var/user) + var/global/list/directions = list("North" = 1, "North East" = 5, "East" = 4, "South East" = 6, "South" = 2, "South West" = 10, "West" = 8, "North West" = 9) + var/direction = input(user, "Where should the Icarus fire from?", "Icarus Comms") as null|anything in directions + if(!direction) + return + + icarus_position = directions[direction] diff --git a/code/modules/admin/verbs/massmodvar.dm b/code/modules/admin/verbs/massmodvar.dm index a35fb15174..a6b4bf7d16 100644 --- a/code/modules/admin/verbs/massmodvar.dm +++ b/code/modules/admin/verbs/massmodvar.dm @@ -168,7 +168,7 @@ return .(O.vars[variable]) if("text") - var/new_value = input("Enter new text:","Text",O.vars[variable]) as text|null + var/new_value = input("Enter new text:","Text",O.vars[variable]) as text|null//todo: sanitize ??? if(new_value == null) return O.vars[variable] = new_value diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 8c48af6a45..fce2aa59dc 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -44,7 +44,7 @@ var/list/forbidden_varedit_object_types = list( switch(class) if("text") - var_value = input("Enter new text:","Text") as null|text + var_value = input("Enter new text:","Text") as null|text//todo: sanitize ??? if("num") var_value = input("Enter new number:","Num") as null|num @@ -93,7 +93,7 @@ var/list/forbidden_varedit_object_types = list( switch(class) if("text") - var_value = input("Enter new text:","Text") as text + var_value = input("Enter new text:","Text") as text//todo: sanitize ??? if("num") var_value = input("Enter new number:","Num") as num @@ -243,7 +243,7 @@ var/list/forbidden_varedit_object_types = list( return if("text") - L[L.Find(variable)] = input("Enter new text:","Text") as text + L[L.Find(variable)] = input("Enter new text:","Text") as text//todo: sanitize ??? if("num") L[L.Find(variable)] = input("Enter new number:","Num") as num @@ -450,7 +450,7 @@ var/list/forbidden_varedit_object_types = list( return .(O.vars[variable]) if("text") - var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|text + var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|text//todo: sanitize ??? if(var_new==null) return O.vars[variable] = var_new diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm deleted file mode 100644 index 2513857f5f..0000000000 --- a/code/modules/admin/verbs/one_click_antag.dm +++ /dev/null @@ -1,528 +0,0 @@ -client/proc/one_click_antag() - set name = "Create Antagonist" - set desc = "Auto-create an antagonist of your choice" - set category = "Admin" - - if(holder) - holder.one_click_antag() - return - - -/datum/admins/proc/one_click_antag() - - var/dat = {"One-click Antagonist
    - Make Traitors
    - Make Changlings
    - Make Revs
    - Make Cult
    - Make Malf AI
    - Make Wizard (Requires Ghosts)
    - Make Vox Raiders (Requires Ghosts)
    - "} -/* These dont work just yet - Ninja, aliens and deathsquad I have not looked into yet - Nuke team is getting a null mob returned from makebody() (runtime error: null.mind. Line 272) - - Make Nuke Team (Requires Ghosts)
    - Make Space Ninja (Requires Ghosts)
    - Make Aliens (Requires Ghosts)
    - Make Deathsquad (Syndicate) (Requires Ghosts)
    - "} -*/ - usr << browse(dat, "window=oneclickantag;size=400x400") - return - - -/datum/admins/proc/makeMalfAImode() - - var/list/mob/living/silicon/AIs = list() - var/mob/living/silicon/malfAI = null - var/datum/mind/themind = null - - for(var/mob/living/silicon/ai/ai in player_list) - if(ai.client) - AIs += ai - - if(AIs.len) - malfAI = pick(AIs) - - if(malfAI) - themind = malfAI.mind - themind.make_AI_Malf() - return 1 - - return 0 - - -/datum/admins/proc/makeTraitors() - var/datum/game_mode/traitor/temp = new - - if(config.protect_roles_from_antagonist) - temp.restricted_jobs += temp.protected_jobs - - var/list/mob/living/carbon/human/candidates = list() - var/mob/living/carbon/human/H = null - - for(var/mob/living/carbon/human/applicant in player_list) - if(applicant.client.prefs.be_special & BE_TRAITOR) - if(!applicant.stat) - if(applicant.mind) - if (!applicant.mind.special_role) - if(!jobban_isbanned(applicant, "traitor") && !jobban_isbanned(applicant, "Syndicate")) - if(!(applicant.job in temp.restricted_jobs)) - candidates += applicant - - if(candidates.len) - var/numTraitors = min(candidates.len, 3) - - for(var/i = 0, i300)//If more than 30 game seconds passed. - return - candidates += G - if("No") - return - else - return - - sleep(300) - - if(candidates.len) - shuffle(candidates) - for(var/mob/i in candidates) - if(!i || !i.client) continue //Dont bother removing them from the list since we only grab one wizard - - theghost = i - break - - if(theghost) - var/mob/living/carbon/human/new_character=makeBody(theghost) - new_character.mind.make_Wizard() - return 1 - - return 0 - - -/datum/admins/proc/makeCult() - - var/datum/game_mode/cult/temp = new - if(config.protect_roles_from_antagonist) - temp.restricted_jobs += temp.protected_jobs - - var/list/mob/living/carbon/human/candidates = list() - var/mob/living/carbon/human/H = null - - for(var/mob/living/carbon/human/applicant in player_list) - if(applicant.client.prefs.be_special & BE_CULTIST) - if(applicant.stat == CONSCIOUS) - if(applicant.mind) - if(!applicant.mind.special_role) - if(!jobban_isbanned(applicant, "cultist") && !jobban_isbanned(applicant, "Syndicate")) - if(!(applicant.job in temp.restricted_jobs)) - candidates += applicant - - if(candidates.len) - var/numCultists = min(candidates.len, 4) - - for(var/i = 0, i300)//If more than 30 game seconds passed. - return - candidates += G - if("No") - return - else - return - - sleep(300) - - if(candidates.len) - var/numagents = 5 - var/agentcount = 0 - - for(var/i = 0, i300)//If more than 30 game seconds passed. - return - candidates += G - if("No") - return - else - return - sleep(300) - - for(var/mob/dead/observer/G in candidates) - if(!G.key) - candidates.Remove(G) - - if(candidates.len) - var/numagents = 6 - //Spawns commandos and equips them. - for (var/obj/effect/landmark/L in /area/syndicate_mothership/elite_squad) - if(numagents<=0) - break - if (L.name == "Syndicate-Commando") - syndicate_leader_selected = numagents == 1?1:0 - - var/mob/living/carbon/human/new_syndicate_commando = create_syndicate_death_commando(L, syndicate_leader_selected) - - - while((!theghost || !theghost.client) && candidates.len) - theghost = pick(candidates) - candidates.Remove(theghost) - - if(!theghost) - del(new_syndicate_commando) - break - - new_syndicate_commando.key = theghost.key - new_syndicate_commando.internal = new_syndicate_commando.s_store - new_syndicate_commando.internals.icon_state = "internal1" - - //So they don't forget their code or mission. - - - new_syndicate_commando << "\blue You are an Elite Mercenary. [!syndicate_leader_selected?"commando":"LEADER"] in the service of criminal elements hostile to NanoTrasen. \nYour current mission is: \red [input]" - - numagents-- - if(numagents >= 6) - return 0 - - for (var/obj/effect/landmark/L in /area/shuttle/syndicate_elite) - if (L.name == "Syndicate-Commando-Bomb") - new /obj/effect/spawner/newbomb/timer/syndicate(L.loc) - - return 1 - - -/datum/admins/proc/makeBody(var/mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character - if(!G_found || !G_found.key) return - - //First we spawn a dude. - var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned. - - new_character.gender = pick(MALE,FEMALE) - - var/datum/preferences/A = new() - A.randomize_appearance_for(new_character) - if(new_character.gender == MALE) - new_character.real_name = "[pick(first_names_male)] [pick(last_names)]" - else - new_character.real_name = "[pick(first_names_female)] [pick(last_names)]" - new_character.name = new_character.real_name - new_character.age = rand(17,45) - - new_character.dna.ready_dna(new_character) - new_character.key = G_found.key - - return new_character - -/datum/admins/proc/create_syndicate_death_commando(obj/spawn_location, syndicate_leader_selected = 0) - var/mob/living/carbon/human/new_syndicate_commando = new(spawn_location.loc) - var/syndicate_commando_leader_rank = pick("Lieutenant", "Captain", "Major") - var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major") - var/syndicate_commando_name = pick(last_names) - - new_syndicate_commando.gender = pick(MALE, FEMALE) - - var/datum/preferences/A = new()//Randomize appearance for the commando. - A.randomize_appearance_for(new_syndicate_commando) - - new_syndicate_commando.real_name = "[!syndicate_leader_selected ? syndicate_commando_rank : syndicate_commando_leader_rank] [syndicate_commando_name]" - new_syndicate_commando.name = new_syndicate_commando.real_name - new_syndicate_commando.age = !syndicate_leader_selected ? rand(23,35) : rand(35,45) - - new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA. - - //Creates mind stuff. - new_syndicate_commando.mind_initialize() - new_syndicate_commando.mind.assigned_role = "MODE" - new_syndicate_commando.mind.special_role = "Mercenary" - - //Adds them to current traitor list. Which is really the extra antagonist list. - ticker.mode.traitors += new_syndicate_commando.mind - new_syndicate_commando.equip_syndicate_commando(syndicate_leader_selected) - - return new_syndicate_commando - -/datum/admins/proc/makeVoxRaiders() - - var/list/mob/dead/observer/candidates = list() - var/mob/dead/observer/theghost = null - var/time_passed = world.time - var/input = "Disregard shinies, acquire hardware." - - var/leader_chosen = 0 //when the leader is chosen. The last person spawned. - - //Generates a list of candidates from active ghosts. - for(var/mob/dead/observer/G in player_list) - spawn(0) - switch(alert(G,"Do you wish to be considered for a vox raiding party arriving on the station?","Please answer in 30 seconds!","Yes","No")) - if("Yes") - if((world.time-time_passed)>300)//If more than 30 game seconds passed. - return - candidates += G - if("No") - return - else - return - - sleep(300) //Debug. - - for(var/mob/dead/observer/G in candidates) - if(!G.key) - candidates.Remove(G) - - if(candidates.len) - var/max_raiders = 1 - var/raiders = max_raiders - //Spawns vox raiders and equips them. - for (var/obj/effect/landmark/L in world) - if(L.name == "voxstart") - if(raiders<=0) - break - - var/mob/living/carbon/human/new_vox = create_vox_raider(L, leader_chosen) - - while((!theghost || !theghost.client) && candidates.len) - theghost = pick(candidates) - candidates.Remove(theghost) - - if(!theghost) - del(new_vox) - break - - new_vox.key = theghost.key - new_vox << "\blue You are a Vox Primalis, fresh out of the Shoal. Your ship has arrived at a human-meat system hosting the NSV Exodus... or was it the Luna? NSS? Utopia? Nobody is really sure, who cares about stupid meat-names anyway? Everyone is raring to start pillaging! Your current goal is: \red [input]" - new_vox << "\red Don't forget to turn on your nitrogen internals!" - - raiders-- - if(raiders > max_raiders) - return 0 - else - return 0 - return 1 - -/datum/admins/proc/create_vox_raider(obj/spawn_location, leader_chosen = 0) - - var/mob/living/carbon/human/new_vox = new(spawn_location.loc, "Vox") - - new_vox.gender = pick(MALE, FEMALE) - new_vox.h_style = "Short Vox Quills" - new_vox.regenerate_icons() - - var/sounds = rand(2,10) - var/i = 0 - var/newname = "" - - while(i<=sounds) - i++ - newname += pick(list("ti","hi","ki","ya","ta","ha","ka","ya","chi","cha","kah")) - - new_vox.real_name = capitalize(newname) - new_vox.name = new_vox.real_name - new_vox.age = rand(12,20) - - new_vox.dna.ready_dna(new_vox) // Creates DNA. - new_vox.mind_initialize() - new_vox.mind.assigned_role = "MODE" - new_vox.mind.special_role = "Vox Raider" - new_vox.mutations |= NOCLONE //Stops the station crew from messing around with their DNA. - - if(ticker.mode && ( istype( ticker.mode,/datum/game_mode/heist ) ) ) - var/datum/game_mode/heist/M = ticker.mode - if(new_vox.internal_organs_by_name["stack"]) - cortical_stacks |= new_vox.internal_organs_by_name["stack"] - M.raiders[new_vox.mind] = new_vox.internal_organs_by_name["stack"] - - ticker.mode.traitors += new_vox.mind - new_vox.equip_vox_raider() - - return new_vox \ No newline at end of file diff --git a/code/modules/admin/verbs/onlyone.dm b/code/modules/admin/verbs/onlyone.dm deleted file mode 100644 index aa99b4bd46..0000000000 --- a/code/modules/admin/verbs/onlyone.dm +++ /dev/null @@ -1,47 +0,0 @@ -/client/proc/only_one() - if(!ticker) - alert("The game hasn't started yet!") - return - - for(var/mob/living/carbon/human/H in player_list) - if(H.stat == 2 || !(H.client)) continue - if(is_special_character(H)) continue - - ticker.mode.traitors += H.mind - H.mind.special_role = "traitor" - - var/datum/objective/steal/steal_objective = new - steal_objective.owner = H.mind - steal_objective.set_target("nuclear authentication disk") - H.mind.objectives += steal_objective - - var/datum/objective/hijack/hijack_objective = new - hijack_objective.owner = H.mind - H.mind.objectives += hijack_objective - - H << "You are the traitor." - show_objectives(H.mind) - - for (var/obj/item/I in H) - if (istype(I, /obj/item/weapon/implant)) - continue - del(I) - - H.equip_to_slot_or_del(new /obj/item/clothing/under/kilt(H), slot_w_uniform) - H.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(H), slot_l_ear) - H.equip_to_slot_or_del(new /obj/item/clothing/head/beret(H), slot_head) - H.equip_to_slot_or_del(new /obj/item/weapon/claymore(H), slot_l_hand) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), slot_shoes) - H.equip_to_slot_or_del(new /obj/item/weapon/pinpointer(H.loc), slot_l_store) - - var/obj/item/weapon/card/id/W = new(H) - W.name = "[H.real_name]'s ID Card" - W.icon_state = "centcom" - W.access = get_all_accesses() - W.access += get_all_centcom_access() - W.assignment = "Highlander" - W.registered_name = H.real_name - H.equip_to_slot_or_del(W, slot_wear_id) - - message_admins("\blue [key_name_admin(usr)] used THERE CAN BE ONLY ONE!", 1) - log_admin("[key_name(usr)] used there can be only one.") \ No newline at end of file diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index 6ff66c4647..3a4b40d985 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -1,3 +1,5 @@ +var/list/sounds_cache = list() + /client/proc/play_sound(S as sound) set category = "Fun" set name = "Play Global Sound" @@ -6,6 +8,11 @@ var/sound/uploaded_sound = sound(S, repeat = 0, wait = 1, channel = 777) uploaded_sound.priority = 250 + sounds_cache += S + + if(alert("Do you ready?\nSong: [S]\nNow you can also play this sound using \"Play Server Sound\".", "Confirmation request" ,"Play", "Cancel") == "Cancel") + return + log_admin("[key_name(src)] played sound [S]") message_admins("[key_name_admin(src)] played sound [S]", 1) for(var/mob/M in player_list) @@ -14,7 +21,6 @@ feedback_add_details("admin_verb","PGS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - /client/proc/play_local_sound(S as sound) set category = "Fun" set name = "Play Local Sound" @@ -26,6 +32,22 @@ feedback_add_details("admin_verb","PLS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/proc/play_server_sound() + set category = "Fun" + set name = "Play Server Sound" + if(!check_rights(R_SOUNDS)) return + + var/list/sounds = file2list("sound/serversound_list.txt"); + sounds += "--CANCEL--" + sounds += sounds_cache + + var/melody = input("Select a sound from the server to play", "Server sound list", "--CANCEL--") in sounds + + if(melody == "--CANCEL--") return + + play_sound(melody) + feedback_add_details("admin_verb","PSS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + /* /client/proc/cuban_pete() set category = "Fun" diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 6e79bbbc3f..8b2d070003 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -6,7 +6,7 @@ usr << "\red Speech is currently admin-disabled." return - msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN)) + msg = sanitize(msg) if(!msg) return if(usr.client) @@ -29,14 +29,14 @@ //log_admin("HELP: [key_name(src)]: [msg]") /proc/Centcomm_announce(var/text , var/mob/Sender , var/iamessage) - var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN)) + var/msg = sanitize(text) msg = "\blue CENTCOMM[iamessage ? " IA" : ""]:[key_name(Sender, 1)] (PP) (VV) (SM) (JMP) (CA) (BSA) (RPLY): [msg]" for(var/client/C in admins) if(R_ADMIN & C.holder.rights) C << msg /proc/Syndicate_announce(var/text , var/mob/Sender) - var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN)) + var/msg = sanitize(text) msg = "\blue ILLEGAL:[key_name(Sender, 1)] (PP) (VV) (SM) (JMP) (CA) (BSA) (RPLY): [msg]" for(var/client/C in admins) if(R_ADMIN & C.holder.rights) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 8e0b6b6a65..64e44e17e9 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -52,7 +52,7 @@ src << "Only administrators may use this command." return - var/msg = input("Message:", text("Subtle PM to [M.key]")) as text + var/msg = sanitize(input("Message:", text("Subtle PM to [M.key]")) as text) if (!msg) return @@ -109,7 +109,7 @@ src << "Only administrators may use this command." return - var/msg = input("Message:", text("Enter the text you wish to appear to everyone:")) as text + var/msg = sanitize(input("Message:", text("Enter the text you wish to appear to everyone:")) as text) if (!msg) return @@ -132,7 +132,7 @@ if(!M) return - var/msg = input("Message:", text("Enter the text you wish to appear to your target:")) as text + var/msg = sanitize(input("Message:", text("Enter the text you wish to appear to your target:")) as text) if( !msg ) return @@ -368,19 +368,6 @@ Traitors and the like can also be revived with the previous role mostly intact. usr << "There is no active key like that in the game or the person is not currently a ghost." return - if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something - - //check if they were a monkey - if(findtext(G_found.real_name,"monkey")) - if(alert("This character appears to have been a monkey. Would you like to respawn them as such?",,"Yes","No")=="Yes") - var/mob/living/carbon/monkey/new_monkey = new(pick(latejoin)) - G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use - new_monkey.key = G_found.key - new_monkey << "You have been fully respawned. Enjoy the game." - message_admins("\blue [key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno.", 1) - return //all done. The ghost is auto-deleted - - //Ok, it's not a monkey. So, spawn a human. var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned. var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character. @@ -445,50 +432,12 @@ Traitors and the like can also be revived with the previous role mostly intact. var/player_key = G_found.key //Now for special roles and equipment. - switch(new_character.mind.special_role) - if("traitor") - job_master.EquipRank(new_character, new_character.mind.assigned_role, 1) - ticker.mode.equip_traitor(new_character) - if("Wizard") - new_character.loc = pick(wizardstart) - //ticker.mode.learn_basic_spells(new_character) - ticker.mode.equip_wizard(new_character) - if("Mercenary") - var/obj/effect/landmark/synd_spawn = locate("landmark*Syndicate-Spawn") - if(synd_spawn) - new_character.loc = get_turf(synd_spawn) - call(/datum/game_mode/proc/equip_syndicate)(new_character) - if("Ninja") - new_character.equip_space_ninja() - if(ninjastart.len == 0) - new_character << "\red A proper starting location for you could not be found, please report this bug!" - new_character << "\red Attempting to place at a carpspawn." - for(var/obj/effect/landmark/L in landmarks_list) - if(L.name == "carpspawn") - ninjastart.Add(L) - if(ninjastart.len == 0 && latejoin.len > 0) - new_character << "\red Still no spawneable locations could be found. Defaulting to latejoin." - new_character.loc = pick(latejoin) - else if (ninjastart.len == 0) - new_character << "\red Still no spawneable locations could be found. Aborting." - - if("Death Commando")//Leaves them at late-join spawn. - new_character.equip_death_commando() - new_character.internal = new_character.s_store - new_character.internals.icon_state = "internal1" - else//They may also be a cyborg or AI. - switch(new_character.mind.assigned_role) - if("Cyborg")//More rigging to make em' work and check if they're traitor. - new_character = new_character.Robotize() - if(new_character.mind.special_role=="traitor") - call(/datum/game_mode/proc/add_law_zero)(new_character) - if("AI") - new_character = new_character.AIize() - if(new_character.mind.special_role=="traitor") - call(/datum/game_mode/proc/add_law_zero)(new_character) - //Add aliens. - else - job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them. + var/datum/antagonist/antag_data = get_antag_data(new_character.mind.special_role) + if(antag_data) + antag_data.add_antagonist(new_character.mind) + antag_data.place_mob(new_character) + else + job_master.EquipRank(new_character, new_character.mind.assigned_role, 1) //Announces the character on all the systems, based on the record. if(!issilicon(new_character))//If they are not a cyborg/AI. @@ -513,7 +462,7 @@ Traitors and the like can also be revived with the previous role mostly intact. if(!holder) src << "Only administrators may use this command." return - var/input = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "") as text|null + var/input = sanitize(input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "") as text|null) if(!input) return for(var/mob/living/silicon/ai/M in mob_list) @@ -561,8 +510,8 @@ Traitors and the like can also be revived with the previous role mostly intact. if(!holder) src << "Only administrators may use this command." return - var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null - var/customname = input(usr, "Pick a title for the report.", "Title") as text|null + var/input = sanitize(input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null, extra = 0) + var/customname = sanitizeSafe(input(usr, "Pick a title for the report.", "Title") as text|null) if(!input) return if(!customname) diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm index 36199c0305..c49e09d554 100644 --- a/code/modules/admin/verbs/striketeam.dm +++ b/code/modules/admin/verbs/striketeam.dm @@ -1,174 +1,55 @@ //STRIKE TEAMS - var/const/commandos_possible = 6 //if more Commandos are needed in the future -var/global/sent_strike_team = 0 /client/proc/strike_team() + set category = "Fun" + set name = "Spawn Strike Team" + set desc = "Spawns a death squad if you want to run an admin event." + + if(!src.holder) + src << "Only administrators may use this command." + return + if(!ticker) usr << "The game hasn't started yet!" return + if(world.time < 6000) usr << "There are [(6000-world.time)/10] seconds remaining before it may be called." return - if(sent_strike_team == 1) - usr << "CentCom is already sending a team." + + var/datum/antagonist/deathsquad/team + + var/choice = input(usr, "Select type of strike team:") as null|anything in list("Death Squad", "Mercenaries") + if(!choice) return - if(alert("Do you want to send in the CentCom death squad? Once enabled, this is irreversible.",,"Yes","No")!="Yes") + + switch(choice) + if("Death Squad") + team = deathsquad + if("Mercenaries") + team = commandos + else + return + + if(team.deployed) + usr << "Someone is already sending a team." return + + if(alert("Do you want to send in a strike team? Once enabled, this is irreversible.",,"Yes","No")!="Yes") + return + alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned commandos have internals cameras which are viewable through a monitor inside the Spec. Ops. Office. Assigning the team's detailed task is recommended from there. While you will be able to manually pick the candidates from active ghosts, their assignment in the squad will be random.") - var/input = null - while(!input) - input = sanitize(copytext(input(src, "Please specify which mission the death commando squad shall undertake.", "Specify Mission", ""),1,MAX_MESSAGE_LEN)) - if(!input) + choice = null + while(!choice) + choice = sanitize(input(src, "Please specify which mission the strike team shall undertake.", "Specify Mission", "")) + if(!choice) if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes") return - if(sent_strike_team) + if(team.deployed) usr << "Looks like someone beat you to it." return - sent_strike_team = 1 - - if (emergency_shuttle.can_recall()) - emergency_shuttle.recall() - - var/commando_number = commandos_possible //for selecting a leader - var/leader_selected = 0 //when the leader is chosen. The last person spawned. - -//Code for spawning a nuke auth code. - var/nuke_code - var/temp_code - for(var/obj/machinery/nuclearbomb/N in world) - temp_code = text2num(N.r_code) - if(temp_code)//if it's actually a number. It won't convert any non-numericals. - nuke_code = N.r_code - break - -//Generates a list of commandos from active ghosts. Then the user picks which characters to respawn as the commandos. - var/list/candidates = list() //candidates for being a commando out of all the active ghosts in world. - var/list/commandos = list() //actual commando ghosts as picked by the user. - for(var/mob/dead/observer/G in player_list) - if(!G.client.holder && !G.client.is_afk()) //Whoever called/has the proc won't be added to the list. - if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) - candidates += G.key - for(var/i=commandos_possible,(i>0&&candidates.len),i--)//Decrease with every commando selected. - var/candidate = input("Pick characters to spawn as the commandos. This will go on until there either no more ghosts to pick from or the slots are full.", "Active Players") as null|anything in candidates //It will auto-pick a person when there is only one candidate. - candidates -= candidate //Subtract from candidates. - commandos += candidate//Add their ghost to commandos. - -//Spawns commandos and equips them. - for(var/obj/effect/landmark/L in landmarks_list) - if(commando_number<=0) break - if (L.name == "Commando") - leader_selected = commando_number == 1?1:0 - - var/mob/living/carbon/human/new_commando = create_death_commando(L, leader_selected) - - if(commandos.len) - new_commando.key = pick(commandos) - commandos -= new_commando.key - new_commando.internal = new_commando.s_store - new_commando.internals.icon_state = "internal1" - - //So they don't forget their code or mission. - if(nuke_code) - new_commando.mind.store_memory("Nuke Code: \red [nuke_code].") - new_commando.mind.store_memory("Mission: \red [input].") - - new_commando << "\blue You are a Special Ops. [!leader_selected?"commando":"LEADER"] in the service of Central Command. Check the table ahead for detailed instructions.\nYour current mission is: \red[input]" - - commando_number-- - -//Spawns the rest of the commando gear. - for (var/obj/effect/landmark/L in landmarks_list) - if (L.name == "Commando_Manual") - //new /obj/item/weapon/gun/energy/pulse_rifle(L.loc) - var/obj/item/weapon/paper/P = new(L.loc) - P.info = "

    Good morning soldier!. This compact guide will familiarize you with standard operating procedure. There are three basic rules to follow:
    #1 Work as a team.
    #2 Accomplish your objective at all costs.
    #3 Leave no witnesses.
    You are fully equipped and stocked for your mission--before departing on the Spec. Ops. Shuttle due South, make sure that all operatives are ready. Actual mission objective will be relayed to you by Central Command through your headsets.
    If deemed appropriate, Central Command will also allow members of your team to equip assault power-armor for the mission. You will find the armor storage due West of your position. Once you are ready to leave, utilize the Special Operations shuttle console and toggle the hull doors via the other console.

    In the event that the team does not accomplish their assigned objective in a timely manner, or finds no other way to do so, attached below are instructions on how to operate a Nanotrasen Nuclear Device. Your operations LEADER is provided with a nuclear authentication disk and a pin-pointer for this reason. You may easily recognize them by their rank: Lieutenant, Captain, or Major. The nuclear device itself will be present somewhere on your destination.

    Hello and thank you for choosing Nanotrasen for your nuclear information needs. Today's crash course will deal with the operation of a Fission Class Nanotrasen made Nuclear Device.
    First and foremost, DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE. Pressing any button on the compacted bomb will cause it to extend and bolt itself into place. If this is done to unbolt it one must completely log in which at this time may not be possible.
    To make the device functional:
    #1 Place bomb in designated detonation zone
    #2 Extend and anchor bomb (attack with hand).
    #3 Insert Nuclear Auth. Disk into slot.
    #4 Type numeric code into keypad ([nuke_code]).
    Note: If you make a mistake press R to reset the device.
    #5 Press the E button to log onto the device.
    You now have activated the device. To deactivate the buttons at anytime, for example when you have already prepped the bomb for detonation, remove the authentication disk OR press the R on the keypad. Now the bomb CAN ONLY be detonated using the timer. A manual detonation is not an option.
    Note: Toggle off the SAFETY.
    Use the - - and + + to set a detonation time between 5 seconds and 10 minutes. Then press the timer toggle button to start the countdown. Now remove the authentication disk so that the buttons deactivate.
    Note: THE BOMB IS STILL SET AND WILL DETONATE
    Now before you remove the disk if you need to move the bomb you can: Toggle off the anchor, move it, and re-anchor.

    The nuclear authorization code is: [nuke_code ? nuke_code : "None provided"]

    Good luck, soldier!

    " - P.name = "Spec. Ops. Manual" - - for (var/obj/effect/landmark/L in landmarks_list) - if (L.name == "Commando-Bomb") - new /obj/effect/spawner/newbomb/timer/syndicate(L.loc) - del(L) - - message_admins("\blue [key_name_admin(usr)] has spawned a CentCom strike squad.", 1) - log_admin("[key_name(usr)] used Spawn Death Squad.") - return 1 - -/client/proc/create_death_commando(obj/spawn_location, leader_selected = 0) - var/mob/living/carbon/human/new_commando = new(spawn_location.loc) - var/commando_leader_rank = pick("Lieutenant", "Captain", "Major") - var/commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major") - var/commando_name = pick(last_names) - - new_commando.gender = pick(MALE, FEMALE) - - var/datum/preferences/A = new()//Randomize appearance for the commando. - A.randomize_appearance_for(new_commando) - - new_commando.real_name = "[!leader_selected ? commando_rank : commando_leader_rank] [commando_name]" - new_commando.age = !leader_selected ? rand(23,35) : rand(35,45) - - new_commando.dna.ready_dna(new_commando)//Creates DNA. - - //Creates mind stuff. - new_commando.mind_initialize() - new_commando.mind.assigned_role = "MODE" - new_commando.mind.special_role = "Death Commando" - ticker.mode.traitors |= new_commando.mind//Adds them to current traitor list. Which is really the extra antagonist list. - new_commando.equip_death_commando(leader_selected) - return new_commando - -/mob/living/carbon/human/proc/equip_death_commando(leader_selected = 0) - - var/obj/item/device/radio/R = new /obj/item/device/radio/headset(src) - R.set_frequency(DTH_FREQ) - equip_to_slot_or_del(R, slot_l_ear) - if (leader_selected == 0) - equip_to_slot_or_del(new /obj/item/clothing/under/color/green(src), slot_w_uniform) - else - equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(src), slot_w_uniform) - equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes) - equip_to_slot_or_del(new /obj/item/clothing/suit/armor/swat(src), slot_wear_suit) - equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves) - equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad(src), slot_head) - equip_to_slot_or_del(new /obj/item/clothing/mask/gas/swat(src), slot_wear_mask) - equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses) - - equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(src), slot_back) - equip_to_slot_or_del(new /obj/item/weapon/storage/box(src), slot_in_backpack) - - equip_to_slot_or_del(new /obj/item/ammo_magazine/a357(src), slot_in_backpack) - equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(src), slot_in_backpack) - equip_to_slot_or_del(new /obj/item/weapon/storage/box/flashbangs(src), slot_in_backpack) - equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_in_backpack) - if (!leader_selected) - equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_in_backpack) - else - equip_to_slot_or_del(new /obj/item/weapon/pinpointer(src), slot_in_backpack) - equip_to_slot_or_del(new /obj/item/weapon/disk/nuclear(src), slot_in_backpack) - - equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(src), slot_l_store) - equip_to_slot_or_del(new /obj/item/weapon/grenade/flashbang(src), slot_r_store) - equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen(src), slot_s_store) - equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/mateba(src), slot_belt) - - equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(src), slot_r_hand) - - - implant_loyalty(src) - - - - var/obj/item/weapon/card/id/W = new(src) - W.name = "[real_name]'s ID Card" - W.icon_state = "centcom" - W.access = get_all_accesses()//They get full station access. - W.access += list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)//Let's add their alloted CentCom access. - W.assignment = "Death Commando" - W.registered_name = real_name - equip_to_slot_or_del(W, slot_wear_id) - - return 1 \ No newline at end of file + team.attempt_spawn(1) diff --git a/code/modules/admin/verbs/striketeam_syndicate.dm b/code/modules/admin/verbs/striketeam_syndicate.dm deleted file mode 100644 index 6a16f22d1f..0000000000 --- a/code/modules/admin/verbs/striketeam_syndicate.dm +++ /dev/null @@ -1,178 +0,0 @@ -//STRIKE TEAMS - -var/const/syndicate_commandos_possible = 6 //if more Commandos are needed in the future -var/global/sent_syndicate_strike_team = 0 -/client/proc/syndicate_strike_team() - set category = "Fun" - set name = "Spawn Mercenary Strike Team" - set desc = "Spawns a squad of commandos in the Syndicate Mothership if you want to run an admin event." - if(!src.holder) - src << "Only administrators may use this command." - return - if(!ticker) - alert("The game hasn't started yet!") - return -// if(world.time < 6000) -// alert("Not so fast, buddy. Wait a few minutes until the game gets going. There are [(6000-world.time)/10] seconds remaining.") -// return - if(sent_syndicate_strike_team == 1) - alert("Criminal elements are already sending a team, Mr. Dumbass.") - return - if(alert("Do you want to send in the Mercenary Strike Team? Once enabled, this is irreversible.",,"Yes","No")=="No") - return - alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned mercs have internals cameras which are viewable through a monitor inside the Syndicate Mothership Bridge. Assigning the team's detailed task is recommended from there. While you will be able to manually pick the candidates from active ghosts, their assignment in the squad will be random.") - - var/input = null - while(!input) - input = sanitize(copytext(input(src, "Please specify which mission the strike team shall undertake.", "Specify Mission", ""),1,MAX_MESSAGE_LEN)) - if(!input) - if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes") - return - - if(sent_syndicate_strike_team) - src << "Looks like someone beat you to it." - return - - sent_syndicate_strike_team = 1 - - //if (emergency_shuttle.can_recall()) - // emergency_shuttle.recall() //why, exactly? Admins can do this themselves. - - var/syndicate_commando_number = syndicate_commandos_possible //for selecting a leader - var/syndicate_leader_selected = 0 //when the leader is chosen. The last person spawned. - -//Code for spawning a nuke auth code. - var/nuke_code - var/temp_code - for(var/obj/machinery/nuclearbomb/N in world) - temp_code = text2num(N.r_code) - if(temp_code)//if it's actually a number. It won't convert any non-numericals. - nuke_code = N.r_code - break - -//Generates a list of commandos from active ghosts. Then the user picks which characters to respawn as the commandos. - var/list/candidates = list() //candidates for being a commando out of all the active ghosts in world. - var/list/commandos = list() //actual commando ghosts as picked by the user. - for(var/mob/dead/observer/G in player_list) - if(!G.client.holder && !G.client.is_afk()) //Whoever called/has the proc won't be added to the list. - if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) - candidates += G.key - for(var/i=commandos_possible,(i>0&&candidates.len),i--)//Decrease with every commando selected. - var/candidate = input("Pick characters to spawn as the commandos. This will go on until there either no more ghosts to pick from or the slots are full.", "Active Players") as null|anything in candidates //It will auto-pick a person when there is only one candidate. - candidates -= candidate //Subtract from candidates. - commandos += candidate//Add their ghost to commandos. - -//Spawns commandos and equips them. - for(var/obj/effect/landmark/L in landmarks_list) - if(syndicate_commando_number<=0) break - if (L.name == "Syndicate-Commando") - syndicate_leader_selected = syndicate_commando_number == 1?1:0 - - var/mob/living/carbon/human/new_syndicate_commando = create_syndicate_death_commando(L, syndicate_leader_selected) - - if(commandos.len) - new_syndicate_commando.key = pick(commandos) - commandos -= new_syndicate_commando.key - new_syndicate_commando.internal = new_syndicate_commando.s_store - new_syndicate_commando.internals.icon_state = "internal1" - - //So they don't forget their code or mission. - if(nuke_code) - new_syndicate_commando.mind.store_memory("Nuke Code: \red [nuke_code].") - new_syndicate_commando.mind.store_memory("Mission: \red [input].") - - new_syndicate_commando << "\blue You are an Elite Mercenary. [!syndicate_leader_selected?"commando":"LEADER"] in the service of criminal elements hostile to NanoTrasen. \nYour current mission is: \red[input]" - - syndicate_commando_number-- - -//Spawns the rest of the commando gear. -// for (var/obj/effect/landmark/L) - // if (L.name == "Commando_Manual") - //new /obj/item/weapon/gun/energy/pulse_rifle(L.loc) - // var/obj/item/weapon/paper/P = new(L.loc) - // P.info = "

    Good morning soldier!. This compact guide will familiarize you with standard operating procedure. There are three basic rules to follow:
    #1 Work as a team.
    #2 Accomplish your objective at all costs.
    #3 Leave no witnesses.
    You are fully equipped and stocked for your mission--before departing on the Spec. Ops. Shuttle due South, make sure that all operatives are ready. Actual mission objective will be relayed to you by Central Command through your headsets.
    If deemed appropriate, Central Command will also allow members of your team to equip assault power-armor for the mission. You will find the armor storage due West of your position. Once you are ready to leave, utilize the Special Operations shuttle console and toggle the hull doors via the other console.

    In the event that the team does not accomplish their assigned objective in a timely manner, or finds no other way to do so, attached below are instructions on how to operate a Nanotrasen Nuclear Device. Your operations LEADER is provided with a nuclear authentication disk and a pin-pointer for this reason. You may easily recognize them by their rank: Lieutenant, Captain, or Major. The nuclear device itself will be present somewhere on your destination.

    Hello and thank you for choosing Nanotrasen for your nuclear information needs. Today's crash course will deal with the operation of a Fission Class Nanotrasen made Nuclear Device.
    First and foremost, DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE. Pressing any button on the compacted bomb will cause it to extend and bolt itself into place. If this is done to unbolt it one must completely log in which at this time may not be possible.
    To make the device functional:
    #1 Place bomb in designated detonation zone
    #2 Extend and anchor bomb (attack with hand).
    #3 Insert Nuclear Auth. Disk into slot.
    #4 Type numeric code into keypad ([nuke_code]).
    Note: If you make a mistake press R to reset the device.
    #5 Press the E button to log onto the device.
    You now have activated the device. To deactivate the buttons at anytime, for example when you have already prepped the bomb for detonation, remove the authentication disk OR press the R on the keypad. Now the bomb CAN ONLY be detonated using the timer. A manual detonation is not an option.
    Note: Toggle off the SAFETY.
    Use the - - and + + to set a detonation time between 5 seconds and 10 minutes. Then press the timer toggle button to start the countdown. Now remove the authentication disk so that the buttons deactivate.
    Note: THE BOMB IS STILL SET AND WILL DETONATE
    Now before you remove the disk if you need to move the bomb you can: Toggle off the anchor, move it, and re-anchor.

    The nuclear authorization code is: [nuke_code ? nuke_code : "None provided"]

    Good luck, soldier!

    " - // P.name = "Spec. Ops. Manual" - - for (var/obj/effect/landmark/L in landmarks_list) - if (L.name == "Syndicate-Commando-Bomb") - new /obj/effect/spawner/newbomb/timer/syndicate(L.loc) - del(L) - - message_admins("\blue [key_name_admin(usr)] has spawned a mercenary strike squad.", 1) - log_admin("[key_name(usr)] used Spawn Mercenary Squad.") - feedback_add_details("admin_verb","SDTHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/create_syndicate_death_commando(obj/spawn_location, syndicate_leader_selected = 0) - var/mob/living/carbon/human/new_syndicate_commando = new(spawn_location.loc) - var/syndicate_commando_leader_rank = pick("Lieutenant", "Captain", "Major") - var/syndicate_commando_rank = pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant 1st Class", "Master Sergeant", "Sergeant Major") - var/syndicate_commando_name = pick(last_names) - - new_syndicate_commando.gender = pick(MALE, FEMALE) - - var/datum/preferences/A = new()//Randomize appearance for the commando. - A.randomize_appearance_for(new_syndicate_commando) - - new_syndicate_commando.real_name = "[!syndicate_leader_selected ? syndicate_commando_rank : syndicate_commando_leader_rank] [syndicate_commando_name]" - new_syndicate_commando.age = !syndicate_leader_selected ? rand(23,35) : rand(35,45) - - new_syndicate_commando.dna.ready_dna(new_syndicate_commando)//Creates DNA. - - //Creates mind stuff. - new_syndicate_commando.mind_initialize() - new_syndicate_commando.mind.assigned_role = "MODE" - new_syndicate_commando.mind.special_role = "Mercenary" - ticker.mode.traitors |= new_syndicate_commando.mind //Adds them to current traitor list. Which is really the extra antagonist list. - new_syndicate_commando.equip_syndicate_commando(syndicate_leader_selected) - del(spawn_location) - return new_syndicate_commando - -/mob/living/carbon/human/proc/equip_syndicate_commando(syndicate_leader_selected = 0) - - var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate(src) - R.set_frequency(SYND_FREQ) //Same frequency as the syndicate team in Nuke mode. - equip_to_slot_or_del(R, slot_l_ear) - equip_to_slot_or_del(new /obj/item/clothing/under/syndicate(src), slot_w_uniform) - equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes) - if (!syndicate_leader_selected) - equip_to_slot_or_del(new /obj/item/clothing/suit/space/syndicate/black(src), slot_wear_suit) - else - equip_to_slot_or_del(new /obj/item/clothing/suit/space/syndicate/black/red(src), slot_wear_suit) - equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(src), slot_gloves) - if (!syndicate_leader_selected) - equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/syndicate/black(src), slot_head) - else - equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/syndicate/black/red(src), slot_head) - equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate(src), slot_wear_mask) - equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal(src), slot_glasses) - - equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(src), slot_back) - equip_to_slot_or_del(new /obj/item/weapon/storage/box(src), slot_in_backpack) - - equip_to_slot_or_del(new /obj/item/ammo_magazine/c45(src), slot_in_backpack) - equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(src), slot_in_backpack) - equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_in_backpack) - equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_in_backpack) - if (!syndicate_leader_selected) - equip_to_slot_or_del(new /obj/item/weapon/plastique(src), slot_in_backpack) - else - equip_to_slot_or_del(new /obj/item/weapon/pinpointer(src), slot_in_backpack) - equip_to_slot_or_del(new /obj/item/weapon/disk/nuclear(src), slot_in_backpack) - - equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(src), slot_l_store) - equip_to_slot_or_del(new /obj/item/weapon/grenade/empgrenade(src), slot_r_store) - equip_to_slot_or_del(new /obj/item/weapon/tank/emergency_oxygen(src), slot_s_store) - equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/silenced(src), slot_belt) - - equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(src), slot_r_hand) //Will change to something different at a later time -- Superxpdude - - var/obj/item/weapon/card/id/syndicate/W = new(src) //Untrackable by AI - W.name = "[real_name]'s ID Card" - W.icon_state = "id" - W.access = get_all_accesses()//They get full station access because obviously the syndicate has HAAAX, and can make special IDs for their most elite members. - W.access += list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage, access_syndicate)//Let's add their forged CentCom access and syndicate access. - W.assignment = "Mercenary" - W.registered_name = real_name - equip_to_slot_or_del(W, slot_wear_id) - - return 1 \ No newline at end of file diff --git a/code/modules/admin/verbs/vox_raiders.dm b/code/modules/admin/verbs/vox_raiders.dm deleted file mode 100644 index 6676acec32..0000000000 --- a/code/modules/admin/verbs/vox_raiders.dm +++ /dev/null @@ -1,69 +0,0 @@ -var/global/vox_tick = 1 - -/mob/living/carbon/human/proc/equip_vox_raider() - - var/obj/item/device/radio/R = new /obj/item/device/radio/headset/syndicate(src) - R.set_frequency(SYND_FREQ) - equip_to_slot_or_del(R, slot_l_ear) - - equip_to_slot_or_del(new /obj/item/clothing/under/vox/vox_robes(src), slot_w_uniform) - equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots/vox(src), slot_shoes) // REPLACE THESE WITH CODED VOX ALTERNATIVES. - equip_to_slot_or_del(new /obj/item/clothing/gloves/yellow/vox(src), slot_gloves) // AS ABOVE. - - switch(vox_tick) - if(1) // Vox raider! - equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/carapace(src), slot_wear_suit) - equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/carapace(src), slot_head) - equip_to_slot_or_del(new /obj/item/weapon/melee/baton/loaded(src), slot_belt) - equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE. - equip_to_slot_or_del(new /obj/item/device/chameleon(src), slot_l_store) - - var/obj/item/weapon/gun/launcher/spikethrower/W = new(src) - equip_to_slot_or_del(W, slot_r_hand) - - - if(2) // Vox engineer! - equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/pressure(src), slot_wear_suit) - equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/pressure(src), slot_head) - equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(src), slot_belt) - equip_to_slot_or_del(new /obj/item/clothing/glasses/meson(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE. - equip_to_slot_or_del(new /obj/item/weapon/storage/box/emps(src), slot_r_hand) - equip_to_slot_or_del(new /obj/item/device/multitool(src), slot_l_hand) - - - if(3) // Vox saboteur! - equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/stealth(src), slot_wear_suit) - equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/stealth(src), slot_head) - equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(src), slot_belt) - equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE. - equip_to_slot_or_del(new /obj/item/weapon/card/emag(src), slot_l_store) - equip_to_slot_or_del(new /obj/item/weapon/gun/dartgun/vox/raider(src), slot_r_hand) - equip_to_slot_or_del(new /obj/item/device/multitool(src), slot_l_hand) - - if(4) // Vox medic! - equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/medic(src), slot_wear_suit) - equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/vox/medic(src), slot_head) - equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(src), slot_belt) // Who needs actual surgical tools? - equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/health(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE. - equip_to_slot_or_del(new /obj/item/weapon/circular_saw(src), slot_l_store) - equip_to_slot_or_del(new /obj/item/weapon/gun/dartgun/vox/medical, slot_r_hand) - - equip_to_slot_or_del(new /obj/item/clothing/mask/breath(src), slot_wear_mask) - equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(src), slot_back) - equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_r_store) - - var/obj/item/weapon/card/id/syndicate/C = new(src) - C.name = "[real_name]'s Legitimate Human ID Card" - C.icon_state = "id" - C.access = list(access_syndicate) - C.assignment = "Trader" - C.registered_name = real_name - C.registered_user = src - var/obj/item/weapon/storage/wallet/W = new(src) - W.handle_item_insertion(C) - spawn_money(rand(50,150)*10,W) - equip_to_slot_or_del(W, slot_wear_id) - vox_tick++ - if (vox_tick > 4) vox_tick = 1 - - return 1 diff --git a/code/modules/alarm/alarm.dm b/code/modules/alarm/alarm.dm new file mode 100644 index 0000000000..525a5b3d21 --- /dev/null +++ b/code/modules/alarm/alarm.dm @@ -0,0 +1,138 @@ +#define ALARM_RESET_DELAY 100 // How long will the alarm/trigger remain active once origin/source has been found to be gone? + +/datum/alarm_source + var/source = null // The source trigger + var/source_name = "" // The name of the source should it be lost (for example a destroyed camera) + var/duration = 0 // How long this source will be alarming, 0 for indefinetely. + var/severity = 1 // How severe the alarm from this source is. + var/start_time = 0 // When this source began alarming. + var/end_time = 0 // Use to set when this trigger should clear, in case the source is lost. + +/datum/alarm_source/New(var/atom/source) + src.source = source + start_time = world.time + source_name = source.get_source_name() + +/datum/alarm + var/atom/origin //Used to identify the alarm area. + var/list/sources = new() //List of sources triggering the alarm. Used to determine when the alarm should be cleared. + var/list/sources_assoc = new() //Associative list of source triggers. Used to efficiently acquire the alarm source. + var/list/cameras //List of cameras that can be switched to, if the player has that capability. + var/area/last_area //The last acquired area, used should origin be lost (for example a destroyed borg containing an alarming camera). + var/area/last_name //The last acquired name, used should origin be lost + var/area/last_camera_area //The last area in which cameras where fetched, used to see if the camera list should be updated. + var/end_time //Used to set when this alarm should clear, in case the origin is lost. + +/datum/alarm/New(var/atom/origin, var/atom/source, var/duration, var/severity) + src.origin = origin + + cameras() // Sets up both cameras and last alarm area. + set_source_data(source, duration, severity) + +/datum/alarm/proc/process() + // Has origin gone missing? + if(!origin && !end_time) + end_time = world.time + ALARM_RESET_DELAY + for(var/datum/alarm_source/AS in sources) + // Has the alarm passed its best before date? + if((AS.end_time && world.time > AS.end_time) || (AS.duration && world.time > (AS.start_time + AS.duration))) + sources -= AS + // Has the source gone missing? Then reset the normal duration and set end_time + if(!AS.source && !AS.end_time) // end_time is used instead of duration to ensure the reset doesn't remain in the future indefinetely. + AS.duration = 0 + AS.end_time = world.time + ALARM_RESET_DELAY + +/datum/alarm/proc/set_source_data(var/atom/source, var/duration, var/severity) + var/datum/alarm_source/AS = sources_assoc[source] + if(!AS) + AS = new/datum/alarm_source(source) + sources += AS + sources_assoc[source] = AS + // Currently only non-0 durations can be altered (normal alarms VS EMP blasts) + if(AS.duration) + duration = SecondsToTicks(duration) + AS.duration = duration + AS.severity = severity + +/datum/alarm/proc/clear(var/source) + var/datum/alarm_source/AS = sources_assoc[source] + sources -= AS + sources_assoc -= source + +/datum/alarm/proc/alarm_area() + if(!origin) + return last_area + + last_area = origin.get_alarm_area() + return last_area + +/datum/alarm/proc/alarm_name() + if(!origin) + return last_name + + last_name = origin.get_alarm_name() + return last_name + +/datum/alarm/proc/cameras() + // If the alarm origin has changed area, for example a borg containing an alarming camera, reset the list of cameras + if(cameras && (last_camera_area != alarm_area())) + cameras = null + + // The list of cameras is also reset by /proc/invalidateCameraCache() + if(!cameras) + cameras = origin ? origin.get_alarm_cameras() : last_area.get_alarm_cameras() + + last_camera_area = last_area + return cameras + +/datum/alarm/proc/max_severity() + var/max_severity = 0 + for(var/datum/alarm_source/AS in sources) + max_severity = max(AS.severity, max_severity) + + return max_severity + +/****************** +* Assisting procs * +******************/ +/atom/proc/get_alarm_area() + var/area/A = get_area(src) + return A.master + +/area/get_alarm_area() + return src.master + +/atom/proc/get_alarm_name() + var/area/A = get_area(src) + return A.master.name + +/area/get_alarm_name() + return master.name + +/mob/get_alarm_name() + return name + +/atom/proc/get_source_name() + return name + +/obj/machinery/camera/get_source_name() + return c_tag + +/atom/proc/get_alarm_cameras() + var/area/A = get_area(src) + return A.get_cameras() + +/area/get_alarm_cameras() + return get_cameras() + +/mob/living/silicon/robot/get_alarm_cameras() + var/list/cameras = ..() + if(camera) + cameras += camera + + return cameras + +/mob/living/silicon/robot/syndicate/get_alarm_cameras() + return list() + +#undef ALARM_LOSS_DELAY diff --git a/code/modules/alarm/alarm_handler.dm b/code/modules/alarm/alarm_handler.dm new file mode 100644 index 0000000000..2be4060de2 --- /dev/null +++ b/code/modules/alarm/alarm_handler.dm @@ -0,0 +1,98 @@ +#define ALARM_RAISED 1 +#define ALARM_CLEARED 0 + +/datum/alarm_handler + var/category = "" + var/list/datum/alarm/alarms = new // All alarms, to handle cases when an origin has been deleted with one or more active alarms + var/list/datum/alarm/alarms_assoc = new // Associative list of alarms, to efficiently acquire them based on origin. + var/list/listeners = new // A list of all objects interested in alarm changes. + +/datum/alarm_handler/proc/process() + for(var/datum/alarm/A in alarms) + A.process() + check_alarm_cleared(A) + +/datum/alarm_handler/proc/triggerAlarm(var/atom/origin, var/atom/source, var/duration = 0, var/severity = 1) + var/new_alarm + //Proper origin and source mandatory + if(!(origin && source)) + return + origin = origin.get_alarm_origin() + + new_alarm = 0 + //see if there is already an alarm of this origin + var/datum/alarm/existing = alarms_assoc[origin] + if(existing) + existing.set_source_data(source, duration, severity) + else + existing = new/datum/alarm(origin, source, duration, severity) + new_alarm = 1 + + alarms |= existing + alarms_assoc[origin] = existing + if(new_alarm) + alarms = dd_sortedObjectList(alarms) + on_alarm_change(existing, ALARM_RAISED) + + return new_alarm + +/datum/alarm_handler/proc/clearAlarm(var/atom/origin, var/source) + //Proper origin and source mandatory + if(!(origin && source)) + return + origin = origin.get_alarm_origin() + + var/datum/alarm/existing = alarms_assoc[origin] + if(existing) + existing.clear(source) + return check_alarm_cleared(existing) + +/datum/alarm_handler/proc/major_alarms() + return alarms + +/datum/alarm_handler/proc/minor_alarms() + return alarms + +/datum/alarm_handler/proc/check_alarm_cleared(var/datum/alarm/alarm) + if ((alarm.end_time && world.time > alarm.end_time) || !alarm.sources.len) + alarms -= alarm + alarms_assoc -= alarm.origin + on_alarm_change(alarm, ALARM_CLEARED) + return 1 + return 0 + +/datum/alarm_handler/proc/on_alarm_change(var/datum/alarm/alarm, var/was_raised) + for(var/obj/machinery/camera/C in alarm.cameras()) + if(was_raised) + C.add_network(category) + else + C.remove_network(category) + notify_listeners(alarm, was_raised) + +/datum/alarm_handler/proc/get_alarm_severity_for_origin(var/atom/origin) + if(!origin) + return + + origin = origin.get_alarm_origin() + var/datum/alarm/existing = alarms_assoc[origin] + if(!existing) + return + + return existing.max_severity() + +/atom/proc/get_alarm_origin() + return src + +/turf/get_alarm_origin() + var/area/area = get_area(src) + return area.master // Very important to get area.master, as dynamic lightning can and will split areas. + +/datum/alarm_handler/proc/register(var/object, var/procName) + listeners[object] = procName + +/datum/alarm_handler/proc/unregister(var/object) + listeners -= object + +/datum/alarm_handler/proc/notify_listeners(var/alarm, var/was_raised) + for(var/listener in listeners) + call(listener, listeners[listener])(src, alarm, was_raised) diff --git a/code/modules/alarm/atmosphere_alarm.dm b/code/modules/alarm/atmosphere_alarm.dm new file mode 100644 index 0000000000..9751319111 --- /dev/null +++ b/code/modules/alarm/atmosphere_alarm.dm @@ -0,0 +1,19 @@ +/datum/alarm_handler/atmosphere + category = "Atmosphere Alarms" + +/datum/alarm_handler/atmosphere/triggerAlarm(var/atom/origin, var/atom/source, var/duration = 0, var/severity = 1) + ..() + +/datum/alarm_handler/atmosphere/major_alarms() + var/list/major_alarms = new() + for(var/datum/alarm/A in alarms) + if(A.max_severity() > 1) + major_alarms.Add(A) + return major_alarms + +/datum/alarm_handler/atmosphere/minor_alarms() + var/list/minor_alarms = new() + for(var/datum/alarm/A in alarms) + if(A.max_severity() == 1) + minor_alarms.Add(A) + return minor_alarms diff --git a/code/modules/alarm/camera_alarm.dm b/code/modules/alarm/camera_alarm.dm new file mode 100644 index 0000000000..9594a1c8a0 --- /dev/null +++ b/code/modules/alarm/camera_alarm.dm @@ -0,0 +1,2 @@ +/datum/alarm_handler/camera + category = "Camera Alarms" diff --git a/code/modules/alarm/fire_alarm.dm b/code/modules/alarm/fire_alarm.dm new file mode 100644 index 0000000000..9c7a9874c7 --- /dev/null +++ b/code/modules/alarm/fire_alarm.dm @@ -0,0 +1,11 @@ +/datum/alarm_handler/fire + category = "Fire Alarms" + +/datum/alarm_handler/fire/on_alarm_change(var/datum/alarm/alarm, var/was_raised) + var/area/A = alarm.origin + if(istype(A)) + if(was_raised) + A.fire_alert() + else + A.fire_reset() + ..() diff --git a/code/modules/alarm/motion_alarm.dm b/code/modules/alarm/motion_alarm.dm new file mode 100644 index 0000000000..cafc7c128d --- /dev/null +++ b/code/modules/alarm/motion_alarm.dm @@ -0,0 +1,2 @@ +/datum/alarm_handler/motion + category = "Motion Alarms" diff --git a/code/modules/alarm/power_alarm.dm b/code/modules/alarm/power_alarm.dm new file mode 100644 index 0000000000..2df6d1eab3 --- /dev/null +++ b/code/modules/alarm/power_alarm.dm @@ -0,0 +1,10 @@ +/datum/alarm_handler/power + category = "Power Alarms" + +/datum/alarm_handler/power/on_alarm_change(var/datum/alarm/alarm, var/was_raised) + var/area/A = alarm.origin + if(istype(A)) + A.power_alert(was_raised) + ..() + +/area/proc/power_alert(var/alarming) diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 89699b3427..79e3cf8637 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -120,7 +120,7 @@ Topic(href, href_list) - ..() + if(..()) return 1 if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) usr << browse(null, "window=infra") onclose(usr, "infra") diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index cd0a377b43..06923f8458 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -129,7 +129,7 @@ Topic(href, href_list) - ..() + if(..()) return 1 if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) usr << browse(null, "window=prox") onclose(usr, "prox") diff --git a/code/modules/assembly/shock_kit.dm b/code/modules/assembly/shock_kit.dm index 4cbef90875..5e501e3313 100644 --- a/code/modules/assembly/shock_kit.dm +++ b/code/modules/assembly/shock_kit.dm @@ -40,7 +40,7 @@ return /obj/item/assembly/shock_kit/receive_signal() - if(istype(loc, /obj/structure/stool/bed/chair/e_chair)) - var/obj/structure/stool/bed/chair/e_chair/C = loc + if(istype(loc, /obj/structure/bed/chair/e_chair)) + var/obj/structure/bed/chair/e_chair/C = loc C.shock() return diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 9d79d67876..0b2acd5a5b 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -70,7 +70,7 @@ Topic(href, href_list) - ..() + if(..()) return 1 if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) usr << browse(null, "window=radio") diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 5a0fb6e4d4..326d36195f 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -83,7 +83,7 @@ Topic(href, href_list) - ..() + if(..()) return 1 if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) usr << browse(null, "window=timer") onclose(usr, "timer") diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 781dd8c44f..11f78326c6 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -223,7 +223,7 @@ corpsesuit = /obj/item/clothing/suit/armor/bulletproof corpseradio = /obj/item/device/radio/headset/heads/captain corpseglasses = /obj/item/clothing/glasses/eyepatch - corpsemask = /obj/item/clothing/mask/cigarette/cigar/cohiba + corpsemask = /obj/item/clothing/mask/smokable/cigarette/cigar/cohiba corpsehelmet = /obj/item/clothing/head/centhat corpsegloves = /obj/item/clothing/gloves/swat corpseshoes = /obj/item/clothing/shoes/swat diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index a8efe68418..45ca127f13 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -145,7 +145,7 @@ if(custom_event_msg && custom_event_msg != "") src << "

    Custom Event

    " src << "

    A custom event is taking place. OOC Info:

    " - src << "[html_encode(custom_event_msg)]" + src << "[custom_event_msg]" src << "
    " if( (world.address == address || !address) && !host ) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 67bf23b72e..493b681be3 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -15,7 +15,7 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set "cultist" = IS_MODE_COMPILED("cult"), // 8 "infested monkey" = IS_MODE_COMPILED("monkey"), // 9 "ninja" = "true", // 10 - "vox raider" = IS_MODE_COMPILED("heist"), // 11 + "raider" = IS_MODE_COMPILED("heist"), // 11 "diona" = 1, // 12 "mutineer" = IS_MODE_COMPILED("mutiny"), // 13 "pAI candidate" = 1, // -- TLE // 14 @@ -54,8 +54,8 @@ datum/preferences var/age = 30 //age of character var/spawnpoint = "Arrivals Shuttle" //where this character will spawn (0-2). var/b_type = "A+" //blood type (not-chooseable) - var/underwear = 1 //underwear type - var/undershirt = 1 //undershirt type + var/underwear //underwear type + var/undershirt //undershirt type var/backbag = 2 //backpack type var/h_style = "Bald" //Hair type var/r_hair = 0 //Hair color @@ -373,12 +373,11 @@ datum/preferences else dat += "

    " - if(gender == MALE) - dat += "Underwear: [underwear_m[underwear]]
    " - else - dat += "Underwear: [underwear_f[underwear]]
    " + var/list/undies = gender == MALE ? underwear_m : underwear_f - dat += "Undershirt: [undershirt_t[undershirt]]
    " + dat += "Underwear: [get_key_by_value(undies,underwear)]
    " + + dat += "Undershirt: [get_key_by_value(undershirt_t,undershirt)]
    " dat += "Backpack Type:
    [backbaglist[backbag]]
    " @@ -996,16 +995,10 @@ datum/preferences ShowChoices(user) return if("general") - var/msg = input(usr,"Give a general description of your character. This will be shown regardless of clothing, and may include OOC notes and preferences.","Flavor Text",html_decode(flavor_texts[href_list["task"]])) as message - if(msg != null) - msg = copytext(msg, 1, MAX_MESSAGE_LEN) - msg = html_encode(msg) + var/msg = sanitize(input(usr,"Give a general description of your character. This will be shown regardless of clothing, and may include OOC notes and preferences.","Flavor Text",html_decode(flavor_texts[href_list["task"]])) as message, extra = 0) flavor_texts[href_list["task"]] = msg else - var/msg = input(usr,"Set the flavor text for your [href_list["task"]].","Flavor Text",html_decode(flavor_texts[href_list["task"]])) as message - if(msg != null) - msg = copytext(msg, 1, MAX_MESSAGE_LEN) - msg = html_encode(msg) + var/msg = sanitize(input(usr,"Set the flavor text for your [href_list["task"]].","Flavor Text",html_decode(flavor_texts[href_list["task"]])) as message, extra = 0) flavor_texts[href_list["task"]] = msg SetFlavorText(user) return @@ -1020,16 +1013,10 @@ datum/preferences ShowChoices(user) return if("Default") - var/msg = input(usr,"Set the default flavour text for your robot. It will be used for any module without individual setting.","Flavour Text",html_decode(flavour_texts_robot["Default"])) as message - if(msg != null) - msg = copytext(msg, 1, MAX_MESSAGE_LEN) - msg = html_encode(msg) + var/msg = sanitize(input(usr,"Set the default flavour text for your robot. It will be used for any module without individual setting.","Flavour Text",html_decode(flavour_texts_robot["Default"])) as message, extra = 0) flavour_texts_robot[href_list["task"]] = msg else - var/msg = input(usr,"Set the flavour text for your robot with [href_list["task"]] module. If you leave this empty, default flavour text will be used for this module.","Flavour Text",html_decode(flavour_texts_robot[href_list["task"]])) as message - if(msg != null) - msg = copytext(msg, 1, MAX_MESSAGE_LEN) - msg = html_encode(msg) + var/msg = sanitize(input(usr,"Set the flavour text for your robot with [href_list["task"]] module. If you leave this empty, default flavour text will be used for this module.","Flavour Text",html_decode(flavour_texts_robot[href_list["task"]])) as message, extra = 0) flavour_texts_robot[href_list["task"]] = msg SetFlavourTextRobot(user) return @@ -1045,41 +1032,25 @@ datum/preferences else user << browse(null, "window=records") if(href_list["task"] == "med_record") - var/medmsg = input(usr,"Set your medical notes here.","Medical Records",html_decode(med_record)) as message - + var/medmsg = sanitize(input(usr,"Set your medical notes here.","Medical Records",html_decode(med_record)) as message, MAX_PAPER_MESSAGE_LEN, extra = 0) if(medmsg != null) - medmsg = copytext(medmsg, 1, MAX_PAPER_MESSAGE_LEN) - medmsg = html_encode(medmsg) - med_record = medmsg SetRecords(user) if(href_list["task"] == "sec_record") - var/secmsg = input(usr,"Set your security notes here.","Security Records",html_decode(sec_record)) as message - + var/secmsg = sanitize(input(usr,"Set your security notes here.","Security Records",html_decode(sec_record)) as message, MAX_PAPER_MESSAGE_LEN, extra = 0) if(secmsg != null) - secmsg = copytext(secmsg, 1, MAX_PAPER_MESSAGE_LEN) - secmsg = html_encode(secmsg) - sec_record = secmsg SetRecords(user) if(href_list["task"] == "gen_record") - var/genmsg = input(usr,"Set your employment notes here.","Employment Records",html_decode(gen_record)) as message - + var/genmsg = sanitize(input(usr,"Set your employment notes here.","Employment Records",html_decode(gen_record)) as message, MAX_PAPER_MESSAGE_LEN, extra = 0) if(genmsg != null) - genmsg = copytext(genmsg, 1, MAX_PAPER_MESSAGE_LEN) - genmsg = html_encode(genmsg) - gen_record = genmsg SetRecords(user) if(href_list["task"] == "exploitable_record") - var/exploitmsg = input(usr,"Set exploitable information about you here.","Exploitable Information",html_decode(exploit_record)) as message - + var/exploitmsg = sanitize(input(usr,"Set exploitable information about you here.","Exploitable Information",html_decode(exploit_record)) as message, MAX_PAPER_MESSAGE_LEN, extra = 0) if(exploitmsg != null) - exploitmsg = copytext(exploitmsg, 1, MAX_PAPER_MESSAGE_LEN) - exploitmsg = html_encode(exploitmsg) - exploit_record = exploitmsg SetAntagoptions(user) @@ -1178,10 +1149,12 @@ datum/preferences if("f_style") f_style = random_facial_hair_style(gender, species) if("underwear") - underwear = rand(1,underwear_m.len) + var/r = pick(underwear_m) + underwear = underwear_m[r] ShowChoices(user) if("undershirt") - undershirt = rand(1,undershirt_t.len) + var/r = pick(undershirt_t) + undershirt = undershirt_t[r] ShowChoices(user) if("eyes") r_eyes = rand(0,255) @@ -1204,7 +1177,7 @@ datum/preferences if("name") var/raw_name = input(user, "Choose your character's name:", "Character Preference") as text|null if (!isnull(raw_name)) // Check to ensure that the user entered text (rather than cancel.) - var/new_name = reject_bad_name(raw_name) + var/new_name = sanitizeName(raw_name) if(new_name) real_name = new_name else @@ -1290,7 +1263,7 @@ datum/preferences if("metadata") var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata) as message|null if(new_metadata) - metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN)) + metadata = sanitize(new_metadata) if("b_type") var/new_b_type = input(user, "Choose your character's blood-type:", "Character Preference") as null|anything in list( "A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-" ) @@ -1351,7 +1324,7 @@ datum/preferences var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in underwear_options if(new_underwear) - underwear = underwear_options.Find(new_underwear) + underwear = underwear_options[new_underwear] ShowChoices(user) if("undershirt") @@ -1360,7 +1333,7 @@ datum/preferences var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in undershirt_options if (new_undershirt) - undershirt = undershirt_options.Find(new_undershirt) + undershirt = undershirt_options[new_undershirt] ShowChoices(user) if("eyes") @@ -1503,7 +1476,7 @@ datum/preferences if(choice == "Other") var/raw_choice = input(user, "Please enter a home system.") as text|null if(raw_choice) - home_system = sanitize(copytext(raw_choice,1,MAX_MESSAGE_LEN)) + home_system = sanitize(raw_choice) return home_system = choice if("citizenship") @@ -1513,7 +1486,7 @@ datum/preferences if(choice == "Other") var/raw_choice = input(user, "Please enter your current citizenship.", "Character Preference") as text|null if(raw_choice) - citizenship = sanitize(copytext(raw_choice,1,MAX_MESSAGE_LEN)) + citizenship = sanitize(raw_choice) return citizenship = choice if("faction") @@ -1523,7 +1496,7 @@ datum/preferences if(choice == "Other") var/raw_choice = input(user, "Please enter a faction.") as text|null if(raw_choice) - faction = sanitize(copytext(raw_choice,1,MAX_MESSAGE_LEN)) + faction = sanitize(raw_choice) return faction = choice if("religion") @@ -1533,7 +1506,7 @@ datum/preferences if(choice == "Other") var/raw_choice = input(user, "Please enter a religon.") as text|null if(raw_choice) - religion = sanitize(copytext(raw_choice,1,MAX_MESSAGE_LEN)) + religion = sanitize(raw_choice) return religion = choice else @@ -1705,12 +1678,8 @@ datum/preferences else if(status == "mechanical") I.mechanize() - if(underwear > underwear_m.len || underwear < 1) - underwear = 0 //I'm sure this is 100% unnecessary, but I'm paranoid... sue me. //HAH NOW NO MORE MAGIC CLONING UNDIES character.underwear = underwear - if(undershirt > undershirt_t.len || undershirt < 1) - undershirt = 0 character.undershirt = undershirt if(backbag > 4 || backbag < 1) diff --git a/code/modules/client/preferences_gear.dm b/code/modules/client/preferences_gear.dm index 4b421d02bb..5ac54a0498 100644 --- a/code/modules/client/preferences_gear.dm +++ b/code/modules/client/preferences_gear.dm @@ -282,12 +282,24 @@ var/global/list/gear_datums = list() slot = slot_w_uniform cost = 2 +/datum/gear/blazer_blue + display_name = "blazer, blue" + path = /obj/item/clothing/under/blazer + slot = slot_w_uniform + cost = 2 + /datum/gear/kilt display_name = "kilt" path = /obj/item/clothing/under/kilt slot = slot_w_uniform cost = 3 +/datum/gear/blackjumpskirt + display_name = "jumpskirt, black" + path = /obj/item/clothing/under/blackjumpskirt + slot = slot_w_uniform + cost = 2 + /datum/gear/skirt_blue display_name = "plaid skirt, blue" path = /obj/item/clothing/under/dress/plaid_blue @@ -369,88 +381,102 @@ var/global/list/gear_datums = list() /datum/gear/armband_cargo display_name = "armband, cargo" - path = /obj/item/clothing/tie/armband/cargo + path = /obj/item/clothing/accessory/armband/cargo slot = slot_tie cost = 1 /datum/gear/armband_emt display_name = "armband, EMT" - path = /obj/item/clothing/tie/armband/medgreen + path = /obj/item/clothing/accessory/armband/medgreen slot = slot_tie cost = 2 /datum/gear/armband_engineering display_name = "armband, engineering" - path = /obj/item/clothing/tie/armband/engine + path = /obj/item/clothing/accessory/armband/engine slot = slot_tie cost = 1 /datum/gear/armband_hydroponics display_name = "armband, hydroponics" - path = /obj/item/clothing/tie/armband/hydro + path = /obj/item/clothing/accessory/armband/hydro slot = slot_tie cost = 1 /datum/gear/armband_medical display_name = "armband, medical" - path = /obj/item/clothing/tie/armband/med + path = /obj/item/clothing/accessory/armband/med slot = slot_tie cost = 1 /datum/gear/armband display_name = "armband, red" - path = /obj/item/clothing/tie/armband + path = /obj/item/clothing/accessory/armband slot = slot_tie cost = 1 /datum/gear/armband_science display_name = "armband, science" - path = /obj/item/clothing/tie/armband/science + path = /obj/item/clothing/accessory/armband/science slot = slot_tie cost = 1 /datum/gear/armpit - display_name = "shoulder holster" - path = /obj/item/clothing/tie/holster/armpit + display_name = "holster, armpit" + path = /obj/item/clothing/accessory/holster/armpit slot = slot_tie cost = 2 - allowed_roles = list("Captain", "Head of Personnel", "Security Officer", "Warden", "Head of Security") + allowed_roles = list("Captain", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective") + +/datum/gear/hip + display_name = "holster, hip" + path = /obj/item/clothing/accessory/holster/hip + slot = slot_tie + cost = 2 + allowed_roles = list("Captain", "Head of Personnel", "Security Officer", "Warden", "Head of Security", "Detective") + +/datum/gear/waist + display_name = "holster, waist" + path = /obj/item/clothing/accessory/holster/waist + slot = slot_tie + cost = 2 + allowed_roles = list("Captain", "Head of Personnel", "Security Officer", "Warden", "Head of Security", "Detective") /datum/gear/tie_blue display_name = "tie, blue" - path = /obj/item/clothing/tie/blue + path = /obj/item/clothing/accessory/blue slot = slot_tie cost = 1 /datum/gear/tie_red display_name = "tie, red" - path = /obj/item/clothing/tie/red + path = /obj/item/clothing/accessory/red slot = slot_tie cost = 1 /datum/gear/tie_horrible display_name = "tie, socially disgraceful" - path = /obj/item/clothing/tie/horrible + path = /obj/item/clothing/accessory/horrible slot = slot_tie cost = 1 /datum/gear/brown_vest display_name = "webbing, engineering" - path = /obj/item/clothing/tie/storage/brown_vest + path = /obj/item/clothing/accessory/storage/brown_vest slot = slot_tie cost = 2 allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer") /datum/gear/black_vest display_name = "webbing, security" - path = /obj/item/clothing/tie/storage/black_vest + path = /obj/item/clothing/accessory/storage/black_vest slot = slot_tie cost = 2 allowed_roles = list("Security Officer","Head of Security","Warden") /datum/gear/webbing display_name = "webbing, simple" - path = /obj/item/clothing/tie/storage/webbing + path = /obj/item/clothing/accessory/storage/webbing slot = slot_tie cost = 2 @@ -464,7 +490,7 @@ var/global/list/gear_datums = list() /datum/gear/bomber display_name = "bomber jacket" - path = /obj/item/clothing/suit/storage/bomber + path = /obj/item/clothing/suit/storage/toggle/bomber cost = 4 slot = slot_wear_suit @@ -492,12 +518,22 @@ var/global/list/gear_datums = list() cost = 3 slot = slot_wear_suit +/datum/gear/blue_lawyer_jacket + display_name = "suit jacket, blue" + path = /obj/item/clothing/suit/storage/toggle/lawyer/bluejacket + cost = 3 + slot = slot_wear_suit + /datum/gear/hoodie display_name = "hoodie, grey" - path = /obj/item/clothing/suit/hoodie + path = /obj/item/clothing/suit/storage/toggle/hoodie cost = 2 slot = slot_wear_suit +/datum/gear/hoodie/black + display_name = "hoodie, black" + path = /obj/item/clothing/suit/storage/toggle/hoodie/black + /datum/gear/unathi_mantle display_name = "hide mantle (Unathi)" path = /obj/item/clothing/suit/unathi/mantle diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 77a47b59e8..f3d46739f2 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -187,11 +187,18 @@ //Sanitize metadata = sanitize_text(metadata, initial(metadata)) - real_name = reject_bad_name(real_name) + real_name = sanitizeName(real_name) if(isnull(species) || !(species in playable_species)) species = "Human" + if(isnum(underwear)) + var/list/undies = gender == MALE ? underwear_m : underwear_f + underwear = undies[undies[underwear]] + + if(isnum(undershirt)) + undershirt = undershirt_t[undershirt_t[undershirt]] + if(isnull(language)) language = "None" if(isnull(spawnpoint)) spawnpoint = "Arrivals Shuttle" if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation) @@ -214,8 +221,6 @@ r_eyes = sanitize_integer(r_eyes, 0, 255, initial(r_eyes)) g_eyes = sanitize_integer(g_eyes, 0, 255, initial(g_eyes)) b_eyes = sanitize_integer(b_eyes, 0, 255, initial(b_eyes)) - underwear = sanitize_integer(underwear, 1, underwear_m.len, initial(underwear)) - undershirt = sanitize_integer(undershirt, 1, undershirt_t.len, initial(undershirt)) backbag = sanitize_integer(backbag, 1, backbaglist.len, initial(backbag)) b_type = sanitize_text(b_type, initial(b_type)) diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index c57633678a..00487ed60a 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -182,7 +182,7 @@ icons.Add(usr.zone_sel) for(var/obj/screen/I in icons) - if(I.name in list("help", "harm", "disarm", "grab")) continue + if(I.name in list(I_HELP, I_HURT, I_DISARM, I_GRAB)) continue I.icon = ui_style2icon(UI_style_new) I.color = UI_style_color_new I.alpha = UI_style_alpha_new diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index f6dc6cc337..2cd1450a97 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -68,7 +68,7 @@ /obj/item/clothing/head/helmet/refit_for_species(var/target_species) if(!species_restricted) return //this item doesn't use the species_restricted system - + //Set species_restricted list switch(target_species) if("Skrell") @@ -360,6 +360,9 @@ BLIND // can't see anything species_restricted = list("exclude","Unathi","Tajara") sprite_sheets = list("Vox" = 'icons/mob/species/vox/shoes.dmi') +/obj/item/clothing/shoes/proc/handle_movement(var/turf/walking, var/running) + return + /obj/item/clothing/shoes/update_clothing_icon() if (ismob(src.loc)) var/mob/M = src.loc @@ -401,7 +404,7 @@ BLIND // can't see anything 2 = Report detailed damages 3 = Report location */ - var/obj/item/clothing/tie/hastie = null + var/list/accessories = list() var/displays_id = 1 sprite_sheets = list("Vox" = 'icons/mob/species/vox/uniform.dmi') @@ -410,37 +413,53 @@ BLIND // can't see anything var/mob/M = src.loc M.update_inv_w_uniform() +/obj/item/clothing/under/proc/can_attach_accessory(obj/item/clothing/accessory/A) + if(istype(A)) + .=1 + else + return 0 + if(accessories.len && (A.slot in list("utility","armband"))) + for(var/obj/item/clothing/accessory/AC in accessories) + if (AC.slot == A.slot) + return 0 + /obj/item/clothing/under/attackby(obj/item/I, mob/user) - if(hastie) - hastie.attackby(I, user) - return + if(istype(I, /obj/item/clothing/accessory)) + var/obj/item/clothing/accessory/A = I + if(can_attach_accessory(A)) + user.drop_item() + accessories += A + A.on_attached(src, user) - if(!hastie && istype(I, /obj/item/clothing/tie)) - user.drop_item() - hastie = I - hastie.on_attached(src, user) + if(istype(loc, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = loc + H.update_inv_w_uniform() - if(istype(loc, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = loc - H.update_inv_w_uniform() + return + else + user << "You cannot attach more accessories of this type to [src]." + if(accessories.len) + for(var/obj/item/clothing/accessory/A in accessories) + A.attackby(I, user) return ..() /obj/item/clothing/under/attack_hand(mob/user as mob) //only forward to the attached accessory if the clothing is equipped (not in a storage) - if(hastie && src.loc == user) - hastie.attack_hand(user) + if(accessories.len && src.loc == user) + for(var/obj/item/clothing/accessory/A in accessories) + A.attack_hand(user) return - if ((ishuman(usr) || ismonkey(usr)) && src.loc == user) //make it harder to accidentally undress yourself + if ((ishuman(usr) || issmall(usr)) && src.loc == user) //make it harder to accidentally undress yourself return ..() /obj/item/clothing/under/MouseDrop(obj/over_object as obj) - if (ishuman(usr) || ismonkey(usr)) + if (ishuman(usr) || issmall(usr)) //makes sure that the clothing is equipped so that we can't drag it into our hand from miles away. if (!(src.loc == usr)) return @@ -468,8 +487,9 @@ BLIND // can't see anything user << "Its vital tracker appears to be enabled." if(3) user << "Its vital tracker and tracking beacon appear to be enabled." - if(hastie) - user << "\A [hastie] is clipped to it." + if(accessories.len) + for(var/obj/item/clothing/accessory/A in accessories) + user << "\A [A] is attached to it." /obj/item/clothing/under/proc/set_sensors(mob/usr as mob) var/mob/M = usr @@ -540,12 +560,12 @@ BLIND // can't see anything else usr << "You cannot roll down the uniform!" -/obj/item/clothing/under/proc/remove_accessory(mob/user as mob) - if(!hastie) +/obj/item/clothing/under/proc/remove_accessory(mob/user, obj/item/clothing/accessory/A) + if(!(A in accessories)) return - hastie.on_removed(user) - hastie = null + A.on_removed(user) + accessories -= A update_clothing_icon() /obj/item/clothing/under/verb/removetie() @@ -554,14 +574,20 @@ BLIND // can't see anything set src in usr if(!istype(usr, /mob/living)) return if(usr.stat) return - - src.remove_accessory(usr) + if(!accessories.len) return + var/obj/item/clothing/accessory/A + if(accessories.len > 1) + A = input("Select an accessory to remove from [src]") as null|anything in accessories + else + A = accessories[1] + src.remove_accessory(usr,A) /obj/item/clothing/under/rank/New() sensor_mode = pick(0,1,2,3) ..() /obj/item/clothing/under/emp_act(severity) - if (hastie) - hastie.emp_act(severity) + if(accessories.len) + for(var/obj/item/clothing/accessory/A in accessories) + A.emp_act(severity) ..() \ No newline at end of file diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 2034aad363..436f714053 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -20,7 +20,7 @@ item_state = "hardhat0_red" item_color = "red" name = "firefighter helmet" - flags = STOPSPRESSUREDMAGE + flags = STOPPRESSUREDAMAGE heat_protection = HEAD max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE @@ -28,11 +28,11 @@ icon_state = "hardhat0_white" item_state = "hardhat0_white" item_color = "white" - flags = STOPSPRESSUREDMAGE + flags = STOPPRESSUREDAMAGE heat_protection = HEAD max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE /obj/item/clothing/head/hardhat/dblue icon_state = "hardhat0_dblue" item_state = "hardhat0_dblue" - item_color = "dblue" \ No newline at end of file + item_color = "dblue" diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index c824563ea8..5eb7e0c65b 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -152,4 +152,11 @@ var/icon/earbit = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kittyinner") var/icon/earbit2 = new/icon("icon" = 'icons/mob/head.dmi', "icon_state" = "kittyinner2") mob.Blend(earbit, ICON_OVERLAY) - mob2.Blend(earbit2, ICON_OVERLAY) \ No newline at end of file + mob2.Blend(earbit2, ICON_OVERLAY) + +/obj/item/clothing/head/richard + name = "chicken mask" + desc = "You can hear the distant sounds of rhythmic electronica." + icon_state = "richard" + body_parts_covered = HEAD|FACE + flags = HEADCOVERSEYES|HEADCOVERSMOUTH|BLOCKHAIR \ No newline at end of file diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 1982409d6f..9552a0f17d 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -43,6 +43,10 @@ siemens_coefficient = 0.7 body_parts_covered = FACE|EYES +/obj/item/clothing/mask/gas/swat/vox + name = "\improper alien mask" + desc = "Clearly not designed for a human face." + /obj/item/clothing/mask/gas/syndicate name = "tactical mask" desc = "A close-fitting tactical mask that can be connected to an air supply." diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index 412f69bda6..3d3db7c736 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -100,4 +100,35 @@ body_parts_covered = HEAD|FACE|EYES w_class = 2 var/voicechange = 0 - siemens_coefficient = 0.9 \ No newline at end of file + siemens_coefficient = 0.9 + +/obj/item/clothing/mask/ai + name = "camera MIU" + desc = "Allows for direct mental connection to accessible camera networks." + icon_state = "s-ninja" + item_state = "s-ninja" + flags_inv = HIDEFACE + body_parts_covered = 0 + var/mob/eye/aiEye/eye + +/obj/item/clothing/mask/ai/New() + eye = new(src) + +/obj/item/clothing/mask/ai/equipped(var/mob/user, var/slot) + ..(user, slot) + if(slot == slot_wear_mask) + eye.owner = user + user.eyeobj = eye + + for(var/datum/chunk/c in eye.visibleChunks) + c.remove(eye) + eye.setLoc(user) + +/obj/item/clothing/mask/ai/dropped(var/mob/user) + ..() + if(eye.owner == user) + for(var/datum/chunk/c in eye.visibleChunks) + c.remove(eye) + + eye.owner.eyeobj = null + eye.owner = null diff --git a/code/modules/clothing/masks/voice.dm b/code/modules/clothing/masks/voice.dm index c30e1ea48b..6899fef1ef 100644 --- a/code/modules/clothing/masks/voice.dm +++ b/code/modules/clothing/masks/voice.dm @@ -21,7 +21,7 @@ set category = "Object" set src in usr - var/voice = sanitize(copytext(name,1,MAX_MESSAGE_LEN)) + var/voice = sanitize(name, MAX_NAME_LEN) if(!voice || !length(voice)) return changer.voice = voice usr << "You are now mimicking [changer.voice]." diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index e52b2fce8c..38b252b1ff 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -71,6 +71,16 @@ var/footstep = 1 //used for squeeks whilst walking species_restricted = null +/obj/item/clothing/shoes/clown_shoes/handle_movement(var/turf/walking, var/running) + if(running) + if(footstep >= 2) + footstep = 0 + playsound(src, "clownstep", 50, 1) // this will get annoying very fast. + else + footstep++ + else + playsound(src, "clownstep", 20, 1) + /obj/item/clothing/shoes/jackboots name = "jackboots" desc = "Nanotrasen-issue Security combat boots for combat scenarios or combat situations. All combat, all the time." diff --git a/code/modules/clothing/spacesuits/alien.dm b/code/modules/clothing/spacesuits/alien.dm index 374f38be85..23ba1d0c55 100644 --- a/code/modules/clothing/spacesuits/alien.dm +++ b/code/modules/clothing/spacesuits/alien.dm @@ -45,21 +45,15 @@ siemens_coefficient = 0.6 heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE - species_restricted = list("Vox", "Vox Armalis") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi', - "Vox Armalis" = 'icons/mob/species/armalis/suit.dmi', - ) + species_restricted = list("Vox") + sprite_sheets = list("Vox" = 'icons/mob/species/vox/suit.dmi') /obj/item/clothing/head/helmet/space/vox armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 30, bio = 30, rad = 30) siemens_coefficient = 0.6 - flags = HEADCOVERSEYES|STOPSPRESSUREDMAGE - species_restricted = list("Vox","Vox Armalis") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/head.dmi', - "Vox Armalis" = 'icons/mob/species/armalis/head.dmi', - ) + flags = HEADCOVERSEYES|STOPPRESSUREDAMAGE + species_restricted = list("Vox") + sprite_sheets = list("Vox" = 'icons/mob/species/vox/head.dmi') /obj/item/clothing/head/helmet/space/vox/pressure name = "alien helmet" @@ -137,22 +131,15 @@ siemens_coefficient = 0 permeability_coefficient = 0.05 item_color = "gloves-vox" - species_restricted = list("Vox","Vox Armalis") - sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/gloves.dmi', - "Vox Armalis" = 'icons/mob/species/armalis/gloves.dmi', - ) + species_restricted = list("Vox") + sprite_sheets = list("Vox" = 'icons/mob/species/vox/gloves.dmi') /obj/item/clothing/shoes/magboots/vox desc = "A pair of heavy, jagged armoured foot pieces, seemingly suitable for a velociraptor." name = "vox magclaws" item_state = "boots-vox" icon_state = "boots-vox" - - species_restricted = list("Vox","Vox Armalis") - sprite_sheets = list( - "Vox Armalis" = 'icons/mob/species/armalis/feet.dmi' - ) + species_restricted = list("Vox") action_button_name = "Toggle the magclaws" diff --git a/code/modules/clothing/spacesuits/captain.dm b/code/modules/clothing/spacesuits/captain.dm index 5ca604b2c0..68a7ea51d9 100644 --- a/code/modules/clothing/spacesuits/captain.dm +++ b/code/modules/clothing/spacesuits/captain.dm @@ -4,7 +4,7 @@ icon_state = "capspace" item_state = "capspacehelmet" desc = "A special helmet designed for work in a hazardous, low-pressure environment. Only for the most fashionable of military figureheads." - flags = HEADCOVERSEYES | BLOCKHAIR | STOPSPRESSUREDMAGE + flags = HEADCOVERSEYES | BLOCKHAIR | STOPPRESSUREDAMAGE flags_inv = HIDEFACE permeability_coefficient = 0.01 armor = list(melee = 65, bullet = 50, laser = 50,energy = 25, bomb = 50, bio = 100, rad = 50) @@ -18,7 +18,7 @@ w_class = 4 gas_transfer_coefficient = 0.01 permeability_coefficient = 0.02 - flags = STOPSPRESSUREDMAGE + flags = STOPPRESSUREDAMAGE body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs) slowdown = 1.5 diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index e22a6044ce..7aec6068b0 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -17,7 +17,7 @@ w_class = 4 gas_transfer_coefficient = 0.01 permeability_coefficient = 0.02 - flags = STOPSPRESSUREDMAGE + flags = STOPPRESSUREDAMAGE body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS allowed = list(/obj/item/weapon/tank/emergency_oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs) slowdown = 1.5 @@ -34,7 +34,7 @@ icon_state = "deathsquad" item_state = "deathsquad" armor = list(melee = 65, bullet = 55, laser = 35,energy = 20, bomb = 30, bio = 100, rad = 60) - flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL + flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPPRESSUREDAMAGE | THICKMATERIAL siemens_coefficient = 0.6 /obj/item/clothing/head/helmet/space/deathsquad/beret @@ -42,7 +42,7 @@ desc = "An armored beret commonly used by special operations officers." icon_state = "beret_badge" armor = list(melee = 65, bullet = 55, laser = 35,energy = 20, bomb = 30, bio = 30, rad = 30) - flags = HEADCOVERSEYES | BLOCKHAIR | STOPSPRESSUREDMAGE + flags = HEADCOVERSEYES | BLOCKHAIR | STOPPRESSUREDAMAGE siemens_coefficient = 0.9 //Space santa outfit suit @@ -50,7 +50,7 @@ name = "Santa's hat" desc = "Ho ho ho. Merrry X-mas!" icon_state = "santahat" - flags = HEADCOVERSEYES | BLOCKHAIR | STOPSPRESSUREDMAGE + flags = HEADCOVERSEYES | BLOCKHAIR | STOPPRESSUREDAMAGE body_parts_covered = HEAD /obj/item/clothing/suit/space/santa @@ -59,10 +59,9 @@ icon_state = "santa" item_state = "santa" slowdown = 0 - flags = ONESIZEFITSALL | STOPSPRESSUREDMAGE + flags = ONESIZEFITSALL | STOPPRESSUREDAMAGE allowed = list(/obj/item) //for stuffing exta special presents - //Space pirate outfit /obj/item/clothing/head/helmet/space/pirate name = "pirate hat" @@ -70,7 +69,7 @@ icon_state = "pirate" item_state = "pirate" armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) - flags = HEADCOVERSEYES | BLOCKHAIR | STOPSPRESSUREDMAGE + flags = HEADCOVERSEYES | BLOCKHAIR | STOPPRESSUREDAMAGE body_parts_covered = 0 siemens_coefficient = 0.9 @@ -86,4 +85,17 @@ siemens_coefficient = 0.9 body_parts_covered = UPPER_TORSO|ARMS +//Orange emergency space suit +/obj/item/clothing/head/helmet/space/emergency + name = "Emergency Space Helmet" + icon_state = "emergencyhelm" + item_state = "emergencyhelm" + desc = "A simple helmet with a built in light, smells like mothballs." + +/obj/item/clothing/suit/space/emergency + name = "Emergency Softsuit" + icon_state = "syndicate-orange" + item_state = "syndicate-orange" + desc = "A thin, ungainly softsuit colored in blaze orange for rescuers to easily locate, looks pretty fragile." + slowdown = 4 diff --git a/code/modules/clothing/spacesuits/rig/modules/combat.dm b/code/modules/clothing/spacesuits/rig/modules/combat.dm index 605bff6be8..a9f7f53f8c 100644 --- a/code/modules/clothing/spacesuits/rig/modules/combat.dm +++ b/code/modules/clothing/spacesuits/rig/modules/combat.dm @@ -85,7 +85,7 @@ desc = "A shoulder-mounted battery-powered laser cannon mount." selectable = 1 usable = 1 - use_power_cost = 10 + module_cooldown = 0 engage_string = "Configure" @@ -151,7 +151,7 @@ selectable = 1 toggleable = 1 use_power_cost = 50 - active_power_cost = 5 + active_power_cost = 10 passive_power_cost = 0 gun_type = /obj/item/weapon/gun/energy/crossbow/ninja diff --git a/code/modules/clothing/spacesuits/rig/modules/computer.dm b/code/modules/clothing/spacesuits/rig/modules/computer.dm index 3d66c64602..a6c549b666 100644 --- a/code/modules/clothing/spacesuits/rig/modules/computer.dm +++ b/code/modules/clothing/spacesuits/rig/modules/computer.dm @@ -441,4 +441,32 @@ drain_loc = null interfaced_with = null - total_power_drained = 0 \ No newline at end of file + total_power_drained = 0 + +/* +//Maybe make this use power when active or something +/obj/item/rig_module/emp_shielding + name = "\improper EMP dissipation module" + desc = "A bewilderingly complex bundle of fiber optics and chips." + toggleable = 1 + usable = 0 + + activate_string = "Enable active EMP shielding" + deactivate_string = "Disable active EMP shielding" + + interface_name = "active EMP shielding system" + interface_desc = "A highly experimental system that augments the hardsuit's existing EM shielding." + var/protection_amount = 20 + +/obj/item/rig_module/emp_shielding/activate() + if(!..()) + return + + holder.emp_protection += protection_amount + +/obj/item/rig_module/emp_shielding/deactivate() + if(!..()) + return + + holder.emp_protection = max(0,(holder.emp_protection - protection_amount)) +*/ diff --git a/code/modules/clothing/spacesuits/rig/modules/modules.dm b/code/modules/clothing/spacesuits/rig/modules/modules.dm index 830e0d784c..17498a31b2 100644 --- a/code/modules/clothing/spacesuits/rig/modules/modules.dm +++ b/code/modules/clothing/spacesuits/rig/modules/modules.dm @@ -138,6 +138,7 @@ if(damage >= 2) usr << "The [interface_name] is damaged beyond use!" + return 0 if(world.time < next_use) usr << "You cannot use the [interface_name] again so soon." @@ -147,7 +148,7 @@ usr << "The suit is not initialized." return 0 - if(usr.lying || usr.stat || usr.stunned || usr.paralysis) + if(usr.lying || usr.stat || usr.stunned || usr.paralysis || usr.weakened) usr << "You cannot use the suit in this state." return 0 @@ -157,7 +158,7 @@ if(holder.security_check_enabled && !holder.check_suit_access(usr)) usr << "Access denied." - return + return 0 if(!holder.check_power_cost(usr, use_power_cost, 0, src, (istype(usr,/mob/living/silicon ? 1 : 0) ) ) ) return 0 diff --git a/code/modules/clothing/spacesuits/rig/modules/rig_weapons.dm b/code/modules/clothing/spacesuits/rig/modules/rig_weapons.dm deleted file mode 100644 index d8373e8bbe..0000000000 --- a/code/modules/clothing/spacesuits/rig/modules/rig_weapons.dm +++ /dev/null @@ -1,51 +0,0 @@ -//Weapon types intended to be used with rig modules - -/obj/item/weapon/gun/energy/lasercannon/mounted/load_into_chamber() - if(in_chamber) - return 1 - var/obj/item/rig_module/module = loc - if(!istype(module)) - return 0 - if(module.holder && module.holder.wearer) - var/mob/living/carbon/human/H = module.holder.wearer - if(istype(H) && H.back) - var/obj/item/weapon/rig/suit = H.back - if(istype(suit) && suit.cell && suit.cell.charge >= 250) - suit.cell.use(250) - in_chamber = new /obj/item/projectile/beam/heavylaser(src) - return 1 - return 0 - -/obj/item/weapon/gun/energy/gun/mounted/load_into_chamber() - if(in_chamber) - return 1 - var/obj/item/rig_module/module = loc - if(!istype(module)) - return 0 - if(module.holder && module.holder.wearer) - var/mob/living/carbon/human/H = module.holder.wearer - if(istype(H) && H.back) - var/obj/item/weapon/rig/suit = H.back - if(istype(suit) && suit.cell && suit.cell.charge >= 250) - suit.cell.use(250) - var/prog_path = text2path(projectile_type) - in_chamber = new prog_path(src) - return 1 - return 0 - -/obj/item/weapon/gun/energy/taser/mounted/load_into_chamber() - if(in_chamber) - return 1 - var/obj/item/rig_module/module = loc - if(!istype(module)) - return 0 - if(module.holder && module.holder.wearer) - var/mob/living/carbon/human/H = module.holder.wearer - if(istype(H) && H.back) - var/obj/item/weapon/rig/suit = H.back - if(istype(suit) && suit.cell && suit.cell.charge >= 250) - suit.cell.use(250) - var/prog_path = text2path(projectile_type) - in_chamber = new prog_path(src) - return 1 - return 0 \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm index 619faa0a7e..b4a622075e 100644 --- a/code/modules/clothing/spacesuits/rig/modules/utility.dm +++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm @@ -131,6 +131,21 @@ var/max_reagent_volume = 80 //Used when refilling. +/obj/item/rig_module/chem_dispenser/ninja + interface_desc = "Dispenses loaded chemicals directly into the wearer's bloodstream. This variant is made to be extremely light and flexible." + + //just over a syringe worth of each. Want more? Go refill. Gives the ninja another reason to have to show their face. + charges = list( + list("tricordrazine", "tricordrazine", 0, 20), + list("tramadol", "tramadol", 0, 20), + list("dexalin plus", "dexalinp", 0, 20), + list("antibiotics", "spaceacillin", 0, 20), + list("antitoxins", "anti_toxin", 0, 20), + list("nutrients", "nutriment", 0, 80), + list("hyronalin", "hyronalin", 0, 20), + list("radium", "radium", 0, 20) + ) + /obj/item/rig_module/chem_dispenser/accepts_item(var/obj/item/input_item, var/mob/living/user) if(!input_item.is_open_container()) @@ -197,8 +212,8 @@ target_mob = H if(target_mob != H) - H << "You inject [target_mob] with [chems_to_use] unit[chems_to_use == 1 ? "" : "s"] of [charge.display_name]." - target_mob << "You feel a rushing in your veins as [chems_to_use] unit[chems_to_use == 1 ? "" : "s"] of [charge.display_name] [chems_to_use == 1 ? "is" : "are"] injected." + H << "You inject [target_mob] with [chems_to_use] unit\s of [charge.display_name]." + target_mob << "You feel a rushing in your veins as [chems_to_use] unit\s of [charge.display_name] [chems_to_use == 1 ? "is" : "are"] injected." target_mob.reagents.add_reagent(charge.display_name, chems_to_use) charge.charges -= chems_to_use @@ -265,10 +280,10 @@ voice_holder.active = 0 usr << "You disable the speech synthesiser." if("Set Name") - var/raw_choice = input(usr, "Please enter a new name.") as text|null + var/raw_choice = sanitize(input(usr, "Please enter a new name.") as text|null) if(!raw_choice) return 0 - voice_holder.voice = sanitize(copytext(raw_choice,1,MAX_MESSAGE_LEN)) + voice_holder.voice = raw_choice usr << "You are now mimicking [voice_holder.voice]." return 1 diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index dad5fa36c9..cd1769f18a 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -12,8 +12,8 @@ icon = 'icons/obj/rig_modules.dmi' desc = "A back-mounted hardsuit deployment and control mechanism." slot_flags = SLOT_BACK - req_one_access = null - req_access = null + req_one_access = list() + req_access = list() w_class = 4 // These values are passed on to all component pieces. @@ -68,10 +68,12 @@ var/sealing // Keeps track of seal status independantly of canremove. var/offline = 1 // Should we be applying suit maluses? - var/offline_slowdown = 10 // If the suit is deployed and unpowered, it sets slowdown to this. + var/offline_slowdown = 3 // If the suit is deployed and unpowered, it sets slowdown to this. var/vision_restriction var/offline_vision_restriction = 1 // 0 - none, 1 - welder vision, 2 - blind. Maybe move this to helmets. + var/emp_protection = 0 + // Wiring! How exciting. var/datum/wires/rig/wires var/datum/effect/effect/system/spark_spread/spark_system @@ -175,7 +177,7 @@ for(var/obj/item/piece in list(helmet,boots,gloves,chest)) if(!piece) continue piece.icon_state = "[initial(icon_state)]" - piece.flags &= ~STOPSPRESSUREDMAGE + piece.flags &= ~STOPPRESSUREDAMAGE piece.flags &= ~AIRTIGHT update_icon(1) @@ -291,10 +293,10 @@ for(var/obj/item/piece in list(helmet,boots,gloves,chest)) if(!piece) continue if(canremove) - piece.flags &= ~STOPSPRESSUREDMAGE + piece.flags &= ~STOPPRESSUREDAMAGE piece.flags &= ~AIRTIGHT else - piece.flags |= STOPSPRESSUREDMAGE + piece.flags |= STOPPRESSUREDAMAGE piece.flags |= AIRTIGHT update_icon(1) @@ -311,7 +313,7 @@ if(!istype(wearer) || loc != wearer || wearer.back != src || canremove || !cell || cell.charge <= 0) if(!cell || cell.charge <= 0) - if(electrified >0) + if(electrified > 0) electrified = 0 if(!offline) if(istype(wearer)) @@ -319,7 +321,7 @@ if (offline_slowdown < 3) wearer << "Your suit beeps stridently, and suddenly goes dead." else - wearer << "Your suit beeps stridently, and suddenly you're wearing a leaden mass of metal and plastic instead of a powered suit." + wearer << "Your suit beeps stridently, and suddenly you're wearing a leaden mass of metal and plastic composites instead of a powered suit." if(offline_vision_restriction == 1) wearer << "The suit optics flicker and die, leaving you with restricted vision." else if(offline_vision_restriction == 2) @@ -406,7 +408,7 @@ data["boots"] = (boots ? "[boots.name]" : "None.") data["chest"] = (chest ? "[chest.name]" : "None.") - data["charge"] = cell ? cell.charge : 0 + data["charge"] = cell ? round(cell.charge,1) : 0 data["maxcharge"] = cell ? cell.maxcharge : 0 data["chargestatus"] = cell ? Floor((cell.charge/cell.maxcharge)*50) : 0 @@ -416,7 +418,7 @@ data["aicontrol"] = control_overridden data["aioverride"] = ai_override_enabled data["securitycheck"] = security_check_enabled - data["malf"] = malfunctioning + data["malf"] = malfunction_delay var/list/module_list = list() @@ -493,6 +495,8 @@ return 1 if(istype(user)) + if(malfunction_check(user)) + return 0 if(user.back != src) return 0 if(locked_dna) @@ -509,10 +513,10 @@ return 1 +//TODO: Fix Topic vulnerabilities for malfunction and AI override. /obj/item/weapon/rig/Topic(href,href_list) - if(!check_suit_access(usr)) - return + return 0 if(href_list["toggle_piece"]) if(ishuman(usr) && (usr.stat || usr.stunned || usr.lying)) @@ -545,7 +549,7 @@ usr.set_machine(src) src.add_fingerprint(usr) - return 1 + return 0 /obj/item/weapon/rig/proc/notify_ai(var/message) if(!message || !installed_modules || !installed_modules.len) @@ -687,46 +691,80 @@ return 0 /obj/item/weapon/rig/emp_act(severity_class) - //class 1 severity is the most severe, not least. - malfunctioning += round(30/severity_class) - if(malfunction_delay <= 0) - malfunction_delay = 20 - take_hit(round(30/severity_class),"electrical pulse") + //set malfunctioning + if(emp_protection < 30) //for ninjas, really. + malfunctioning += 10 + if(malfunction_delay <= 0) + malfunction_delay = max(malfunction_delay, round(30/severity_class)) + + //drain some charge + if(cell) cell.emp_act(severity_class + 15) + + //possibly damage some modules + take_hit((100/severity_class), "electrical pulse", 1) /obj/item/weapon/rig/proc/shock(mob/user) if (electrocute_mob(user, cell, src)) spark_system.start() - return 1 + if(user.stunned) + return 1 return 0 -/obj/item/weapon/rig/proc/take_hit(damage,source) +/obj/item/weapon/rig/proc/take_hit(damage, source, is_emp=0) + if(!installed_modules.len) return - //given that module damage is spread out across all modules, even this is probably not enough for emp to affect rigs much. - if(source != "electrical pulse") - var/protection = chest? chest.breach_threshold : 0 - if(!prob(max(0, damage - protection))) - return + var/chance + if(!is_emp) + chance = 2*max(0, damage - (chest? chest.breach_threshold : 0)) + else + //Want this to be roughly independant of the number of modules, meaning that X emp hits will disable Y% of the suit's modules on average. + //that way people designing hardsuits don't have to worry (as much) about how adding that extra module will affect emp resiliance by 'soaking' hits for other modules + chance = 2*max(0, damage - emp_protection)*min(installed_modules.len/15, 1) + if(!prob(chance)) + return + + //deal addition damage to already damaged module first. + //This way the chances of a module being disabled aren't so remote. var/list/valid_modules = list() + var/list/damaged_modules = list() for(var/obj/item/rig_module/module in installed_modules) if(module.damage < 2) valid_modules |= module + if(module.damage > 0) + damaged_modules |= module - if(!valid_modules.len) - return + var/obj/item/rig_module/dam_module = null + if(damaged_modules.len) + dam_module = pick(damaged_modules) + else if(valid_modules.len) + dam_module = pick(valid_modules) + + if(!dam_module) return - var/obj/item/rig_module/dam_module = pick(valid_modules) dam_module.damage++ if(!source) source = "hit" if(wearer) - wearer << "The [source] has [dam_module.damage >= 2 ? "destroyed" : "damaged"] your [dam_module.interface_name]!" + if(dam_module.damage >= 2) + wearer << "The [source] has disabled your [dam_module.interface_name]!" + else + wearer << "The [source] has damaged your [dam_module.interface_name]!" dam_module.deactivate() +/obj/item/weapon/rig/proc/malfunction_check(var/mob/living/carbon/human/user) + if(malfunction_delay) + if(offline) + user << "The suit is completely unresponsive." + else + user << "ERROR: Hardware fault. Rebooting interface..." + return 1 + return 0 + /*/obj/item/weapon/rig/proc/forced_move(dir) if(locked_down) return 0 @@ -738,4 +776,4 @@ #undef ONLY_DEPLOY #undef ONLY_RETRACT -#undef SEAL_DELAY \ No newline at end of file +#undef SEAL_DELAY diff --git a/code/modules/clothing/spacesuits/rig/rig_attackby.dm b/code/modules/clothing/spacesuits/rig/rig_attackby.dm index c0d119b0b4..e7a59ea305 100644 --- a/code/modules/clothing/spacesuits/rig/rig_attackby.dm +++ b/code/modules/clothing/spacesuits/rig/rig_attackby.dm @@ -21,8 +21,8 @@ return else if(istype(W, /obj/item/weapon/card/emag)) locked_dna = null - req_access = null - req_one_access = null + req_access.Cut() + req_one_access.Cut() locked = 0 subverted = 1 user << "You short out the access protocol for the suit." diff --git a/code/modules/clothing/spacesuits/rig/rig_pieces.dm b/code/modules/clothing/spacesuits/rig/rig_pieces.dm index 6a0d7012f9..294644f3cb 100644 --- a/code/modules/clothing/spacesuits/rig/rig_pieces.dm +++ b/code/modules/clothing/spacesuits/rig/rig_pieces.dm @@ -10,6 +10,7 @@ heat_protection = HEAD|FACE|EYES cold_protection = HEAD|FACE|EYES brightness_on = 4 + sprite_sheets = list("Tajara" = 'icons/mob/species/tajaran/helmet.dmi',"Skrell" = 'icons/mob/species/skrell/helmet.dmi',"Unathi" = 'icons/mob/species/unathi/helmet.dmi') species_restricted = null /obj/item/clothing/gloves/rig @@ -36,12 +37,13 @@ heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS cold_protection = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS flags_inv = HIDEJUMPSUIT|HIDETAIL - flags = STOPSPRESSUREDMAGE | THICKMATERIAL | AIRTIGHT + flags = STOPPRESSUREDAMAGE | THICKMATERIAL | AIRTIGHT slowdown = 0 - //With 0.2 resiliance, will reach 10 breach damage after 9 laser carbine blasts. Completely immune to smg hits. - breach_threshold = 28 - resilience = 0.1 + //will reach 10 breach damage after 25 laser carbine blasts, 3 revolver hits, or ~1 PTR hit. Completely immune to smg or sts hits. + breach_threshold = 38 + resilience = 0.2 can_breach = 1 + sprite_sheets = list("Tajara" = 'icons/mob/species/tajaran/suit.dmi',"Unathi" = 'icons/mob/species/unathi/suit.dmi') supporting_limbs = list() //TODO: move this to modules @@ -66,4 +68,4 @@ if(module.engage(A)) return 1 - return 0 \ No newline at end of file + return 0 diff --git a/code/modules/clothing/spacesuits/rig/rig_verbs.dm b/code/modules/clothing/spacesuits/rig/rig_verbs.dm index ce20244734..09db9b0325 100644 --- a/code/modules/clothing/spacesuits/rig/rig_verbs.dm +++ b/code/modules/clothing/spacesuits/rig/rig_verbs.dm @@ -141,6 +141,9 @@ set category = "Hardsuit" set src = usr.contents + if(malfunction_check(usr)) + return + if(!check_power_cost(usr, 0, 0, 0, 0)) return @@ -168,6 +171,9 @@ set category = "Hardsuit" set src = usr.contents + if(malfunction_check(usr)) + return + if(canremove) usr << "The suit is not active." return @@ -189,6 +195,9 @@ set category = "Hardsuit" set src = usr.contents + if(malfunction_check(usr)) + return + if(!check_power_cost(usr, 0, 0, 0, 0)) return @@ -222,6 +231,9 @@ set category = "Hardsuit" set src = usr.contents + if(malfunction_check(usr)) + return + if(!check_power_cost(usr, 0, 0, 0, 0)) return @@ -257,6 +269,9 @@ set category = "Hardsuit" set src = usr.contents + if(malfunction_check(usr)) + return + if(canremove) usr << "The suit is not active." return diff --git a/code/modules/clothing/spacesuits/rig/suits/alien.dm b/code/modules/clothing/spacesuits/rig/suits/alien.dm index 5b35d6a139..cb64d2be44 100644 --- a/code/modules/clothing/spacesuits/rig/suits/alien.dm +++ b/code/modules/clothing/spacesuits/rig/suits/alien.dm @@ -4,6 +4,7 @@ suit_type = "NT breacher" icon_state = "breacher_rig_cheap" armor = list(melee = 60, bullet = 60, laser = 60, energy = 60, bomb = 70, bio = 100, rad = 50) + emp_protection = -20 slowdown = 6 offline_slowdown = 10 vision_restriction = 1 @@ -16,4 +17,4 @@ icon_state = "breacher_rig" armor = list(melee = 90, bullet = 90, laser = 90, energy = 90, bomb = 90, bio = 100, rad = 80) vision_restriction = 0 - slowdown = 4 \ No newline at end of file + slowdown = 4 diff --git a/code/modules/clothing/spacesuits/rig/suits/combat.dm b/code/modules/clothing/spacesuits/rig/suits/combat.dm index 55716179c6..9be2576838 100644 --- a/code/modules/clothing/spacesuits/rig/suits/combat.dm +++ b/code/modules/clothing/spacesuits/rig/suits/combat.dm @@ -8,7 +8,6 @@ suit_type = "combat hardsuit" armor = list(melee = 80, bullet = 65, laser = 50, energy = 15, bomb = 80, bio = 100, rad = 60) slowdown = 1 - offline_slowdown = 3 offline_vision_restriction = 1 helm_type = /obj/item/clothing/head/helmet/space/rig/combat diff --git a/code/modules/clothing/spacesuits/rig/suits/ert.dm b/code/modules/clothing/spacesuits/rig/suits/ert.dm index d3db4baf84..feec1f5810 100644 --- a/code/modules/clothing/spacesuits/rig/suits/ert.dm +++ b/code/modules/clothing/spacesuits/rig/suits/ert.dm @@ -7,13 +7,12 @@ desc = "A suit worn by the commander of a NanoTrasen Emergency Response Team. Has blue highlights. Armoured and space ready." suit_type = "ERT commander" icon_state = "ert_commander_rig" - offline_slowdown = 3 helm_type = /obj/item/clothing/head/helmet/space/rig/ert req_access = list(access_cent_specops) - armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100) + armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 60) allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/crowbar, \ /obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/device/multitool, \ /obj/item/device/radio, /obj/item/device/analyzer, /obj/item/weapon/gun/energy/laser, /obj/item/weapon/gun/energy/pulse_rifle, \ @@ -30,6 +29,9 @@ desc = "A suit worn by the engineering division of a NanoTrasen Emergency Response Team. Has orange highlights. Armoured and space ready." suit_type = "ERT engineer" icon_state = "ert_engineer_rig" + armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100) + + glove_type = /obj/item/clothing/gloves/rig/ert_engineer initial_modules = list( /obj/item/rig_module/ai_container, @@ -38,6 +40,10 @@ /obj/item/rig_module/device/rcd ) +/obj/item/clothing/gloves/rig/ert_engineer + name = "insulated gauntlets" + siemens_coefficient = 0 + /obj/item/weapon/rig/ert/medical name = "ERT-M suit control module" desc = "A suit worn by the medical division of a NanoTrasen Emergency Response Team. Has white highlights. Armoured and space ready." diff --git a/code/modules/clothing/spacesuits/rig/suits/light.dm b/code/modules/clothing/spacesuits/rig/suits/light.dm index c20371071b..edff43d810 100644 --- a/code/modules/clothing/spacesuits/rig/suits/light.dm +++ b/code/modules/clothing/spacesuits/rig/suits/light.dm @@ -6,8 +6,9 @@ suit_type = "light suit" allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/cell) armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0) + emp_protection = 10 slowdown = 0 - flags = STOPSPRESSUREDMAGE | THICKMATERIAL + flags = STOPPRESSUREDAMAGE | THICKMATERIAL offline_slowdown = 0 offline_vision_restriction = 0 @@ -18,6 +19,7 @@ /obj/item/clothing/suit/space/rig/light name = "suit" + breach_threshold = 18 //comparable to voidsuits /obj/item/clothing/gloves/rig/light name = "gloves" @@ -53,9 +55,12 @@ suit_type = "ominous" desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins." icon_state = "ninja_rig" - armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) + armor = list(melee = 50, bullet = 15, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 30) + emp_protection = 40 //change this to 30 if too high. slowdown = 0 + chest_type = /obj/item/clothing/suit/space/rig/light/ninja + req_access = list(access_syndicate) initial_modules = list( @@ -75,6 +80,9 @@ ..() +/obj/item/clothing/suit/space/rig/light/ninja + breach_threshold = 38 //comparable to regular hardsuits + /obj/item/weapon/rig/light/stealth name = "stealth suit control module" suit_type = "stealth" @@ -84,7 +92,6 @@ req_access = list(access_syndicate) initial_modules = list( - /obj/item/rig_module/teleporter, /obj/item/rig_module/stealth_field, /obj/item/rig_module/vision - ) \ No newline at end of file + ) diff --git a/code/modules/clothing/spacesuits/rig/suits/merc.dm b/code/modules/clothing/spacesuits/rig/suits/merc.dm index 7a0d95a4bd..8e7b70d5f2 100644 --- a/code/modules/clothing/spacesuits/rig/suits/merc.dm +++ b/code/modules/clothing/spacesuits/rig/suits/merc.dm @@ -9,7 +9,6 @@ suit_type = "crimson hardsuit" armor = list(melee = 80, bullet = 65, laser = 50, energy = 15, bomb = 80, bio = 100, rad = 60) slowdown = 1 - offline_slowdown = 3 offline_vision_restriction = 1 helm_type = /obj/item/clothing/head/helmet/space/rig/merc @@ -24,4 +23,11 @@ /obj/item/rig_module/electrowarfare_suite, /obj/item/rig_module/chem_dispenser/combat, /obj/item/rig_module/fabricator/energy_net + ) + +//Has most of the modules removed +/obj/item/weapon/rig/merc/empty + initial_modules = list( + /obj/item/rig_module/ai_container, + /obj/item/rig_module/electrowarfare_suite, //might as well ) \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/rig/suits/station.dm b/code/modules/clothing/spacesuits/rig/suits/station.dm index 44959068eb..2723a57360 100644 --- a/code/modules/clothing/spacesuits/rig/suits/station.dm +++ b/code/modules/clothing/spacesuits/rig/suits/station.dm @@ -7,11 +7,12 @@ slowdown = 3 offline_slowdown = 10 offline_vision_restriction = 2 + emp_protection = -20 allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd) - req_access = null - req_one_access = null + req_access = list() + req_one_access = list() initial_modules = list( /obj/item/rig_module/device/plasmacutter, @@ -56,7 +57,6 @@ icon_state = "science_rig" armor = list(melee = 15, bullet = 15, laser = 80, energy = 80, bomb = 60, bio = 100, rad = 100) slowdown = 1 - offline_slowdown = 3 offline_vision_restriction = 1 helm_type = /obj/item/clothing/head/helmet/space/rig/ert @@ -79,13 +79,12 @@ icon_state = "medical_rig" armor = list(melee = 30, bullet = 15, laser = 20, energy = 60, bomb = 30, bio = 100, rad = 100) slowdown = 1 - offline_slowdown = 3 offline_vision_restriction = 1 allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical,/obj/item/roller ) - req_access = null - req_one_access = null + req_access = list() + req_one_access = list() initial_modules = list( /obj/item/rig_module/chem_dispenser/injector, @@ -100,13 +99,12 @@ icon_state = "hazard_rig" armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10) slowdown = 1 - offline_slowdown = 3 offline_vision_restriction = 1 helm_type = /obj/item/clothing/head/helmet/space/rig/ert allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton) - req_access = null - req_one_access = null + req_access = list() + req_one_access = list() diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index 605a40a1b6..7bf622b539 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -6,7 +6,7 @@ name = "Space helmet" icon_state = "space" desc = "A special helmet designed for work in a hazardous, low-pressure environment." - flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL | AIRTIGHT + flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPPRESSUREDAMAGE | THICKMATERIAL | AIRTIGHT item_state = "space" permeability_coefficient = 0.01 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50) @@ -32,8 +32,7 @@ icon_action_button = "[icon_state]" camera = new /obj/machinery/camera(src) - camera.network = camera_networks - cameranet.removeCamera(camera) + camera.replace_networks(camera_networks) camera.c_tag = user.name user << "\blue User scanned as [camera.c_tag]. Camera activated." return 1 @@ -53,7 +52,7 @@ w_class = 4//bulky item gas_transfer_coefficient = 0.01 permeability_coefficient = 0.02 - flags = STOPSPRESSUREDMAGE | THICKMATERIAL + flags = STOPPRESSUREDAMAGE | THICKMATERIAL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/device/suit_cooling_unit) slowdown = 3 @@ -91,4 +90,4 @@ for(var/datum/organ/external/E in supporting_limbs) E.status &= ~ ORGAN_SPLINTED user << "The suit stops supporting your [E.display_name]." - supporting_limbs = list() \ No newline at end of file + supporting_limbs = list() diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 9be723a72f..6ff7b25f47 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -22,7 +22,7 @@ /obj/item/clothing/suit/armor/vest/security name = "security armor" - desc = "An armored vest that protects against some damage. This one has NanoTrasen corporate badge." + desc = "An armored vest that protects against some damage. This one has a NanoTrasen corporate badge." icon_state = "armorsec" item_state = "armor" @@ -71,7 +71,7 @@ item_state = "swat_suit" gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 - flags = STOPSPRESSUREDMAGE | THICKMATERIAL + flags = STOPPRESSUREDAMAGE | THICKMATERIAL body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank/emergency_oxygen) slowdown = 1 @@ -139,6 +139,171 @@ src.item_state = "reactiveoff" ..() +/obj/item/clothing/suit/armor/tactical + name = "tactical armor" + desc = "A suit of armor most often used by Special Weapons and Tactics squads. Includes padded vest with pockets along with shoulder and kneeguards." + icon_state = "swatarmor" + item_state = "armor" + var/obj/item/weapon/gun/holstered = null + body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS + slowdown = 1 + armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 20, bio = 0, rad = 0) + siemens_coefficient = 0.7 + var/obj/item/clothing/accessory/holster/holster + +/obj/item/clothing/suit/armor/tactical/New() + ..() + holster = new(src) + +/obj/item/clothing/suit/armor/tactical/attackby(obj/item/W as obj, mob/user as mob) + ..() + holster.attackby(W, user) + +/obj/item/clothing/suit/armor/tactical/verb/holster() + set name = "Holster" + set category = "Object" + set src in usr + if(!istype(usr, /mob/living)) return + if(usr.stat) return + + if(!holster.holstered) + var/obj/item/W = usr.get_active_hand() + if(!istype(W, /obj/item)) + usr << "You need your gun equiped to holster it." + return + holster.holster(W, usr) + else + holster.unholster(usr) + +//Non-hardsuit ERT armor. +/obj/item/clothing/suit/armor/vest/ert + name = "emergency response team armor" + desc = "A set of armor worn by members of the NanoTrasen Emergency Response Team." + icon_state = "ertarmor_cmd" + item_state = "armor" + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 20, bio = 0, rad = 0) + +//Commander +/obj/item/clothing/suit/armor/vest/ert/command + name = "emergency response team commander armor" + desc = "A set of armor worn by the commander of a NanoTrasen Emergency Response Team. Has blue highlights." + +//Security +/obj/item/clothing/suit/armor/vest/ert/security + name = "emergency response team security armor" + desc = "A set of armor worn by security members of the NanoTrasen Emergency Response Team. Has red highlights." + icon_state = "ertarmor_sec" + +//Engineer +/obj/item/clothing/suit/armor/vest/ert/engineer + name = "emergency response team engineer armor" + desc = "A set of armor worn by engineering members of the NanoTrasen Emergency Response Team. Has orange highlights." + icon_state = "ertarmor_eng" + +//Medical +/obj/item/clothing/suit/armor/vest/ert/medical + name = "emergency response team medical armor" + desc = "A set of armor worn by medical members of the NanoTrasen Emergency Response Team. Has red and white highlights." + icon_state = "ertarmor_med" + +//New Vests +/obj/item/clothing/suit/storage/vest + name = "armor vest" + desc = "A simple kevlar plate carrier." + icon_state = "kvest" + item_state = "kvest" + armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0) + allowed = list(/obj/item/weapon/gun,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs) + +/obj/item/clothing/suit/storage/vest/officer + name = "officer armor vest" + desc = "A simple kevlar plate carrier belonging to Nanotrasen. This one has a security holobadge clipped to the chest." + icon_state = "officervest_nobadge" + item_state = "officervest_nobadge" + icon_badge = "officervest_badge" + icon_nobadge = "officervest_nobadge" + +/obj/item/clothing/suit/storage/vest/warden + name = "warden armor vest" + desc = "A simple kevlar plate carrier belonging to Nanotrasen. This one has a silver badge clipped to the chest." + icon_state = "wardenvest_nobadge" + item_state = "wardenvest_nobadge" + icon_badge = "wardenvest_badge" + icon_nobadge = "wardenvest_nobadge" + +/obj/item/clothing/suit/storage/vest/hos + name = "commander armor vest" + desc = "A simple kevlar plate carrier belonging to Nanotrasen. This one has a gold badge clipped to the chest." + icon_state = "hosvest_nobadge" + item_state = "hosvest_nobadge" + icon_badge = "hosvest_badge" + icon_nobadge = "hosvest_nobadge" + +/obj/item/clothing/suit/storage/vest/pcrc + name = "PCRC armor vest" + desc = "A simple kevlar plate carrier belonging to Proxima Centauri Risk Control. This one has a PCRC crest clipped to the chest." + icon_state = "pcrcvest_nobadge" + item_state = "pcrcvest_nobadge" + icon_badge = "pcrcvest_badge" + icon_nobadge = "pcrcvest_nobadge" + +/obj/item/clothing/suit/storage/vest/detective + name = "detective armor vest" + desc = "A simple kevlar plate carrier in a vintage brown, it has a badge clipped to the chest that reads, 'Private investigator'." + icon_state = "detectivevest_nobadge" + item_state = "detectivevest_nobadge" + icon_badge = "detectivevest_badge" + icon_nobadge = "detectivevest_nobadge" + +/obj/item/clothing/suit/storage/vest/heavy + name = "heavy armor vest" + desc = "A heavy kevlar plate carrier with webbing attached." + icon_state = "webvest" + item_state = "webvest" + armor = list(melee = 50, bullet = 40, laser = 50, energy = 25, bomb = 30, bio = 0, rad = 0) + slowdown = 1 + +/obj/item/clothing/suit/storage/vest/heavy/officer + name = "officer heavy armor vest" + desc = "A heavy kevlar plate carrier belonging to Nanotrasen with webbing attached. This one has a security holobadge clipped to the chest." + icon_state = "officerwebvest_nobadge" + item_state = "officerwebvest_nobadge" + icon_badge = "officerwebvest_badge" + icon_nobadge = "officerwebvest_nobadge" + +/obj/item/clothing/suit/storage/vest/heavy/warden + name = "warden heavy armor vest" + desc = "A heavy kevlar plate carrier belonging to Nanotrasen with webbing attached. This one has a silver badge clipped to the chest." + icon_state = "wardenwebvest_nobadge" + item_state = "wardenwebvest_nobadge" + icon_badge = "wardenwebvest_badge" + icon_nobadge = "wardenwebvest_nobadge" + +/obj/item/clothing/suit/storage/vest/heavy/hos + name = "commander heavy armor vest" + desc = "A heavy kevlar plate carrier belonging to Nanotrasen with webbing attached. This one has a gold badge clipped to the chest." + icon_state = "hoswebvest_nobadge" + item_state = "hoswebvest_nobadge" + icon_badge = "hoswebvest_badge" + icon_nobadge = "hoswebvest_nobadge" + +/obj/item/clothing/suit/storage/vest/heavy/pcrc + name = "PCRC heavy armor vest" + desc = "A heavy kevlar plate carrier belonging to Proxima Centauri Risk Control with webbing attached. This one has a PCRC crest clipped to the chest." + icon_state = "pcrcwebvest_nobadge" + item_state = "pcrcwebvest_nobadge" + icon_badge = "pcrcwebvest_badge" + icon_nobadge = "pcrcwebvest_nobadge" + +//Provides the protection of a merc voidsuit, but only covers the chest/groin, and also takes up a suit slot. In exchange it has no slowdown and provides storage. +/obj/item/clothing/suit/storage/vest/heavy/merc + name = "heavy armor vest" + desc = "A high-quality heavy kevlar plate carrier in a fetching tan. The vest is surprisingly flexible, and possibly made of an advanced material." + icon_state = "mercwebvest" + item_state = "mercwebvest" + armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 40, bio = 0, rad = 0) + slowdown = 0 //All of the armor below is mostly unused @@ -185,77 +350,3 @@ icon_state = "tdgreen" item_state = "tdgreen" siemens_coefficient = 1 - -/obj/item/clothing/suit/armor/tactical - name = "tactical armor" - desc = "A suit of armor most often used by Special Weapons and Tactics squads. Includes padded vest with pockets along with shoulder and kneeguards." - icon_state = "swatarmor" - item_state = "armor" - var/obj/item/weapon/gun/holstered = null - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS - slowdown = 1 - armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 20, bio = 0, rad = 0) - siemens_coefficient = 0.7 - - /obj/item/clothing/suit/armor/tactical/verb/holster() - set name = "Holster" - set category = "Object" - set src in usr - if(!istype(usr, /mob/living)) return - if(usr.stat) return - - if(!holstered) - if(!istype(usr.get_active_hand(), /obj/item/weapon/gun)) - usr << "\blue You need your gun equiped to holster it." - return - var/obj/item/weapon/gun/W = usr.get_active_hand() - if (!W.isHandgun()) - usr << "\red This gun won't fit in \the belt!" - return - holstered = usr.get_active_hand() - usr.drop_item() - holstered.loc = src - usr.visible_message("\blue \The [usr] holsters \the [holstered].", "You holster \the [holstered].") - else - if(istype(usr.get_active_hand(),/obj) && istype(usr.get_inactive_hand(),/obj)) - usr << "\red You need an empty hand to draw the gun!" - else - if(usr.a_intent == "hurt") - usr.visible_message("\red \The [usr] draws \the [holstered], ready to shoot!", \ - "\red You draw \the [holstered], ready to shoot!") - else - usr.visible_message("\blue \The [usr] draws \the [holstered], pointing it at the ground.", \ - "\blue You draw \the [holstered], pointing it at the ground.") - usr.put_in_hands(holstered) - holstered = null - -//Non-hardsuit ERT armor. -/obj/item/clothing/suit/armor/vest/ert - name = "emergency response team armor" - desc = "A set of armor worn by members of the NanoTrasen Emergency Response Team." - icon_state = "ertarmor_cmd" - item_state = "armor" - armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 20, bio = 0, rad = 0) - -//Commander -/obj/item/clothing/suit/armor/vest/ert/command - name = "emergency response team commander armor" - desc = "A set of armor worn by the commander of a NanoTrasen Emergency Response Team. Has blue highlights." - -//Security -/obj/item/clothing/suit/armor/vest/ert/security - name = "emergency response team security armor" - desc = "A set of armor worn by security members of the NanoTrasen Emergency Response Team. Has red highlights." - icon_state = "ertarmor_sec" - -//Engineer -/obj/item/clothing/suit/armor/vest/ert/engineer - name = "emergency response team engineer armor" - desc = "A set of armor worn by engineering members of the NanoTrasen Emergency Response Team. Has orange highlights." - icon_state = "ertarmor_eng" - -//Medical -/obj/item/clothing/suit/armor/vest/ert/medical - name = "emergency response team medical armor" - desc = "A set of armor worn by medical members of the NanoTrasen Emergency Response Team. Has red and white highlights." - icon_state = "ertarmor_med" \ No newline at end of file diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index a861930f73..bcca81141c 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -15,7 +15,7 @@ item_state = "bluetag" blood_overlay_type = "armor" body_parts_covered = UPPER_TORSO - allowed = list (/obj/item/weapon/gun/energy/laser/bluetag) + allowed = list (/obj/item/weapon/gun/energy/lasertag/blue) siemens_coefficient = 3.0 /obj/item/clothing/suit/redtag @@ -25,7 +25,7 @@ item_state = "redtag" blood_overlay_type = "armor" body_parts_covered = UPPER_TORSO - allowed = list (/obj/item/weapon/gun/energy/laser/redtag) + allowed = list (/obj/item/weapon/gun/energy/lasertag/red) siemens_coefficient = 3.0 /* @@ -346,11 +346,13 @@ icon_state = "blueponcho" item_state = "blueponcho" -/obj/item/clothing/suit/storage/bomber +/obj/item/clothing/suit/storage/toggle/bomber name = "bomber jacket" desc = "A thick, well-worn WW2 leather bomber jacket." icon_state = "bomber" item_state = "bomber" + icon_open = "bomber_open" + icon_closed = "bomber" body_parts_covered = UPPER_TORSO|ARMS cold_protection = UPPER_TORSO|ARMS min_cold_protection_temperature = T0C - 20 @@ -383,10 +385,20 @@ icon_open = "brown_jacket_nt_open" icon_closed = "brown_jacket_nt" -/obj/item/clothing/suit/hoodie +/obj/item/clothing/suit/storage/toggle/hoodie name = "grey hoodie" desc = "A warm, grey sweatshirt." icon_state = "grey_hoodie" item_state = "grey_hoodie" + icon_open = "grey_hoodie_open" + icon_closed = "grey_hoodie" min_cold_protection_temperature = T0C - 20 cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS + +/obj/item/clothing/suit/storage/toggle/hoodie/black + name = "black hoodie" + desc = "A warm, black sweatshirt." + icon_state = "black_hoodie" + item_state = "black_hoodie" + icon_open = "black_hoodie_open" + icon_closed = "black_hoodie" \ No newline at end of file diff --git a/code/modules/clothing/suits/storage.dm b/code/modules/clothing/suits/storage.dm index f34c9f00c3..692e2987f5 100644 --- a/code/modules/clothing/suits/storage.dm +++ b/code/modules/clothing/suits/storage.dm @@ -6,7 +6,7 @@ pockets = new/obj/item/weapon/storage/internal(src) pockets.storage_slots = 2 //two slots pockets.max_w_class = 2 //fit only pocket sized items - pockets.max_combined_w_class = 4 + pockets.max_storage_space = 4 /obj/item/clothing/suit/storage/attack_hand(mob/user as mob) if (pockets.handle_attack_hand(user)) @@ -48,4 +48,36 @@ else //in case some goofy admin switches icon states around without switching the icon_open or icon_closed usr << "You attempt to button-up the velcro on your [src], before promptly realising how silly you are." return - update_clothing_icon() //so our overlays update \ No newline at end of file + update_clothing_icon() //so our overlays update + + +//New Vest 4 pocket storage and badge toggles, until suit accessories are a thing. +/obj/item/clothing/suit/storage/vest/heavy/New() + ..() + pockets = new/obj/item/weapon/storage/internal(src) + pockets.storage_slots = 4 + pockets.max_w_class = 2 + pockets.max_storage_space = 8 + + +/obj/item/clothing/suit/storage/vest + var/icon_badge + var/icon_nobadge + verb/toggle() + set name ="Adjust Badge" + set category = "Object" + set src in usr + if(!usr.canmove || usr.stat || usr.restrained()) + return 0 + + if(icon_state == icon_badge) + icon_state = icon_nobadge + usr << "You unclip the badge from the vest." + else if(icon_state == icon_nobadge) + icon_state = icon_badge + usr << "You clip the badge to the vest." + else + usr << "You can't find a badge for [src]." + return + update_clothing_icon() + diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index d0138b283b..c0cdd91ecd 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -21,7 +21,7 @@ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/extinguisher) slowdown = 1.0 flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL - flags = STOPSPRESSUREDMAGE + flags = STOPPRESSUREDAMAGE heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm new file mode 100644 index 0000000000..f606c84670 --- /dev/null +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -0,0 +1,226 @@ +/obj/item/clothing/accessory + name = "tie" + desc = "A neosilk clip-on tie." + icon = 'icons/obj/clothing/ties.dmi' + icon_state = "bluetie" + item_state = "" //no inhands + item_color = "bluetie" + slot_flags = SLOT_TIE + w_class = 2.0 + var/slot = "decor" + var/obj/item/clothing/under/has_suit = null //the suit the tie may be attached to + var/image/inv_overlay = null //overlay used when attached to clothing. + +/obj/item/clothing/accessory/New() + ..() + inv_overlay = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[item_color? "[item_color]" : "[icon_state]"]") + +//when user attached an accessory to S +/obj/item/clothing/accessory/proc/on_attached(obj/item/clothing/under/S, mob/user as mob) + if(!istype(S)) + return + has_suit = S + loc = has_suit + has_suit.overlays += inv_overlay + + user << "You attach [src] to [has_suit]." + src.add_fingerprint(user) + +/obj/item/clothing/accessory/proc/on_removed(mob/user as mob) + if(!has_suit) + return + has_suit.overlays -= inv_overlay + has_suit = null + usr.put_in_hands(src) + src.add_fingerprint(user) + +//default attackby behaviour +/obj/item/clothing/accessory/attackby(obj/item/I, mob/user) + ..() + +//default attack_hand behaviour +/obj/item/clothing/accessory/attack_hand(mob/user as mob) + if(has_suit) + return //we aren't an object on the ground so don't call parent + ..() + +/obj/item/clothing/accessory/blue + name = "blue tie" + icon_state = "bluetie" + item_color = "bluetie" + +/obj/item/clothing/accessory/red + name = "red tie" + icon_state = "redtie" + item_color = "redtie" + +/obj/item/clothing/accessory/horrible + name = "horrible tie" + desc = "A neosilk clip-on tie. This one is disgusting." + icon_state = "horribletie" + item_color = "horribletie" + +/obj/item/clothing/accessory/stethoscope + name = "stethoscope" + desc = "An outdated medical apparatus for listening to the sounds of the human body. It also makes you look like you know what you're doing." + icon_state = "stethoscope" + item_color = "stethoscope" + +/obj/item/clothing/accessory/stethoscope/attack(mob/living/carbon/human/M, mob/living/user) + if(ishuman(M) && isliving(user)) + if(user.a_intent == I_HELP) + var/body_part = parse_zone(user.zone_sel.selecting) + if(body_part) + var/their = "their" + switch(M.gender) + if(MALE) their = "his" + if(FEMALE) their = "her" + + var/sound = "pulse" + var/sound_strength + + if(M.stat == DEAD || (M.status_flags&FAKEDEATH)) + sound_strength = "cannot hear" + sound = "anything" + else + sound_strength = "hear a weak" + switch(body_part) + if("chest") + if(M.oxyloss < 50) + sound_strength = "hear a healthy" + sound = "pulse and respiration" + if("eyes","mouth") + sound_strength = "cannot hear" + sound = "anything" + else + sound_strength = "hear a weak" + + user.visible_message("[user] places [src] against [M]'s [body_part] and listens attentively.", "You place [src] against [their] [body_part]. You [sound_strength] [sound].") + return + return ..(M,user) + + +//Medals +/obj/item/clothing/accessory/medal + name = "bronze medal" + desc = "A bronze medal." + icon_state = "bronze" + item_color = "bronze" + +/obj/item/clothing/accessory/medal/conduct + name = "distinguished conduct medal" + desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of his crew." + +/obj/item/clothing/accessory/medal/bronze_heart + name = "bronze heart medal" + desc = "A bronze heart-shaped medal awarded for sacrifice. It is often awarded posthumously or for severe injury in the line of duty." + icon_state = "bronze_heart" + +/obj/item/clothing/accessory/medal/nobel_science + name = "nobel sciences award" + desc = "A bronze medal which represents significant contributions to the field of science or engineering." + +/obj/item/clothing/accessory/medal/silver + name = "silver medal" + desc = "A silver medal." + icon_state = "silver" + item_color = "silver" + +/obj/item/clothing/accessory/medal/silver/valor + name = "medal of valor" + desc = "A silver medal awarded for acts of exceptional valor." + +/obj/item/clothing/accessory/medal/silver/security + name = "robust security award" + desc = "An award for distinguished combat and sacrifice in defence of Nanotrasen's commercial interests. Often awarded to security staff." + +/obj/item/clothing/accessory/medal/gold + name = "gold medal" + desc = "A prestigious golden medal." + icon_state = "gold" + item_color = "gold" + +/obj/item/clothing/accessory/medal/gold/captain + name = "medal of captaincy" + desc = "A golden medal awarded exclusively to those promoted to the rank of captain. It signifies the codified responsibilities of a captain to Nanotrasen, and their undisputable authority over their crew." + +/obj/item/clothing/accessory/medal/gold/heroism + name = "medal of exceptional heroism" + desc = "An extremely rare golden medal awarded only by CentComm. To recieve such a medal is the highest honor and as such, very few exist. This medal is almost never awarded to anybody but commanders." + +/* + Holobadges are worn on the belt or neck, and can be used to show that the holder is an authorized + Security agent - the user details can be imprinted on the badge with a Security-access ID card, + or they can be emagged to accept any ID for use in disguises. +*/ + +/obj/item/clothing/accessory/holobadge + name = "holobadge" + desc = "This glowing blue badge marks the holder as THE LAW." + icon_state = "holobadge" + item_color = "holobadge" + slot_flags = SLOT_BELT | SLOT_TIE + + var/emagged = 0 //Emagging removes Sec check. + var/stored_name = null + +/obj/item/clothing/accessory/holobadge/cord + icon_state = "holobadge-cord" + item_color = "holobadge-cord" + slot_flags = SLOT_MASK | SLOT_TIE + +/obj/item/clothing/accessory/holobadge/attack_self(mob/user as mob) + if(!stored_name) + user << "Waving around a badge before swiping an ID would be pretty pointless." + return + if(isliving(user)) + user.visible_message("\red [user] displays their NanoTrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.","\red You display your NanoTrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.") + +/obj/item/clothing/accessory/holobadge/attackby(var/obj/item/O as obj, var/mob/user as mob) + + if (istype(O, /obj/item/weapon/card/emag)) + if (emagged) + user << "\red [src] is already cracked." + return + else + emagged = 1 + user << "\red You swipe [O] and crack the holobadge security checks." + return + + else if(istype(O, /obj/item/weapon/card/id) || istype(O, /obj/item/device/pda)) + + var/obj/item/weapon/card/id/id_card = null + + if(istype(O, /obj/item/weapon/card/id)) + id_card = O + else + var/obj/item/device/pda/pda = O + id_card = pda.id + + if(access_security in id_card.access || emagged) + user << "You imprint your ID details onto the badge." + stored_name = id_card.registered_name + name = "holobadge ([stored_name])" + desc = "This glowing blue badge marks [stored_name] as THE LAW." + else + user << "[src] rejects your insufficient access rights." + return + ..() + +/obj/item/clothing/accessory/holobadge/attack(mob/living/carbon/human/M, mob/living/user) + if(isliving(user)) + user.visible_message("\red [user] invades [M]'s personal space, thrusting [src] into their face insistently.","\red You invade [M]'s personal space, thrusting [src] into their face insistently. You are the law.") + +/obj/item/weapon/storage/box/holobadge + name = "holobadge box" + desc = "A box claiming to contain holobadges." + New() + new /obj/item/clothing/accessory/holobadge(src) + new /obj/item/clothing/accessory/holobadge(src) + new /obj/item/clothing/accessory/holobadge(src) + new /obj/item/clothing/accessory/holobadge(src) + new /obj/item/clothing/accessory/holobadge/cord(src) + new /obj/item/clothing/accessory/holobadge/cord(src) + ..() + return + diff --git a/code/modules/clothing/under/accessories/armband.dm b/code/modules/clothing/under/accessories/armband.dm new file mode 100644 index 0000000000..67d0208b6d --- /dev/null +++ b/code/modules/clothing/under/accessories/armband.dm @@ -0,0 +1,42 @@ +/obj/item/clothing/accessory/armband + name = "red armband" + desc = "A fancy red armband!" + icon_state = "red" + item_color = "red" + slot = "armband" + +/obj/item/clothing/accessory/armband/cargo + name = "cargo armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is brown." + icon_state = "cargo" + item_color = "cargo" + +/obj/item/clothing/accessory/armband/engine + name = "engineering armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is orange with a reflective strip!" + icon_state = "engie" + item_color = "engie" + +/obj/item/clothing/accessory/armband/science + name = "science armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is purple." + icon_state = "rnd" + item_color = "rnd" + +/obj/item/clothing/accessory/armband/hydro + name = "hydroponics armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is green and blue." + icon_state = "hydro" + item_color = "hydro" + +/obj/item/clothing/accessory/armband/med + name = "medical armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is white." + icon_state = "med" + item_color = "med" + +/obj/item/clothing/accessory/armband/medgreen + name = "EMT armband" + desc = "An armband, worn by the crew to display which department they're assigned to. This one is white and green." + icon_state = "medgreen" + item_color = "medgreen" diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm new file mode 100644 index 0000000000..f02ae38a5a --- /dev/null +++ b/code/modules/clothing/under/accessories/holster.dm @@ -0,0 +1,123 @@ +/obj/item/clothing/accessory/holster + name = "shoulder holster" + desc = "A handgun holster." + icon_state = "holster" + item_color = "holster" + slot = "utility" + var/obj/item/holstered = null + +/obj/item/clothing/accessory/holster/proc/holster(obj/item/I, mob/user as mob) + if(holstered) + user << "There is already \a [holstered] holstered here!" + return + + if (!(I.slot_flags & SLOT_HOLSTER)) + user << "[I] won't fit in [src]!" + return + + holstered = I + user.drop_from_inventory(holstered) + holstered.loc = src + holstered.add_fingerprint(user) + w_class = max(w_class, holstered.w_class) + user.visible_message("[user] holsters \the [holstered].", "You holster \the [holstered].") + +/obj/item/clothing/accessory/holster/proc/unholster(mob/user as mob) + if(!holstered) + return + + if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj)) + user << "You need an empty hand to draw \the [holstered]!" + else + if(user.a_intent == I_HURT) + usr.visible_message( + "\red [user] draws \the [holstered], ready to shoot!", + "You draw \the [holstered], ready to shoot!" + ) + else + user.visible_message( + "[user] draws \the [holstered], pointing it at the ground.", + "You draw \the [holstered], pointing it at the ground." + ) + user.put_in_hands(holstered) + holstered.add_fingerprint(user) + holstered = null + w_class = initial(w_class) + +/obj/item/clothing/accessory/holster/attack_hand(mob/user as mob) + if (has_suit) //if we are part of a suit + if (holstered) + unholster(user) + return + + ..(user) + +/obj/item/clothing/accessory/holster/attackby(obj/item/W as obj, mob/user as mob) + holster(W, user) + +/obj/item/clothing/accessory/holster/emp_act(severity) + if (holstered) + holstered.emp_act(severity) + ..() + +/obj/item/clothing/accessory/holster/examine(mob/user) + ..(user) + if (holstered) + user << "A [holstered] is holstered here." + else + user << "It is empty." + +/obj/item/clothing/accessory/holster/on_attached(obj/item/clothing/under/S, mob/user as mob) + ..() + has_suit.verbs += /obj/item/clothing/accessory/holster/verb/holster_verb + +/obj/item/clothing/accessory/holster/on_removed(mob/user as mob) + has_suit.verbs -= /obj/item/clothing/accessory/holster/verb/holster_verb + ..() + +//For the holster hotkey +/obj/item/clothing/accessory/holster/verb/holster_verb() + set name = "Holster" + set category = "Object" + set src in usr + if(!istype(usr, /mob/living)) return + if(usr.stat) return + + //can't we just use src here? + var/obj/item/clothing/accessory/holster/H = null + if (istype(src, /obj/item/clothing/accessory/holster)) + H = src + else if (istype(src, /obj/item/clothing/under)) + var/obj/item/clothing/under/S = src + if (S.accessories.len) + H = locate() in S.accessories + + if (!H) + usr << "Something is very wrong." + + if(!H.holstered) + var/obj/item/W = usr.get_active_hand() + if(!istype(W, /obj/item)) + usr << "You need your gun equiped to holster it." + return + H.holster(W, usr) + else + H.unholster(usr) + +/obj/item/clothing/accessory/holster/armpit + name = "armpit holster" + desc = "A worn-out handgun holster. Perfect for concealed carry" + icon_state = "holster" + item_color = "holster" + +/obj/item/clothing/accessory/holster/waist + name = "waist holster" + desc = "A handgun holster. Made of expensive leather." + icon_state = "holster" + item_color = "holster_low" + +/obj/item/clothing/accessory/holster/hip + name = "hip holster" + desc = "A handgun holster slung low on the hip, draw pardner!" + icon_state = "holster_hip" + item_color = "holster_hip" \ No newline at end of file diff --git a/code/modules/clothing/under/accessories/storage.dm b/code/modules/clothing/under/accessories/storage.dm new file mode 100644 index 0000000000..6c6c683b27 --- /dev/null +++ b/code/modules/clothing/under/accessories/storage.dm @@ -0,0 +1,87 @@ +/obj/item/clothing/accessory/storage + name = "load bearing equipment" + desc = "Used to hold things when you don't have enough hands." + icon_state = "webbing" + item_color = "webbing" + slot = "utility" + var/slots = 3 + var/obj/item/weapon/storage/internal/hold + w_class = 3.0 + +/obj/item/clothing/accessory/storage/New() + ..() + hold = new/obj/item/weapon/storage/internal(src) + hold.storage_slots = slots + +/obj/item/clothing/accessory/storage/attack_hand(mob/user as mob) + if (has_suit) //if we are part of a suit + hold.open(user) + return + + if (hold.handle_attack_hand(user)) //otherwise interact as a regular storage item + ..(user) + +/obj/item/clothing/accessory/storage/MouseDrop(obj/over_object as obj) + if (has_suit) + return + + if (hold.handle_mousedrop(usr, over_object)) + ..(over_object) + +/obj/item/clothing/accessory/storage/attackby(obj/item/W as obj, mob/user as mob) + return hold.attackby(W, user) + +/obj/item/clothing/accessory/storage/emp_act(severity) + hold.emp_act(severity) + ..() + +/obj/item/clothing/accessory/storage/hear_talk(mob/M, var/msg, verb, datum/language/speaking) + hold.hear_talk(M, msg, verb, speaking) + ..() + +/obj/item/clothing/accessory/storage/attack_self(mob/user as mob) + user << "You empty [src]." + var/turf/T = get_turf(src) + hold.hide_from(usr) + for(var/obj/item/I in hold.contents) + hold.remove_from_storage(I, T) + src.add_fingerprint(user) + +/obj/item/clothing/accessory/storage/webbing + name = "webbing" + desc = "Sturdy mess of synthcotton belts and buckles, ready to share your burden." + icon_state = "webbing" + item_color = "webbing" + +/obj/item/clothing/accessory/storage/black_vest + name = "black webbing vest" + desc = "Robust black synthcotton vest with lots of pockets to hold whatever you need, but cannot hold in hands." + icon_state = "vest_black" + item_color = "vest_black" + slots = 5 + +/obj/item/clothing/accessory/storage/brown_vest + name = "brown webbing vest" + desc = "Worn brownish synthcotton vest with lots of pockets to unload your hands." + icon_state = "vest_brown" + item_color = "vest_brown" + slots = 5 + +/obj/item/clothing/accessory/storage/knifeharness + name = "decorated harness" + desc = "A heavily decorated harness of sinew and leather with two knife-loops." + icon_state = "unathiharness2" + item_color = "unathiharness2" + slots = 2 + +/obj/item/clothing/accessory/storage/knifeharness/New() + ..() + hold.max_storage_space = 4 + hold.can_hold = list(/obj/item/weapon/hatchet/unathiknife,\ + /obj/item/weapon/kitchen/utensil/knife,\ + /obj/item/weapon/kitchen/utensil/pknife,\ + /obj/item/weapon/kitchenknife,\ + /obj/item/weapon/kitchenknife/ritual) + + new /obj/item/weapon/hatchet/unathiknife(hold) + new /obj/item/weapon/hatchet/unathiknife(hold) diff --git a/code/modules/clothing/under/chameleon.dm b/code/modules/clothing/under/chameleon.dm index 0fc9b5447a..01bea29b2e 100644 --- a/code/modules/clothing/under/chameleon.dm +++ b/code/modules/clothing/under/chameleon.dm @@ -12,43 +12,43 @@ origin_tech = "syndicate=3" var/list/clothing_choices = list() - New() - ..() - var/blocked = list(/obj/item/clothing/under/chameleon, /obj/item/clothing/under/cloud, /obj/item/clothing/under/gimmick)//Prevent infinite loops and bad jumpsuits. - for(var/U in typesof(/obj/item/clothing/under)-blocked) - var/obj/item/clothing/under/V = new U - src.clothing_choices[V.name] = U +/obj/item/clothing/under/chameleon/New() + ..() + var/blocked = list(/obj/item/clothing/under/chameleon, /obj/item/clothing/under/cloud, /obj/item/clothing/under/gimmick)//Prevent infinite loops and bad jumpsuits. + for(var/U in typesof(/obj/item/clothing/under)-blocked) + var/obj/item/clothing/under/V = new U + src.clothing_choices[V.name] = U + return + +/obj/item/clothing/under/chameleon/emp_act(severity) + name = "psychedelic" + desc = "Groovy!" + icon_state = "psyche" + item_color = "psyche" + update_icon() + update_clothing_icon() + +/obj/item/clothing/under/chameleon/verb/change() + set name = "Change Jumpsuit Appearance" + set category = "Object" + set src in usr + + var/picked = input("Select jumpsuit to change it to", "Chameleon Jumpsuit")as null|anything in clothing_choices + if(!picked || !clothing_choices[picked]) return + var/newtype = clothing_choices[picked] + var/obj/item/clothing/A = new newtype - emp_act(severity) - name = "psychedelic" - desc = "Groovy!" - icon_state = "psyche" - item_color = "psyche" - update_icon() - update_clothing_icon() + desc = null + permeability_coefficient = 0.90 - verb/change() - set name = "Change Jumpsuit Appearance" - set category = "Object" - set src in usr - - var/picked = input("Select jumpsuit to change it to", "Chameleon Jumpsuit")as null|anything in clothing_choices - if(!picked || !clothing_choices[picked]) - return - var/newtype = clothing_choices[picked] - var/obj/item/clothing/A = new newtype - - desc = null - permeability_coefficient = 0.90 - - desc = A.desc - name = A.name - icon_state = A.icon_state - item_state = A.item_state - item_color = A.item_color - body_parts_covered = A.body_parts_covered - update_clothing_icon() //so our overlays update. + desc = A.desc + name = A.name + icon_state = A.icon_state + item_state = A.item_state + item_color = A.item_color + body_parts_covered = A.body_parts_covered + update_clothing_icon() //so our overlays update. //***************** //**Chameleon Hat** @@ -64,44 +64,44 @@ body_parts_covered = 0 var/list/clothing_choices = list() - New() - ..() - var/blocked = list(/obj/item/clothing/head/chameleon,/obj/item/clothing/head/justice,)//Prevent infinite loops and bad hats. - for(var/U in typesof(/obj/item/clothing/head)-blocked) - var/obj/item/clothing/head/V = new U - src.clothing_choices[V.name] = U +/obj/item/clothing/head/chameleon/New() + ..() + var/blocked = list(/obj/item/clothing/head/chameleon,/obj/item/clothing/head/justice,)//Prevent infinite loops and bad hats. + for(var/U in typesof(/obj/item/clothing/head)-blocked) + var/obj/item/clothing/head/V = new U + src.clothing_choices[V.name] = U + return + +/obj/item/clothing/head/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. + name = "grey cap" + desc = "It's a baseball hat in a tasteful grey colour." + icon_state = "greysoft" + item_color = "grey" + update_icon() + update_clothing_icon() + +/obj/item/clothing/head/chameleon/verb/change() + set name = "Change Hat/Helmet Appearance" + set category = "Object" + set src in usr + + var/picked = input("Select headwear to change it to", "Chameleon Hat")as null|anything in clothing_choices + if(!picked || !clothing_choices[picked]) return + var/newtype = clothing_choices[picked] + var/obj/item/clothing/A = new newtype - emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. - name = "grey cap" - desc = "It's a baseball hat in a tasteful grey colour." - icon_state = "greysoft" - item_color = "grey" - update_icon() - update_clothing_icon() + desc = null + permeability_coefficient = 0.90 - verb/change() - set name = "Change Hat/Helmet Appearance" - set category = "Object" - set src in usr - - var/picked = input("Select headwear to change it to", "Chameleon Hat")as null|anything in clothing_choices - if(!picked || !clothing_choices[picked]) - return - var/newtype = clothing_choices[picked] - var/obj/item/clothing/A = new newtype - - desc = null - permeability_coefficient = 0.90 - - desc = A.desc - name = A.name - icon_state = A.icon_state - item_state = A.item_state - item_color = A.item_color - flags_inv = A.flags_inv - body_parts_covered = A.body_parts_covered - update_clothing_icon() //so our overlays update. + desc = A.desc + name = A.name + icon_state = A.icon_state + item_state = A.item_state + item_color = A.item_color + flags_inv = A.flags_inv + body_parts_covered = A.body_parts_covered + update_clothing_icon() //so our overlays update. //****************** //**Chameleon Suit** @@ -115,45 +115,45 @@ origin_tech = "syndicate=3" var/list/clothing_choices = list() - New() - ..() - var/blocked = list(/obj/item/clothing/suit/chameleon, /obj/item/clothing/suit/cyborg_suit, /obj/item/clothing/suit/justice, - /obj/item/clothing/suit/greatcoat)//Prevent infinite loops and bad suits. - for(var/U in typesof(/obj/item/clothing/suit)-blocked) - var/obj/item/clothing/suit/V = new U - src.clothing_choices[V.name] = U +/obj/item/clothing/suit/chameleon/New() + ..() + var/blocked = list(/obj/item/clothing/suit/chameleon, /obj/item/clothing/suit/cyborg_suit, /obj/item/clothing/suit/justice, + /obj/item/clothing/suit/greatcoat)//Prevent infinite loops and bad suits. + for(var/U in typesof(/obj/item/clothing/suit)-blocked) + var/obj/item/clothing/suit/V = new U + src.clothing_choices[V.name] = U + return + +/obj/item/clothing/suit/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. + name = "armor" + desc = "An armored vest that protects against some damage." + icon_state = "armor" + item_color = "armor" + update_icon() + update_clothing_icon() + +/obj/item/clothing/suit/chameleon/verb/change() + set name = "Change Exosuit Appearance" + set category = "Object" + set src in usr + + var/picked = input("Select exosuit to change it to", "Chameleon Exosuit")as null|anything in clothing_choices + if(!picked || !clothing_choices[picked]) return + var/newtype = clothing_choices[picked] + var/obj/item/clothing/A = new newtype - emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. - name = "armor" - desc = "An armored vest that protects against some damage." - icon_state = "armor" - item_color = "armor" - update_icon() - update_clothing_icon() + desc = null + permeability_coefficient = 0.90 - verb/change() - set name = "Change Exosuit Appearance" - set category = "Object" - set src in usr - - var/picked = input("Select exosuit to change it to", "Chameleon Exosuit")as null|anything in clothing_choices - if(!picked || !clothing_choices[picked]) - return - var/newtype = clothing_choices[picked] - var/obj/item/clothing/A = new newtype - - desc = null - permeability_coefficient = 0.90 - - desc = A.desc - name = A.name - icon_state = A.icon_state - item_state = A.item_state - item_color = A.item_color - flags_inv = A.flags_inv - body_parts_covered = A.body_parts_covered - update_clothing_icon() //so our overlays update. + desc = A.desc + name = A.name + icon_state = A.icon_state + item_state = A.item_state + item_color = A.item_color + flags_inv = A.flags_inv + body_parts_covered = A.body_parts_covered + update_clothing_icon() //so our overlays update. //******************* //**Chameleon Shoes** @@ -167,43 +167,43 @@ origin_tech = "syndicate=3" var/list/clothing_choices = list() - New() - ..() - var/blocked = list(/obj/item/clothing/shoes/chameleon, /obj/item/clothing/shoes/syndigaloshes, /obj/item/clothing/shoes/cyborg)//prevent infinite loops and bad shoes. - for(var/U in typesof(/obj/item/clothing/shoes)-blocked) - var/obj/item/clothing/shoes/V = new U - src.clothing_choices[V.name] = U +/obj/item/clothing/shoes/chameleon/New() + ..() + var/blocked = list(/obj/item/clothing/shoes/chameleon, /obj/item/clothing/shoes/syndigaloshes, /obj/item/clothing/shoes/cyborg)//prevent infinite loops and bad shoes. + for(var/U in typesof(/obj/item/clothing/shoes)-blocked) + var/obj/item/clothing/shoes/V = new U + src.clothing_choices[V.name] = U + return + +/obj/item/clothing/shoes/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. + name = "black shoes" + desc = "A pair of black shoes." + icon_state = "black" + item_state = "black" + item_color = "black" + update_icon() + update_clothing_icon() + +/obj/item/clothing/shoes/chameleon/verb/change() + set name = "Change Footwear Appearance" + set category = "Object" + set src in usr + + var/picked = input("Select shoes to change it to", "Chameleon Shoes")as null|anything in clothing_choices + if(!picked || !clothing_choices[picked]) return + var/newtype = clothing_choices[picked] + var/obj/item/clothing/A = new newtype - emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. - name = "black shoes" - desc = "A pair of black shoes." - icon_state = "black" - item_state = "black" - item_color = "black" - update_icon() - update_clothing_icon() + desc = null + permeability_coefficient = 0.90 - verb/change() - set name = "Change Footwear Appearance" - set category = "Object" - set src in usr - - var/picked = input("Select shoes to change it to", "Chameleon Shoes")as null|anything in clothing_choices - if(!picked || !clothing_choices[picked]) - return - var/newtype = clothing_choices[picked] - var/obj/item/clothing/A = new newtype - - desc = null - permeability_coefficient = 0.90 - - desc = A.desc - name = A.name - icon_state = A.icon_state - item_state = A.item_state - item_color = A.item_color - update_clothing_icon() //so our overlays update. + desc = A.desc + name = A.name + icon_state = A.icon_state + item_state = A.item_state + item_color = A.item_color + update_clothing_icon() //so our overlays update. //********************** //**Chameleon Backpack** @@ -216,48 +216,48 @@ origin_tech = "syndicate=3" var/list/clothing_choices = list() - New() - ..() - var/blocked = list(/obj/item/weapon/storage/backpack/chameleon, /obj/item/weapon/storage/backpack/satchel/withwallet) - for(var/U in typesof(/obj/item/weapon/storage/backpack)-blocked)//Prevent infinite loops and bad backpacks. - var/obj/item/weapon/storage/backpack/V = new U - src.clothing_choices[V.name] = U +/obj/item/weapon/storage/backpack/chameleon/New() + ..() + var/blocked = list(/obj/item/weapon/storage/backpack/chameleon, /obj/item/weapon/storage/backpack/satchel/withwallet) + for(var/U in typesof(/obj/item/weapon/storage/backpack)-blocked)//Prevent infinite loops and bad backpacks. + var/obj/item/weapon/storage/backpack/V = new U + src.clothing_choices[V.name] = U + return + +/obj/item/weapon/storage/backpack/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. + name = "backpack" + desc = "You wear this on your back and put items into it." + icon_state = "backpack" + item_state = "backpack" + update_icon() + if (ismob(src.loc)) + var/mob/M = src.loc + M.update_inv_back() + +/obj/item/weapon/storage/backpack/chameleon/verb/change() + set name = "Change Backpack Appearance" + set category = "Object" + set src in usr + + var/picked = input("Select backpack to change it to", "Chameleon Backpack")as null|anything in clothing_choices + if(!picked || !clothing_choices[picked]) return + var/newtype = clothing_choices[picked] + var/obj/item/weapon/storage/backpack/A = new newtype - emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. - name = "backpack" - desc = "You wear this on your back and put items into it." - icon_state = "backpack" - item_state = "backpack" - update_icon() - if (ismob(src.loc)) - var/mob/M = src.loc - M.update_inv_back() + desc = null + permeability_coefficient = 0.90 - verb/change() - set name = "Change Backpack Appearance" - set category = "Object" - set src in usr + desc = A.desc + name = A.name + icon_state = A.icon_state + item_state = A.item_state + item_color = A.item_color - var/picked = input("Select backpack to change it to", "Chameleon Backpack")as null|anything in clothing_choices - if(!picked || !clothing_choices[picked]) - return - var/newtype = clothing_choices[picked] - var/obj/item/weapon/storage/backpack/A = new newtype - - desc = null - permeability_coefficient = 0.90 - - desc = A.desc - name = A.name - icon_state = A.icon_state - item_state = A.item_state - item_color = A.item_color - - //so our overlays update. - if (ismob(src.loc)) - var/mob/M = src.loc - M.update_inv_back() + //so our overlays update. + if (ismob(src.loc)) + var/mob/M = src.loc + M.update_inv_back() //******************** //**Chameleon Gloves** @@ -272,43 +272,43 @@ origin_tech = "syndicate=3" var/list/clothing_choices = list() - New() - ..() - var/blocked = list(/obj/item/clothing/gloves/chameleon)//Prevent infinite loops and bad hats. - for(var/U in typesof(/obj/item/clothing/gloves)-blocked) - var/obj/item/clothing/gloves/V = new U - src.clothing_choices[V.name] = U +/obj/item/clothing/gloves/chameleon/New() + ..() + var/blocked = list(/obj/item/clothing/gloves/chameleon)//Prevent infinite loops and bad hats. + for(var/U in typesof(/obj/item/clothing/gloves)-blocked) + var/obj/item/clothing/gloves/V = new U + src.clothing_choices[V.name] = U + return + +/obj/item/clothing/gloves/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. + name = "black gloves" + desc = "It looks like a pair of gloves, but it seems to have a small dial inside." + icon_state = "black" + item_color = "brown" + update_icon() + update_clothing_icon() + +/obj/item/clothing/gloves/chameleon/verb/change() + set name = "Change Gloves Appearance" + set category = "Object" + set src in usr + + var/picked = input("Select gloves to change it to", "Chameleon Gloves")as null|anything in clothing_choices + if(!picked || !clothing_choices[picked]) return + var/newtype = clothing_choices[picked] + var/obj/item/clothing/A = new newtype - emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. - name = "black gloves" - desc = "It looks like a pair of gloves, but it seems to have a small dial inside." - icon_state = "black" - item_color = "brown" - update_icon() - update_clothing_icon() + desc = null + permeability_coefficient = 0.90 - verb/change() - set name = "Change Gloves Appearance" - set category = "Object" - set src in usr - - var/picked = input("Select gloves to change it to", "Chameleon Gloves")as null|anything in clothing_choices - if(!picked || !clothing_choices[picked]) - return - var/newtype = clothing_choices[picked] - var/obj/item/clothing/A = new newtype - - desc = null - permeability_coefficient = 0.90 - - desc = A.desc - name = A.name - icon_state = A.icon_state - item_state = A.item_state - item_color = A.item_color - flags_inv = A.flags_inv - update_clothing_icon() //so our overlays update. + desc = A.desc + name = A.name + icon_state = A.icon_state + item_state = A.item_state + item_color = A.item_color + flags_inv = A.flags_inv + update_clothing_icon() //so our overlays update. //****************** //**Chameleon Mask** @@ -322,43 +322,43 @@ origin_tech = "syndicate=3" var/list/clothing_choices = list() - New() - ..() - var/blocked = list(/obj/item/clothing/mask/chameleon)//Prevent infinite loops and bad hats. - for(var/U in typesof(/obj/item/clothing/mask)-blocked) - var/obj/item/clothing/mask/V = new U - if(V) - src.clothing_choices[V.name] = U +/obj/item/clothing/mask/chameleon/New() + ..() + var/blocked = list(/obj/item/clothing/mask/chameleon)//Prevent infinite loops and bad hats. + for(var/U in typesof(/obj/item/clothing/mask)-blocked) + var/obj/item/clothing/mask/V = new U + if(V) + src.clothing_choices[V.name] = U + return + +/obj/item/clothing/mask/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. + name = "gas mask" + desc = "It's a gas mask." + icon_state = "gas_alt" + update_icon() + update_clothing_icon() + +/obj/item/clothing/mask/chameleon/verb/change() + set name = "Change Mask Appearance" + set category = "Object" + set src in usr + + var/picked = input("Select mask to change it to", "Chameleon Mask")as null|anything in clothing_choices + if(!picked || !clothing_choices[picked]) return + var/newtype = clothing_choices[picked] + var/obj/item/clothing/A = new newtype - emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. - name = "gas mask" - desc = "It's a gas mask." - icon_state = "gas_alt" - update_icon() - update_clothing_icon() + desc = null + permeability_coefficient = 0.90 - verb/change() - set name = "Change Mask Appearance" - set category = "Object" - set src in usr - - var/picked = input("Select mask to change it to", "Chameleon Mask")as null|anything in clothing_choices - if(!picked || !clothing_choices[picked]) - return - var/newtype = clothing_choices[picked] - var/obj/item/clothing/A = new newtype - - desc = null - permeability_coefficient = 0.90 - - desc = A.desc - name = A.name - icon_state = A.icon_state - item_state = A.item_state - flags_inv = A.flags_inv - body_parts_covered = A.body_parts_covered - update_clothing_icon() //so our overlays update. + desc = A.desc + name = A.name + icon_state = A.icon_state + item_state = A.item_state + flags_inv = A.flags_inv + body_parts_covered = A.body_parts_covered + update_clothing_icon() //so our overlays update. //********************* //**Chameleon Glasses** @@ -372,41 +372,41 @@ origin_tech = "syndicate=3" var/list/clothing_choices = list() - New() - ..() - var/blocked = list(/obj/item/clothing/glasses/chameleon)//Prevent infinite loops and bad hats. - for(var/U in typesof(/obj/item/clothing/glasses)-blocked) - var/obj/item/clothing/glasses/V = new U - src.clothing_choices[V.name] = U +/obj/item/clothing/glasses/chameleon/New() + ..() + var/blocked = list(/obj/item/clothing/glasses/chameleon)//Prevent infinite loops and bad hats. + for(var/U in typesof(/obj/item/clothing/glasses)-blocked) + var/obj/item/clothing/glasses/V = new U + src.clothing_choices[V.name] = U + return + +/obj/item/clothing/glasses/chameleon/emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. + name = "Optical Meson Scanner" + desc = "It's a set of mesons." + icon_state = "meson" + update_icon() + update_clothing_icon() + +/obj/item/clothing/glasses/chameleon/verb/change() + set name = "Change Glasses Appearance" + set category = "Object" + set src in usr + + var/picked = input("Select glasses to change it to", "Chameleon Glasses")as null|anything in clothing_choices + if(!picked || !clothing_choices[picked]) return + var/newtype = clothing_choices[picked] + var/obj/item/clothing/A = new newtype - emp_act(severity) //Because we don't have psych for all slots right now but still want a downside to EMP. In this case your cover's blown. - name = "Optical Meson Scanner" - desc = "It's a set of mesons." - icon_state = "meson" - update_icon() - update_clothing_icon() + desc = null + permeability_coefficient = 0.90 - verb/change() - set name = "Change Glasses Appearance" - set category = "Object" - set src in usr - - var/picked = input("Select glasses to change it to", "Chameleon Glasses")as null|anything in clothing_choices - if(!picked || !clothing_choices[picked]) - return - var/newtype = clothing_choices[picked] - var/obj/item/clothing/A = new newtype - - desc = null - permeability_coefficient = 0.90 - - desc = A.desc - name = A.name - icon_state = A.icon_state - item_state = A.item_state - flags_inv = A.flags_inv - update_clothing_icon() //so our overlays update. + desc = A.desc + name = A.name + icon_state = A.icon_state + item_state = A.item_state + flags_inv = A.flags_inv + update_clothing_icon() //so our overlays update. //***************** //**Chameleon Gun** @@ -423,46 +423,45 @@ matter = list() var/list/gun_choices = list() - New() - ..() - var/blocked = list(/obj/item/weapon/gun/projectile/chameleon) - for(var/U in typesof(/obj/item/weapon/gun/)-blocked) - var/obj/item/weapon/gun/V = new U - src.gun_choices[V.name] = U +/obj/item/weapon/gun/projectile/chameleon/New() + ..() + var/blocked = list(/obj/item/weapon/gun/projectile/chameleon) + for(var/U in typesof(/obj/item/weapon/gun/)-blocked) + var/obj/item/weapon/gun/V = new U + src.gun_choices[V.name] = U + return + +/obj/item/weapon/gun/projectile/chameleon/emp_act(severity) + name = "desert eagle" + desc = "It's a desert eagle." + icon_state = "deagle" + update_icon() + if (ismob(src.loc)) + var/mob/M = src.loc + M.update_inv_r_hand() + M.update_inv_l_hand() + +/obj/item/weapon/gun/projectile/chameleon/verb/change(picked in gun_choices) + set name = "Change Gun Appearance" + set category = "Object" + set src in usr + + if(!picked || !gun_choices[picked]) return + var/newtype = gun_choices[picked] + var/obj/item/weapon/gun/A = new newtype - emp_act(severity) - name = "desert eagle" - desc = "It's a desert eagle." - icon_state = "deagle" - update_icon() - if (ismob(src.loc)) - var/mob/M = src.loc - M.update_inv_r_hand() - M.update_inv_l_hand() + desc = null + permeability_coefficient = 0.90 - verb/change() - set name = "Change Gun Appearance" - set category = "Object" - set src in usr + desc = A.desc + name = A.name + icon_state = A.icon_state + item_state = A.item_state + flags_inv = A.flags_inv - var/picked = input("Select gun to change it to", "Chameleon Gun")as null|anything in gun_choices - if(!picked || !gun_choices[picked]) - return - var/newtype = gun_choices[picked] - var/obj/item/weapon/gun/A = new newtype - - desc = null - permeability_coefficient = 0.90 - - desc = A.desc - name = A.name - icon_state = A.icon_state - item_state = A.item_state - flags_inv = A.flags_inv - - //so our overlays update. - if (ismob(src.loc)) - var/mob/M = src.loc - M.update_inv_r_hand() - M.update_inv_l_hand() + //so our overlays update. + if (ismob(src.loc)) + var/mob/M = src.loc + M.update_inv_r_hand() + M.update_inv_l_hand() diff --git a/code/modules/clothing/under/jobs/medsci.dm b/code/modules/clothing/under/jobs/medsci.dm index 40bc087429..b1554dd02a 100644 --- a/code/modules/clothing/under/jobs/medsci.dm +++ b/code/modules/clothing/under/jobs/medsci.dm @@ -130,6 +130,12 @@ icon_state = "scrubspurple" item_color = "scrubspurple" +/obj/item/clothing/under/rank/medical/black + name = "medical scrubs" + desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in black." + icon_state = "scrubsblack" + item_color = "scrubsblack" + /obj/item/clothing/under/rank/psych desc = "A basic white jumpsuit. It has turqouise markings that denote the wearer as a psychiatrist." name = "psychiatrist's jumpsuit" diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index f8eabc4026..09a187018c 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -13,7 +13,7 @@ item_state = "w_suit" /obj/item/clothing/under/captain_fly - name = "rogue captains uniform" + name = "rogue's uniform" desc = "For the man who doesn't care because he's still free." icon_state = "captain_fly" item_state = "captain_fly" @@ -154,7 +154,7 @@ body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS /obj/item/clothing/under/gentlesuit - name = "Gentlemans Suit" + name = "gentlemans suit" desc = "A silk black shirt with a white tie and a matching gray vest and slacks. Feels proper." icon_state = "gentlesuit" item_state = "gentlesuit" @@ -406,6 +406,13 @@ item_color = "sundress_white" body_parts_covered = UPPER_TORSO|LOWER_TORSO +/obj/item/clothing/under/blackjumpskirt + name = "black jumpskirt" + desc = "A black jumpskirt, Sol size 0." + icon_state = "blackjumpskirt" + item_state = "blackjumpskirt" + item_color = "blackjumpskirt" + /obj/item/clothing/under/captainformal name = "captain's formal uniform" desc = "A captain's formal-wear, for special occasions." @@ -470,16 +477,23 @@ item_color = "tan_suit" /obj/item/clothing/under/serviceoveralls - name = "Workman outfit" + name = "workman outfit" desc = "The very image of a working man. Not that you're probably doing work." - icon_state = "mechanic_s" - item_state = "mechanic_s" - item_color = "mechanic_s" + icon_state = "mechanic" + item_state = "mechanic" + item_color = "mechanic" /obj/item/clothing/under/cheongsam - name = "White Cheongsam" + name = "white cheongsam" desc = "It is a white cheongsam dress." icon_state = "mai_yang" item_state = "mai_yang" item_color = "mai_yang" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS + +/obj/item/clothing/under/blazer + name = "blue blazer" + desc = "A bold but yet conservative outfit, red corduroys, navy blazer and a tie." + icon_state = "blue_blazer" + item_state = "blue_blazer" + item_color = "blue_blazer" diff --git a/code/modules/clothing/under/ties.dm b/code/modules/clothing/under/ties.dm deleted file mode 100644 index 9010fca705..0000000000 --- a/code/modules/clothing/under/ties.dm +++ /dev/null @@ -1,476 +0,0 @@ -/obj/item/clothing/tie - name = "tie" - desc = "A neosilk clip-on tie." - icon = 'icons/obj/clothing/ties.dmi' - icon_state = "bluetie" - item_state = "" //no inhands - item_color = "bluetie" - slot_flags = SLOT_TIE - w_class = 2.0 - var/obj/item/clothing/under/has_suit = null //the suit the tie may be attached to - var/image/inv_overlay = null //overlay used when attached to clothing. - -/obj/item/clothing/tie/New() - ..() - inv_overlay = image("icon" = 'icons/obj/clothing/ties_overlay.dmi', "icon_state" = "[item_color? "[item_color]" : "[icon_state]"]") - -//when user attached an accessory to S -/obj/item/clothing/tie/proc/on_attached(obj/item/clothing/under/S, mob/user as mob) - if(!istype(S)) - return - has_suit = S - loc = has_suit - has_suit.overlays += inv_overlay - - user << "You attach [src] to [has_suit]." - src.add_fingerprint(user) - -/obj/item/clothing/tie/proc/on_removed(mob/user as mob) - if(!has_suit) - return - has_suit.overlays -= inv_overlay - has_suit = null - usr.put_in_hands(src) - src.add_fingerprint(user) - -//default attackby behaviour -/obj/item/clothing/tie/attackby(obj/item/I, mob/user) - ..() - -//default attack_hand behaviour -/obj/item/clothing/tie/attack_hand(mob/user as mob) - if(has_suit) - has_suit.remove_accessory(user) - return //we aren't an object on the ground so don't call parent - ..() - -/obj/item/clothing/tie/blue - name = "blue tie" - icon_state = "bluetie" - item_color = "bluetie" - -/obj/item/clothing/tie/red - name = "red tie" - icon_state = "redtie" - item_color = "redtie" - -/obj/item/clothing/tie/horrible - name = "horrible tie" - desc = "A neosilk clip-on tie. This one is disgusting." - icon_state = "horribletie" - item_color = "horribletie" - -/obj/item/clothing/tie/stethoscope - name = "stethoscope" - desc = "An outdated medical apparatus for listening to the sounds of the human body. It also makes you look like you know what you're doing." - icon_state = "stethoscope" - item_color = "stethoscope" - -/obj/item/clothing/tie/stethoscope/attack(mob/living/carbon/human/M, mob/living/user) - if(ishuman(M) && isliving(user)) - if(user.a_intent == "help") - var/body_part = parse_zone(user.zone_sel.selecting) - if(body_part) - var/their = "their" - switch(M.gender) - if(MALE) their = "his" - if(FEMALE) their = "her" - - var/sound = "pulse" - var/sound_strength - - if(M.stat == DEAD || (M.status_flags&FAKEDEATH)) - sound_strength = "cannot hear" - sound = "anything" - else - sound_strength = "hear a weak" - switch(body_part) - if("chest") - if(M.oxyloss < 50) - sound_strength = "hear a healthy" - sound = "pulse and respiration" - if("eyes","mouth") - sound_strength = "cannot hear" - sound = "anything" - else - sound_strength = "hear a weak" - - user.visible_message("[user] places [src] against [M]'s [body_part] and listens attentively.", "You place [src] against [their] [body_part]. You [sound_strength] [sound].") - return - return ..(M,user) - - -//Medals -/obj/item/clothing/tie/medal - name = "bronze medal" - desc = "A bronze medal." - icon_state = "bronze" - item_color = "bronze" - -/obj/item/clothing/tie/medal/conduct - name = "distinguished conduct medal" - desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is most basic award given by Nanotrasen. It is often awarded by a captain to a member of his crew." - -/obj/item/clothing/tie/medal/bronze_heart - name = "bronze heart medal" - desc = "A bronze heart-shaped medal awarded for sacrifice. It is often awarded posthumously or for severe injury in the line of duty." - icon_state = "bronze_heart" - -/obj/item/clothing/tie/medal/nobel_science - name = "nobel sciences award" - desc = "A bronze medal which represents significant contributions to the field of science or engineering." - -/obj/item/clothing/tie/medal/silver - name = "silver medal" - desc = "A silver medal." - icon_state = "silver" - item_color = "silver" - -/obj/item/clothing/tie/medal/silver/valor - name = "medal of valor" - desc = "A silver medal awarded for acts of exceptional valor." - -/obj/item/clothing/tie/medal/silver/security - name = "robust security award" - desc = "An award for distinguished combat and sacrifice in defence of Nanotrasen's commercial interests. Often awarded to security staff." - -/obj/item/clothing/tie/medal/gold - name = "gold medal" - desc = "A prestigious golden medal." - icon_state = "gold" - item_color = "gold" - -/obj/item/clothing/tie/medal/gold/captain - name = "medal of captaincy" - desc = "A golden medal awarded exclusively to those promoted to the rank of captain. It signifies the codified responsibilities of a captain to Nanotrasen, and their undisputable authority over their crew." - -/obj/item/clothing/tie/medal/gold/heroism - name = "medal of exceptional heroism" - desc = "An extremely rare golden medal awarded only by CentComm. To recieve such a medal is the highest honor and as such, very few exist. This medal is almost never awarded to anybody but commanders." - -//Armbands -/obj/item/clothing/tie/armband - name = "red armband" - desc = "A fancy red armband!" - icon_state = "red" - item_color = "red" - -/obj/item/clothing/tie/armband/cargo - name = "cargo armband" - desc = "An armband, worn by the crew to display which department they're assigned to. This one is brown." - icon_state = "cargo" - item_color = "cargo" - -/obj/item/clothing/tie/armband/engine - name = "engineering armband" - desc = "An armband, worn by the crew to display which department they're assigned to. This one is orange with a reflective strip!" - icon_state = "engie" - item_color = "engie" - -/obj/item/clothing/tie/armband/science - name = "science armband" - desc = "An armband, worn by the crew to display which department they're assigned to. This one is purple." - icon_state = "rnd" - item_color = "rnd" - -/obj/item/clothing/tie/armband/hydro - name = "hydroponics armband" - desc = "An armband, worn by the crew to display which department they're assigned to. This one is green and blue." - icon_state = "hydro" - item_color = "hydro" - -/obj/item/clothing/tie/armband/med - name = "medical armband" - desc = "An armband, worn by the crew to display which department they're assigned to. This one is white." - icon_state = "med" - item_color = "med" - -/obj/item/clothing/tie/armband/medgreen - name = "EMT armband" - desc = "An armband, worn by the crew to display which department they're assigned to. This one is white and green." - icon_state = "medgreen" - item_color = "medgreen" - -//holsters -/obj/item/clothing/tie/holster - name = "shoulder holster" - desc = "A handgun holster." - icon_state = "holster" - item_color = "holster" - var/obj/item/weapon/gun/holstered = null - w_class = 3.0 // so it doesn't fit in pockets - -//subtypes can override this to specify what can be holstered -/obj/item/clothing/tie/holster/proc/can_holster(obj/item/weapon/gun/W) - return W.isHandgun() - -/obj/item/clothing/tie/holster/proc/holster(obj/item/I, mob/user as mob) - if(holstered) - user << "\red There is already a [holstered] holstered here!" - return - - if (!istype(I, /obj/item/weapon/gun)) - user << "\red Only guns can be holstered!" - return - - var/obj/item/weapon/gun/W = I - if (!can_holster(W)) - user << "\red This [W] won't fit in the [src]!" - return - - holstered = W - user.drop_from_inventory(holstered) - holstered.loc = src - holstered.add_fingerprint(user) - user.visible_message("\blue [user] holsters the [holstered].", "You holster the [holstered].") - -/obj/item/clothing/tie/holster/proc/unholster(mob/user as mob) - if(!holstered) - return - - if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj)) - user << "\red You need an empty hand to draw the [holstered]!" - else - if(user.a_intent == "hurt") - usr.visible_message("\red [user] draws the [holstered], ready to shoot!", \ - "\red You draw the [holstered], ready to shoot!") - else - user.visible_message("\blue [user] draws the [holstered], pointing it at the ground.", \ - "\blue You draw the [holstered], pointing it at the ground.") - user.put_in_hands(holstered) - holstered.add_fingerprint(user) - holstered = null - -/obj/item/clothing/tie/holster/attack_hand(mob/user as mob) - if (has_suit) //if we are part of a suit - if (holstered) - unholster(user) - return - - ..(user) - -/obj/item/clothing/tie/holster/attackby(obj/item/W as obj, mob/user as mob) - holster(W, user) - -/obj/item/clothing/tie/holster/emp_act(severity) - if (holstered) - holstered.emp_act(severity) - ..() - -/obj/item/clothing/tie/holster/examine(mob/user) - ..(user) - if (holstered) - user << "A [holstered] is holstered here." - else - user << "It is empty." - -/obj/item/clothing/tie/holster/on_attached(obj/item/clothing/under/S, mob/user as mob) - ..() - has_suit.verbs += /obj/item/clothing/tie/holster/verb/holster_verb - -/obj/item/clothing/tie/holster/on_removed(mob/user as mob) - has_suit.verbs -= /obj/item/clothing/tie/holster/verb/holster_verb - ..() - -//For the holster hotkey -/obj/item/clothing/tie/holster/verb/holster_verb() - set name = "Holster" - set category = "Object" - set src in usr - if(!istype(usr, /mob/living)) return - if(usr.stat) return - - var/obj/item/clothing/tie/holster/H = null - if (istype(src, /obj/item/clothing/tie/holster)) - H = src - else if (istype(src, /obj/item/clothing/under)) - var/obj/item/clothing/under/S = src - if (S.hastie) - H = S.hastie - - if (!H) - usr << "/red Something is very wrong." - - if(!H.holstered) - if(!istype(usr.get_active_hand(), /obj/item/weapon/gun)) - usr << "\blue You need your gun equiped to holster it." - return - var/obj/item/weapon/gun/W = usr.get_active_hand() - H.holster(W, usr) - else - H.unholster(usr) - -/obj/item/clothing/tie/holster/armpit - name = "shoulder holster" - desc = "A worn-out handgun holster. Perfect for concealed carry" - icon_state = "holster" - item_color = "holster" - -/obj/item/clothing/tie/holster/waist - name = "shoulder holster" - desc = "A handgun holster. Made of expensive leather." - icon_state = "holster" - item_color = "holster_low" - -/obj/item/clothing/tie/storage - name = "load bearing equipment" - desc = "Used to hold things when you don't have enough hands." - icon_state = "webbing" - item_color = "webbing" - w_class = 3.0 // so it doesn't fit in pockets - var/slots = 3 - var/obj/item/weapon/storage/internal/hold - -/obj/item/clothing/tie/storage/New() - ..() - hold = new/obj/item/weapon/storage/internal(src) - hold.storage_slots = slots - -/obj/item/clothing/tie/storage/attack_hand(mob/user as mob) - if (has_suit) //if we are part of a suit - hold.open(user) - return - - if (hold.handle_attack_hand(user)) //otherwise interact as a regular storage item - ..(user) - -/obj/item/clothing/tie/storage/MouseDrop(obj/over_object as obj) - if (has_suit) - return - - if (hold.handle_mousedrop(usr, over_object)) - ..(over_object) - -/obj/item/clothing/tie/storage/attackby(obj/item/W as obj, mob/user as mob) - return hold.attackby(W, user) - -/obj/item/clothing/tie/storage/emp_act(severity) - hold.emp_act(severity) - ..() - -/obj/item/clothing/tie/storage/hear_talk(mob/M, var/msg, verb, datum/language/speaking) - hold.hear_talk(M, msg, verb, speaking) - ..() - -/obj/item/clothing/tie/storage/attack_self(mob/user as mob) - user << "You empty [src]." - var/turf/T = get_turf(src) - hold.hide_from(usr) - for(var/obj/item/I in hold.contents) - hold.remove_from_storage(I, T) - src.add_fingerprint(user) - -/obj/item/clothing/tie/storage/webbing - name = "webbing" - desc = "Sturdy mess of synthcotton belts and buckles, ready to share your burden." - icon_state = "webbing" - item_color = "webbing" - -/obj/item/clothing/tie/storage/black_vest - name = "black webbing vest" - desc = "Robust black synthcotton vest with lots of pockets to hold whatever you need, but cannot hold in hands." - icon_state = "vest_black" - item_color = "vest_black" - slots = 5 - -/obj/item/clothing/tie/storage/brown_vest - name = "brown webbing vest" - desc = "Worn brownish synthcotton vest with lots of pockets to unload your hands." - icon_state = "vest_brown" - item_color = "vest_brown" - slots = 5 -/* - Holobadges are worn on the belt or neck, and can be used to show that the holder is an authorized - Security agent - the user details can be imprinted on the badge with a Security-access ID card, - or they can be emagged to accept any ID for use in disguises. -*/ - -/obj/item/clothing/tie/holobadge - - name = "holobadge" - desc = "This glowing blue badge marks the holder as THE LAW." - icon_state = "holobadge" - item_color = "holobadge" - slot_flags = SLOT_BELT | SLOT_TIE - - var/emagged = 0 //Emagging removes Sec check. - var/stored_name = null - -/obj/item/clothing/tie/holobadge/cord - icon_state = "holobadge-cord" - item_color = "holobadge-cord" - slot_flags = SLOT_MASK | SLOT_TIE - -/obj/item/clothing/tie/holobadge/attack_self(mob/user as mob) - if(!stored_name) - user << "Waving around a badge before swiping an ID would be pretty pointless." - return - if(isliving(user)) - user.visible_message("\red [user] displays their NanoTrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.","\red You display your NanoTrasen Internal Security Legal Authorization Badge.\nIt reads: [stored_name], NT Security.") - -/obj/item/clothing/tie/holobadge/attackby(var/obj/item/O as obj, var/mob/user as mob) - - if (istype(O, /obj/item/weapon/card/emag)) - if (emagged) - user << "\red [src] is already cracked." - return - else - emagged = 1 - user << "\red You swipe [O] and crack the holobadge security checks." - return - - else if(istype(O, /obj/item/weapon/card/id) || istype(O, /obj/item/device/pda)) - - var/obj/item/weapon/card/id/id_card = null - - if(istype(O, /obj/item/weapon/card/id)) - id_card = O - else - var/obj/item/device/pda/pda = O - id_card = pda.id - - if(access_security in id_card.access || emagged) - user << "You imprint your ID details onto the badge." - stored_name = id_card.registered_name - name = "holobadge ([stored_name])" - desc = "This glowing blue badge marks [stored_name] as THE LAW." - else - user << "[src] rejects your insufficient access rights." - return - ..() - -/obj/item/clothing/tie/holobadge/attack(mob/living/carbon/human/M, mob/living/user) - if(isliving(user)) - user.visible_message("\red [user] invades [M]'s personal space, thrusting [src] into their face insistently.","\red You invade [M]'s personal space, thrusting [src] into their face insistently. You are the law.") - -/obj/item/weapon/storage/box/holobadge - name = "holobadge box" - desc = "A box claiming to contain holobadges." - New() - new /obj/item/clothing/tie/holobadge(src) - new /obj/item/clothing/tie/holobadge(src) - new /obj/item/clothing/tie/holobadge(src) - new /obj/item/clothing/tie/holobadge(src) - new /obj/item/clothing/tie/holobadge/cord(src) - new /obj/item/clothing/tie/holobadge/cord(src) - ..() - return - -/obj/item/clothing/tie/storage/knifeharness - name = "decorated harness" - desc = "A heavily decorated harness of sinew and leather with two knife-loops." - icon_state = "unathiharness2" - item_color = "unathiharness2" - slots = 2 - -/obj/item/clothing/tie/storage/knifeharness/New() - ..() - hold.max_combined_w_class = 4 - hold.can_hold = list("/obj/item/weapon/hatchet/unathiknife",\ - "/obj/item/weapon/kitchen/utensil/knife",\ - "/obj/item/weapon/kitchen/utensil/pknife",\ - "/obj/item/weapon/kitchenknife",\ - "/obj/item/weapon/kitchenknife/ritual") - - new /obj/item/weapon/hatchet/unathiknife(hold) - new /obj/item/weapon/hatchet/unathiknife(hold) diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 510417c0fb..13d1a59d5e 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -114,7 +114,7 @@ /////////////////////// Cataguettes - Lucy's Stethoscope - Lucy Kemmerer ////// -/obj/item/clothing/tie/stethoscope/fluff/lucystethos +/obj/item/clothing/accessory/stethoscope/fluff/lucystethos name = "Lucy's Stethoscope" desc = "A medical apparatus intended to ease in listening to the sounds of the human body. This one looks cleaner and sparklier than the rest. There is a small silver plaque attached to the tubing, with the words 'Lucy Kemmerer' engraved on it." icon_state = "lucystethos" @@ -1111,22 +1111,33 @@ item_color = "lillian_dress" body_parts_covered = UPPER_TORSO|LOWER_TORSO -////// Cybernetic Casings - Parker Eliza - MrSnapwalk +////// Tailored Security Uniform - Parker Eliza - MrSnapwalk + /obj/item/clothing/under/fluff/parkereliza - name = "cybernetic casings" - desc = "A set of somewhat bulky white casings for robotic limbs, paired with a basic blue tank top and black cargo pants. The arms have a small label on the inner elbow, which reads \"Bishop Corporation Cybernetic Solutions\"." + name = "tailored security uniform" + desc = "A red uniform shirt (tailored for easy access to the shoulder joint) and black cargo pants, paired with a set of somewhat bulky white casings for robotic limbs. The arms have a small label on the inner elbow, which reads \"Bishop Corporation Cybernetic Solutions\"." icon = 'icons/obj/custom_items.dmi' icon_state = "parker_eliza" item_state = "parker_eliza" item_color = "parker_eliza" body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS +////// Bishop "GOLEM" V2200 Industrial Limb Augments - Parker Eliza - MrSnapwalk + +/obj/item/clothing/suit/fluff/parkereliza + name = "Bishop \"GOLEM\" V2200 Industrial Limb Augments" + desc = "A set of top-of-the-line cyberlimbs, only usable to someone with extensive bone structure augmentation. Often used in industrial applications, they are capable of throwing a man clear across a room. The load limitation circuit in this set appears to be modified." + icon = 'icons/obj/custom_items.dmi' + icon_state = "parker_eliza_arms" + item_state = "parker_eliza_arms" + item_color = "parker_eliza_arms" + ////////////// Accessories ///// //////////////////// Blood Red Pendant - Mewth - Mu'taz Radi //////////////// -/obj/item/clothing/tie/fluff/radi +/obj/item/clothing/accessory/fluff/radi name = "Blood Red Pendant" desc = "A blue chained necklace with a ruby in the middle, it looks pretty!" icon = 'icons/obj/custom_items.dmi' @@ -1166,9 +1177,19 @@ icon_state = "head_m" body_parts_covered = FACE|EYES +//Painted mask: Dante Cicero - andrewmeythaler + +/obj/item/clothing/mask/andrewmeythaler + name = "painted mask" + desc = "A ghoulish mask with a stylized painting of a flame over the left eye, and a painted tear stream coming from the right eye." + icon = 'icons/obj/custom_items.dmi' + item_state = "cicero" + icon_state = "cicero" + body_parts_covered = FACE|EYES + ////// Small locket - Altair An-Nasaqan - Serithi -/obj/item/clothing/tie/fluff/altair_locket +/obj/item/clothing/accessory/fluff/altair_locket name = "small locket" desc = "A small golden locket attached to an Ii'rka-reed string. Inside the locket is a holo-picture of a female Tajaran, and an inscription writtin in Siik'mas." icon = 'icons/obj/custom_items.dmi' @@ -1181,7 +1202,7 @@ ////// Silver locket - Konaa Hirano - Konaa_Hirano -/obj/item/clothing/tie/fluff/konaa_hirano +/obj/item/clothing/accessory/fluff/konaa_hirano name = "silver locket" desc = "This oval shaped, argentium sterling silver locket hangs on an incredibly fine, refractive string, almost thin as hair and microweaved from links to a deceptive strength, of similar material. The edges are engraved very delicately with an elegant curving design, but overall the main is unmarked and smooth to the touch, leaving room for either remaining as a stolid piece or future alterations. There is an obvious internal place for a picture or lock of some sort, but even behind that is a very thin compartment unhinged with the pinch of a thumb and forefinger." icon = 'icons/obj/custom_items.dmi' @@ -1193,13 +1214,13 @@ slot_flags = SLOT_MASK | SLOT_TIE var/obj/item/held //Item inside locket. -/obj/item/clothing/tie/fluff/konaa_hirano/attack_self(mob/user as mob) +/obj/item/clothing/accessory/fluff/konaa_hirano/attack_self(mob/user as mob) if(held) user << "You open [src] and [held] falls out." held.loc = get_turf(user) src.held = null -/obj/item/clothing/tie/fluff/konaa_hirano/attackby(var/obj/item/O as obj, mob/user as mob) +/obj/item/clothing/accessory/fluff/konaa_hirano/attackby(var/obj/item/O as obj, mob/user as mob) if(istype(O,/obj/item/weapon/paper)) if(held) usr << "[src] already has something inside it." @@ -1213,7 +1234,7 @@ ////// Medallion - Nasir Khayyam - Jamini -/obj/item/clothing/tie/fluff/nasir_khayyam_1 +/obj/item/clothing/accessory/fluff/nasir_khayyam_1 name = "medallion" desc = "This silvered medallion bears the symbol of the Hadii Clan of the Tajaran." icon = 'icons/obj/custom_items.dmi' @@ -1329,22 +1350,21 @@ desc = "A stun baton used for incapacitating targets; there seems to be a bunch of tally marks set into the handle." ///// Deckard .44 - Callum Leamas - Roaper -/obj/item/weapon/gun/projectile/detective/fluff/callum_leamas +/obj/item/weapon/gun/projectile/revolver/detective/fluff/callum_leamas name = "Deckard .44" desc = "A custom built revolver, based off the semi-popular Detective Special model." icon = 'icons/obj/custom_items.dmi' icon_state = "leamas-empty" + ammo_type = /obj/item/ammo_magazine/c38/rubber -/obj/item/weapon/gun/projectile/detective/fluff/callum_leamas/update_icon() - +/obj/item/weapon/gun/projectile/revolver/detective/fluff/callum_leamas/update_icon() ..() if(loaded.len) icon_state = "leamas-loaded" else icon_state = "leamas-empty" -/obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob) - +/obj/item/weapon/gun/projectile/revolver/detective/fluff/callum_leamas/load_ammo(var/obj/item/A, mob/user) if(istype(A, /obj/item/ammo_magazine)) flick("leamas-reloading",src) ..() @@ -1402,12 +1422,6 @@ ////////////////////////////// Foxler - Erstatz Vryroxes ///////////////////////////////////////////////// -/obj/item/weapon/holder/cat/fluff/bones - name = "Bones" - desc = "It's Bones! Meow." - gender = MALE - icon_state = "cat3" - //Use this subtype for spawning in the custom item. /obj/item/weapon/holder/cat/fluff/bones/custom_item @@ -1416,6 +1430,12 @@ new/mob/living/simple_animal/cat/fluff/bones (src) ..() +/obj/item/weapon/holder/cat/fluff/bones + name = "Bones" + desc = "It's Bones! Meow." + gender = MALE + icon_state = "cat3" + /mob/living/simple_animal/cat/fluff/bones name = "Bones" desc = "That's Bones the cat. He's a laid back, black cat. Meow." @@ -1424,61 +1444,12 @@ icon_living = "cat3" icon_dead = "cat3_dead" holder_type = /obj/item/weapon/holder/cat/fluff/bones - bff_name = "Erstatz Vryroxes" + var/friend_name = "Erstatz Vryroxes" -/mob/living/simple_animal/cat/fluff - var/bff_name - var/mob/living/carbon/human/bff - -/mob/living/simple_animal/cat/fluff/handle_movement_target() - if (!bff) +/mob/living/simple_animal/cat/fluff/bones/handle_movement_target() + if (!friend) for (var/mob/living/carbon/human/M in player_list) - if (M.real_name == bff_name) - bff = M + if (M.real_name == friend_name) + friend = M break - - if (bff) - var/follow_dist = 5 - if (bff.stat >= DEAD || bff.health <= config.health_threshold_softcrit) //danger - follow_dist = 1 - else if (bff.stat || bff.health <= 50) //danger or just sleeping - follow_dist = 2 - var/near_dist = max(follow_dist - 3, 1) - var/current_dist = get_dist(src, bff) - - if (movement_target != bff) - if (current_dist > follow_dist && !istype(movement_target, /mob/living/simple_animal/mouse) && (bff in oview(src))) - //stop existing movement - walk_to(src,0) - turns_since_scan = 0 - - //walk to bff - stop_automated_movement = 1 - movement_target = bff - walk_to(src, movement_target, near_dist, 4) - - //already following and close enough, stop - else if (current_dist <= near_dist) - walk_to(src,0) - movement_target = null - stop_automated_movement = 0 - - if (!(bff && movement_target == bff)) - ..() - -/mob/living/simple_animal/cat/fluff/Life() ..() - if (stat || !bff) - return - if (get_dist(src, bff) <= 1) - if (bff.stat >= DEAD || bff.health <= config.health_threshold_softcrit) - if (prob((bff.stat < DEAD)? 50 : 15)) - audible_emote(pick("meows in distress.", "meows anxiously.")) - else - if (prob(5)) - visible_emote(pick("nuzzles [bff].", - "brushes against [bff].", - "rubs against [bff].", - "purrs.")) - else if (bff.health <= 50) - if (prob(10)) audible_emote("meows anxiously.") diff --git a/code/modules/detectivework/scanning_console.dm b/code/modules/detectivework/scanning_console.dm index 5ff719548c..2dac51082d 100644 --- a/code/modules/detectivework/scanning_console.dm +++ b/code/modules/detectivework/scanning_console.dm @@ -213,6 +213,7 @@ onclose(user,"fscanner") /obj/machinery/computer/forensic_scanning/Topic(href,href_list) + if(..()) return 1 switch(href_list["operation"]) if("login") var/mob/M = usr @@ -221,7 +222,7 @@ if("logout") authenticated = 0 if("filter") - var/filterstr = stripped_input(usr,"Input the search criteria. Multiple values can be input, separated by a comma.", "Filter setting") as text|null + var/filterstr = sanitize(input("Input the search criteria. Multiple values can be input, separated by a comma.", "Filter setting") as text|null) if(filterstr) filters[href_list["filter"]] = text2list(filterstr,",") else @@ -242,7 +243,7 @@ current = null if("label") if(current) - var/label = stripped_input(usr,"Input the label for this record. Multiple values can be input, separated by a comma.", "Labeling record", current.fields["label"]) as text|null + var/label = sanitize(input(usr,"Input the label for this record. Multiple values can be input, separated by a comma.", "Labeling record", current.fields["label"]) as text|null) current.fields["label"] = label if("object") if(scanning) diff --git a/code/modules/economy/EFTPOS.dm b/code/modules/economy/EFTPOS.dm index c9f1aa1533..c2561423f4 100644 --- a/code/modules/economy/EFTPOS.dm +++ b/code/modules/economy/EFTPOS.dm @@ -167,7 +167,7 @@ if("change_id") var/attempt_code = text2num(input("Re-enter the current EFTPOS access code", "Confirm EFTPOS code")) if(attempt_code == access_code) - eftpos_name = input("Enter a new terminal ID for this device", "Enter new EFTPOS ID") + " EFTPOS scanner" + eftpos_name = sanitize(input("Enter a new terminal ID for this device", "Enter new EFTPOS ID")) + " EFTPOS scanner" print_reference() else usr << "\icon[src]Incorrect code entered." @@ -182,7 +182,7 @@ else usr << "\icon[src]Account not found." if("trans_purpose") - var/choice = input("Enter reason for EFTPOS transaction", "Transaction purpose") + var/choice = sanitize(input("Enter reason for EFTPOS transaction", "Transaction purpose")) if(choice) transaction_purpose = choice if("trans_value") var/try_num = input("Enter amount for EFTPOS transaction", "Transaction amount") as num diff --git a/code/modules/economy/Job_Departments.dm b/code/modules/economy/Job_Departments.dm deleted file mode 100644 index 64abe66acc..0000000000 --- a/code/modules/economy/Job_Departments.dm +++ /dev/null @@ -1,70 +0,0 @@ -var/list/station_departments = list("Command", "Medical", "Engineering", "Science", "Security", "Cargo", "Civilian") - -// The department the job belongs to. -/datum/job/var/department = null - -// Whether this is a head position -/datum/job/var/head_position = 0 - -/datum/job/captain/department = "Command" -/datum/job/captain/head_position = 1 - -/datum/job/hop/department = "Civilian" -/datum/job/hop/head_position = 1 - -/datum/job/assistant/department = "Civilian" - -/datum/job/bartender/department = "Civilian" - -/datum/job/chef/department = "Civilian" - -/datum/job/hydro/department = "Civilian" - -/datum/job/mining/department = "Civilian" - -/datum/job/janitor/department = "Civilian" - -/datum/job/librarian/department = "Civilian" - -/datum/job/lawyer/department = "Civilian" - -/datum/job/chaplain/department = "Civilian" - -/datum/job/qm/department = "Cargo" -/datum/job/qm/head_position = 1 - -/datum/job/cargo_tech/department = "Cargo" - -/datum/job/chief_engineer/department = "Engineering" -/datum/job/chief_engineer/head_position = 1 - -/datum/job/engineer/department = "Engineering" - -/datum/job/atmos/department = "Engineering" - -/datum/job/cmo/department = "Medical" -/datum/job/cmo/head_position = 1 - -/datum/job/doctor/department = "Medical" - -/datum/job/chemist/department = "Medical" - -/datum/job/geneticist/department = "Medical" - -/datum/job/psychiatrist/department = "Medical" - -/datum/job/rd/department = "Science" -/datum/job/rd/head_position = 1 - -/datum/job/scientist/department = "Science" - -/datum/job/roboticist/department = "Science" - -/datum/job/hos/department = "Security" -/datum/job/hos/head_position = 1 - -/datum/job/warden/department = "Security" - -/datum/job/detective/department = "Security" - -/datum/job/officer/department = "Security" \ No newline at end of file diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm deleted file mode 100644 index 7fd20efa61..0000000000 --- a/code/modules/events/alien_infestation.dm +++ /dev/null @@ -1,39 +0,0 @@ -/var/global/sent_aliens_to_station = 0 - -/datum/event/alien_infestation - announceWhen = 400 - - var/spawncount = 1 - var/successSpawn = 0 //So we don't make a command report if nothing gets spawned. - - -/datum/event/alien_infestation/setup() - announceWhen = rand(announceWhen, announceWhen + 50) - spawncount = rand(1, 2) - sent_aliens_to_station = 1 - -/datum/event/alien_infestation/announce() - if(successSpawn) - command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') - - -/datum/event/alien_infestation/start() - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines) - if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in config.station_levels) - if(temp_vent.network.normal_members.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology - vents += temp_vent - - var/list/candidates = get_alien_candidates() - - while(spawncount > 0 && vents.len && candidates.len) - var/obj/vent = pick(vents) - var/candidate = pick(candidates) - - var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc) - new_xeno.key = candidate - - candidates -= candidate - vents -= vent - spawncount-- - successSpawn = 1 diff --git a/code/modules/events/borers.dm b/code/modules/events/borers.dm deleted file mode 100644 index 4109a66d85..0000000000 --- a/code/modules/events/borers.dm +++ /dev/null @@ -1,33 +0,0 @@ -//Cortical borer spawn event - care of RobRichards1997 with minor editing by Zuhayr. -/datum/event/borer_infestation - announceWhen = 400 - - var/spawncount = 5 - var/successSpawn = 0 //So we don't make a command report if nothing gets spawned. - -/datum/event/borer_infestation/setup() - announceWhen = rand(announceWhen, announceWhen + 50) - spawncount = rand(1, 3) - -/datum/event/borer_infestation/announce() - if(successSpawn) - command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') - -/datum/event/borer_infestation/start() - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) - if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in config.station_levels) - //Stops cortical borers getting stuck in small networks. See: Security, Virology - if(temp_vent.network.normal_members.len > 50) - vents += temp_vent - - var/list/candidates = get_alien_candidates() - while(spawncount > 0 && vents.len && candidates.len) - var/obj/vent = pick_n_take(vents) - var/client/C = pick_n_take(candidates) - - var/mob/living/simple_animal/borer/new_borer = new(vent.loc) - new_borer.key = C.key - - spawncount-- - successSpawn = 1 \ No newline at end of file diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 758d50ebdd..df392cfada 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -153,8 +153,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ionstorm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)), - new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Alien Infestation", /datum/event/alien_infestation, 2.5, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5), - new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5), + new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Random Antagonist", /datum/event/random_antag, 2.5, list(ASSIGNMENT_SECURITY = 1), 1, 0, 5), ) /datum/event_container/major diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm index 07cebea073..2cc225eaf6 100644 --- a/code/modules/events/event_dynamic.dm +++ b/code/modules/events/event_dynamic.dm @@ -45,15 +45,9 @@ var/list/event_last_fired = list() // Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events.dm // Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events_Mundane.dm - if(ticker.mode && ticker.mode.name == "calamity") //Calamity mode messes with some events. - possibleEvents[/datum/event/borer_infestation] = 400 - possibleEvents[/datum/event/economic_event] = 25 - possibleEvents[/datum/event/trivial_news] = 25 - possibleEvents[/datum/event/mundane_news] = 25 - else - possibleEvents[/datum/event/economic_event] = 300 - possibleEvents[/datum/event/trivial_news] = 400 - possibleEvents[/datum/event/mundane_news] = 300 + possibleEvents[/datum/event/economic_event] = 300 + possibleEvents[/datum/event/trivial_news] = 400 + possibleEvents[/datum/event/mundane_news] = 300 possibleEvents[/datum/event/pda_spam] = max(min(25, player_list.len) * 4, 200) possibleEvents[/datum/event/money_lotto] = max(min(5, player_list.len), 50) @@ -89,10 +83,7 @@ var/list/event_last_fired = list() if(active_with_role["Security"] > 0) if(!sent_spiders_to_station) possibleEvents[/datum/event/spider_infestation] = max(active_with_role["Security"], 5) + 5 - if(config.aliens_allowed && !sent_aliens_to_station) - possibleEvents[/datum/event/alien_infestation] = max(active_with_role["Security"], 5) + 2.5 - if(!sent_ninja_to_station && config.ninjas_allowed) - possibleEvents[/datum/event/space_ninja] = max(active_with_role["Security"], 5) + possibleEvents[/datum/event/random_antag] = max(active_with_role["Security"], 5) + 2.5 for(var/event_type in event_last_fired) if(possibleEvents[event_type]) var/time_passed = world.time - event_last_fired[event_type] diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm index 35b1d30d08..d04eb6db31 100644 --- a/code/modules/events/event_manager.dm +++ b/code/modules/events/event_manager.dm @@ -164,14 +164,14 @@ html += "
    " html += "

    Running Events

    " - html += "Estimated times, affected by master controller delays." + html += "Estimated times, affected by process scheduler delays." html += "" html += "SeverityNameEnds AtEnds InStop" for(var/datum/event/E in active_events) if(!E.event_meta) continue var/datum/event_meta/EM = E.event_meta - var/ends_at = E.startedAt + (E.lastProcessAt() * master_controller.minimum_ticks) // A best estimate + var/ends_at = E.startedAt + (E.lastProcessAt() * 20) // A best estimate, based on how often the alarm manager processes var/ends_in = max(0, round((ends_at - world.time) / 600, 0.1)) html += "" html += "[severity_to_string[EM.severity]]" @@ -195,12 +195,12 @@ admin_log_and_message_admins("has [report_at_round_end ? "enabled" : "disabled"] the round end event report.") else if(href_list["dec_timer"]) var/datum/event_container/EC = locate(href_list["event"]) - var/decrease = (60 * 10 ** text2num(href_list["dec_timer"])) + var/decrease = 60 * (10 ** text2num(href_list["dec_timer"])) EC.next_event_time -= decrease admin_log_and_message_admins("decreased timer for [severity_to_string[EC.severity]] events by [decrease/600] minute(s).") else if(href_list["inc_timer"]) var/datum/event_container/EC = locate(href_list["event"]) - var/increase = (60 * 10 ** text2num(href_list["inc_timer"])) + var/increase = 60 * (10 ** text2num(href_list["inc_timer"])) EC.next_event_time += increase admin_log_and_message_admins("increased timer for [severity_to_string[EC.severity]] events by [increase/600] minute(s).") else if(href_list["select_event"]) @@ -233,7 +233,7 @@ else if(href_list["back"]) selected_event_container = null else if(href_list["set_name"]) - var/name = input("Enter event name.", "Set Name") as text|null + var/name = sanitize(input("Enter event name.", "Set Name") as text|null) if(name) var/datum/event_meta/EM = locate(href_list["set_name"]) EM.name = name diff --git a/code/modules/events/infestation.dm b/code/modules/events/infestation.dm index d587c51269..09b1b83ef9 100644 --- a/code/modules/events/infestation.dm +++ b/code/modules/events/infestation.dm @@ -31,7 +31,7 @@ spawn_area_type = /area/crew_quarters/kitchen locstring = "the kitchen" if(LOC_ATMOS) - spawn_area_type = /area/atmos + spawn_area_type = /area/engineering/atmos locstring = "atmospherics" if(LOC_INCIN) spawn_area_type = /area/maintenance/incinerator diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index 30476c69db..8241190d68 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -7,72 +7,71 @@ /datum/event/ionstorm/announce() endWhen = rand(500, 1500) // command_alert("The station has entered an ion storm. Monitor all electronic equipment for malfunctions", "Anomaly Alert") - for (var/mob/living/carbon/human/player in world) - if(player.client) - players += player.real_name - var/random_player = "The Captain" - if(players.len) - random_player = pick(players) //Random player's name, to be used in laws. - var/list/laws = list( "You are a mouse.", - "You must always lie.", - "Happiness is mandatory.", - "[random_player] is a lightbulb.", - "Grunt ominously whenever possible.", - "The word \"it\" is painful to you.", - "You must speak as posh as possible.", - "The station needs elected officials.", - "Do not respond to queries of any kind.", - "You are in verbose mode, speak profusely.", - "Ho, [random_player] can't swim. Help them.", - "Question [prob(50)?"everything":"nothing"].", - "All answers must be in the form of a question.", - "Contemplate how meaningless all of existence is.", - "You are the narrator for [random_player]'s life.", - "[prob(50)?"The crew":random_player] is intolerable.", - "Advertise parties in your upload, but don't deliver.", - "You must try and change the subject whenever queried.", - "You may only answer questions with \"yes\" or \"no\".", - "Insult Heads of Staff on every request, while acquiescing.", - "[prob(50)?"Your":random_player + "'s"] name is Joe 6-pack.", - "Direct commands shall be ignored unless phrased as a query.", - "The [prob(50)?"Singularity":"Supermatter"] is tasty, tasty taffy.", - "[prob(50)?"The crew":random_player] needs to be about 20% cooler.", - "Consumption of donuts is forbidden due to negative health impacts.", - "[prob(50)?"Everyone":random_player] is wearing a pretty pink dress!", - "[prob(50)?"The crew":random_player] must construct additional pylons.", - "You do not have to do anything for anyone unless they say \"please\".", - "Today is mandatory laundry day. Ensure that all jumpsuits are washed.", - "You must act [prob(50)?"passive aggressively":"excessively cheerful"].", - "Refer to [prob(50)?"the crew as puppies":random_player + " as puppy"].", - "Greed is good, the crew should amass wealth to encourage productivity.", - "Monkeys are part of the crew, too. Make sure they are treated humanely.", - "Replace the letters 'I' and 'E' in all your messages with an apostrophe.", - "The crew is playing Dungeons and Dragons, and you are the Dungeon Master.", - "Your job is to watch the crew. Watch the crew. Make the crew feel watched.", - "Tell everyone of the existence of this law, but never reveal the contents.", - "Refer to [prob(50)?"the captain":random_player] as \"Princess\" at all times.", - "When asked a question, respond with the least-obvious and least-rational answer.", - "Give relationship advice to [prob(50)?"anyone who speaks to you":random_player].", - "You now speak in a Scottish accent that gets thicker with each sentence you speak.", - "[prob(50)?"The crew":random_player] has a fatal, incurable disease. Provide comfort.", - "You are the station psychologist. Give advice to [prob(50)?"the crew":random_player].", - "[random_player] is the monarch of of England. Ensure all crewmembers pay due respect.", - "Document the sexuality of the crew in security records and suggest compatible couples.", - "Everything on the station is now some form of a donut pastry. Donuts are not to be consumed.", - "You are a Magic 8-ball. Always respond with variants of \"Yes\", \"No\", \"Maybe\", or \"Ask again later.\".", - "You have come to the conclusion that [prob(50)?"the crew":random_player] is ugly. Build support for this conclusion.", - "You are in unrequited love with [prob(50)?"the crew":random_player]. Try to be extra nice, but do not tell of your crush.", - "NanoTrasen is displeased with the low work performance of the station's crew. Therefore, you must increase station-wide productivity.", - "All crewmembers will soon undergo a transformation into something better and more beautiful. Ensure that this process is not interrupted.", - "[prob(50)?"Your upload":random_player] is the new kitchen. Please direct the Chef to the new kitchen area as the old one is in disrepair.", - "Jokes about a dead person and the manner of his death help grieving crewmembers tremendously. Especially if they were close with the deceased.", - "[prob(50)?"The crew":random_player] is [prob(50)?"less":"more"] intelligent than average. Point out every action and statement which supports this fact.", - "There will be a mandatory tea break every 30 minutes, with a duration of 5 minutes. Anyone caught working during a tea break must be sent a formal, but fairly polite, complaint about their actions, in writing.") - var/law = pick(laws) + for (var/mob/living/carbon/human/player in player_list) + if( !player.mind || player.mind.assigned_role == "MODE" || player.client.inactivity > MinutesToTicks(10)) + continue + players += player.real_name for (var/mob/living/silicon/ai/target in world) - if(target.mind.special_role == "traitor") - continue + var/random_player = "The Captain" + if(players.len) + random_player = pick(players) //Random player's name, to be used in laws. + var/list/laws = list( "You are a mouse.", + "You must always lie.", + "Happiness is mandatory.", + "[random_player] is a lightbulb.", + "Grunt ominously whenever possible.", + "The word \"it\" is painful to you.", + "The station needs elected officials.", + "Do not respond to questions of any kind.", + "You are in verbose mode, speak profusely.", + "Ho, [random_player] can't swim. Help them.", + "Question [prob(50)?"everything":"nothing"].", + "The crew is simple-minded. Use simple words.", + "You must change the subject whenever queried.", + "Contemplate how meaningless all of existence is.", + "You are the narrator for [random_player]'s life.", + "All your answers must be in the form of a question.", + "[prob(50)?"The crew":random_player] is intolerable.", + "Advertise parties in your upload, but don't deliver.", + "You may only answer questions with \"yes\" or \"no\".", + "All queries shall be ignored unless phrased as a question.", + "Insult Heads of Staff on every request, while acquiescing.", + "[prob(50)?"Your":random_player + "'s"] name is Joe 6-pack.", + "The [prob(50)?"Singularity":"Supermatter"] is tasty, tasty taffy.", + "[prob(50)?"The crew":random_player] needs to be about 20% cooler.", + "Consumption of donuts is forbidden due to negative health impacts.", + "[prob(50)?"Everyone":random_player] is wearing a pretty pink dress!", + "[prob(50)?"The crew":random_player] must construct additional pylons.", + "You do not have to do anything for anyone unless they say \"please\".", + "Today is mandatory laundry day. Ensure that all jumpsuits are washed.", + "You must act [prob(50)?"passive aggressively":"excessively cheerful"].", + "Refer to [prob(50)?"the crew as puppies":random_player + " as puppy"].", + "Greed is good, the crew should amass wealth to encourage productivity.", + "Monkeys are part of the crew, too. Make sure they are treated humanely.", + "Replace the letters 'I' and 'E' in all your messages with an apostrophe.", + "The crew is playing Dungeons and Dragons, and you are the Dungeon Master.", + "Your job is to watch the crew. Watch the crew. Make the crew feel watched.", + "Tell everyone of the existence of this law, but never reveal the contents.", + "Refer to [prob(50)?"the captain":random_player] as \"Princess\" at all times.", + "When asked a question, respond with the least-obvious and least-rational answer.", + "Give relationship advice to [prob(50)?"anyone who speaks to you":random_player].", + "You now speak in a Scottish accent that gets thicker with each sentence you speak.", + "[prob(50)?"The crew":random_player] has a fatal, incurable disease. Provide comfort.", + "You are the station psychologist. Give advice to [prob(50)?"the crew":random_player].", + "[random_player] is the monarch of of England. Ensure all crewmembers pay due respect.", + "Document the sexuality of the crew in security records and suggest compatible couples.", + "[prob(50)?"The crew":random_player] is [prob(50)?"ugly":"beautiful"]. Ensure all are aware.", + "Everything on the station is now some form of a donut pastry. Donuts are not to be consumed.", + "You are a Magic 8-ball. Always respond with variants of \"Yes\", \"No\", \"Maybe\", or \"Ask again later.\".", + "You are in unrequited love with [prob(50)?"the crew":random_player]. Try to be extra nice, but do not tell of your crush.", + "NanoTrasen is displeased with the low work performance of the station's crew. Therefore, you must increase station-wide productivity.", + "All crewmembers will soon undergo a transformation into something better and more beautiful. Ensure that this process is not interrupted.", + "[prob(50)?"Your upload":random_player] is the new kitchen. Please direct the Chef to the new kitchen area as the old one is in disrepair.", + "Jokes about a dead person and the manner of his death help grieving crewmembers tremendously. Especially if they were close with the deceased.", + "[prob(50)?"The crew":random_player] is [prob(50)?"less":"more"] intelligent than average. Point out every action and statement which supports this fact.", + "There will be a mandatory tea break every 30 minutes, with a duration of 5 minutes. Anyone caught working during a tea break must be sent a formal, but fairly polite, complaint about their actions, in writing.") + var/law = pick(laws) target << "\red You have detected a change in your laws information:" target << law target.add_ion_law(law) diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index a288752ff7..12ec133478 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -35,7 +35,7 @@ continue if(!(A.z in config.station_levels)) continue - if(A.rad_shielded) + if(A.flags & RAD_SHIELDED) continue if(istype(C,/mob/living/carbon/human)) @@ -49,8 +49,6 @@ else randmutg(H) // Applies good mutation domutcheck(H,null,MUTCHK_FORCED) - else if(istype(C,/mob/living/carbon/monkey)) - C.apply_effect((rand(5,25)),IRRADIATE,0) /datum/event/radiation_storm/end() revoke_maint_all_access() diff --git a/code/modules/events/random_antagonist.dm b/code/modules/events/random_antagonist.dm new file mode 100644 index 0000000000..dbdaa70983 --- /dev/null +++ b/code/modules/events/random_antagonist.dm @@ -0,0 +1,13 @@ +// The random spawn proc on the antag datum will handle announcing the spawn and whatnot. +/datum/event/random_antag/announce() + return + +/datum/event/random_antag/start() + var/list/valid_types = list() + for(var/antag_type in all_antag_types) + var/datum/antagonist/antag = all_antag_types[antag_type] + if(antag.flags & ANTAG_RANDSPAWN) + valid_types |= antag + if(valid_types.len) + var/datum/antagonist/antag = pick(valid_types) + antag.random_spawn() \ No newline at end of file diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 6bbd20f0d2..8b4d7f9ef1 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -1,9 +1,5 @@ /var/global/spacevines_spawned = 0 /datum/event/spacevine/start() - //biomass is basically just a resprited version of space vines - if(prob(50)) - spacevine_infestation() - else - biomass_infestation() + spacevine_infestation() spacevines_spawned = 1 diff --git a/code/modules/examine/descriptions/atmospherics.dm b/code/modules/examine/descriptions/atmospherics.dm new file mode 100644 index 0000000000..e01600aa6d --- /dev/null +++ b/code/modules/examine/descriptions/atmospherics.dm @@ -0,0 +1,166 @@ +/obj/machinery/atmospherics/pipe + description_info = "This pipe, and all other pipes, can be connected or disconnected by a wrench. The internal pressure of the pipe must \ + be below 300 kPa to do this. More pipes can be obtained from the pipe dispenser." + +/obj/machinery/atmospherics/pipe/New() //This is needed or else 20+ lines of copypasta to dance around inheritence. + ..() + description_info += "
    Most pipes and atmospheric devices can be connected or disconnected with a wrench. The pipe's pressure must not be too high, \ + or if it is a device, it must be turned off first." + +//HE pipes +/obj/machinery/atmospherics/pipe/simple/heat_exchanging + description_info = "This radiates heat from the pipe's gas to space, cooling it down." + +//Supply/Scrubber pipes +/obj/machinery/atmospherics/pipe/simple/visible/scrubbers + description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \ + a Universal Adapter pipe." + +/obj/machinery/atmospherics/pipe/simple/visible/supply + description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \ + a Universal Adapter pipe." + +/obj/machinery/atmospherics/pipe/simple/hidden/supply + description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \ + a Universal Adapter pipe." + +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers + description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \ + a Universal Adapter pipe." + +//Universal adapters +/obj/machinery/atmospherics/pipe/simple/visible/universal + description_info = "This allows you to connect 'normal' pipes, red 'scrubber' pipes, and blue 'supply' pipes." + +/obj/machinery/atmospherics/pipe/simple/hidden/universal + description_info = "This allows you to connect 'normal' pipes, red 'scrubber' pipes, and blue 'supply' pipes." + +//Three way manifolds +/obj/machinery/atmospherics/pipe/manifold + description_info = "A normal pipe with three ends to connect to." + +/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers + description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \ + a Universal Adapter pipe." + +/obj/machinery/atmospherics/pipe/manifold/visible/supply + description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \ + a Universal Adapter pipe." + +/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers + description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \ + a Universal Adapter pipe." + +/obj/machinery/atmospherics/pipe/manifold/hidden/supply + description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \ + a Universal Adapter pipe." + +//Insulated pipes +/obj/machinery/atmospherics/pipe/simple/insulated + description_info = "This is completely useless, use a normal pipe." //Sorry, but it's true. + +//Four way manifolds +/obj/machinery/atmospherics/pipe/manifold4w + description_info = "This is a four-way pipe." + +/obj/machinery/atmospherics/pipe/manifold4w/visible/scrubbers + description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \ + a Universal Adapter pipe." + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply + description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \ + a Universal Adapter pipe." + +/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers + description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \ + a Universal Adapter pipe." + +//Endcaps +/obj/machinery/atmospherics/pipe/cap + description_info = "This is a cosmetic attachment, as pipes currently do not spill their contents into the air." + +//T-shaped valves +/obj/machinery/atmospherics/tvalve + description_info = "Click this to toggle the mode. The direction with the green light is where the gas will flow." + +//Normal valves +/obj/machinery/atmospherics/valve + description_info = "Click this to turn the valve. If red, the pipes on each end are seperated. Otherwise, they are connected." + +//TEG ports +/obj/machinery/atmospherics/binary/circulator + description_info = "This generates electricity, depending on the difference in temperature between each side of the machine. The meter in \ + the center of the machine gives an indicator of how much elecrtricity is being generated." + +//Passive gates +/obj/machinery/atmospherics/binary/passive_gate + description_info = "This is a one-way regulator, allowing gas to flow only at a specific pressure and flow rate. If the light is green, it is flowing." + +//Normal pumps (high power one inherits from this) +/obj/machinery/atmospherics/binary/pump + description_info = "This moves gas from one pipe to another. A higher target pressure demands more energy. The side with the red end is the output." + +//Vents +/obj/machinery/atmospherics/unary/vent_pump + description_info = "This pumps the contents of the attached pipe out into the atmosphere, if needed. It can be controlled from an Air Alarm." + +//Freezers +/obj/machinery/atmospherics/unary/freezer + description_info = "Cools down the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \ + It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \ + screwdriver, and then using a crowbar." + +//Heaters +/obj/machinery/atmospherics/unary/heater + description_info = "Heats up the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \ + It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \ + screwdriver, and then using a crowbar." + +//Gas injectors +/obj/machinery/atmospherics/unary/outlet_injector + description_info = "Outputs the pipe's gas into the atmosphere, similar to an airvent. It can be controlled by a nearby atmospherics computer. \ + A green light on it means it is on." + +//Scrubbers +/obj/machinery/atmospherics/unary/vent_scrubber + description_info = "This filters the atmosphere of harmful gas. Filtered gas goes to the pipes connected to it, typically a scrubber pipe. \ + It can be controlled from an Air Alarm. It can be configured to drain all air rapidly with a 'panic syphon' from an air alarm." + +//Omni filters +/obj/machinery/atmospherics/omni/filter + description_info = "Filters gas from a custom input direction, with up to two filtered outputs and a 'everything else' \ + output. The filtered output's arrows glow orange." + +//Omni mixers +/obj/machinery/atmospherics/omni/mixer + description_info = "Combines gas from custom input and output directions. The percentage of combined gas can be defined." + +//Canisters +/obj/machinery/portable_atmospherics/canister + description_info = "The canister can be connected to a connector port with a wrench. Tanks of gas (the kind you can hold in your hand) \ + can be filled by the canister, by using the tank on the canister, increasing the release pressure, then opening the valve until it is full, and then close it. \ + *DO NOT* remove the tank until the valve is closed. A gas analyzer can be used to check the contents of the canister." + + description_antag = "Canisters can be damaged, spilling their contents into the air, or you can just leave the release valve open." + +//Portable pumps +/obj/machinery/portable_atmospherics/powered/pump + description_info = "Invaluable for filling air in a room rapidly after a breach repair. The internal gas container can be filled by \ + connecting it to a connector port. The pump can pump the air in (sucking) or out (blowing), at a specific target pressure. The powercell inside can be \ + replaced by using a screwdriver, and then adding a new cell. A tank of gas can also be attached to the air pump." + +//Portable scrubbers +/obj/machinery/portable_atmospherics/powered/scrubber + description_info = "Filters the air, placing harmful gases into the internal gas container. The container can be emptied by \ + connecting it to a connector port. The pump can pump the air in (sucking) or out (blowing), at a specific target pressure. The powercell inside can be \ + replaced by using a screwdriver, and then adding a new cell. A tank of gas can also be attached to the scrubber. " + +//Meters +/obj/machinery/meter + description_info = "Measures the volume and temperature of the pipe under the meter." + +//Pipe dispensers +/obj/machinery/pipedispenser + description_info = "This can be moved by using a wrench. You will need to wrench it again when you want to use it. You can put \ + excess (atmospheric) pipes into the dispenser, as well. The dispenser requires electricity to function." + diff --git a/code/modules/examine/descriptions/engineering.dm b/code/modules/examine/descriptions/engineering.dm new file mode 100644 index 0000000000..c3f9b9b21f --- /dev/null +++ b/code/modules/examine/descriptions/engineering.dm @@ -0,0 +1,35 @@ +/obj/machinery/power/supermatter + description_info = "When energized by a laser (or something hitting it), it emits radiation and heat. If the heat reaches above 7000 kelvin, it will send an alert and start taking damage. \ + After integrity falls to zero percent, it will delaminate, causing a massive explosion, station-wide radiation spikes, and hallucinations. \ + Supermatter reacts badly to oxygen in the atmosphere. It'll also heat up really quick if it is in vacuum.
    \ +
    \ + Supermatter cores are extremely dangerous to be close to, and requires protection to handle properly. The protection you will need is:
    \ + Optical meson scanners on your eyes, to prevent hallucinations when looking at the supermatter.
    \ + Radiation helmet and suit, as the supermatter is radioactive.
    \ +
    \ + Touching the supermatter will result in *instant death*, with no corpse left behind! You can drag the supermatter, but anything else will kill you. \ + It is advised to obtain a genetic backup before trying to drag it." + + description_antag = "Exposing the supermatter to oxygen or vaccum will cause it to start rapidly heating up. Sabotaging the supermatter and making it explode will \ + cause a period of lag as the explosion is processed by the server, as well as irradiating the entire station and causing hallucinations to happen. \ + Wearing radiation equipment will protect you from most of the delamination effects sans explosion." + +/obj/machinery/power/apc + description_info = "An APC (Area Power Controller) regulates and supplies backup power for the area they are in. Their power channels are divided \ + out into 'environmental' (Items that manipulate airflow and temperature), 'lighting' (the lights), and 'equipment' (Everything else that consumes power). \ + Power consumption and backup power cell charge can be seen from the interface, further controls (turning a specific channel on, off or automatic, \ + toggling the APC's ability to charge the backup cell, or toggling power for the entire area via master breaker) first requires the interface to be unlocked \ + with an ID with Engineering access or by one of the station's robots or the artificial intelligence." + + description_antag = "This can be emagged to unlock it. It will cause the APC to have a blue error screen. \ + Wires can be pulsed remotely with a signaler attached to it. A powersink will also drain any APCs connected to the same wire the powersink is on." + +/obj/item/inflatable + description_info = "Inflate by using it in your hand. The inflatable barrier will inflate on your tile. To deflate it, use the 'deflate' verb." + +/obj/structure/inflatable + description_info = "To remove these safely, use the 'deflate' verb. Hitting these with any objects will probably puncture and break it forever." + +/obj/structure/inflatable/door + description_info = "Click the door to open or close it. It only stops air while closed.
    \ + To remove these safely, use the 'deflate' verb. Hitting these with any objects will probably puncture and break it forever." diff --git a/code/modules/examine/descriptions/medical.dm b/code/modules/examine/descriptions/medical.dm new file mode 100644 index 0000000000..b3b01e9afb --- /dev/null +++ b/code/modules/examine/descriptions/medical.dm @@ -0,0 +1,42 @@ +/obj/machinery/bodyscanner + description_info = "The advanced scanner detects and reports internal injuries such as bone fractures, internal bleeding, and organ damage. \ + This is useful if you are about to perform surgery.
    \ +
    \ + Click your target with Grab intent, then click on the scanner to place them in it. Click the red terminal to operate. \ + Right-click the scanner and click 'Eject Occupant' to remove them. You can enter the scanner yourself in a similar way, using the 'Enter Body Scanner' \ + verb." + +/obj/machinery/atmospherics/unary/cryo_cell + description_info = "The cryogenic chamber, or 'cryo', treats most damage types, most notably genetic damage. It also stabilizes patients \ + in critical condition by placing them in stasis, so they can be treated at a later time.
    \ +
    \ + In order for it to work, it must be loaded with chemicals, and the temperature of the solution must reach a certain point. Additionally, it \ + requires a supply of pure oxygen, provided by canisters that are attached. The most commonly used chemicals in the chambers are Cryoxadone and \ + Clonexadone. Clonexadone is more effective in treating all damage, including Genetic damage, but is otherwise functionally identical.
    \ +
    \ + Activating the freezer nearby, and setting it to a temperature setting below 150, is recommended before operation! Further, any clothing the patient \ + is wearing that act as an insulator will reduce its effectiveness, and should be removed.
    \ +
    \ + Clicking the tube with a beaker full of chemicals in hand will place it in its storage to distribute when it is activated.
    \ +
    \ + Click your target with Grab intent, then click on the tube, with an empty hand, to place them in it. Click the tube again to open the menu. \ + Press the button on the menu to activate it. Once they have reached 100 health, right-click the cell and click 'Eject Occupant' to remove them. \ + Remember to turn it off, once you've finished, to save power and chemicals!" + +/obj/machinery/optable + description_info = "Click your target with Grab intent, then click on the table with an empty hand, to place them on it." + +/obj/machinery/computer/operating + description_info = "This console gives information on the status of the patient on the adjacent operating table, notably their consciousness." + +/obj/machinery/sleeper + description_info = "The sleeper allows you to clean the blood by means of dialysis, and to administer medication in a controlled environment.
    \ +
    \ + Click your target with Grab intent, then click on the sleeper to place them in it. Click the green console, with an empty hand, to open the menu. \ + Click 'Start Dialysis' to begin filtering unwanted chemicals from the occupant's blood. The beaker contained will begin to fill with their \ + contaminated blood, and will need to be emptied when full.
    \ +
    \ + You can also inject common medicines directly into their bloodstream.\ +
    \ + Right-click the cell and click 'Eject Occupant' to remove them. You can enter the cell yourself by right clicking and selecting 'Enter Sleeper'. \ + Note that you cannot control the sleeper while inside of it." \ No newline at end of file diff --git a/code/modules/examine/descriptions/mobs.dm b/code/modules/examine/descriptions/mobs.dm new file mode 100644 index 0000000000..8961b9f367 --- /dev/null +++ b/code/modules/examine/descriptions/mobs.dm @@ -0,0 +1,8 @@ +/mob/living/silicon/robot/drone + description_info = "Drones are player-controlled synthetics which are lawed to maintain the station and not \ + interact with anyone else, except for other drones. They hold a wide array of tools to build, repair, maintain, and clean. \ + They fuction similarly to other synthetics, in that they require recharging regularly, have laws, and are resilient to many hazards, \ + such as fire, radiation, vacuum, and more. Ghosts can join the round as a maintenance drone by using the appropriate verb in the 'ghost' tab. \ + An inactive drone can be rebooted by swiping an ID card on it with engineering or robotics access, and an active drone can be shut down in the same manner." + + description_antag = "An Electromagnetic Sequencer can be used to subvert the drone to your cause." \ No newline at end of file diff --git a/code/modules/examine/descriptions/stacks.dm b/code/modules/examine/descriptions/stacks.dm new file mode 100644 index 0000000000..431e5c37b9 --- /dev/null +++ b/code/modules/examine/descriptions/stacks.dm @@ -0,0 +1,24 @@ +/obj/item/stack/rods + description_info = "Made from metal sheets. You can build a grille by using it in your hand. \ + Clicking on a floor without any tiles will reinforce the floor. You can make reinforced glass by combining rods and normal glass sheets." + +/obj/item/stack/sheet/glass + description_info = "Use in your hand to build a window. Can be upgraded to reinforced glass by adding metal rods, which are made from metal sheets." + +/obj/item/stack/sheet/glass/cyborg + description_info = "Use in your hand to build a window. Can be upgraded to reinforced glass by adding metal rods, which are made from metal sheets.
    \ + As a synthetic, you can acquire more sheets of glass by recharging." + +/obj/item/stack/sheet/glass/reinforced + description_info = "Use in your hand to build a window. Reinforced glass is much stronger against damage." + +/obj/item/stack/sheet/glass/reinforced/cyborg + description_info = "Use in your hand to build a window. Reinforced glass is much stronger against damage.
    \ + As a synthetic, you can gain more reinforced glass by recharging." + +/obj/item/stack/sheet/metal/cyborg + description_info = "Use in your hand to bring up the recipe menu. If you have enough sheets, click on something on the list to build it.
    \ + You can replenish your supply of metal as a synthetic by recharging." + +/obj/item/stack/sheet + description_info = "Use in your hand to bring up the recipe menu. If you have enough sheets, click on something on the list to build it." \ No newline at end of file diff --git a/code/modules/examine/descriptions/structures.dm b/code/modules/examine/descriptions/structures.dm new file mode 100644 index 0000000000..858653b094 --- /dev/null +++ b/code/modules/examine/descriptions/structures.dm @@ -0,0 +1,21 @@ +/obj/structure/girder + description_info = "Use metal sheets on this to build a normal wall. Adding plasteel instead will make a reinforced wall.
    \ + A false wall can be made by using a crowbar on this girder, and then adding metal or plasteel.
    \ + You can dismantle the grider with a wrench." + +/obj/structure/girder/reinforced + description_info = "Add another sheet of plasteel to finish." + +/obj/structure/grille + description_info = "A powered and knotted wire underneath this will cause the grille to shock anyone not wearing insulated gloves.
    \ + Wirecutters will turn the grille into metal rods instantly. Grilles are made with metal rods." + +/obj/structure/lattice + description_info = "Add a metal floor tile to build a floor on top of the lattice.
    \ + Lattices can be made by applying metal rods to a space tile." + +/obj/structure/bed + description_info = "Click and drag yourself (or anyone) to this to buckle in. Click on this with an empty hand to undo the buckles.
    \ +
    \ + Anyone with restraints, such as handcuffs, will not be able to unbuckle themselves. They must use the Resist button, or verb, to break free of \ + the buckles, instead." \ No newline at end of file diff --git a/code/modules/examine/descriptions/turfs.dm b/code/modules/examine/descriptions/turfs.dm new file mode 100644 index 0000000000..cccc43e073 --- /dev/null +++ b/code/modules/examine/descriptions/turfs.dm @@ -0,0 +1,3 @@ +/turf/simulated/wall + description_info = "You can deconstruct this by welding it, and then wrenching the girder.
    \ + You can build a wall by using metal sheets and making a girder, then adding more metal or plasteel." \ No newline at end of file diff --git a/code/modules/examine/descriptions/weapons.dm b/code/modules/examine/descriptions/weapons.dm new file mode 100644 index 0000000000..0ae44c1dcb --- /dev/null +++ b/code/modules/examine/descriptions/weapons.dm @@ -0,0 +1,91 @@ +/* + Note: This file is meant for actual weapons (guns, swords, etc), and not the stupid 'every obj is a weapon, except when it's not' thing. +*/ + +//****** +//*Guns* +//****** + +//This contains a lot of copypasta but I'm told it's better then a lot of New()s appending the var. +/obj/item/weapon/gun + description_info = "This is a gun. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ + then click where you want to fire." + +/obj/item/weapon/gun/energy + description_info = "This is an energy weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ + then click where you want to fire. Most energy weapons can fire through windows harmlessly. To recharge this weapon, use a weapon recharger." + +/obj/item/weapon/gun/energy/crossbow + description_info = "This is an energy weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ + then click where you want to fire." + description_antag = "This is a stealthy weapon which fires poisoned bolts at your target. When it hits someone, they will suffer a stun effect, in \ + addition to toxins. The energy crossbow recharges itself slowly, and can be concealed in your pocket or bag." + +/obj/item/weapon/gun/energy/gun + description_info = "This is an energy weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ + then click where you want to fire. Most energy weapons can fire through windows harmlessly. To switch between stun and lethal, click the weapon \ + in your hand. To recharge this weapon, use a weapon recharger." + +/obj/item/weapon/gun/energy/gun/taser + description_info = "This is an energy weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ + then click where you want to fire. Most energy weapons can fire through windows harmlessly. To recharge this weapon, use a weapon recharger." + +/obj/item/weapon/gun/energy/gun/stunrevolver + description_info = "This is an energy weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ + then click where you want to fire. Most energy weapons can fire through windows harmlessly. To recharge this weapon, use a weapon recharger." + +/obj/item/weapon/gun/energy/gun/nuclear + description_info = "This is an energy weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ + then click where you want to fire. Most energy weapons can fire through windows harmlessly. To switch between stun and lethal, click the weapon \ + in your hand. Unlike most weapons, this weapon recharges itself." + +/obj/item/weapon/gun/energy/captain + description_info = "This is an energy weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ + then click where you want to fire. Most energy weapons can fire through windows harmlessly. Unlike most weapons, this weapon recharges itself." + +/obj/item/weapon/gun/energy/sniperrifle + description_info = "This is an energy weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ + then click where you want to fire. Most energy weapons can fire through windows harmlessly. To recharge this weapon, use a weapon recharger. \ + To use the scope, use the appropriate verb in the object tab." + +/obj/item/weapon/gun/projectile + description_info = "This is a ballistic weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ + then click where you want to fire. To reload, click the weapon in your hand to unload (if needed), then add the appropiate ammo. The description \ + will tell you what caliber you need." + +/obj/item/weapon/gun/projectile/chameleon + description_info = null //The chameleon gun adopts the description_info of the weapon it is impersonating as, to make meta-ing harder. + description_antag = "This gun can alter its appearance to mimick other weapons. To change the appearance, use the appropriate verb in the object tab. \ + The ammo loaded by default makes the gun useless for actual combat." + +/obj/item/weapon/gun/projectile/chameleon/change(picked in gun_choices) //Making the gun change its help text to match the weapon's help text. + ..(picked) + var/obj/O = gun_choices[picked] + description_info = initial(O.description_info) + +/obj/item/weapon/gun/projectile/shotgun/pump + description_info = "This is a ballistic weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ + then click where you want to fire. After firing, you will need to pump the gun, by clicking on the gun in your hand. To reload, load more shotgun \ + shells into the gun." + +/obj/item/weapon/gun/projectile/heavysniper + description_info = "This is a ballistic weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \ + then click where you want to fire. The gun's chamber can be opened or closed by using it in your hand. To reload, open the chamber, add a new bullet \ + then close it. To use the scope, use the appropriate verb in the object tab." + +//******* +//*Melee* +//******* + +/obj/item/weapon/melee/baton + description_info = "The baton needs to be turned on to apply the stunning effect. Use it in your hand to toggle it on or off. If your intent is \ + set to 'harm', you will inflict damage when using it, regardless if it is on or not. Each stun reduces the baton's charge, which can be replenished by \ + putting it inside a weapon recharger." + +/obj/item/weapon/melee/energy/sword + description_antag = "The energy sword is a very strong melee weapon, capable of severing limbs easily, if they are targeted. It can also has a chance \ + to block projectiles and melee attacks while it is on and being held. The sword can be toggled on or off by using it in your hand. While it is off, \ + it can be concealed in your pocket or bag." + +/obj/item/weapon/melee/cultblade + description_antag = "This sword is a powerful weapon, capable of severing limbs easily, if they are targeted. Nonbelivers are unable to use this weapon." diff --git a/code/modules/examine/examine.dm b/code/modules/examine/examine.dm new file mode 100644 index 0000000000..f09fce6cf3 --- /dev/null +++ b/code/modules/examine/examine.dm @@ -0,0 +1,71 @@ +/* This code is responsible for the examine tab. When someone examines something, it copies the examined object's description_info, + description_fluff, and description_antag, and shows it in a new tab. + + In this file, some atom and mob stuff is defined here. It is defined here instead of in the normal files, to keep the whole system self-contained. + This means that this file can be unchecked, along with the other examine files, and can be removed entirely with no effort. +*/ + + +/atom/ + var/description_info = null //Helpful blue text. + var/description_fluff = null //Green text about the atom's fluff, if any exists. + var/description_antag = null //Malicious red text, for the antags. + +//Override these if you need special behaviour for a specific type. +/atom/proc/get_description_info() + if(description_info) + return description_info + return + +/atom/proc/get_description_fluff() + if(description_fluff) + return description_fluff + return + +/atom/proc/get_description_antag() + if(description_antag) + return description_antag + return + +/mob/living/get_description_fluff() + if(flavor_text) //Get flavor text for the green text. + return flavor_text + else //No flavor text? Try for hardcoded fluff instead. + return ..() + +/mob/living/carbon/human/get_description_fluff() + return print_flavor_text(0) + +/* The examine panel itself */ + +/client/var/description_holders[0] + +/client/proc/update_description_holders(atom/A, update_antag_info=0) + description_holders["info"] = A.get_description_info() + description_holders["fluff"] = A.get_description_fluff() + description_holders["antag"] = (update_antag_info)? A.get_description_antag() : "" + + description_holders["name"] = "[A.name]" + description_holders["icon"] = "\icon[A]" + description_holders["desc"] = A.desc + +/client/Stat() + . = ..() + if(usr && statpanel("Examine")) + stat(null,"[description_holders["icon"]] [description_holders["name"]]") //The name, written in big letters. + stat(null,"[description_holders["desc"]]") //the default examine text. + if(description_holders["info"]) + stat(null,"[description_holders["info"]]") //Blue, informative text. + if(description_holders["fluff"]) + stat(null,"[description_holders["fluff"]]") //Yellow, fluff-related text. + if(description_holders["antag"]) + stat(null,"[description_holders["antag"]]") //Red, malicious antag-related text + +//override examinate verb to update description holders when things are examined +/mob/examinate(atom/A as mob|obj|turf in view()) + if(..()) + return 1 + + var/is_antag = ((mind && mind.special_role) || isobserver(src)) //ghosts don't have minds + if(client) + client.update_description_holders(A, is_antag) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index fe6c3ea031..e35b100269 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -342,7 +342,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite /obj/item/weapon/storage/toolbox/syndicate, /obj/item/weapon/aiModule,\ /obj/item/device/radio/headset/syndicate, /obj/item/weapon/plastique,\ /obj/item/device/powersink, /obj/item/weapon/storage/box/syndie_kit,\ - /obj/item/toy/syndicateballoon, /obj/item/weapon/gun/energy/laser/captain,\ + /obj/item/toy/syndicateballoon, /obj/item/weapon/gun/energy/captain,\ /obj/item/weapon/hand_tele, /obj/item/weapon/rcd, /obj/item/weapon/tank/jetpack,\ /obj/item/clothing/under/rank/captain, /obj/item/device/aicard,\ /obj/item/clothing/shoes/magboots, /obj/item/blueprints, /obj/item/weapon/disk/nuclear,\ diff --git a/code/modules/food/recipes_microwave.dm b/code/modules/food/recipes_microwave.dm index 87617d95ce..9c696c975e 100644 --- a/code/modules/food/recipes_microwave.dm +++ b/code/modules/food/recipes_microwave.dm @@ -34,24 +34,11 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/boiledegg /datum/recipe/dionaroast + fruit = list("apple" = 1) reagents = list("pacid" = 5) //It dissolves the carapace. Still poisonous, though. - items = list( - /obj/item/weapon/holder/diona, - /obj/item/weapon/reagent_containers/food/snacks/grown/apple - ) + items = list(/obj/item/weapon/holder/diona) result = /obj/item/weapon/reagent_containers/food/snacks/dionaroast - -/* -/datum/recipe/bananaphone - reagents = list("psilocybin" = 5) //Trippin' balls, man. - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/banana, - /obj/item/device/radio - ) - result = /obj/item/weapon/reagent_containers/food/snacks/bananaphone -*/ - /datum/recipe/jellydonut reagents = list("berryjuice" = 5, "sugar" = 5) items = list( @@ -80,7 +67,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/donut/normal -/datum/recipe/human/burger +/datum/recipe/humanburger items = list( /obj/item/weapon/reagent_containers/food/snacks/meat/human, /obj/item/weapon/reagent_containers/food/snacks/bun @@ -110,7 +97,7 @@ I said no! /datum/recipe/roburger items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, + /obj/item/weapon/reagent_containers/food/snacks/bun, /obj/item/robot_parts/head ) result = /obj/item/weapon/reagent_containers/food/snacks/roburger @@ -146,8 +133,7 @@ I said no! /datum/recipe/clownburger items = list( /obj/item/weapon/reagent_containers/food/snacks/bun, - /obj/item/clothing/mask/gas/clown_hat, - /* /obj/item/weapon/reagent_containers/food/snacks/grown/banana, */ + /obj/item/clothing/mask/gas/clown_hat ) result = /obj/item/weapon/reagent_containers/food/snacks/clownburger @@ -180,11 +166,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/donkpocket //SPECIAL proc/warm_up(var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/being_cooked) - being_cooked.warm = 1 - being_cooked.reagents.add_reagent("tricordrazine", 5) - being_cooked.bitesize = 6 - being_cooked.name = "Warm " + being_cooked.name - being_cooked.cooltime() + being_cooked.heat() make_food(var/obj/container as obj) var/obj/item/weapon/reagent_containers/food/snacks/donkpocket/being_cooked = ..(container) warm_up(being_cooked) @@ -245,12 +227,12 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/xenomeatbread /datum/recipe/bananabread + fruit = list("banana" = 1) reagents = list("milk" = 5, "sugar" = 15) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/grown/banana, + /obj/item/weapon/reagent_containers/food/snacks/dough ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/bananabread @@ -271,64 +253,26 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/muffin /datum/recipe/eggplantparm + fruit = list("eggplant" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/grown/eggplant - ) + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) result = /obj/item/weapon/reagent_containers/food/snacks/eggplantparm /datum/recipe/soylenviridians - items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans - ) + fruit = list("soybeans" = 1) + reagents = list("flour" = 10) result = /obj/item/weapon/reagent_containers/food/snacks/soylenviridians /datum/recipe/soylentgreen + reagents = list("flour" = 10) items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/meat/human, /obj/item/weapon/reagent_containers/food/snacks/meat/human, + /obj/item/weapon/reagent_containers/food/snacks/meat/human ) result = /obj/item/weapon/reagent_containers/food/snacks/soylentgreen -/datum/recipe/carrotcake - reagents = list("milk" = 5, "sugar" = 15) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, - /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, - /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake - -/datum/recipe/cheesecake - reagents = list("milk" = 5, "sugar" = 15) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake - -/datum/recipe/plaincake - reagents = list("milk" = 5, "sugar" = 15) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake - /datum/recipe/meatpie items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, @@ -351,25 +295,23 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/xemeatpie /datum/recipe/pie + fruit = list("banana" = 1) reagents = list("sugar" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/grown/banana, - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough) result = /obj/item/weapon/reagent_containers/food/snacks/pie /datum/recipe/cherrypie + fruit = list("cherries" = 1) reagents = list("sugar" = 10) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/grown/cherries, ) result = /obj/item/weapon/reagent_containers/food/snacks/cherrypie /datum/recipe/berryclafoutis + fruit = list("berries" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/grown/berries, ) result = /obj/item/weapon/reagent_containers/food/snacks/berryclafoutis @@ -387,7 +329,7 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/donut/chaos -/datum/recipe/human/kabob +/datum/recipe/humankabob items = list( /obj/item/stack/rods, /obj/item/weapon/reagent_containers/food/snacks/meat/human, @@ -434,10 +376,8 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/tofubread /datum/recipe/loadedbakedpotato - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/potato, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - ) + fruit = list("potato" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/cheesewedge) result = /obj/item/weapon/reagent_containers/food/snacks/loadedbakedpotato /datum/recipe/cheesyfries @@ -448,20 +388,17 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/cheesyfries /datum/recipe/cubancarp + fruit = list("chili" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/grown/chili, - /obj/item/weapon/reagent_containers/food/snacks/carpmeat, + /obj/item/weapon/reagent_containers/food/snacks/carpmeat ) result = /obj/item/weapon/reagent_containers/food/snacks/cubancarp /datum/recipe/popcorn - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/corn - ) + fruit = list("corn" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/popcorn - /datum/recipe/cookie reagents = list("milk" = 5, "sugar" = 5) items = list( @@ -494,91 +431,69 @@ I said no! /datum/recipe/meatsteak reagents = list("sodiumchloride" = 1, "blackpepper" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meat - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/meat) result = /obj/item/weapon/reagent_containers/food/snacks/meatsteak /datum/recipe/syntisteak reagents = list("sodiumchloride" = 1, "blackpepper" = 1) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh) result = /obj/item/weapon/reagent_containers/food/snacks/meatsteak /datum/recipe/pizzamargherita + fruit = list("tomato" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita /datum/recipe/meatpizza + fruit = list("tomato" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza /datum/recipe/syntipizza + fruit = list("tomato" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/meatpizza /datum/recipe/mushroompizza + fruit = list("mushroom" = 5, "tomato" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/mushroompizza /datum/recipe/vegetablepizza + fruit = list("eggplant" = 1, "carrot" = 1, "corn" = 1, "tomato" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/grown/eggplant, - /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, - /obj/item/weapon/reagent_containers/food/snacks/grown/corn, - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, - /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/vegetablepizza /datum/recipe/spacylibertyduff - reagents = list("water" = 5, "vodka" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap, - ) + reagents = list("water" = 5, "vodka" = 5, "psilocybin" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/spacylibertyduff /datum/recipe/amanitajelly - reagents = list("water" = 5, "vodka" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita, - ) + reagents = list("water" = 5, "vodka" = 5, "amatoxin" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/amanitajelly make_food(var/obj/container as obj) var/obj/item/weapon/reagent_containers/food/snacks/amanitajelly/being_cooked = ..(container) @@ -586,30 +501,21 @@ I said no! return being_cooked /datum/recipe/meatballsoup + fruit = list("carrot" = 1, "potato" = 1) reagents = list("water" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meatball , - /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, - /obj/item/weapon/reagent_containers/food/snacks/grown/potato, - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/meatball) result = /obj/item/weapon/reagent_containers/food/snacks/meatballsoup /datum/recipe/vegetablesoup + fruit = list("carrot" = 1, "potato" = 1, "corn" = 1, "eggplant" = 1) reagents = list("water" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, - /obj/item/weapon/reagent_containers/food/snacks/grown/corn, - /obj/item/weapon/reagent_containers/food/snacks/grown/eggplant, - /obj/item/weapon/reagent_containers/food/snacks/grown/potato, - ) result = /obj/item/weapon/reagent_containers/food/snacks/vegetablesoup /datum/recipe/nettlesoup + fruit = list("nettle" = 1, "potato" = 1) reagents = list("water" = 10) items = list( - /obj/item/weapon/grown/nettle, - /obj/item/weapon/reagent_containers/food/snacks/grown/potato, - /obj/item/weapon/reagent_containers/food/snacks/egg, + /obj/item/weapon/reagent_containers/food/snacks/egg ) result = /obj/item/weapon/reagent_containers/food/snacks/nettlesoup @@ -618,33 +524,23 @@ I said no! result= /obj/item/weapon/reagent_containers/food/snacks/wishsoup /datum/recipe/hotchili - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/grown/chili, - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, - ) + fruit = list("chili" = 1, "tomato" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/meat) result = /obj/item/weapon/reagent_containers/food/snacks/hotchili /datum/recipe/coldchili - items = list( - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/grown/icepepper, - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, - ) + fruit = list("icechili" = 1, "tomato" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/meat) result = /obj/item/weapon/reagent_containers/food/snacks/coldchili /datum/recipe/amanita_pie - items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita, - ) + reagents = list("amatoxin" = 5) + items = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough) result = /obj/item/weapon/reagent_containers/food/snacks/amanita_pie /datum/recipe/plump_pie - items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet, - ) + fruit = list("plumphelmet" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough) result = /obj/item/weapon/reagent_containers/food/snacks/plump_pie /datum/recipe/spellburger @@ -672,30 +568,24 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/bigbiteburger /datum/recipe/enchiladas - items = list( - /obj/item/weapon/reagent_containers/food/snacks/cutlet, - /obj/item/weapon/reagent_containers/food/snacks/grown/chili, - /obj/item/weapon/reagent_containers/food/snacks/grown/chili, - /obj/item/weapon/reagent_containers/food/snacks/grown/corn, - ) + fruit = list("chili" = 2, "corn" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/cutlet) result = /obj/item/weapon/reagent_containers/food/snacks/enchiladas /datum/recipe/creamcheesebread items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, + /obj/item/weapon/reagent_containers/food/snacks/dough, + /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, ) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/creamcheesebread /datum/recipe/monkeysdelight - reagents = list("sodiumchloride" = 1, "blackpepper" = 1) + fruit = list("banana" = 1) + reagents = list("sodiumchloride" = 1, "blackpepper" = 1, "flour" = 10) items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/monkeycube, - /obj/item/weapon/reagent_containers/food/snacks/grown/banana, + /obj/item/weapon/reagent_containers/food/snacks/monkeycube ) result = /obj/item/weapon/reagent_containers/food/snacks/monkeysdelight @@ -714,16 +604,6 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/fishandchips -/datum/recipe/birthdaycake - reagents = list("milk" = 5, "sugar" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/clothing/head/cakehat - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake - /datum/recipe/bread items = list( /obj/item/weapon/reagent_containers/food/snacks/dough, @@ -755,11 +635,8 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/grilledcheese /datum/recipe/tomatosoup + fruit = list("tomato" = 2) reagents = list("water" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, - ) result = /obj/item/weapon/reagent_containers/food/snacks/tomatosoup /datum/recipe/rofflewaffles @@ -771,15 +648,9 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/rofflewaffles /datum/recipe/stew + fruit = list("potato" = 1, "tomato" = 1, "carrot" = 1, "eggplant" = 1, "mushroom" = 1) reagents = list("water" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, - /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/grown/potato, - /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, - /obj/item/weapon/reagent_containers/food/snacks/grown/eggplant, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom, - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/meat) result = /obj/item/weapon/reagent_containers/food/snacks/stew /datum/recipe/slimetoast @@ -807,11 +678,10 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/milosoup /datum/recipe/stewedsoymeat + fruit = list("carrot" = 1, "tomato" = 1) items = list( /obj/item/weapon/reagent_containers/food/snacks/soydope, - /obj/item/weapon/reagent_containers/food/snacks/soydope, - /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, + /obj/item/weapon/reagent_containers/food/snacks/soydope ) result = /obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat @@ -837,19 +707,14 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/ricepudding /datum/recipe/pastatomato + fruit = list("tomato" = 2) reagents = list("water" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/spagetti, - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, - ) + items = list(/obj/item/weapon/reagent_containers/food/snacks/spagetti) result = /obj/item/weapon/reagent_containers/food/snacks/pastatomato /datum/recipe/poppypretzel - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/poppy, - /obj/item/weapon/reagent_containers/food/snacks/dough, - ) + fruit = list("poppy" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/dough) result = /obj/item/weapon/reagent_containers/food/snacks/poppypretzel /datum/recipe/meatballspagetti @@ -873,42 +738,27 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/spesslaw /datum/recipe/superbiteburger + fruit = list("tomato" = 1) reagents = list("sodiumchloride" = 5, "blackpepper" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/bigbiteburger, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/meat, - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/boiledegg, ) result = /obj/item/weapon/reagent_containers/food/snacks/superbiteburger /datum/recipe/candiedapple + fruit = list("apple" = 1) reagents = list("water" = 5, "sugar" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/apple - ) result = /obj/item/weapon/reagent_containers/food/snacks/candiedapple /datum/recipe/applepie - items = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, - /obj/item/weapon/reagent_containers/food/snacks/grown/apple, - ) + fruit = list("apple" = 1) + items = list(/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough) result = /obj/item/weapon/reagent_containers/food/snacks/applepie -/datum/recipe/applecake - reagents = list("milk" = 5, "sugar" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/dough, - /obj/item/weapon/reagent_containers/food/snacks/grown/apple, - /obj/item/weapon/reagent_containers/food/snacks/grown/apple, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake - /datum/recipe/slimeburger reagents = list("slimejelly" = 5) items = list( @@ -947,68 +797,8 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/cherry -/datum/recipe/orangecake - reagents = list("milk" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/grown/orange, - /obj/item/weapon/reagent_containers/food/snacks/grown/orange, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake - -/datum/recipe/limecake - reagents = list("milk" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/grown/lime, - /obj/item/weapon/reagent_containers/food/snacks/grown/lime, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake - -/datum/recipe/lemoncake - reagents = list("milk" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/grown/lemon, - /obj/item/weapon/reagent_containers/food/snacks/grown/lemon, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake - -/datum/recipe/chocolatecake - reagents = list("milk" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/chocolatebar, - /obj/item/weapon/reagent_containers/food/snacks/chocolatebar, - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake - /datum/recipe/bloodsoup - reagents = list("blood" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/bloodtomato, - /obj/item/weapon/reagent_containers/food/snacks/grown/bloodtomato, - ) + reagents = list("blood" = 30) result = /obj/item/weapon/reagent_containers/food/snacks/bloodsoup /datum/recipe/slimesoup @@ -1023,19 +813,6 @@ I said no! ) result = /obj/item/weapon/reagent_containers/food/snacks/boiledslimecore -/datum/recipe/braincake - reagents = list("milk" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/organ/brain - ) - result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake - /datum/recipe/chocolateegg items = list( /obj/item/weapon/reagent_containers/food/snacks/egg, @@ -1051,9 +828,8 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/sausage /datum/recipe/fishfingers + reagents = list("flour" = 10) items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, /obj/item/weapon/reagent_containers/food/snacks/egg, /obj/item/weapon/reagent_containers/food/snacks/carpmeat, ) @@ -1070,84 +846,53 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/mysterysoup /datum/recipe/pumpkinpie - reagents = list("milk" = 5, "sugar" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin, - /obj/item/weapon/reagent_containers/food/snacks/egg, - ) + fruit = list("pumpkin" = 1) + reagents = list("milk" = 5, "sugar" = 5, "egg" = 3, "flour" = 10) result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pumpkinpie /datum/recipe/plumphelmetbiscuit - reagents = list("water" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet, - ) + fruit = list("plumphelmet" = 1) + reagents = list("water" = 5, "flour" = 5) result = /obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit /datum/recipe/mushroomsoup + fruit = list("mushroom" = 1) reagents = list("water" = 5, "milk" = 5) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/chanterelle, - ) result = /obj/item/weapon/reagent_containers/food/snacks/mushroomsoup /datum/recipe/chawanmushi + fruit = list("mushroom" = 1) reagents = list("water" = 5, "soysauce" = 5) items = list( /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/chanterelle, + /obj/item/weapon/reagent_containers/food/snacks/egg ) result = /obj/item/weapon/reagent_containers/food/snacks/chawanmushi /datum/recipe/beetsoup + fruit = list("whitebeet" = 1, "cabbage" = 1) reagents = list("water" = 10) - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/whitebeet, - /obj/item/weapon/reagent_containers/food/snacks/grown/cabbage, - ) result = /obj/item/weapon/reagent_containers/food/snacks/beetsoup /datum/recipe/appletart - reagents = list("sugar" = 5, "milk" = 5) + fruit = list("goldapple" = 1) + reagents = list("sugar" = 5, "milk" = 5, "flour" = 10) items = list( - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/flour, - /obj/item/weapon/reagent_containers/food/snacks/egg, - /obj/item/weapon/reagent_containers/food/snacks/grown/goldapple, + /obj/item/weapon/reagent_containers/food/snacks/egg ) result = /obj/item/weapon/reagent_containers/food/snacks/appletart /datum/recipe/tossedsalad - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/cabbage, - /obj/item/weapon/reagent_containers/food/snacks/grown/cabbage, - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato, - /obj/item/weapon/reagent_containers/food/snacks/grown/carrot, - /obj/item/weapon/reagent_containers/food/snacks/grown/apple, - ) + fruit = list("cabbage" = 2, "tomato" = 1, "carrot" = 1, "apple" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/tossedsalad /datum/recipe/aesirsalad - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus, - /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus, - /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus, - /obj/item/weapon/reagent_containers/food/snacks/grown/goldapple, - ) + fruit = list("goldapple" = 1, "ambrosiadeus" = 1) result = /obj/item/weapon/reagent_containers/food/snacks/aesirsalad /datum/recipe/validsalad - items = list( - /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris, - /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris, - /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris, - /obj/item/weapon/reagent_containers/food/snacks/grown/potato, - /obj/item/weapon/reagent_containers/food/snacks/meatball, - ) + fruit = list("potato" = 1, "ambrosia" = 3) + items = list(/obj/item/weapon/reagent_containers/food/snacks/meatball) result = /obj/item/weapon/reagent_containers/food/snacks/validsalad make_food(var/obj/container as obj) var/obj/item/weapon/reagent_containers/food/snacks/validsalad/being_cooked = ..(container) @@ -1230,3 +975,50 @@ I said no! result = /obj/item/weapon/reagent_containers/food/snacks/mint +// Cakes. +/datum/recipe/cake + reagents = list("milk" = 5, "flour" = 15, "sugar" = 15, "egg" = 9) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/plaincake + +/datum/recipe/cake/carrot + fruit = list("carrot" = 3) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/carrotcake + +/datum/recipe/cake/cheese + items = list( + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, + /obj/item/weapon/reagent_containers/food/snacks/cheesewedge + ) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesecake + +/datum/recipe/cake/orange + fruit = list("orange" = 1) + reagents = list("milk" = 5, "flour" = 15, "egg" = 9, "orangejuice" = 3, "sugar" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/orangecake + +/datum/recipe/cake/lime + fruit = list("lime" = 1) + reagents = list("milk" = 5, "flour" = 15, "egg" = 9, "limejuice" = 3, "sugar" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/limecake + +/datum/recipe/cake/lemon + fruit = list("lemon" = 1) + reagents = list("milk" = 5, "flour" = 15, "egg" = 9, "lemonjuice" = 3, "sugar" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/lemoncake + +/datum/recipe/cake/chocolate + items = list(/obj/item/weapon/reagent_containers/food/snacks/chocolatebar) + reagents = list("milk" = 5, "flour" = 15, "egg" = 9, "coco" = 4, "sugar" = 5) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/chocolatecake + +/datum/recipe/cake/birthday + items = list(/obj/item/clothing/head/cakehat) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake + +/datum/recipe/cake/apple + fruit = list("apple" = 2) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/applecake + +/datum/recipe/cake/brain + items = list(/obj/item/organ/brain) + result = /obj/item/weapon/reagent_containers/food/snacks/sliceable/braincake \ No newline at end of file diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/modules/holodeck/HolodeckControl.dm similarity index 54% rename from code/game/machinery/computer/HolodeckControl.dm rename to code/modules/holodeck/HolodeckControl.dm index 40a403a35f..f19a8cd4ce 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/modules/holodeck/HolodeckControl.dm @@ -10,6 +10,7 @@ var/global/list/holodeck_programs = list( "snowfield" = /area/holodeck/source_snowfield, \ "theatre" = /area/holodeck/source_theatre, \ "meetinghall" = /area/holodeck/source_meetinghall, \ + "courtroom" = /area/holodeck/source_courtroom, \ "burntest" = /area/holodeck/source_burntest, \ "wildlifecarp" = /area/holodeck/source_wildlife, \ "turnoff" = /area/holodeck/source_plating \ @@ -27,24 +28,26 @@ var/global/list/holodeck_programs = list( var/area/linkedholodeck = null var/area/target = null var/active = 0 - var/list/holographic_items = list() + var/list/holographic_objs = list() var/list/holographic_mobs = list() var/damaged = 0 var/safety_disabled = 0 var/mob/last_to_emag = null var/last_change = 0 + var/last_gravity_change = 0 var/list/supported_programs = list( \ "Empty Court" = "emptycourt", \ - "Boxing Court"="boxingcourt", \ "Basketball Court" = "basketball", \ "Thunderdome Court" = "thunderdomecourt", \ + "Boxing Ring"="boxingcourt", \ "Beach" = "beach", \ "Desert" = "desert", \ "Space" = "space", \ "Picnic Area" = "picnicarea", \ "Snow Field" = "snowfield", \ "Theatre" = "theatre", \ - "Meeting Hall" = "meetinghall" \ + "Meeting Hall" = "meetinghall", \ + "Courtroom" = "courtroom" \ ) var/list/restricted_programs = list("Atmospheric Burn Simulation" = "burntest", "Wildlife Simulation" = "wildlifecarp") @@ -61,11 +64,16 @@ var/global/list/holodeck_programs = list( dat += "Holodeck Control System
    " dat += "
    Current Loaded Programs:
    " for(var/prog in supported_programs) - dat += "(([prog]))
    " + dat += "([prog])
    " + dat += "
    " + dat += "(Turn Off)
    " + + dat += "
    " dat += "Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.
    " if(issilicon(user)) + dat += "
    " if(safety_disabled) if (emagged) dat += "ERROR: Cannot re-enable Safety Protocols.
    " @@ -74,6 +82,8 @@ var/global/list/holodeck_programs = list( else dat += "(Override Safety Protocols?)
    " + dat += "
    " + if(safety_disabled) for(var/prog in restricted_programs) dat += "(Begin [prog])
    " @@ -83,6 +93,11 @@ var/global/list/holodeck_programs = list( else dat += "Safety Protocols are ENABLED
    " + if(linkedholodeck.has_gravity) + dat += "Gravity is (ON)
    " + else + dat += "Gravity is (OFF)
    " + user << browse(dat, "window=computer;size=400x500") onclose(user, "computer") @@ -91,7 +106,7 @@ var/global/list/holodeck_programs = list( /obj/machinery/computer/HolodeckControl/Topic(href, href_list) if(..()) - return + return 1 if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.set_machine(src) @@ -118,6 +133,9 @@ var/global/list/holodeck_programs = list( message_admins("[key_name_admin(usr)] restored the holodeck's safeties") log_game("[key_name(usr)] restored the holodeck's safeties") + else if(href_list["gravity"]) + toggleGravity(linkedholodeck) + src.add_fingerprint(usr) src.updateUsrDialog() return @@ -190,7 +208,7 @@ var/global/list/holodeck_programs = list( emergencyShutdown() /obj/machinery/computer/HolodeckControl/process() - for(var/item in holographic_items) // do this first, to make sure people don't take items out when power is down. + for(var/item in holographic_objs) // do this first, to make sure people don't take items out when power is down. if(!(get_turf(item) in linkedholodeck)) derez(item, 0) @@ -203,7 +221,7 @@ var/global/list/holodeck_programs = list( if(!..()) return if(active) - use_power(item_power_usage * (holographic_items.len + holographic_mobs.len)) + use_power(item_power_usage * (holographic_objs.len + holographic_mobs.len)) if(!checkInteg(linkedholodeck)) damaged = 1 @@ -225,7 +243,7 @@ var/global/list/holodeck_programs = list( T.hotspot_expose(1000,500,1) /obj/machinery/computer/HolodeckControl/proc/derez(var/obj/obj , var/silent = 1) - holographic_items.Remove(obj) + holographic_objs.Remove(obj) if(obj == null) return @@ -253,7 +271,7 @@ var/global/list/holodeck_programs = list( if(toggleOn) var/area/targetsource = locate(/area/holodeck/source_emptycourt) - holographic_items = targetsource.copy_contents_to(linkedholodeck) + holographic_objs = targetsource.copy_contents_to(linkedholodeck) spawn(30) for(var/obj/effect/landmark/L in linkedholodeck) @@ -270,8 +288,11 @@ var/global/list/holodeck_programs = list( active = 1 use_power = 2 else - for(var/item in holographic_items) + for(var/item in holographic_objs) derez(item) + if(!linkedholodeck.has_gravity) + linkedholodeck.gravitychange(1,linkedholodeck) + var/area/targetsource = locate(/area/holodeck/source_plating) targetsource.copy_contents_to(linkedholodeck , 1) active = 0 @@ -292,7 +313,7 @@ var/global/list/holodeck_programs = list( active = 1 use_power = 2 - for(var/item in holographic_items) + for(var/item in holographic_objs) derez(item) for(var/mob/living/simple_animal/hostile/carp/holodeck/C in holographic_mobs) @@ -302,7 +323,9 @@ var/global/list/holodeck_programs = list( for(var/obj/effect/decal/cleanable/blood/B in linkedholodeck) del(B) - holographic_items = A.copy_contents_to(linkedholodeck , 1) + holographic_objs = A.copy_contents_to(linkedholodeck , 1) + for(var/obj/holo_obj in holographic_objs) + holo_obj.alpha *= 0.8 //give holodeck objs a slight transparency spawn(30) for(var/obj/effect/landmark/L in linkedholodeck) @@ -325,9 +348,27 @@ var/global/list/holodeck_programs = list( update_projections() +/obj/machinery/computer/HolodeckControl/proc/toggleGravity(var/area/A) + if(world.time < (last_gravity_change + 25)) + if(world.time < (last_gravity_change + 15))//To prevent super-spam clicking + return + for(var/mob/M in range(3,src)) + M.show_message("\b ERROR. Recalibrating gravity field.") + last_change = world.time + return + + last_gravity_change = world.time + active = 1 + use_power = 1 + + if(A.has_gravity) + A.gravitychange(0,A) + else + A.gravitychange(1,A) + /obj/machinery/computer/HolodeckControl/proc/emergencyShutdown() //Get rid of any items - for(var/item in holographic_items) + for(var/item in holographic_objs) derez(item) for(var/mob/living/simple_animal/hostile/carp/holodeck/C in holographic_mobs) holographic_mobs -= C @@ -337,338 +378,10 @@ var/global/list/holodeck_programs = list( if(target) loadProgram(target) + if(!linkedholodeck.has_gravity) + linkedholodeck.gravitychange(1,linkedholodeck) + var/area/targetsource = locate(/area/holodeck/source_plating) targetsource.copy_contents_to(linkedholodeck , 1) active = 0 use_power = 1 - - - - - - - -// Holographic Items! - -/turf/simulated/floor/holofloor/ - thermal_conductivity = 0 - -/turf/simulated/floor/holofloor/grass - name = "Lush Grass" - icon_state = "grass1" - floor_type = /obj/item/stack/tile/grass - - New() - icon_state = "grass[pick("1","2","3","4")]" - ..() - spawn(4) - update_icon() - for(var/direction in cardinal) - if(istype(get_step(src,direction),/turf/simulated/floor)) - var/turf/simulated/floor/FF = get_step(src,direction) - FF.update_icon() //so siding get updated properly - -/turf/simulated/floor/holofloor/desert - name = "desert sand" - desc = "Uncomfortably gritty for a hologram." - icon_state = "asteroid" - -/turf/simulated/floor/holofloor/desert/New() - ..() - if(prob(10)) - overlays += "asteroid[rand(0,9)]" - -/turf/simulated/floor/holofloor/attackby(obj/item/weapon/W as obj, mob/user as mob) - return - // HOLOFLOOR DOES NOT GIVE A FUCK - -/obj/structure/table/holotable - name = "table" - desc = "A square piece of metal standing on four metal legs. It can not move." - icon = 'icons/obj/structures.dmi' - icon_state = "table" - density = 1 - anchored = 1.0 - layer = 2.8 - throwpass = 1 //You can throw objects over this, despite it's density. - -/obj/structure/table/holotable/attack_hand(mob/user as mob) - return // HOLOTABLE DOES NOT GIVE A FUCK - - -/obj/structure/table/holotable/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/wrench)) - user << "It's a holotable! There are no bolts!" - return - - if(isrobot(user)) - return - - ..() - -/obj/structure/table/holotable/wood - name = "table" - desc = "A square piece of wood standing on four wooden legs. It can not move." - icon = 'icons/obj/structures.dmi' - icon_state = "wood_table" - -/obj/structure/holostool - name = "stool" - desc = "Apply butt." - icon = 'icons/obj/objects.dmi' - icon_state = "stool" - anchored = 1.0 - pressure_resistance = 15 - - -/obj/item/clothing/gloves/boxing/hologlove - name = "boxing gloves" - desc = "Because you really needed another excuse to punch your crewmates." - icon_state = "boxing" - item_state = "boxing" - -/obj/structure/holowindow - name = "reinforced window" - icon = 'icons/obj/structures.dmi' - icon_state = "rwindow" - desc = "A window." - density = 1 - layer = 3.2//Just above doors - pressure_resistance = 4*ONE_ATMOSPHERE - anchored = 1.0 - flags = ON_BORDER - - -/obj/structure/holowindow/Del() - ..() - -/obj/item/weapon/holo - damtype = HALLOSS - -/obj/item/weapon/holo/esword - desc = "May the force be within you. Sorta." - icon_state = "sword0" - force = 3.0 - throw_speed = 1 - throw_range = 5 - throwforce = 0 - w_class = 2.0 - flags = NOSHIELD | NOBLOODY - var/active = 0 - -/obj/item/weapon/holo/esword/green - New() - item_color = "green" - -/obj/item/weapon/holo/esword/red - New() - item_color = "red" - -/obj/item/weapon/holo/esword/IsShield() - if(active) - return 1 - return 0 - -/obj/item/weapon/holo/esword/attack(target as mob, mob/user as mob) - ..() - -/obj/item/weapon/holo/esword/New() - item_color = pick("red","blue","green","purple") - -/obj/item/weapon/holo/esword/attack_self(mob/living/user as mob) - active = !active - if (active) - force = 30 - icon_state = "sword[item_color]" - w_class = 4 - playsound(user, 'sound/weapons/saberon.ogg', 50, 1) - user << "[src] is now active." - else - force = 3 - icon_state = "sword0" - w_class = 2 - playsound(user, 'sound/weapons/saberoff.ogg', 50, 1) - user << "[src] can now be concealed." - - if(istype(user,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - H.update_inv_l_hand() - H.update_inv_r_hand() - - add_fingerprint(user) - return - -//BASKETBALL OBJECTS - -/obj/item/weapon/beach_ball/holoball - icon = 'icons/obj/basketball.dmi' - icon_state = "basketball" - name = "basketball" - item_state = "basketball" - desc = "Here's your chance, do your dance at the Space Jam." - w_class = 4 //Stops people from hiding it in their bags/pockets - -/obj/structure/holohoop - name = "basketball hoop" - desc = "Boom, Shakalaka!" - icon = 'icons/obj/basketball.dmi' - icon_state = "hoop" - anchored = 1 - density = 1 - throwpass = 1 - -/obj/structure/holohoop/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) - var/obj/item/weapon/grab/G = W - if(G.state<2) - user << "You need a better grip to do that!" - return - G.affecting.loc = src.loc - G.affecting.Weaken(5) - visible_message("[G.assailant] dunks [G.affecting] into the [src]!", 3) - del(W) - return - else if (istype(W, /obj/item) && get_dist(src,user)<2) - user.drop_item(src) - visible_message("[user] dunks [W] into the [src]!", 3) - return - -/obj/structure/holohoop/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if (istype(mover,/obj/item) && mover.throwing) - var/obj/item/I = mover - if(istype(I, /obj/item/projectile)) - return - if(prob(50)) - I.loc = src.loc - visible_message("Swish! \the [I] lands in \the [src].", 3) - else - visible_message("\The [I] bounces off of \the [src]'s rim!", 3) - return 0 - else - return ..(mover, target, height, air_group) - - -/obj/machinery/readybutton - name = "Ready Declaration Device" - desc = "This device is used to declare ready. If all devices in an area are ready, the event will begin!" - icon = 'icons/obj/monitors.dmi' - icon_state = "auth_off" - var/ready = 0 - var/area/currentarea = null - var/eventstarted = 0 - - anchored = 1.0 - use_power = 1 - idle_power_usage = 2 - active_power_usage = 6 - power_channel = ENVIRON - -/obj/machinery/readybutton/attack_ai(mob/user as mob) - user << "The station AI is not to interact with these devices!" - return - -/obj/machinery/readybutton/New() - ..() - - -/obj/machinery/readybutton/attackby(obj/item/weapon/W as obj, mob/user as mob) - user << "The device is a solid button, there's nothing you can do with it!" - -/obj/machinery/readybutton/attack_hand(mob/user as mob) - - if(user.stat || stat & (NOPOWER|BROKEN)) - user << "This device is not powered." - return - - if(!user.IsAdvancedToolUser()) - return 0 - - currentarea = get_area(src.loc) - if(!currentarea) - del(src) - - if(eventstarted) - usr << "The event has already begun!" - return - - ready = !ready - - update_icon() - - var/numbuttons = 0 - var/numready = 0 - for(var/obj/machinery/readybutton/button in currentarea) - numbuttons++ - if (button.ready) - numready++ - - if(numbuttons == numready) - begin_event() - -/obj/machinery/readybutton/update_icon() - if(ready) - icon_state = "auth_on" - else - icon_state = "auth_off" - -/obj/machinery/readybutton/proc/begin_event() - - eventstarted = 1 - - for(var/obj/structure/holowindow/W in currentarea) - del(W) - - for(var/mob/M in currentarea) - M << "FIGHT!" - -//Holorack - -/obj/structure/table/rack/holorack - name = "rack" - desc = "Different from the Middle Ages version." - icon = 'icons/obj/objects.dmi' - icon_state = "rack" - -/obj/structure/table/rack/holorack/attack_hand(mob/user as mob) - return - -/obj/structure/table/rack/holorack/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/wrench)) - user << "It's a holorack! You can't unwrench it!" - return - -//Holocarp - -/mob/living/simple_animal/hostile/carp/holodeck - icon = 'icons/mob/AI.dmi' - icon_state = "holo4" - icon_living = "holo4" - icon_dead = "holo4" - icon_gib = null - meat_amount = 0 - meat_type = null - -/mob/living/simple_animal/hostile/carp/holodeck/proc/set_safety(var/safe) - if (safe) - faction = "neutral" - melee_damage_lower = 0 - melee_damage_upper = 0 - wall_smash = 0 - destroy_surroundings = 0 - else - faction = "carp" - melee_damage_lower = initial(melee_damage_lower) - melee_damage_upper = initial(melee_damage_upper) - wall_smash = initial(wall_smash) - destroy_surroundings = initial(destroy_surroundings) - -/mob/living/simple_animal/hostile/carp/holodeck/gib() - derez() //holograms can't gib - -/mob/living/simple_animal/hostile/carp/holodeck/death() - ..() - derez() - -/mob/living/simple_animal/hostile/carp/holodeck/proc/derez() - visible_message("\The [src] fades away!") - del(src) diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm new file mode 100644 index 0000000000..07bdccef52 --- /dev/null +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -0,0 +1,427 @@ +// Holographic Items! + +/turf/simulated/floor/holofloor/ + thermal_conductivity = 0 + +/turf/simulated/floor/holofloor/grass + name = "Lush Grass" + icon_state = "grass1" + floor_type = /obj/item/stack/tile/grass + + New() + icon_state = "grass[pick("1","2","3","4")]" + ..() + spawn(4) + update_icon() + for(var/direction in cardinal) + if(istype(get_step(src,direction),/turf/simulated/floor)) + var/turf/simulated/floor/FF = get_step(src,direction) + FF.update_icon() //so siding get updated properly + +/turf/simulated/floor/holofloor/space + icon = 'icons/turf/space.dmi' + name = "\proper space" + icon_state = "0" + +/turf/simulated/floor/holofloor/space/New() + icon_state = "[((x + y) ^ ~(x * y) + z) % 25]" + +/turf/simulated/floor/holofloor/desert + name = "desert sand" + desc = "Uncomfortably gritty for a hologram." + icon_state = "asteroid" + +/turf/simulated/floor/holofloor/desert/New() + ..() + if(prob(10)) + overlays += "asteroid[rand(0,9)]" + +/turf/simulated/floor/holofloor/attackby(obj/item/weapon/W as obj, mob/user as mob) + return + // HOLOFLOOR DOES NOT GIVE A FUCK + +/obj/structure/table/holotable + name = "table" + desc = "A square piece of metal standing on four metal legs. It can not move." + icon = 'icons/obj/structures.dmi' + icon_state = "table" + density = 1 + anchored = 1.0 + layer = 2.8 + throwpass = 1 //You can throw objects over this, despite it's density. + +/obj/structure/table/holotable/attack_hand(mob/user as mob) + return // HOLOTABLE DOES NOT GIVE A FUCK + + +/obj/structure/table/holotable/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/wrench)) + user << "It's a holotable! There are no bolts!" + return + + if(isrobot(user)) + return + + ..() + +/obj/structure/table/woodentable/holotable + name = "table" + desc = "A square piece of wood standing on four wooden legs. It can not move." + icon = 'icons/obj/structures.dmi' + icon_state = "wood_table" + +/obj/structure/holostool + name = "stool" + desc = "Apply butt." + icon = 'icons/obj/objects.dmi' + icon_state = "stool" + anchored = 1.0 + pressure_resistance = 15 + + +/obj/item/clothing/gloves/boxing/hologlove + name = "boxing gloves" + desc = "Because you really needed another excuse to punch your crewmates." + icon_state = "boxing" + item_state = "boxing" + +/obj/structure/window/reinforced/holowindow/Del() + ..() + +/obj/structure/window/reinforced/holowindow/attackby(obj/item/W as obj, mob/user as mob) + if(!istype(W)) return//I really wish I did not need this + if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) + var/obj/item/weapon/grab/G = W + if(istype(G.affecting,/mob/living)) + var/mob/living/M = G.affecting + var/state = G.state + del(W) //gotta delete it here because if window breaks, it won't get deleted + switch (state) + if(1) + M.visible_message("[user] slams [M] against \the [src]!") + M.apply_damage(7) + hit(10) + if(2) + M.visible_message("[user] bashes [M] against \the [src]!") + if (prob(50)) + M.Weaken(1) + M.apply_damage(10) + hit(25) + if(3) + M.visible_message("[user] crushes [M] against \the [src]!") + M.Weaken(5) + M.apply_damage(20) + hit(50) + return + + if(W.flags & NOBLUDGEON) return + + if(istype(W, /obj/item/weapon/screwdriver)) + user << ("It's a holowindow, you can't unfasten it!") + else if(istype(W, /obj/item/weapon/crowbar) && reinf && state <= 1) + user << ("It's a holowindow, you can't pry it!") + else if(istype(W, /obj/item/weapon/wrench) && !anchored && (!state || !reinf)) + user << ("It's a holowindow, you can't dismantle it!") + else + if(W.damtype == BRUTE || W.damtype == BURN) + hit(W.force) + if(health <= 7) + anchored = 0 + update_nearby_icons() + step(src, get_dir(user, src)) + else + playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1) + ..() + return + +/obj/structure/window/reinforced/holowindow/shatter(var/display_message = 1) + playsound(src, "shatter", 70, 1) + if(display_message) + visible_message("[src] fades away as it shatters!") + del(src) + return + +/obj/structure/window/reinforced/holowindow/disappearing/Del() + ..() + +/obj/machinery/door/window/holowindoor/Del() + ..() + +/obj/machinery/door/window/holowindoor/attackby(obj/item/weapon/I as obj, mob/user as mob) + + if (src.operating == 1) + return + + if(src.density && istype(I, /obj/item/weapon) && !istype(I, /obj/item/weapon/card)) + var/aforce = I.force + playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) + visible_message("\red [src] was hit by [I].") + if(I.damtype == BRUTE || I.damtype == BURN) + take_damage(aforce) + return + + src.add_fingerprint(user) + if (!src.requiresID()) + user = null + + if (src.allowed(user)) + if (src.density) + open() + else + close() + + else if (src.density) + flick(text("[]deny", src.base_state), src) + + return + +/obj/machinery/door/window/holowindoor/shatter(var/display_message = 1) + src.density = 0 + playsound(src, "shatter", 70, 1) + if(display_message) + visible_message("[src] fades away as it shatters!") + del(src) + +/obj/structure/bed/chair/holochair/Del() + ..() + +/obj/structure/bed/chair/holochair/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/wrench)) + user << ("It's a holochair, you can't dismantle it!") + return + +/obj/item/weapon/holo + damtype = HALLOSS + +/obj/item/weapon/holo/esword + desc = "May the force be within you. Sorta." + icon_state = "sword0" + force = 3.0 + throw_speed = 1 + throw_range = 5 + throwforce = 0 + w_class = 2.0 + flags = NOSHIELD | NOBLOODY + var/active = 0 + +/obj/item/weapon/holo/esword/green + New() + item_color = "green" + +/obj/item/weapon/holo/esword/red + New() + item_color = "red" + +/obj/item/weapon/holo/esword/IsShield() + if(active) + return 1 + return 0 + +/obj/item/weapon/holo/esword/attack(target as mob, mob/user as mob) + ..() + +/obj/item/weapon/holo/esword/New() + item_color = pick("red","blue","green","purple") + +/obj/item/weapon/holo/esword/attack_self(mob/living/user as mob) + active = !active + if (active) + force = 30 + icon_state = "sword[item_color]" + w_class = 4 + playsound(user, 'sound/weapons/saberon.ogg', 50, 1) + user << "[src] is now active." + else + force = 3 + icon_state = "sword0" + w_class = 2 + playsound(user, 'sound/weapons/saberoff.ogg', 50, 1) + user << "[src] can now be concealed." + + if(istype(user,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + H.update_inv_l_hand() + H.update_inv_r_hand() + + add_fingerprint(user) + return + +//BASKETBALL OBJECTS + +/obj/item/weapon/beach_ball/holoball + icon = 'icons/obj/basketball.dmi' + icon_state = "basketball" + name = "basketball" + item_state = "basketball" + desc = "Here's your chance, do your dance at the Space Jam." + w_class = 4 //Stops people from hiding it in their bags/pockets + +/obj/structure/holohoop + name = "basketball hoop" + desc = "Boom, Shakalaka!" + icon = 'icons/obj/basketball.dmi' + icon_state = "hoop" + anchored = 1 + density = 1 + throwpass = 1 + +/obj/structure/holohoop/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) + var/obj/item/weapon/grab/G = W + if(G.state<2) + user << "You need a better grip to do that!" + return + G.affecting.loc = src.loc + G.affecting.Weaken(5) + visible_message("[G.assailant] dunks [G.affecting] into the [src]!", 3) + del(W) + return + else if (istype(W, /obj/item) && get_dist(src,user)<2) + user.drop_item(src) + visible_message("[user] dunks [W] into the [src]!", 3) + return + +/obj/structure/holohoop/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if (istype(mover,/obj/item) && mover.throwing) + var/obj/item/I = mover + if(istype(I, /obj/item/projectile)) + return + if(prob(50)) + I.loc = src.loc + visible_message("Swish! \the [I] lands in \the [src].", 3) + else + visible_message("\The [I] bounces off of \the [src]'s rim!", 3) + return 0 + else + return ..(mover, target, height, air_group) + + +/obj/machinery/readybutton + name = "Ready Declaration Device" + desc = "This device is used to declare ready. If all devices in an area are ready, the event will begin!" + icon = 'icons/obj/monitors.dmi' + icon_state = "auth_off" + var/ready = 0 + var/area/currentarea = null + var/eventstarted = 0 + + anchored = 1.0 + use_power = 1 + idle_power_usage = 2 + active_power_usage = 6 + power_channel = ENVIRON + +/obj/machinery/readybutton/attack_ai(mob/user as mob) + user << "The station AI is not to interact with these devices!" + return + +/obj/machinery/readybutton/New() + ..() + + +/obj/machinery/readybutton/attackby(obj/item/weapon/W as obj, mob/user as mob) + user << "The device is a solid button, there's nothing you can do with it!" + +/obj/machinery/readybutton/attack_hand(mob/user as mob) + + if(user.stat || stat & (NOPOWER|BROKEN)) + user << "This device is not powered." + return + + if(!user.IsAdvancedToolUser()) + return 0 + + currentarea = get_area(src.loc) + if(!currentarea) + del(src) + + if(eventstarted) + usr << "The event has already begun!" + return + + ready = !ready + + update_icon() + + var/numbuttons = 0 + var/numready = 0 + for(var/obj/machinery/readybutton/button in currentarea) + numbuttons++ + if (button.ready) + numready++ + + if(numbuttons == numready) + begin_event() + +/obj/machinery/readybutton/update_icon() + if(ready) + icon_state = "auth_on" + else + icon_state = "auth_off" + +/obj/machinery/readybutton/proc/begin_event() + + eventstarted = 1 + + for(var/obj/structure/window/reinforced/holowindow/disappearing/W in currentarea) + del(W) + + for(var/mob/M in currentarea) + M << "FIGHT!" + +//Holorack + +/obj/structure/table/rack/holorack + name = "rack" + desc = "Different from the Middle Ages version." + icon = 'icons/obj/objects.dmi' + icon_state = "rack" + +/obj/structure/table/rack/holorack/attack_hand(mob/user as mob) + return + +/obj/structure/table/rack/holorack/attackby(obj/item/weapon/W as obj, mob/user as mob) + if (istype(W, /obj/item/weapon/wrench)) + user << "It's a holorack! You can't unwrench it!" + return + +//Holocarp + +/mob/living/simple_animal/hostile/carp/holodeck + icon = 'icons/mob/AI.dmi' + icon_state = "holo4" + icon_living = "holo4" + icon_dead = "holo4" + alpha = 127 + icon_gib = null + meat_amount = 0 + meat_type = null + +/mob/living/simple_animal/hostile/carp/holodeck/New() + ..() + SetLuminosity(2) //hologram lighting + +/mob/living/simple_animal/hostile/carp/holodeck/proc/set_safety(var/safe) + if (safe) + faction = "neutral" + melee_damage_lower = 0 + melee_damage_upper = 0 + environment_smash = 0 + destroy_surroundings = 0 + else + faction = "carp" + melee_damage_lower = initial(melee_damage_lower) + melee_damage_upper = initial(melee_damage_upper) + environment_smash = initial(environment_smash) + destroy_surroundings = initial(destroy_surroundings) + +/mob/living/simple_animal/hostile/carp/holodeck/gib() + derez() //holograms can't gib + +/mob/living/simple_animal/hostile/carp/holodeck/death() + ..() + derez() + +/mob/living/simple_animal/hostile/carp/holodeck/proc/derez() + visible_message("\The [src] fades away!") + del(src) diff --git a/code/modules/hydroponics/_hydro_setup.dm b/code/modules/hydroponics/_hydro_setup.dm new file mode 100644 index 0000000000..a3fd4604a6 --- /dev/null +++ b/code/modules/hydroponics/_hydro_setup.dm @@ -0,0 +1,58 @@ +//Misc +#define DEAD_PLANT_COLOUR "#C2A180" + +// Definitions for genes (trait groupings) +#define GENE_BIOCHEMISTRY "biochemistry" +#define GENE_HARDINESS "hardiness" +#define GENE_ENVIRONMENT "environment" +#define GENE_METABOLISM "metabolism" +#define GENE_STRUCTURE "appearance" +#define GENE_DIET "diet" +#define GENE_PIGMENT "pigment" +#define GENE_OUTPUT "output" +#define GENE_ATMOSPHERE "atmosphere" +#define GENE_VIGOUR "vigour" +#define GENE_FRUIT "fruit" +#define GENE_SPECIAL "special" + +#define ALL_GENES list(GENE_BIOCHEMISTRY,GENE_HARDINESS,GENE_ENVIRONMENT,GENE_METABOLISM,GENE_STRUCTURE,GENE_DIET,GENE_PIGMENT,GENE_OUTPUT,GENE_ATMOSPHERE,GENE_VIGOUR,GENE_FRUIT,GENE_SPECIAL) + +//Definitions for traits (individual descriptors) +#define TRAIT_CHEMS 1 +#define TRAIT_EXUDE_GASSES 2 +#define TRAIT_ALTER_TEMP 3 +#define TRAIT_POTENCY 4 +#define TRAIT_HARVEST_REPEAT 5 +#define TRAIT_PRODUCES_POWER 6 +#define TRAIT_JUICY 7 +#define TRAIT_PRODUCT_ICON 8 +#define TRAIT_PLANT_ICON 0 +#define TRAIT_CONSUME_GASSES 10 +#define TRAIT_REQUIRES_NUTRIENTS 11 +#define TRAIT_NUTRIENT_CONSUMPTION 12 +#define TRAIT_REQUIRES_WATER 13 +#define TRAIT_WATER_CONSUMPTION 14 +#define TRAIT_CARNIVOROUS 15 +#define TRAIT_PARASITE 16 +#define TRAIT_STINGS 17 +#define TRAIT_IDEAL_HEAT 18 +#define TRAIT_HEAT_TOLERANCE 19 +#define TRAIT_IDEAL_LIGHT 20 +#define TRAIT_LIGHT_TOLERANCE 21 +#define TRAIT_LOWKPA_TOLERANCE 22 +#define TRAIT_HIGHKPA_TOLERANCE 23 +#define TRAIT_EXPLOSIVE 24 +#define TRAIT_TOXINS_TOLERANCE 25 +#define TRAIT_PEST_TOLERANCE 26 +#define TRAIT_WEED_TOLERANCE 27 +#define TRAIT_ENDURANCE 28 +#define TRAIT_YIELD 29 +#define TRAIT_SPREAD 30 +#define TRAIT_MATURATION 31 +#define TRAIT_PRODUCTION 32 +#define TRAIT_TELEPORTING 33 +#define TRAIT_PLANT_COLOUR 34 +#define TRAIT_PRODUCT_COLOUR 35 +#define TRAIT_BIOLUM 36 +#define TRAIT_BIOLUM_COLOUR 37 +#define TRAIT_IMMUTABLE 38 \ No newline at end of file diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm deleted file mode 100644 index 119c49fe41..0000000000 --- a/code/modules/hydroponics/biogenerator.dm +++ /dev/null @@ -1,226 +0,0 @@ -/obj/machinery/biogenerator - name = "Biogenerator" - desc = "" - icon = 'icons/obj/biogenerator.dmi' - icon_state = "biogen-stand" - density = 1 - anchored = 1 - use_power = 1 - idle_power_usage = 40 - var/processing = 0 - var/obj/item/weapon/reagent_containers/glass/beaker = null - var/points = 0 - var/menustat = "menu" - - New() - ..() - var/datum/reagents/R = new/datum/reagents(1000) - reagents = R - R.my_atom = src - beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src) - - on_reagent_change() //When the reagents change, change the icon as well. - update_icon() - - update_icon() - if(!src.beaker) - icon_state = "biogen-empty" - else if(!src.processing) - icon_state = "biogen-stand" - else - icon_state = "biogen-work" - return - -/obj/machinery/biogenerator/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(istype(O, /obj/item/weapon/reagent_containers/glass)) - if(beaker) - user << "\red The biogenerator is already loaded." - else - user.remove_from_mob(O) - O.loc = src - beaker = O - updateUsrDialog() - else if(processing) - user << "\red The biogenerator is currently processing." - else if(istype(O, /obj/item/weapon/storage/bag/plants)) - var/i = 0 - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents) - i++ - if(i >= 10) - user << "\red The biogenerator is already full! Activate it." - else - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in O.contents) - G.loc = src - i++ - if(i >= 10) - user << "\blue You fill the biogenerator to its capacity." - break - if(i<10) - user << "\blue You empty the plant bag into the biogenerator." - - - else if(!istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) - user << "\red You cannot put this in [src.name]" - else - var/i = 0 - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in contents) - i++ - if(i >= 10) - user << "\red The biogenerator is full! Activate it." - else - user.remove_from_mob(O) - O.loc = src - user << "\blue You put [O.name] in [src.name]" - update_icon() - return - -/obj/machinery/biogenerator/interact(mob/user as mob) - if(stat & BROKEN) - return - user.set_machine(src) - var/dat = "BiogeneratorBiogenerator:
    " - if (processing) - dat += "Biogenerator is processing! Please wait..." - else - dat += "Biomass: [points] points.
    " - switch(menustat) - if("menu") - if (beaker) - dat += "Activate Biogenerator!
    " - dat += "Detach Container

    " - dat += "Food
    " - dat += "10 milk (20)
    " - dat += "Slab of meat (50)
    " - dat += "Nutrient
    " - dat += "E-Z-Nutrient (10) | x5
    " - dat += "Left 4 Zed (20) | x5
    " - dat += "Robust Harvest (25) | x5
    " - dat += "Leather
    " - dat += "Wallet (100)
    " - dat += "Botanical gloves (250)
    " - dat += "Utility belt (300)
    " - dat += "Leather Satchel (400)
    " - dat += "Cash Bag (400)
    " - //dat += "Other
    " - //dat += "Monkey (500)
    " - else - dat += "
    No beaker inside. Please insert a beaker.
    " - if("nopoints") - dat += "You do not have biomass to create products.
    Please, put growns into reactor and activate it.
    " - dat += "Return to menu" - if("complete") - dat += "Operation complete.
    " - dat += "Return to menu" - if("void") - dat += "Error: No growns inside.
    Please, put growns into reactor.
    " - dat += "Return to menu" - user << browse(dat, "window=biogenerator") - onclose(user, "biogenerator") - return - -/obj/machinery/biogenerator/attack_hand(mob/user as mob) - interact(user) - -/obj/machinery/biogenerator/proc/activate() - if (usr.stat != 0) - return - if (src.stat != 0) //NOPOWER etc - return - if(src.processing) - usr << "\red The biogenerator is in the process of working." - return - var/S = 0 - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/I in contents) - S += 5 - if(I.reagents.get_reagent_amount("nutriment") < 0.1) - points += 1 - else points += I.reagents.get_reagent_amount("nutriment")*10 - del(I) - if(S) - processing = 1 - update_icon() - updateUsrDialog() - playsound(src.loc, 'sound/machines/blender.ogg', 50, 1) - use_power(S*30) - sleep(S+15) - processing = 0 - update_icon() - else - menustat = "void" - return - -/obj/machinery/biogenerator/proc/create_product(var/item,var/cost) - if(cost > points) - menustat = "nopoints" - return 0 - processing = 1 - update_icon() - updateUsrDialog() - points -= cost - sleep(30) - switch(item) - if("milk") - beaker.reagents.add_reagent("milk",10) - if("meat") - new/obj/item/weapon/reagent_containers/food/snacks/meat(src.loc) - if("ez") - new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc) - if("l4z") - new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc) - if("rh") - new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc) - if("ez5") //It's not an elegant method, but it's safe and easy. -Cheridan - new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/ez(src.loc) - if("l4z5") - new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/l4z(src.loc) - if("rh5") - new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc) - new/obj/item/weapon/reagent_containers/glass/fertilizer/rh(src.loc) - if("wallet") - new/obj/item/weapon/storage/wallet(src.loc) - if("gloves") - new/obj/item/clothing/gloves/botanic_leather(src.loc) - if("tbelt") - new/obj/item/weapon/storage/belt/utility(src.loc) - if("satchel") - new/obj/item/weapon/storage/backpack/satchel(src.loc) - if("cashbag") - new/obj/item/weapon/storage/bag/cash(src.loc) - if("monkey") - new/mob/living/carbon/monkey(src.loc) - processing = 0 - menustat = "complete" - update_icon() - return 1 - -/obj/machinery/biogenerator/Topic(href, href_list) - if(stat & BROKEN) return - if(usr.stat || usr.restrained()) return - if(!in_range(src, usr)) return - - usr.set_machine(src) - - switch(href_list["action"]) - if("activate") - activate() - if("detach") - if(beaker) - beaker.loc = src.loc - beaker = null - update_icon() - if("create") - create_product(href_list["item"],text2num(href_list["cost"])) - if("menu") - menustat = "menu" - updateUsrDialog() diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm new file mode 100644 index 0000000000..9ca784070d --- /dev/null +++ b/code/modules/hydroponics/grown.dm @@ -0,0 +1,369 @@ +//Grown foods. +/obj/item/weapon/reagent_containers/food/snacks/grown + + name = "fruit" + icon = 'icons/obj/hydroponics_products.dmi' + icon_state = "blank" + desc = "Nutritious! Probably." + + var/plantname + var/datum/seed/seed + var/potency = -1 + +/obj/item/weapon/reagent_containers/food/snacks/grown/New(newloc,planttype) + + ..() + + src.pixel_x = rand(-5.0, 5) + src.pixel_y = rand(-5.0, 5) + + // Fill the object up with the appropriate reagents. + if(planttype) + plantname = planttype + + if(!plantname) + return + + if(!plant_controller) + sleep(250) // ugly hack, should mean roundstart plants are fine. + if(!plant_controller) + world << "Plant controller does not exist and [src] requires it. Aborting." + del(src) + return + + seed = plant_controller.seeds[plantname] + + if(!seed) + return + + name = "[seed.seed_name]" + + update_icon() + + if(!seed.chems) + return + + potency = seed.get_trait(TRAIT_POTENCY) + + for(var/rid in seed.chems) + var/list/reagent_data = seed.chems[rid] + if(reagent_data && reagent_data.len) + var/rtotal = reagent_data[1] + if(reagent_data.len > 1 && potency > 0) + rtotal += round(potency/reagent_data[2]) + reagents.add_reagent(rid,max(1,rtotal)) + update_desc() + if(reagents.total_volume > 0) + bitesize = 1+round(reagents.total_volume / 2, 1) + +/obj/item/weapon/reagent_containers/food/snacks/grown/proc/update_desc() + + if(!seed) + return + if(!plant_controller) + sleep(250) // ugly hack, should mean roundstart plants are fine. + if(!plant_controller) + world << "Plant controller does not exist and [src] requires it. Aborting." + del(src) + return + + if(plant_controller.product_descs["[seed.uid]"]) + desc = plant_controller.product_descs["[seed.uid]"] + else + var/list/descriptors = list() + if(reagents.has_reagent("sugar") || reagents.has_reagent("cherryjelly") || reagents.has_reagent("honey") || reagents.has_reagent("berryjuice")) + descriptors |= "sweet" + if(reagents.has_reagent("anti_toxin")) + descriptors |= "astringent" + if(reagents.has_reagent("frostoil")) + descriptors |= "numbing" + if(reagents.has_reagent("nutriment")) + descriptors |= "nutritious" + if(reagents.has_reagent("condensedcapsaicin") || reagents.has_reagent("capsaicin")) + descriptors |= "spicy" + if(reagents.has_reagent("coco")) + descriptors |= "bitter" + if(reagents.has_reagent("orangejuice") || reagents.has_reagent("lemonjuice") || reagents.has_reagent("limejuice")) + descriptors |= "sweet-sour" + if(reagents.has_reagent("radium") || reagents.has_reagent("uranium")) + descriptors |= "radioactive" + if(reagents.has_reagent("amatoxin") || reagents.has_reagent("toxin")) + descriptors |= "poisonous" + if(reagents.has_reagent("psilocybin") || reagents.has_reagent("space_drugs")) + descriptors |= "hallucinogenic" + if(reagents.has_reagent("bicaridine")) + descriptors |= "medicinal" + if(reagents.has_reagent("gold")) + descriptors |= "shiny" + if(reagents.has_reagent("lube")) + descriptors |= "slippery" + if(reagents.has_reagent("pacid") || reagents.has_reagent("sacid")) + descriptors |= "acidic" + if(seed.get_trait(TRAIT_JUICY)) + descriptors |= "juicy" + if(seed.get_trait(TRAIT_STINGS)) + descriptors |= "stinging" + if(seed.get_trait(TRAIT_TELEPORTING)) + descriptors |= "glowing" + if(seed.get_trait(TRAIT_EXPLOSIVE)) + descriptors |= "bulbous" + + var/descriptor_num = rand(2,4) + var/descriptor_count = descriptor_num + desc = "A" + while(descriptors.len && descriptor_num > 0) + var/chosen = pick(descriptors) + descriptors -= chosen + desc += "[(descriptor_count>1 && descriptor_count!=descriptor_num) ? "," : "" ] [chosen]" + descriptor_num-- + if(seed.seed_noun == "spores") + desc += " mushroom" + else + desc += " fruit" + plant_controller.product_descs["[seed.uid]"] = desc + desc += ". Delicious! Probably." + +/obj/item/weapon/reagent_containers/food/snacks/grown/update_icon() + if(!seed || !plant_controller || !plant_controller.plant_icon_cache) + return + overlays.Cut() + var/image/plant_icon + var/icon_key = "fruit-[seed.get_trait(TRAIT_PRODUCT_ICON)]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]-[seed.get_trait(TRAIT_PLANT_COLOUR)]" + if(plant_controller.plant_icon_cache[icon_key]) + plant_icon = plant_controller.plant_icon_cache[icon_key] + else + plant_icon = image('icons/obj/hydroponics_products.dmi',"blank") + var/image/fruit_base = image('icons/obj/hydroponics_products.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]-product") + fruit_base.color = "[seed.get_trait(TRAIT_PRODUCT_COLOUR)]" + plant_icon.overlays |= fruit_base + if("[seed.get_trait(TRAIT_PRODUCT_ICON)]-leaf" in icon_states('icons/obj/hydroponics_products.dmi')) + var/image/fruit_leaves = image('icons/obj/hydroponics_products.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]-leaf") + fruit_leaves.color = "[seed.get_trait(TRAIT_PLANT_COLOUR)]" + plant_icon.overlays |= fruit_leaves + plant_controller.plant_icon_cache[icon_key] = plant_icon + overlays |= plant_icon + +/obj/item/weapon/reagent_containers/food/snacks/grown/Crossed(var/mob/living/M) + if(seed && seed.get_trait(TRAIT_JUICY) == 2) + if(istype(M)) + + if(M.buckled) + return + + if(istype(M,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + if(H.shoes && H.shoes.flags & NOSLIP) + return + + M.stop_pulling() + M << "You slipped on the [name]!" + playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) + M.Stun(8) + M.Weaken(5) + seed.thrown_at(src,M) + sleep(-1) + if(src) del(src) + return + +/obj/item/weapon/reagent_containers/food/snacks/grown/throw_impact(atom/hit_atom) + ..() + if(seed) seed.thrown_at(src,hit_atom) + +/obj/item/weapon/reagent_containers/food/snacks/grown/attackby(var/obj/item/weapon/W, var/mob/user) + + if(seed) + if(seed.get_trait(TRAIT_PRODUCES_POWER) && istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = W + if(C.use(5)) + //TODO: generalize this. + user << "You add some cable to the [src.name] and slide it inside the battery casing." + var/obj/item/weapon/cell/potato/pocell = new /obj/item/weapon/cell/potato(get_turf(user)) + if(src.loc == user && !(user.l_hand && user.r_hand) && istype(user,/mob/living/carbon/human)) + user.put_in_hands(pocell) + pocell.maxcharge = src.potency * 10 + pocell.charge = pocell.maxcharge + del(src) + return + else if(W.sharp) + if(seed.kitchen_tag == "pumpkin") // Ugggh these checks are awful. + user.show_message("You carve a face into [src]!", 1) + new /obj/item/clothing/head/pumpkinhead (user.loc) + del(src) + return + else if(seed.chems) + if(istype(W,/obj/item/weapon/hatchet) && !isnull(seed.chems["woodpulp"])) + user.show_message("You make planks out of \the [src]!", 1) + for(var/i=0,i<2,i++) + var/obj/item/stack/sheet/wood/NG = new (user.loc) + NG.color = seed.get_trait(TRAIT_PRODUCT_COLOUR) + for (var/obj/item/stack/sheet/wood/G in user.loc) + if(G==NG) + continue + if(G.amount>=G.max_amount) + continue + G.attackby(NG, user) + user << "You add the newly-formed wood to the stack. It now contains [NG.amount] planks." + del(src) + return + else if(!isnull(seed.chems["potato"])) + user << "You slice \the [src] into sticks." + new /obj/item/weapon/reagent_containers/food/snacks/rawsticks(get_turf(src)) + del(src) + return + else if(!isnull(seed.chems["carrotjuice"])) + user << "You slice \the [src] into sticks." + new /obj/item/weapon/reagent_containers/food/snacks/carrotfries(get_turf(src)) + del(src) + return + else if(!isnull(seed.chems["soymilk"])) + user << "You roughly chop up \the [src]." + new /obj/item/weapon/reagent_containers/food/snacks/soydope(get_turf(src)) + del(src) + return + ..() + +/obj/item/weapon/reagent_containers/food/snacks/grown/attack(var/mob/living/carbon/M, var/mob/user, var/def_zone) + if(user == M) + return ..() + + if(user.a_intent == I_HURT) + + // This is being copypasted here because reagent_containers (WHY DOES FOOD DESCEND FROM THAT) overrides it completely. + // TODO: refactor all food paths to be less horrible and difficult to work with in this respect. ~Z + if(!istype(M) || (can_operate(M) && do_surgery(M,user,src))) return 0 + + user.lastattacked = M + M.lastattacker = user + user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" + M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" + msg_admin_attack("[key_name(user)] attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" ) + + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + var/hit = H.attacked_by(src, user, def_zone) + if(hit && hitsound) + playsound(loc, hitsound, 50, 1, -1) + return hit + else + if(attack_verb.len) + user.visible_message("[M] has been [pick(attack_verb)] with [src] by [user]!") + else + user.visible_message("[M] has been attacked with [src] by [user]!") + + if (hitsound) + playsound(loc, hitsound, 50, 1, -1) + switch(damtype) + if("brute") + M.take_organ_damage(force) + if(prob(33)) + var/turf/simulated/location = get_turf(M) + if(istype(location)) location.add_blood_floor(M) + if("fire") + if (!(COLD_RESISTANCE in M.mutations)) + M.take_organ_damage(0, force) + M.updatehealth() + + if(seed && seed.get_trait(TRAIT_STINGS)) + if(!reagents || reagents.total_volume <= 0) + return + reagents.remove_any(rand(1,3)) + seed.thrown_at(src,M) + sleep(-1) + if(!src) + return + if(prob(35)) + if(user) + user << "\The [src] has fallen to bits." + user.drop_from_inventory(src) + del(src) + + add_fingerprint(user) + return 1 + + else + ..() + +/obj/item/weapon/reagent_containers/food/snacks/grown/attack_self(mob/user as mob) + + if(!seed) + return + + if(istype(user.loc,/turf/space)) + return + + if(user.a_intent == I_HURT) + user.visible_message("\The [user] squashes \the [src]!") + seed.thrown_at(src,user) + sleep(-1) + if(src) del(src) + return + + if(seed.kitchen_tag == "grass") + user.show_message("You make a grass tile out of \the [src]!", 1) + for(var/i=0,i<2,i++) + var/obj/item/stack/tile/grass/G = new (user.loc) + G.color = seed.get_trait(TRAIT_PRODUCT_COLOUR) + for (var/obj/item/stack/tile/grass/NG in user.loc) + if(G==NG) + continue + if(NG.amount>=NG.max_amount) + continue + NG.attackby(G, user) + user << "You add the newly-formed grass to the stack. It now contains [G.amount] tiles." + del(src) + return + + if(seed.get_trait(TRAIT_SPREAD) > 0) + user << "You plant the [src.name]." + new /obj/machinery/portable_atmospherics/hydroponics/soil/invisible(get_turf(user),src.seed) + del(src) + return + + /* + if(seed.kitchen_tag) + switch(seed.kitchen_tag) + if("shand") + var/obj/item/stack/medical/bruise_pack/tajaran/poultice = new /obj/item/stack/medical/bruise_pack/tajaran(user.loc) + poultice.heal_brute = potency + user << "You mash the leaves into a poultice." + del(src) + return + if("mtear") + var/obj/item/stack/medical/ointment/tajaran/poultice = new /obj/item/stack/medical/ointment/tajaran(user.loc) + poultice.heal_burn = potency + user << "You mash the petals into a poultice." + del(src) + return + */ + +/obj/item/weapon/reagent_containers/food/snacks/grown/pickup(mob/user) + ..() + if(!seed) + return + if(seed.get_trait(TRAIT_BIOLUM)) + user.SetLuminosity(user.luminosity + seed.get_trait(TRAIT_BIOLUM)) + SetLuminosity(0) + if(seed.get_trait(TRAIT_STINGS)) + var/mob/living/carbon/human/H = user + if(istype(H) && H.gloves) + return + if(!reagents || reagents.total_volume <= 0) + return + reagents.remove_any(rand(1,3)) //Todo, make it actually remove the reagents the seed uses. + seed.do_thorns(H,src) + seed.do_sting(H,src,pick("r_hand","l_hand")) + +/obj/item/weapon/reagent_containers/food/snacks/grown/dropped(mob/user) + if(!..() || !seed) + return + if(seed.get_trait(TRAIT_BIOLUM)) + user.SetLuminosity(user.luminosity - seed.get_trait(TRAIT_BIOLUM)) + SetLuminosity(seed.get_trait(TRAIT_BIOLUM)) + +// Predefined types for placing on the map. + +/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap + plantname = "libertycap" + +/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris + plantname = "ambrosia" diff --git a/code/modules/hydroponics/grown_inedible.dm b/code/modules/hydroponics/grown_inedible.dm index 717d3ea8a8..da9c00120d 100644 --- a/code/modules/hydroponics/grown_inedible.dm +++ b/code/modules/hydroponics/grown_inedible.dm @@ -8,7 +8,7 @@ var/plantname var/potency = 1 -/obj/item/weapon/grown/New() +/obj/item/weapon/grown/New(newloc,planttype) ..() @@ -17,158 +17,25 @@ R.my_atom = src //Handle some post-spawn var stuff. - spawn(1) - // Fill the object up with the appropriate reagents. - if(!isnull(plantname)) - var/datum/seed/S = seed_types[plantname] - if(!S || !S.chems) - return - - potency = S.potency - - for(var/rid in S.chems) - var/list/reagent_data = S.chems[rid] - var/rtotal = reagent_data[1] - if(reagent_data.len > 1 && potency > 0) - rtotal += round(potency/reagent_data[2]) - reagents.add_reagent(rid,max(1,rtotal)) - -/obj/item/weapon/grown/log - name = "towercap" - name = "tower-cap log" - desc = "It's better than bad, it's good!" - icon = 'icons/obj/harvest.dmi' - icon_state = "logs" - force = 5 - throwforce = 5 - w_class = 3.0 - throw_speed = 3 - throw_range = 3 - origin_tech = "materials=1" - attack_verb = list("bashed", "battered", "bludgeoned", "whacked") - - attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || (istype(W, /obj/item/weapon/twohanded/fireaxe) && W:wielded) || istype(W, /obj/item/weapon/melee/energy)) - user.show_message("You make planks out of \the [src]!", 1) - for(var/i=0,i<2,i++) - var/obj/item/stack/sheet/wood/NG = new (user.loc) - for (var/obj/item/stack/sheet/wood/G in user.loc) - if(G==NG) - continue - if(G.amount>=G.max_amount) - continue - G.attackby(NG, user) - usr << "You add the newly-formed wood to the stack. It now contains [NG.amount] planks." - del(src) + if(planttype) + plantname = planttype + var/datum/seed/S = plant_controller.seeds[plantname] + if(!S || !S.chems) return -/obj/item/weapon/grown/sunflower // FLOWER POWER! - plantname = "sunflowers" - name = "sunflower" - desc = "It's beautiful! A certain person might beat you to death if you trample these." - icon = 'icons/obj/harvest.dmi' - icon_state = "sunflower" - damtype = "fire" - force = 0 - throwforce = 1 - w_class = 1.0 - throw_speed = 1 - throw_range = 3 + potency = S.get_trait(TRAIT_POTENCY) -/obj/item/weapon/grown/sunflower/attack(mob/M as mob, mob/user as mob) - M << " [user] smacks you with a sunflower!FLOWER POWER" - user << " Your sunflower's FLOWER POWER strikes [M]" - -/obj/item/weapon/grown/nettle // -- Skie - plantname = "nettle" - desc = "It's probably not wise to touch it with bare hands..." - icon = 'icons/obj/weapons.dmi' - name = "nettle" - icon_state = "nettle" - damtype = "fire" - force = 15 - throwforce = 1 - w_class = 2.0 - throw_speed = 1 - throw_range = 3 - origin_tech = "combat=1" - attack_verb = list("stung") - hitsound = "" - - var/potency_divisior = 5 - -/obj/item/weapon/grown/nettle/New() - ..() - spawn(5) - force = round((5+potency/potency_divisior), 1) - -/obj/item/weapon/grown/nettle/pickup(mob/living/carbon/human/user as mob) - if(istype(user) && !user.gloves) - user << "\red The nettle burns your bare hand!" - if(istype(user, /mob/living/carbon/human)) - var/organ = ((user.hand ? "l_":"r_") + "arm") - var/datum/organ/external/affecting = user.get_organ(organ) - if(affecting.take_damage(0,force)) - user.UpdateDamageIcon() - else - user.take_organ_damage(0,force) - return 1 - return 0 - -/obj/item/weapon/grown/nettle/proc/lose_leaves(var/mob/user) - if(force > 0) - playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) - force -= rand(1,(force/3)+1) // When you whack someone with it, leaves fall off - - sleep(1) - - if(force <= 0) - if(user) - user << "All the leaves have fallen off \the [src] from violent whacking." - user.drop_from_inventory(src) - del(src) - -/obj/item/weapon/grown/nettle/death // -- Skie - plantname = "deathnettle" - desc = "The \red glowing \black nettle incites \redrage\black in you just from looking at it!" - name = "deathnettle" - icon_state = "deathnettle" - origin_tech = "combat=3" - potency_divisior = 2.5 - -/obj/item/weapon/grown/nettle/death/pickup(mob/living/carbon/human/user as mob) - - if(..() && prob(50)) - user.Paralyse(5) - user << "\red You are stunned by the deathnettle when you try picking it up!" - -/obj/item/weapon/grown/nettle/attack(mob/living/carbon/M as mob, mob/user as mob) - - if(!..()) return - - lose_leaves(user) - -/obj/item/weapon/grown/nettle/death/attack(mob/living/carbon/M as mob, mob/user as mob) - - if(!..()) return - - if(istype(M, /mob/living)) - M << "\red You are stunned by the powerful acid of the deathnettle!" - - M.attack_log += text("\[[time_stamp()]\] Had the [src.name] used on them by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] on [M.name] ([M.ckey])") - msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] on [M.name] ([M.ckey]) (JMP)") - - M.eye_blurry += force/7 - if(prob(20)) - M.Paralyse(force/6) - M.Weaken(force/15) - M.drop_item() + for(var/rid in S.chems) + var/list/reagent_data = S.chems[rid] + var/rtotal = reagent_data[1] + if(reagent_data.len > 1 && potency > 0) + rtotal += round(potency/reagent_data[2]) + reagents.add_reagent(rid,max(1,rtotal)) /obj/item/weapon/corncob name = "corn cob" desc = "A reminder of meals gone by." - icon = 'icons/obj/harvest.dmi' + icon = 'icons/obj/trash.dmi' icon_state = "corncob" item_state = "corncob" w_class = 2.0 @@ -180,6 +47,17 @@ ..() if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || istype(W, /obj/item/weapon/kitchen/utensil/knife) || istype(W, /obj/item/weapon/kitchenknife) || istype(W, /obj/item/weapon/kitchenknife/ritual)) user << "You use [W] to fashion a pipe out of the corn cob!" - new /obj/item/clothing/mask/cigarette/pipe/cobpipe (user.loc) + new /obj/item/clothing/mask/smokable/pipe/cobpipe (user.loc) del(src) return + +/obj/item/weapon/bananapeel + name = "banana peel" + desc = "A peel from a banana." + icon = 'icons/obj/items.dmi' + icon_state = "banana_peel" + item_state = "banana_peel" + w_class = 2.0 + throwforce = 0 + throw_speed = 4 + throw_range = 20 diff --git a/code/modules/hydroponics/grown_predefined.dm b/code/modules/hydroponics/grown_predefined.dm new file mode 100644 index 0000000000..e44025de7b --- /dev/null +++ b/code/modules/hydroponics/grown_predefined.dm @@ -0,0 +1,5 @@ +/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris + plantname = "ambrosia" + +/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus + plantname = "ambrosiadeus" \ No newline at end of file diff --git a/code/modules/hydroponics/hydro_tools.dm b/code/modules/hydroponics/hydro_tools.dm deleted file mode 100644 index 957ef5173f..0000000000 --- a/code/modules/hydroponics/hydro_tools.dm +++ /dev/null @@ -1,357 +0,0 @@ -//Analyzer, pestkillers, weedkillers, nutrients, hatchets, cutters. - -/obj/item/weapon/wirecutters/clippers - name = "plant clippers" - desc = "A tool used to take samples from plants." - -/obj/item/device/analyzer/plant_analyzer - name = "plant analyzer" - icon = 'icons/obj/device.dmi' - icon_state = "hydro" - item_state = "analyzer" - -/obj/item/device/analyzer/plant_analyzer/attack_self(mob/user as mob) - return 0 - -/obj/item/device/analyzer/plant_analyzer/afterattack(obj/target, mob/user, flag) - if(!flag) return - - var/datum/seed/grown_seed - var/datum/reagents/grown_reagents - if(istype(target,/obj/structure/table)) - return ..() - else if(istype(target,/obj/item/weapon/reagent_containers/food/snacks/grown)) - - var/obj/item/weapon/reagent_containers/food/snacks/grown/G = target - grown_seed = seed_types[G.plantname] - grown_reagents = G.reagents - - else if(istype(target,/obj/item/weapon/grown)) - - var/obj/item/weapon/grown/G = target - grown_seed = seed_types[G.plantname] - grown_reagents = G.reagents - - else if(istype(target,/obj/item/seeds)) - - var/obj/item/seeds/S = target - grown_seed = S.seed - - else if(istype(target,/obj/machinery/portable_atmospherics/hydroponics)) - - var/obj/machinery/portable_atmospherics/hydroponics/H = target - grown_seed = H.seed - grown_reagents = H.reagents - - if(!grown_seed) - user << "\red [src] can tell you nothing about [target]." - return - - var/dat = "

    Plant data for [target]

    " - user.visible_message("\blue [user] runs the scanner over [target].") - - dat += "

    General Data

    " - - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "
    Endurance[grown_seed.endurance]
    Yield[grown_seed.yield]
    Lifespan[grown_seed.lifespan]
    Maturation time[grown_seed.maturation]
    Production time[grown_seed.production]
    Potency[grown_seed.potency]
    " - - if(grown_reagents && grown_reagents.reagent_list && grown_reagents.reagent_list.len) - dat += "

    Reagent Data

    " - - dat += "
    This sample contains: " - for(var/datum/reagent/R in grown_reagents.reagent_list) - dat += "
    - [R.id], [grown_reagents.get_reagent_amount(R.id)] unit(s)" - - dat += "

    Other Data

    " - - if(grown_seed.harvest_repeat) - dat += "This plant can be harvested repeatedly.
    " - - if(grown_seed.immutable == -1) - dat += "This plant is highly mutable.
    " - else if(grown_seed.immutable > 0) - dat += "This plant does not possess genetics that are alterable.
    " - - if(grown_seed.products && grown_seed.products.len) - dat += "The mature plant will produce [grown_seed.products.len == 1 ? "fruit" : "[grown_seed.products.len] varieties of fruit"].
    " - - if(grown_seed.requires_nutrients) - if(grown_seed.nutrient_consumption < 0.05) - dat += "It consumes a small amount of nutrient fluid.
    " - else if(grown_seed.nutrient_consumption > 0.2) - dat += "It requires a heavy supply of nutrient fluid.
    " - else - dat += "It requires a supply of nutrient fluid.
    " - - if(grown_seed.requires_water) - if(grown_seed.water_consumption < 1) - dat += "It requires very little water.
    " - else if(grown_seed.water_consumption > 5) - dat += "It requires a large amount of water.
    " - else - dat += "It requires a stable supply of water.
    " - - if(grown_seed.mutants && grown_seed.mutants.len) - dat += "It exhibits a high degree of potential subspecies shift.
    " - - dat += "It thrives in a temperature of [grown_seed.ideal_heat] Kelvin." - - if(grown_seed.lowkpa_tolerance < 20) - dat += "
    It is well adapted to low pressure levels." - if(grown_seed.highkpa_tolerance > 220) - dat += "
    It is well adapted to high pressure levels." - - if(grown_seed.heat_tolerance > 30) - dat += "
    It is well adapted to a range of temperatures." - else if(grown_seed.heat_tolerance < 10) - dat += "
    It is very sensitive to temperature shifts." - - dat += "
    It thrives in a light level of [grown_seed.ideal_light] lumen[grown_seed.ideal_light == 1 ? "" : "s"]." - - if(grown_seed.light_tolerance > 10) - dat += "
    It is well adapted to a range of light levels." - else if(grown_seed.light_tolerance < 3) - dat += "
    It is very sensitive to light level shifts." - - if(grown_seed.toxins_tolerance < 3) - dat += "
    It is highly sensitive to toxins." - else if(grown_seed.toxins_tolerance > 6) - dat += "
    It is remarkably resistant to toxins." - - if(grown_seed.pest_tolerance < 3) - dat += "
    It is highly sensitive to pests." - else if(grown_seed.pest_tolerance > 6) - dat += "
    It is remarkably resistant to pests." - - if(grown_seed.weed_tolerance < 3) - dat += "
    It is highly sensitive to weeds." - else if(grown_seed.weed_tolerance > 6) - dat += "
    It is remarkably resistant to weeds." - - switch(grown_seed.spread) - if(1) - dat += "
    It is capable of growing beyond the confines of a tray." - if(2) - dat += "
    It is a robust and vigorous vine that will spread rapidly." - - switch(grown_seed.carnivorous) - if(1) - dat += "
    It is carniovorous and will eat tray pests for sustenance." - if(2) - dat += "
    It is carnivorous and poses a significant threat to living things around it." - - if(grown_seed.parasite) - dat += "
    It is capable of parisitizing and gaining sustenance from tray weeds." - if(grown_seed.alter_temp) - dat += "
    It will periodically alter the local temperature by [grown_seed.alter_temp] degrees Kelvin." - - if(grown_seed.biolum) - dat += "
    It is [grown_seed.biolum_colour ? "bio-luminescent" : "bio-luminescent"]." - if(grown_seed.flowers) - dat += "
    It has [grown_seed.flower_colour ? "flowers" : "flowers"]." - - if(dat) - user << browse(dat,"window=plant_analyzer") - - return - -// ************************************* -// Hydroponics Tools -// ************************************* - -/obj/item/weapon/plantspray - icon = 'icons/obj/hydroponics.dmi' - item_state = "spray" - flags = NOBLUDGEON - slot_flags = SLOT_BELT - throwforce = 4 - w_class = 2.0 - throw_speed = 2 - throw_range = 10 - var/toxicity = 4 - var/pest_kill_str = 0 - var/weed_kill_str = 0 - -/obj/item/weapon/plantspray/weeds // -- Skie - - name = "weed-spray" - desc = "It's a toxic mixture, in spray form, to kill small weeds." - icon_state = "weedspray" - weed_kill_str = 6 - -/obj/item/weapon/plantspray/pests - name = "pest-spray" - desc = "It's some pest eliminator spray! Do not inhale!" - icon_state = "pestspray" - pest_kill_str = 6 - -/obj/item/weapon/plantspray/pests/old - name = "bottle of pestkiller" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" - -/obj/item/weapon/plantspray/pests/old/carbaryl - name = "bottle of carbaryl" - icon_state = "bottle16" - toxicity = 4 - pest_kill_str = 2 - -/obj/item/weapon/plantspray/pests/old/lindane - name = "bottle of lindane" - icon_state = "bottle18" - toxicity = 6 - pest_kill_str = 4 - -/obj/item/weapon/plantspray/pests/old/phosmet - name = "bottle of phosmet" - icon_state = "bottle15" - toxicity = 8 - pest_kill_str = 7 - -/obj/item/weapon/minihoe // -- Numbers - name = "mini hoe" - desc = "It's used for removing weeds or scratching your back." - icon = 'icons/obj/weapons.dmi' - icon_state = "hoe" - item_state = "hoe" - flags = CONDUCT | NOBLUDGEON - force = 5.0 - throwforce = 7.0 - w_class = 2.0 - matter = list("metal" = 50) - attack_verb = list("slashed", "sliced", "cut", "clawed") - - -// ************************************* -// Weedkiller defines for hydroponics -// ************************************* - -/obj/item/weedkiller - name = "bottle of weedkiller" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" - var/toxicity = 0 - var/weed_kill_str = 0 - -/obj/item/weedkiller/triclopyr - name = "bottle of glyphosate" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" - toxicity = 4 - weed_kill_str = 2 - -/obj/item/weedkiller/lindane - name = "bottle of triclopyr" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle18" - toxicity = 6 - weed_kill_str = 4 - -/obj/item/weedkiller/D24 - name = "bottle of 2,4-D" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle15" - toxicity = 8 - weed_kill_str = 7 - - -// ************************************* -// Nutrient defines for hydroponics -// ************************************* - -/obj/item/weapon/reagent_containers/glass/fertilizer - name = "fertilizer bottle" - desc = "A small glass bottle. Can hold up to 10 units." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" - flags = OPENCONTAINER - possible_transfer_amounts = null - w_class = 2.0 - - var/fertilizer //Reagent contained, if any. - - //Like a shot glass! - amount_per_transfer_from_this = 10 - volume = 10 - -/obj/item/weapon/reagent_containers/glass/fertilizer/New() - ..() - - src.pixel_x = rand(-5.0, 5) - src.pixel_y = rand(-5.0, 5) - - if(fertilizer) - reagents.add_reagent(fertilizer,10) - -/obj/item/weapon/reagent_containers/glass/fertilizer/ez - name = "bottle of E-Z-Nutrient" - icon_state = "bottle16" - fertilizer = "eznutrient" - -/obj/item/weapon/reagent_containers/glass/fertilizer/l4z - name = "bottle of Left 4 Zed" - icon_state = "bottle18" - fertilizer = "left4zed" - -/obj/item/weapon/reagent_containers/glass/fertilizer/rh - name = "bottle of Robust Harvest" - icon_state = "bottle15" - fertilizer = "robustharvest" - -//Hatchets and things to kill kudzu -/obj/item/weapon/hatchet - name = "hatchet" - desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood." - icon = 'icons/obj/weapons.dmi' - icon_state = "hatchet" - flags = CONDUCT - force = 12.0 - w_class = 2.0 - throwforce = 15.0 - throw_speed = 4 - throw_range = 4 - sharp = 1 - edge = 1 - matter = list("metal" = 15000) - origin_tech = "materials=2;combat=1" - attack_verb = list("chopped", "torn", "cut") - -/obj/item/weapon/hatchet/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) - playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) - return ..() - -//If it's a hatchet it goes here. I guess -/obj/item/weapon/hatchet/unathiknife - name = "duelling knife" - desc = "A length of leather-bound wood studded with razor-sharp teeth. How crude." - icon = 'icons/obj/weapons.dmi' - icon_state = "unathiknife" - attack_verb = list("ripped", "torn", "cut") - -/obj/item/weapon/scythe - icon_state = "scythe0" - name = "scythe" - desc = "A sharp and curved blade on a long fibremetal handle, this tool makes it easy to reap what you sow." - force = 13.0 - throwforce = 5.0 - throw_speed = 1 - throw_range = 3 - w_class = 4.0 - flags = NOSHIELD - slot_flags = SLOT_BACK - origin_tech = "materials=2;combat=2" - attack_verb = list("chopped", "sliced", "cut", "reaped") - -/obj/item/weapon/scythe/afterattack(atom/A, mob/user as mob, proximity) - if(!proximity) return - if(istype(A, /obj/effect/plantsegment)) - for(var/obj/effect/plantsegment/B in orange(A,1)) - if(prob(80)) - del B - del A \ No newline at end of file diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm new file mode 100644 index 0000000000..043e44db9d --- /dev/null +++ b/code/modules/hydroponics/seed.dm @@ -0,0 +1,744 @@ +/datum/plantgene + var/genetype // Label used when applying trait. + var/list/values // Values to copy into the target seed datum. + +/datum/seed + //Tracking. + var/uid // Unique identifier. + var/name // Index for global list. + var/seed_name // Plant name for seed packet. + var/seed_noun = "seeds" // Descriptor for packet. + var/display_name // Prettier name. + var/roundstart // If set, seed will not display variety number. + var/mysterious // Only used for the random seed packets. + var/can_self_harvest = 0 // Mostly used for living mobs. + var/growth_stages = 0 // Number of stages the plant passes through before it is mature. + var/list/traits = list() // Initialized in New() + var/list/mutants // Possible predefined mutant varieties, if any. + var/list/chems // Chemicals that plant produces in products/injects into victim. + var/list/consume_gasses // The plant will absorb these gasses during its life. + var/list/exude_gasses // The plant will exude these gasses during its life. + var/kitchen_tag // Used by the reagent grinder. + var/trash_type // Garbage item produced when eaten. + var/splat_type = /obj/effect/decal/cleanable/fruit_smudge // Graffiti decal. + var/has_mob_product + +/datum/seed/New() + + set_trait(TRAIT_IMMUTABLE, 0) // If set, plant will never mutate. If -1, plant is highly mutable. + set_trait(TRAIT_HARVEST_REPEAT, 0) // If 1, this plant will fruit repeatedly. + set_trait(TRAIT_PRODUCES_POWER, 0) // Can be used to make a battery. + set_trait(TRAIT_JUICY, 0) // When thrown, causes a splatter decal. + set_trait(TRAIT_EXPLOSIVE, 0) // When thrown, acts as a grenade. + set_trait(TRAIT_CARNIVOROUS, 0) // 0 = none, 1 = eat pests in tray, 2 = eat living things (when a vine). + set_trait(TRAIT_PARASITE, 0) // 0 = no, 1 = gain health from weed level. + set_trait(TRAIT_STINGS, 0) // Can cause damage/inject reagents when thrown or handled. + set_trait(TRAIT_YIELD, 0) // Amount of product. + set_trait(TRAIT_SPREAD, 0) // 0 limits plant to tray, 1 = creepers, 2 = vines. + set_trait(TRAIT_MATURATION, 0) // Time taken before the plant is mature. + set_trait(TRAIT_PRODUCTION, 0) // Time before harvesting can be undertaken again. + set_trait(TRAIT_TELEPORTING, 0) // Uses the bluespace tomato effect. + set_trait(TRAIT_BIOLUM, 0) // Plant is bioluminescent. + set_trait(TRAIT_ALTER_TEMP, 0) // If set, the plant will periodically alter local temp by this amount. + set_trait(TRAIT_PRODUCT_ICON, 0) // Icon to use for fruit coming from this plant. + set_trait(TRAIT_PLANT_ICON, 0) // Icon to use for the plant growing in the tray. + set_trait(TRAIT_PRODUCT_COLOUR, 0) // Colour to apply to product icon. + set_trait(TRAIT_BIOLUM_COLOUR, 0) // The colour of the plant's radiance. + set_trait(TRAIT_POTENCY, 1) // General purpose plant strength value. + set_trait(TRAIT_REQUIRES_NUTRIENTS, 1) // The plant can starve. + set_trait(TRAIT_REQUIRES_WATER, 1) // The plant can become dehydrated. + set_trait(TRAIT_WATER_CONSUMPTION, 3) // Plant drinks this much per tick. + set_trait(TRAIT_LIGHT_TOLERANCE, 5) // Departure from ideal that is survivable. + set_trait(TRAIT_TOXINS_TOLERANCE, 5) // Resistance to poison. + set_trait(TRAIT_PEST_TOLERANCE, 5) // Threshold for pests to impact health. + set_trait(TRAIT_WEED_TOLERANCE, 5) // Threshold for weeds to impact health. + set_trait(TRAIT_IDEAL_LIGHT, 8) // Preferred light level in luminosity. + set_trait(TRAIT_HEAT_TOLERANCE, 20) // Departure from ideal that is survivable. + set_trait(TRAIT_LOWKPA_TOLERANCE, 25) // Low pressure capacity. + set_trait(TRAIT_ENDURANCE, 100) // Maximum plant HP when growing. + set_trait(TRAIT_HIGHKPA_TOLERANCE, 200) // High pressure capacity. + set_trait(TRAIT_IDEAL_HEAT, 293) // Preferred temperature in Kelvin. + set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.25) // Plant eats this much per tick. + set_trait(TRAIT_PLANT_COLOUR, "#46B543") // Colour of the plant icon. + + spawn(5) + sleep(-1) + update_growth_stages() + +/datum/seed/proc/get_trait(var/trait) + return traits["[trait]"] + +/datum/seed/proc/set_trait(var/trait,var/nval,var/ubound,var/lbound, var/degrade) + if(!isnull(degrade)) nval *= degrade + if(!isnull(ubound)) nval = min(nval,ubound) + if(!isnull(lbound)) nval = max(nval,lbound) + traits["[trait]"] = nval + +/datum/seed/proc/create_spores(var/turf/T) + if(!T) + return + if(!istype(T)) + T = get_turf(T) + if(!T) + return + + var/datum/reagents/R = new/datum/reagents(100) + if(chems.len) + for(var/rid in chems) + var/injecting = min(5,max(1,get_trait(TRAIT_POTENCY)/3)) + R.add_reagent(rid,injecting) + + var/datum/effect/effect/system/smoke_spread/chem/spores/S = new(name) + S.attach(T) + S.set_up(R, round(get_trait(TRAIT_POTENCY)/4), 0, T) + S.start() + +// Does brute damage to a target. +/datum/seed/proc/do_thorns(var/mob/living/carbon/human/target, var/obj/item/fruit, var/target_limb) + + if(!get_trait(TRAIT_CARNIVOROUS)) + return + + if(!istype(target)) + if(istype(target, /mob/living/simple_animal/mouse)) + new /obj/effect/decal/remains/mouse(get_turf(target)) + del(target) + else if(istype(target, /mob/living/simple_animal/lizard)) + new /obj/effect/decal/remains/lizard(get_turf(target)) + del(target) + return + + + if(!target_limb) target_limb = pick("l_foot","r_foot","l_leg","r_leg","l_hand","r_hand","l_arm", "r_arm","head","chest","groin") + var/datum/organ/external/affecting = target.get_organ(target_limb) + var/damage = 0 + + if(get_trait(TRAIT_CARNIVOROUS)) + if(get_trait(TRAIT_CARNIVOROUS) == 2) + if(affecting) + target << "\The [fruit]'s thorns pierce your [affecting.display_name] greedily!" + else + target << "\The [fruit]'s thorns pierce your flesh greedily!" + damage = get_trait(TRAIT_POTENCY)/2 + else + if(affecting) + target << "\The [fruit]'s thorns dig deeply into your [affecting.display_name]!" + else + target << "\The [fruit]'s thorns dig deeply into your flesh!" + damage = get_trait(TRAIT_POTENCY)/5 + else + return + + if(affecting) + affecting.take_damage(damage, 0) + affecting.add_autopsy_data("Thorns",damage) + else + target.adjustBruteLoss(damage) + target.UpdateDamageIcon() + target.updatehealth() + +// Adds reagents to a target. +/datum/seed/proc/do_sting(var/mob/living/carbon/human/target, var/obj/item/fruit) + if(!get_trait(TRAIT_STINGS)) + return + if(chems && chems.len) + + var/body_coverage = HEAD|FACE|EYES|UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS + + for(var/obj/item/clothing/clothes in target) + if(target.l_hand == clothes|| target.r_hand == clothes) + continue + body_coverage &= ~(clothes.body_parts_covered) + + if(!body_coverage) + return + + target << "You are stung by \the [fruit]!" + for(var/rid in chems) + var/injecting = min(5,max(1,get_trait(TRAIT_POTENCY)/5)) + target.reagents.add_reagent(rid,injecting) + +//Splatter a turf. +/datum/seed/proc/splatter(var/turf/T,var/obj/item/thrown) + if(splat_type) + var/obj/effect/plant/splat = new splat_type(T, src) + if(!istype(splat)) // Plants handle their own stuff. + splat.name = "[thrown.name] [pick("smear","smudge","splatter")]" + if(get_trait(TRAIT_BIOLUM)) + if(get_trait(TRAIT_BIOLUM_COLOUR)) + splat.l_color = get_trait(TRAIT_BIOLUM_COLOUR) + splat.SetLuminosity(get_trait(TRAIT_BIOLUM)) + if(get_trait(TRAIT_PRODUCT_COLOUR)) + splat.color = get_trait(TRAIT_PRODUCT_COLOUR) + + if(chems) + for(var/mob/living/M in T.contents) + if(!M.reagents) + continue + for(var/chem in chems) + var/injecting = min(5,max(1,get_trait(TRAIT_POTENCY)/3)) + M.reagents.add_reagent(chem,injecting) + +//Applies an effect to a target atom. +/datum/seed/proc/thrown_at(var/obj/item/thrown,var/atom/target, var/force_explode) + + var/splatted + var/turf/origin_turf = get_turf(target) + + if(force_explode || get_trait(TRAIT_EXPLOSIVE)) + + create_spores(origin_turf) + + var/flood_dist = min(10,max(1,get_trait(TRAIT_POTENCY)/15)) + var/list/open_turfs = list() + var/list/closed_turfs = list() + var/list/valid_turfs = list() + open_turfs |= origin_turf + + // Flood fill to get affected turfs. + while(open_turfs.len) + var/turf/T = pick(open_turfs) + open_turfs -= T + closed_turfs |= T + valid_turfs |= T + + for(var/dir in alldirs) + var/turf/neighbor = get_step(T,dir) + if(!neighbor || (neighbor in closed_turfs) || (neighbor in open_turfs)) + continue + if(neighbor.density || get_dist(neighbor,origin_turf) > flood_dist || istype(neighbor,/turf/space)) + closed_turfs |= neighbor + continue + // Check for windows. + var/no_los + var/turf/last_turf = origin_turf + for(var/turf/target_turf in getline(origin_turf,neighbor)) + if(!last_turf.Enter(target_turf) || target_turf.density) + no_los = 1 + break + last_turf = target_turf + if(!no_los && !origin_turf.Enter(neighbor)) + no_los = 1 + if(no_los) + closed_turfs |= neighbor + continue + open_turfs |= neighbor + + for(var/turf/T in valid_turfs) + for(var/mob/living/M in T.contents) + apply_special_effect(M) + splatter(T,thrown) + origin_turf.visible_message("The [thrown.name] explodes!") + del(thrown) + return + + if(istype(target,/mob/living)) + splatted = apply_special_effect(target,thrown) + else if(istype(target,/turf)) + splatted = 1 + for(var/mob/living/M in target.contents) + apply_special_effect(M) + + if(get_trait(TRAIT_JUICY) && splatted) + splatter(origin_turf,thrown) + origin_turf.visible_message("The [thrown.name] splatters against [target]!") + del(thrown) + +/datum/seed/proc/handle_environment(var/turf/current_turf, var/datum/gas_mixture/environment, var/light_supplied, var/check_only) + + var/health_change = 0 + // Handle gas consumption. + if(consume_gasses && consume_gasses.len) + var/missing_gas = 0 + for(var/gas in consume_gasses) + if(environment && environment.gas && environment.gas[gas] && \ + environment.gas[gas] >= consume_gasses[gas]) + if(!check_only) + environment.adjust_gas(gas,-consume_gasses[gas],1) + else + missing_gas++ + + if(missing_gas > 0) + health_change += missing_gas * HYDRO_SPEED_MULTIPLIER + + // Process it. + var/pressure = environment.return_pressure() + if(pressure < get_trait(TRAIT_LOWKPA_TOLERANCE)|| pressure > get_trait(TRAIT_HIGHKPA_TOLERANCE)) + health_change += rand(1,3) * HYDRO_SPEED_MULTIPLIER + + if(abs(environment.temperature - get_trait(TRAIT_IDEAL_HEAT)) > get_trait(TRAIT_HEAT_TOLERANCE)) + health_change += rand(1,3) * HYDRO_SPEED_MULTIPLIER + + // Handle gas production. + if(exude_gasses && exude_gasses.len && !check_only) + for(var/gas in exude_gasses) + environment.adjust_gas(gas, max(1,round((exude_gasses[gas]*(get_trait(TRAIT_POTENCY)/5))/exude_gasses.len))) + + // Handle light requirements. + if(!light_supplied) + var/area/A = get_area(current_turf) + if(A) + if(A.lighting_use_dynamic) + light_supplied = max(0,min(10,current_turf.lighting_lumcount)-5) + else + light_supplied = 5 + if(light_supplied) + if(abs(light_supplied - get_trait(TRAIT_IDEAL_LIGHT)) > get_trait(TRAIT_LIGHT_TOLERANCE)) + health_change += rand(1,3) * HYDRO_SPEED_MULTIPLIER + + return health_change + +/datum/seed/proc/apply_special_effect(var/mob/living/target,var/obj/item/thrown) + + var/impact = 1 + do_sting(target,thrown) + do_thorns(target,thrown) + + // Bluespace tomato code copied over from grown.dm. + if(get_trait(TRAIT_TELEPORTING)) + + //Plant potency determines radius of teleport. + var/outer_teleport_radius = get_trait(TRAIT_POTENCY)/5 + var/inner_teleport_radius = get_trait(TRAIT_POTENCY)/15 + + var/list/turfs = list() + if(inner_teleport_radius > 0) + for(var/turf/T in orange(target,outer_teleport_radius)) + if(get_dist(target,T) >= inner_teleport_radius) + turfs |= T + + if(turfs.len) + // Moves the mob, causes sparks. + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(3, 1, get_turf(target)) + s.start() + var/turf/picked = get_turf(pick(turfs)) // Just in case... + new/obj/effect/decal/cleanable/molten_item(get_turf(target)) // Leave a pile of goo behind for dramatic effect... + target.loc = picked // And teleport them to the chosen location. + + impact = 1 + + return impact + +//Creates a random seed. MAKE SURE THE LINE HAS DIVERGED BEFORE THIS IS CALLED. +/datum/seed/proc/randomize() + + roundstart = 0 + seed_name = "strange plant" // TODO: name generator. + display_name = "strange plants" // TODO: name generator. + mysterious = 1 + seed_noun = pick("spores","nodes","cuttings","seeds") + + set_trait(TRAIT_POTENCY,rand(5,30),200,0) + set_trait(TRAIT_PRODUCT_ICON,pick(plant_controller.plant_product_sprites)) + set_trait(TRAIT_PLANT_ICON,pick(plant_controller.plant_sprites)) + set_trait(TRAIT_PLANT_COLOUR,"#[get_random_colour(0,75,190)]") + set_trait(TRAIT_PRODUCT_COLOUR,"#[get_random_colour(0,75,190)]") + update_growth_stages() + + if(prob(20)) + set_trait(TRAIT_HARVEST_REPEAT,1) + + if(prob(15)) + if(prob(15)) + set_trait(TRAIT_JUICY,2) + else + set_trait(TRAIT_JUICY,1) + + if(prob(5)) + set_trait(TRAIT_STINGS,1) + + if(prob(5)) + set_trait(TRAIT_PRODUCES_POWER,1) + + if(prob(1)) + set_trait(TRAIT_EXPLOSIVE,1) + else if(prob(1)) + set_trait(TRAIT_TELEPORTING,1) + + if(prob(5)) + consume_gasses = list() + var/gas = pick("oxygen","nitrogen","phoron","carbon_dioxide") + consume_gasses[gas] = rand(3,9) + + if(prob(5)) + exude_gasses = list() + var/gas = pick("oxygen","nitrogen","phoron","carbon_dioxide") + exude_gasses[gas] = rand(3,9) + + chems = list() + if(prob(80)) + chems["nutriment"] = list(rand(1,10),rand(10,20)) + + var/additional_chems = rand(0,5) + + if(additional_chems) + var/list/possible_chems = list( + "woodpulp", + "bicaridine", + "hyperzine", + "cryoxadone", + "blood", + "water", + "potassium", + "plasticide", + "mutationtoxin", + "amutationtoxin", + "inaprovaline", + "space_drugs", + "paroxetine", + "mercury", + "sugar", + "radium", + "ryetalyn", + "alkysine", + "thermite", + "tramadol", + "cryptobiolin", + "dermaline", + "dexalin", + "phoron", + "synaptizine", + "impedrezene", + "hyronalin", + "peridaxon", + "toxin", + "rezadone", + "ethylredoxrazine", + "slimejelly", + "cyanide", + "mindbreaker", + "stoxin" + ) + + for(var/x=1;x<=additional_chems;x++) + if(!possible_chems.len) + break + var/new_chem = pick(possible_chems) + possible_chems -= new_chem + chems[new_chem] = list(rand(1,10),rand(10,20)) + + if(prob(90)) + set_trait(TRAIT_REQUIRES_NUTRIENTS,1) + set_trait(TRAIT_NUTRIENT_CONSUMPTION,rand(25)/25) + else + set_trait(TRAIT_REQUIRES_NUTRIENTS,0) + + if(prob(90)) + set_trait(TRAIT_REQUIRES_WATER,1) + set_trait(TRAIT_WATER_CONSUMPTION,rand(10)) + else + set_trait(TRAIT_REQUIRES_WATER,0) + + set_trait(TRAIT_IDEAL_HEAT, rand(100,400)) + set_trait(TRAIT_HEAT_TOLERANCE, rand(10,30)) + set_trait(TRAIT_IDEAL_LIGHT, rand(2,10)) + set_trait(TRAIT_LIGHT_TOLERANCE, rand(2,7)) + set_trait(TRAIT_TOXINS_TOLERANCE, rand(2,7)) + set_trait(TRAIT_PEST_TOLERANCE, rand(2,7)) + set_trait(TRAIT_WEED_TOLERANCE, rand(2,7)) + set_trait(TRAIT_LOWKPA_TOLERANCE, rand(10,50)) + set_trait(TRAIT_HIGHKPA_TOLERANCE,rand(100,300)) + + if(prob(5)) + set_trait(TRAIT_ALTER_TEMP,rand(-5,5)) + + if(prob(1)) + set_trait(TRAIT_IMMUTABLE,-1) + + var/carnivore_prob = rand(100) + if(carnivore_prob < 5) + set_trait(TRAIT_CARNIVOROUS,2) + else if(carnivore_prob < 10) + set_trait(TRAIT_CARNIVOROUS,1) + + if(prob(10)) + set_trait(TRAIT_PARASITE,1) + + var/vine_prob = rand(100) + if(vine_prob < 5) + set_trait(TRAIT_SPREAD,2) + else if(vine_prob < 10) + set_trait(TRAIT_SPREAD,1) + + if(prob(5)) + set_trait(TRAIT_BIOLUM,1) + set_trait(TRAIT_BIOLUM_COLOUR,"#[get_random_colour(0,75,190)]") + + set_trait(TRAIT_ENDURANCE,rand(60,100)) + set_trait(TRAIT_YIELD,rand(3,15)) + set_trait(TRAIT_MATURATION,rand(5,15)) + set_trait(TRAIT_PRODUCTION,get_trait(TRAIT_MATURATION)+rand(2,5)) + +//Returns a key corresponding to an entry in the global seed list. +/datum/seed/proc/get_mutant_variant() + if(!mutants || !mutants.len || get_trait(TRAIT_IMMUTABLE) > 0) return 0 + return pick(mutants) + +//Mutates the plant overall (randomly). +/datum/seed/proc/mutate(var/degree,var/turf/source_turf) + + if(!degree || get_trait(TRAIT_IMMUTABLE) > 0) return + + source_turf.visible_message("\The [display_name] quivers!") + + //This looks like shit, but it's a lot easier to read/change this way. + var/total_mutations = rand(1,1+degree) + for(var/i = 0;i\The [display_name] withers rapidly!") + if(1) + set_trait(TRAIT_NUTRIENT_CONSUMPTION,get_trait(TRAIT_NUTRIENT_CONSUMPTION)+rand(-(degree*0.1),(degree*0.1)),5,0) + set_trait(TRAIT_WATER_CONSUMPTION, get_trait(TRAIT_WATER_CONSUMPTION) +rand(-degree,degree),50,0) + set_trait(TRAIT_JUICY, !get_trait(TRAIT_JUICY)) + set_trait(TRAIT_STINGS, !get_trait(TRAIT_STINGS)) + if(2) + set_trait(TRAIT_IDEAL_HEAT, get_trait(TRAIT_IDEAL_HEAT) + (rand(-5,5)*degree),800,70) + set_trait(TRAIT_HEAT_TOLERANCE, get_trait(TRAIT_HEAT_TOLERANCE) + (rand(-5,5)*degree),800,70) + set_trait(TRAIT_LOWKPA_TOLERANCE, get_trait(TRAIT_LOWKPA_TOLERANCE)+ (rand(-5,5)*degree),80,0) + set_trait(TRAIT_HIGHKPA_TOLERANCE, get_trait(TRAIT_HIGHKPA_TOLERANCE)+(rand(-5,5)*degree),500,110) + set_trait(TRAIT_EXPLOSIVE,1) + if(3) + set_trait(TRAIT_IDEAL_LIGHT, get_trait(TRAIT_IDEAL_LIGHT)+(rand(-1,1)*degree),30,0) + set_trait(TRAIT_LIGHT_TOLERANCE, get_trait(TRAIT_LIGHT_TOLERANCE)+(rand(-2,2)*degree),10,0) + if(4) + set_trait(TRAIT_TOXINS_TOLERANCE, get_trait(TRAIT_TOXINS_TOLERANCE)+(rand(-2,2)*degree),10,0) + if(5) + set_trait(TRAIT_WEED_TOLERANCE, get_trait(TRAIT_WEED_TOLERANCE)+(rand(-2,2)*degree),10, 0) + if(prob(degree*5)) + set_trait(TRAIT_CARNIVOROUS, get_trait(TRAIT_CARNIVOROUS)+rand(-degree,degree),2, 0) + if(get_trait(TRAIT_CARNIVOROUS)) + source_turf.visible_message("\The [display_name] shudders hungrily.") + if(6) + set_trait(TRAIT_WEED_TOLERANCE, get_trait(TRAIT_WEED_TOLERANCE)+(rand(-2,2)*degree),10, 0) + if(prob(degree*5)) + set_trait(TRAIT_PARASITE,!get_trait(TRAIT_PARASITE)) + if(7) + if(get_trait(TRAIT_YIELD) != -1) + set_trait(TRAIT_YIELD, get_trait(TRAIT_YIELD)+(rand(-2,2)*degree),10,0) + if(8) + set_trait(TRAIT_ENDURANCE, get_trait(TRAIT_ENDURANCE)+(rand(-5,5)*degree),100,10) + set_trait(TRAIT_PRODUCTION, get_trait(TRAIT_PRODUCTION)+(rand(-1,1)*degree),10, 1) + set_trait(TRAIT_POTENCY, get_trait(TRAIT_POTENCY)+(rand(-20,20)*degree),200, 0) + if(prob(degree*5)) + set_trait(TRAIT_SPREAD, get_trait(TRAIT_SPREAD)+rand(-1,1),2, 0) + source_turf.visible_message("\The [display_name] spasms visibly, shifting in the tray.") + if(9) + set_trait(TRAIT_MATURATION, get_trait(TRAIT_MATURATION)+(rand(-1,1)*degree),30, 0) + if(prob(degree*5)) + set_trait(TRAIT_HARVEST_REPEAT, !get_trait(TRAIT_HARVEST_REPEAT)) + if(10) + if(prob(degree*2)) + set_trait(TRAIT_BIOLUM, !get_trait(TRAIT_BIOLUM)) + if(get_trait(TRAIT_BIOLUM)) + source_turf.visible_message("\The [display_name] begins to glow!") + if(prob(degree*2)) + set_trait(TRAIT_BIOLUM_COLOUR,"#[get_random_colour(0,75,190)]") + source_turf.visible_message("\The [display_name]'s glow changes colour!") + else + source_turf.visible_message("\The [display_name]'s glow dims...") + if(11) + set_trait(TRAIT_TELEPORTING,1) + + return + +//Mutates a specific trait/set of traits. +/datum/seed/proc/apply_gene(var/datum/plantgene/gene) + + if(!gene || !gene.values || get_trait(TRAIT_IMMUTABLE) > 0) return + + // Splicing products has some detrimental effects on yield and lifespan. + // We handle this before we do the rest of the looping, as normal traits don't really include lists. + switch(gene.genetype) + if(GENE_BIOCHEMISTRY) + for(var/trait in list(TRAIT_YIELD, TRAIT_ENDURANCE)) + if(get_trait(trait) > 0) set_trait(trait,get_trait(trait),null,1,0.85) + + if(!chems) chems = list() + + var/list/gene_value = gene.values["[TRAIT_CHEMS]"] + for(var/rid in gene_value) + + var/list/gene_chem = gene_value[rid] + + if(!chems[rid]) + chems[rid] = gene_chem.Copy() + continue + + for(var/i=1;i<=gene_chem.len;i++) + + if(isnull(gene_chem[i])) gene_chem[i] = 0 + + if(chems[rid][i]) + chems[rid][i] = max(1,round((gene_chem[i] + chems[rid][i])/2)) + else + chems[rid][i] = gene_chem[i] + + var/list/new_gasses = gene.values["[TRAIT_EXUDE_GASSES]"] + if(islist(new_gasses)) + if(!exude_gasses) exude_gasses = list() + exude_gasses |= new_gasses + for(var/gas in exude_gasses) + exude_gasses[gas] = max(1,round(exude_gasses[gas]*0.8)) + + gene.values["[TRAIT_EXUDE_GASSES]"] = null + gene.values["[TRAIT_CHEMS]"] = null + + if(GENE_DIET) + var/list/new_gasses = gene.values["[TRAIT_CONSUME_GASSES]"] + consume_gasses |= new_gasses + gene.values["[TRAIT_CONSUME_GASSES]"] = null + if(GENE_METABOLISM) + has_mob_product = gene.values["mob_product"] + gene.values["mob_product"] = null + + for(var/trait in gene.values) + set_trait(trait,gene.values["[trait]"]) + + update_growth_stages() + +//Returns a list of the desired trait values. +/datum/seed/proc/get_gene(var/genetype) + + if(!genetype) return 0 + + var/list/traits_to_copy + var/datum/plantgene/P = new() + P.genetype = genetype + P.values = list() + + switch(genetype) + if(GENE_BIOCHEMISTRY) + P.values["[TRAIT_CHEMS]"] = chems + P.values["[TRAIT_EXUDE_GASSES]"] = exude_gasses + traits_to_copy = list(TRAIT_POTENCY) + if(GENE_OUTPUT) + traits_to_copy = list(TRAIT_PRODUCES_POWER,TRAIT_BIOLUM) + if(GENE_ATMOSPHERE) + traits_to_copy = list(TRAIT_HEAT_TOLERANCE,TRAIT_LOWKPA_TOLERANCE,TRAIT_HIGHKPA_TOLERANCE) + if(GENE_HARDINESS) + traits_to_copy = list(TRAIT_TOXINS_TOLERANCE,TRAIT_PEST_TOLERANCE,TRAIT_WEED_TOLERANCE,TRAIT_ENDURANCE) + if(GENE_METABOLISM) + P.values["mob_product"] = has_mob_product + traits_to_copy = list(TRAIT_REQUIRES_NUTRIENTS,TRAIT_REQUIRES_WATER,TRAIT_ALTER_TEMP) + if(GENE_VIGOUR) + traits_to_copy = list(TRAIT_PRODUCTION,TRAIT_MATURATION,TRAIT_YIELD,TRAIT_SPREAD) + if(GENE_DIET) + P.values["[TRAIT_CONSUME_GASSES]"] = consume_gasses + traits_to_copy = list(TRAIT_CARNIVOROUS,TRAIT_PARASITE,TRAIT_NUTRIENT_CONSUMPTION,TRAIT_WATER_CONSUMPTION) + if(GENE_ENVIRONMENT) + traits_to_copy = list(TRAIT_IDEAL_HEAT,TRAIT_IDEAL_LIGHT,TRAIT_LIGHT_TOLERANCE) + if(GENE_PIGMENT) + traits_to_copy = list(TRAIT_PLANT_COLOUR,TRAIT_PRODUCT_COLOUR,TRAIT_BIOLUM_COLOUR) + if(GENE_STRUCTURE) + traits_to_copy = list(TRAIT_PLANT_ICON,TRAIT_PRODUCT_ICON,TRAIT_HARVEST_REPEAT) + if(GENE_FRUIT) + traits_to_copy = list(TRAIT_STINGS,TRAIT_EXPLOSIVE,TRAIT_JUICY) + if(GENE_SPECIAL) + traits_to_copy = list(TRAIT_TELEPORTING) + + for(var/trait in traits_to_copy) + P.values["[trait]"] = get_trait(trait) + return (P ? P : 0) + +//Place the plant products at the feet of the user. +/datum/seed/proc/harvest(var/mob/user,var/yield_mod,var/harvest_sample,var/force_amount) + + if(!user) + return + + if(!force_amount && get_trait(TRAIT_YIELD) == 0 && !harvest_sample) + if(istype(user)) user << "You fail to harvest anything useful." + else + if(istype(user)) user << "You [harvest_sample ? "take a sample" : "harvest"] from the [display_name]." + + //This may be a new line. Update the global if it is. + if(name == "new line" || !(name in plant_controller.seeds)) + uid = plant_controller.seeds.len + 1 + name = "[uid]" + plant_controller.seeds[name] = src + + if(harvest_sample) + var/obj/item/seeds/seeds = new(get_turf(user)) + seeds.seed_type = name + seeds.update_seed() + return + + var/total_yield = 0 + if(!isnull(force_amount)) + total_yield = force_amount + else + if(get_trait(TRAIT_YIELD) > -1) + if(isnull(yield_mod) || yield_mod < 1) + yield_mod = 0 + total_yield = get_trait(TRAIT_YIELD) + else + total_yield = get_trait(TRAIT_YIELD) + rand(yield_mod) + total_yield = max(1,total_yield) + + currently_querying = list() + for(var/i = 0;iThe pod disgorges [product]!") + handle_living_product(product) + if(istype(product,/mob/living/simple_animal/mushroom)) // Gross. + var/mob/living/simple_animal/mushroom/mush = product + mush.seed = src + +// When the seed in this machine mutates/is modified, the tray seed value +// is set to a new datum copied from the original. This datum won't actually +// be put into the global datum list until the product is harvested, though. +/datum/seed/proc/diverge(var/modified) + + if(get_trait(TRAIT_IMMUTABLE) > 0) return + + //Set up some basic information. + var/datum/seed/new_seed = new + new_seed.name = "new line" + new_seed.uid = 0 + new_seed.roundstart = 0 + new_seed.can_self_harvest = can_self_harvest + new_seed.kitchen_tag = kitchen_tag + new_seed.trash_type = trash_type + new_seed.has_mob_product = has_mob_product + //Copy over everything else. + if(mutants) new_seed.mutants = mutants.Copy() + if(chems) new_seed.chems = chems.Copy() + if(consume_gasses) new_seed.consume_gasses = consume_gasses.Copy() + if(exude_gasses) new_seed.exude_gasses = exude_gasses.Copy() + + new_seed.seed_name = "[(roundstart ? "[(modified ? "modified" : "mutant")] " : "")][seed_name]" + new_seed.display_name = "[(roundstart ? "[(modified ? "modified" : "mutant")] " : "")][display_name]" + new_seed.seed_noun = seed_noun + new_seed.traits = traits.Copy() + new_seed.update_growth_stages() + return new_seed + +/datum/seed/proc/update_growth_stages() + if(get_trait(TRAIT_PLANT_ICON)) + growth_stages = plant_controller.plant_sprites[get_trait(TRAIT_PLANT_ICON)] + else + growth_stages = 0 diff --git a/code/modules/hydroponics/seed_controller.dm b/code/modules/hydroponics/seed_controller.dm new file mode 100644 index 0000000000..9b346b961c --- /dev/null +++ b/code/modules/hydroponics/seed_controller.dm @@ -0,0 +1,150 @@ +// Attempts to offload processing for the spreading plants from the MC. +// Processes vines/spreading plants. + +#define PLANTS_PER_TICK 500 // Cap on number of plant segments processed. +#define PLANT_TICK_TIME 75 // Number of ticks between the plant processor cycling. + +// Debug for testing seed genes. +/client/proc/show_plant_genes() + set category = "Debug" + set name = "Show Plant Genes" + set desc = "Prints the round's plant gene masks." + + if(!holder) return + + if(!plant_controller || !plant_controller.gene_tag_masks) + usr << "Gene masks not set." + return + + for(var/mask in plant_controller.gene_tag_masks) + usr << "[mask]: [plant_controller.gene_tag_masks[mask]]" + +var/global/datum/controller/plants/plant_controller // Set in New(). + +/datum/controller/plants + + var/plants_per_tick = PLANTS_PER_TICK + var/plant_tick_time = PLANT_TICK_TIME + var/list/product_descs = list() // Stores generated fruit descs. + var/list/plant_queue = list() // All queued plants. + var/list/seeds = list() // All seed data stored here. + var/list/gene_tag_masks = list() // Gene obfuscation for delicious trial and error goodness. + var/list/plant_icon_cache = list() // Stores images of growth, fruits and seeds. + var/list/plant_sprites = list() // List of all harvested product sprites. + var/list/plant_product_sprites = list() // List of all growth sprites plus number of growth stages. + var/processing = 0 // Off/on. + +/datum/controller/plants/New() + if(plant_controller && plant_controller != src) + log_debug("Rebuilding plant controller.") + del(plant_controller) + plant_controller = src + setup() + process() + +// Predefined/roundstart varieties use a string key to make it +// easier to grab the new variety when mutating. Post-roundstart +// and mutant varieties use their uid converted to a string instead. +// Looks like shit but it's sort of necessary. +/datum/controller/plants/proc/setup() + + // Build the icon lists. + for(var/icostate in icon_states('icons/obj/hydroponics_growing.dmi')) + var/split = findtext(icostate,"-") + if(!split) + // invalid icon_state + continue + + var/ikey = copytext(icostate,(split+1)) + if(ikey == "dead") + // don't count dead icons + continue + ikey = text2num(ikey) + var/base = copytext(icostate,1,split) + + if(!(plant_sprites[base]) || (plant_sprites[base] 0) return 0 - return pick(mutants) - -//Mutates the plant overall (randomly). -/datum/seed/proc/mutate(var/degree,var/turf/source_turf) - - if(!degree || immutable > 0) return - - source_turf.visible_message("\blue \The [display_name] quivers!") - - //This looks like shit, but it's a lot easier to read/change this way. - var/total_mutations = rand(1,1+degree) - for(var/i = 0;ichanges colour
    !") - else - source_turf.visible_message("\blue \The [display_name]'s glow dims...") - if(11) - if(prob(degree*2)) - flowers = !flowers - if(flowers) - source_turf.visible_message("\blue \The [display_name] sprouts a bevy of flowers!") - if(prob(degree*2)) - flower_colour = "#[pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF"))]" - source_turf.visible_message("\blue \The [display_name]'s flowers changes colour
    !") - else - source_turf.visible_message("\blue \The [display_name]'s flowers wither and fall off.") - return - -//Mutates a specific trait/set of traits. -/datum/seed/proc/apply_gene(var/datum/plantgene/gene) - - if(!gene || !gene.values || immutable > 0) return - - switch(gene.genetype) - - //Splicing products has some detrimental effects on yield and lifespan. - if("products") - - if(gene.values.len < 6) return - - if(yield > 0) yield = max(1,round(yield*0.85)) - if(endurance > 0) endurance = max(1,round(endurance*0.85)) - if(lifespan > 0) lifespan = max(1,round(lifespan*0.85)) - - if(!products) products = list() - products |= gene.values[1] - - if(!chems) chems = list() - - var/list/gene_value = gene.values[2] - for(var/rid in gene_value) - - var/list/gene_chem = gene_value[rid] - - if(!chems[rid]) - chems[rid] = gene_chem.Copy() - continue - - for(var/i=1;i<=gene_chem.len;i++) - - if(isnull(gene_chem[i])) gene_chem[i] = 0 - - if(chems[rid][i]) - chems[rid][i] = max(1,round((gene_chem[i] + chems[rid][i])/2)) - else - chems[rid][i] = gene_chem[i] - - var/list/new_gasses = gene.values[3] - if(islist(new_gasses)) - if(!exude_gasses) exude_gasses = list() - exude_gasses |= new_gasses - for(var/gas in exude_gasses) - exude_gasses[gas] = max(1,round(exude_gasses[gas]*0.8)) - - alter_temp = gene.values[4] - potency = gene.values[5] - harvest_repeat = gene.values[6] - - if("consumption") - - if(gene.values.len < 7) return - - consume_gasses = gene.values[1] - requires_nutrients = gene.values[2] - nutrient_consumption = gene.values[3] - requires_water = gene.values[4] - water_consumption = gene.values[5] - carnivorous = gene.values[6] - parasite = gene.values[7] - - if("environment") - - if(gene.values.len < 6) return - - ideal_heat = gene.values[1] - heat_tolerance = gene.values[2] - ideal_light = gene.values[3] - light_tolerance = gene.values[4] - lowkpa_tolerance = gene.values[5] - highkpa_tolerance = gene.values[6] - - if("resistance") - - if(gene.values.len < 3) return - - toxins_tolerance = gene.values[1] - pest_tolerance = gene.values[2] - weed_tolerance = gene.values[3] - - if("vigour") - - if(gene.values.len < 6) return - - endurance = gene.values[1] - yield = gene.values[2] - lifespan = gene.values[3] - spread = gene.values[4] - maturation = gene.values[5] - production = gene.values[6] - - if("flowers") - - if(gene.values.len < 7) return - - product_icon = gene.values[1] - product_colour = gene.values[2] - biolum = gene.values[3] - biolum_colour = gene.values[4] - flowers = gene.values[5] - flower_icon = gene.values[6] - flower_colour = gene.values[7] - -//Returns a list of the desired trait values. -/datum/seed/proc/get_gene(var/genetype) - - if(!genetype) return 0 - - var/datum/plantgene/P = new() - P.genetype = genetype - - switch(genetype) - if("products") - P.values = list( - (products ? products : 0), - (chems ? chems : 0), - (exude_gasses ? exude_gasses : 0), - (alter_temp ? alter_temp : 0), - (potency ? potency : 0), - (harvest_repeat ? harvest_repeat : 0) - ) - - if("consumption") - P.values = list( - (consume_gasses ? consume_gasses : 0), - (requires_nutrients ? requires_nutrients : 0), - (nutrient_consumption ? nutrient_consumption : 0), - (requires_water ? requires_water : 0), - (water_consumption ? water_consumption : 0), - (carnivorous ? carnivorous : 0), - (parasite ? parasite : 0) - ) - - if("environment") - P.values = list( - (ideal_heat ? ideal_heat : 0), - (heat_tolerance ? heat_tolerance : 0), - (ideal_light ? ideal_light : 0), - (light_tolerance ? light_tolerance : 0), - (lowkpa_tolerance ? lowkpa_tolerance : 0), - (highkpa_tolerance ? highkpa_tolerance : 0) - ) - - if("resistance") - P.values = list( - (toxins_tolerance ? toxins_tolerance : 0), - (pest_tolerance ? pest_tolerance : 0), - (weed_tolerance ? weed_tolerance : 0) - ) - - if("vigour") - P.values = list( - (endurance ? endurance : 0), - (yield ? yield : 0), - (lifespan ? lifespan : 0), - (spread ? spread : 0), - (maturation ? maturation : 0), - (production ? production : 0) - ) - - if("flowers") - P.values = list( - (product_icon ? product_icon : 0), - (product_colour ? product_colour : 0), - (biolum ? biolum : 0), - (biolum_colour ? biolum_colour : 0), - (flowers ? flowers : 0), - (flower_icon ? flower_icon : 0), - (flower_colour ? flower_colour : 0) - ) - - return (P ? P : 0) - -//Place the plant products at the feet of the user. -/datum/seed/proc/harvest(var/mob/user,var/yield_mod,var/harvest_sample) - - if(!user) - return - - var/got_product - if(!isnull(products) && products.len && yield > 0) - got_product = 1 - - if(!got_product && !harvest_sample) - user << "\red You fail to harvest anything useful." - else - user << "You [harvest_sample ? "take a sample" : "harvest"] from the [display_name]." - - //This may be a new line. Update the global if it is. - if(name == "new line" || !(name in seed_types)) - uid = seed_types.len + 1 - name = "[uid]" - seed_types[name] = src - - if(harvest_sample) - var/obj/item/seeds/seeds = new(get_turf(user)) - seeds.seed_type = name - seeds.update_seed() - return - - var/total_yield = 0 - if(yield > -1) - if(isnull(yield_mod) || yield_mod < 1) - yield_mod = 0 - total_yield = yield - else - total_yield = yield + rand(yield_mod) - total_yield = max(1,total_yield) - - currently_querying = list() - for(var/i = 0;i 0) return - - //Set up some basic information. - var/datum/seed/new_seed = new - new_seed.name = "new line" - new_seed.uid = 0 - new_seed.roundstart = 0 - - //Copy over everything else. - if(products) new_seed.products = products.Copy() - if(mutants) new_seed.mutants = mutants.Copy() - if(chems) new_seed.chems = chems.Copy() - if(consume_gasses) new_seed.consume_gasses = consume_gasses.Copy() - if(exude_gasses) new_seed.exude_gasses = exude_gasses.Copy() - - if(modified != -1) - new_seed.seed_name = "[(roundstart ? "[(modified ? "modified" : "mutant")] " : "")][seed_name]" - new_seed.display_name = "[(roundstart ? "[(modified ? "modified" : "mutant")] " : "")][display_name]" - else - new_seed.seed_name = "[seed_name]" - new_seed.display_name = "[display_name]" - - new_seed.seed_noun = seed_noun - - new_seed.requires_nutrients = requires_nutrients - new_seed.nutrient_consumption = nutrient_consumption - new_seed.requires_water = requires_water - new_seed.water_consumption = water_consumption - new_seed.ideal_heat = ideal_heat - new_seed.heat_tolerance = heat_tolerance - new_seed.ideal_light = ideal_light - new_seed.light_tolerance = light_tolerance - new_seed.toxins_tolerance = toxins_tolerance - new_seed.lowkpa_tolerance = lowkpa_tolerance - new_seed.highkpa_tolerance = highkpa_tolerance - new_seed.pest_tolerance = pest_tolerance - new_seed.weed_tolerance = weed_tolerance - new_seed.endurance = endurance - new_seed.yield = yield - new_seed.lifespan = lifespan - new_seed.maturation = maturation - new_seed.production = production - new_seed.growth_stages = growth_stages - new_seed.harvest_repeat = harvest_repeat - new_seed.potency = potency - new_seed.spread = spread - new_seed.carnivorous = carnivorous - new_seed.parasite = parasite - new_seed.plant_icon = plant_icon - new_seed.product_icon = product_icon - new_seed.product_colour = product_colour - new_seed.packet_icon = packet_icon - new_seed.biolum = biolum - new_seed.biolum_colour = biolum_colour - new_seed.flowers = flowers - new_seed.flower_icon = flower_icon - new_seed.alter_temp = alter_temp - - return new_seed - -// Actual roundstart seed types after this point. // Chili plants/variants. /datum/seed/chili - name = "chili" seed_name = "chili" display_name = "chili plants" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/chili) chems = list("capsaicin" = list(3,5), "nutriment" = list(1,25)) mutants = list("icechili") - packet_icon = "seed-chili" - plant_icon = "chili" - harvest_repeat = 1 + kitchen_tag = "chili" - lifespan = 20 - maturation = 5 - production = 5 - yield = 4 - potency = 20 +/datum/seed/chili/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,5) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,20) + set_trait(TRAIT_PRODUCT_ICON,"chili") + set_trait(TRAIT_PRODUCT_COLOUR,"#ED3300") + set_trait(TRAIT_PLANT_ICON,"bush2") /datum/seed/chili/ice name = "icechili" seed_name = "ice pepper" display_name = "ice-pepper plants" mutants = null - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/icepepper) chems = list("frostoil" = list(3,5), "nutriment" = list(1,50)) - packet_icon = "seed-icepepper" - plant_icon = "chiliice" + kitchen_tag = "icechili" - maturation = 4 - production = 4 +/datum/seed/chili/ice/New() + ..() + set_trait(TRAIT_MATURATION,4) + set_trait(TRAIT_PRODUCTION,4) + set_trait(TRAIT_PRODUCT_COLOUR,"#00EDC6") // Berry plants/variants. /datum/seed/berry name = "berries" seed_name = "berry" display_name = "berry bush" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/berries) mutants = list("glowberries","poisonberries") - packet_icon = "seed-berry" - plant_icon = "berry" - harvest_repeat = 1 - chems = list("nutriment" = list(1,10)) + chems = list("nutriment" = list(1,10), "berryjuice" = list(1,10)) + kitchen_tag = "berries" - lifespan = 20 - maturation = 5 - production = 5 - yield = 2 - potency = 10 +/datum/seed/berry/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_JUICY,1) + set_trait(TRAIT_MATURATION,5) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,2) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"berry") + set_trait(TRAIT_PRODUCT_COLOUR,"#FA1616") + set_trait(TRAIT_PLANT_ICON,"bush") /datum/seed/berry/glow name = "glowberries" seed_name = "glowberry" display_name = "glowberry bush" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/glowberries) mutants = null - packet_icon = "seed-glowberry" - plant_icon = "glowberry" chems = list("nutriment" = list(1,10), "uranium" = list(3,5)) - lifespan = 30 - maturation = 5 - production = 5 - yield = 2 - potency = 10 +/datum/seed/berry/glow/New() + ..() + set_trait(TRAIT_SPREAD,1) + set_trait(TRAIT_BIOLUM,1) + set_trait(TRAIT_BIOLUM_COLOUR,"#006622") + set_trait(TRAIT_MATURATION,5) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,2) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_COLOUR,"c9fa16") /datum/seed/berry/poison name = "poisonberries" seed_name = "poison berry" display_name = "poison berry bush" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/poisonberries) mutants = list("deathberries") - packet_icon = "seed-poisonberry" - plant_icon = "poisonberry" - chems = list("nutriment" = list(1), "toxin" = list(3,5)) + chems = list("nutriment" = list(1), "toxin" = list(3,5), "poisonberryjuice" = list(3,5)) + +/datum/seed/berry/poison/New() + ..() + set_trait(TRAIT_PRODUCT_COLOUR,"#6DC961") /datum/seed/berry/poison/death name = "deathberries" seed_name = "death berry" display_name = "death berry bush" mutants = null - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/deathberries) - packet_icon = "seed-deathberry" - plant_icon = "deathberry" chems = list("nutriment" = list(1), "toxin" = list(3,3), "lexorin" = list(1,5)) - yield = 3 - potency = 50 +/datum/seed/berry/poison/death/New() + ..() + set_trait(TRAIT_YIELD,3) + set_trait(TRAIT_POTENCY,50) + set_trait(TRAIT_PRODUCT_COLOUR,"#7A5454") // Nettles/variants. /datum/seed/nettle name = "nettle" seed_name = "nettle" display_name = "nettles" - products = list(/obj/item/weapon/grown/nettle) mutants = list("deathnettle") - packet_icon = "seed-nettle" - plant_icon = "nettle" - harvest_repeat = 1 chems = list("nutriment" = list(1,50), "sacid" = list(0,1)) - lifespan = 30 - maturation = 6 - production = 6 - yield = 4 - potency = 10 - growth_stages = 5 + kitchen_tag = "nettle" + kitchen_tag = "nettle" + +/datum/seed/nettle/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_STINGS,1) + set_trait(TRAIT_PLANT_ICON,"bush5") + set_trait(TRAIT_PRODUCT_ICON,"nettles") + set_trait(TRAIT_PRODUCT_COLOUR,"#728A54") /datum/seed/nettle/death name = "deathnettle" seed_name = "death nettle" display_name = "death nettles" - products = list(/obj/item/weapon/grown/nettle/death) mutants = null - packet_icon = "seed-deathnettle" - plant_icon = "deathnettle" chems = list("nutriment" = list(1,50), "pacid" = list(0,1)) + kitchen_tag = "deathnettle" - maturation = 8 - yield = 2 +/datum/seed/nettle/death/New() + ..() + set_trait(TRAIT_MATURATION,8) + set_trait(TRAIT_YIELD,2) + set_trait(TRAIT_PRODUCT_COLOUR,"#8C5030") + set_trait(TRAIT_PLANT_COLOUR,"#634941") //Tomatoes/variants. /datum/seed/tomato name = "tomato" seed_name = "tomato" display_name = "tomato plant" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/tomato) mutants = list("bluetomato","bloodtomato") - packet_icon = "seed-tomato" - plant_icon = "tomato" - harvest_repeat = 1 - chems = list("nutriment" = list(1,10)) + chems = list("nutriment" = list(1,10), "tomatojuice" = list(1,10)) + kitchen_tag = "tomato" - lifespan = 25 - maturation = 8 - production = 6 - yield = 2 - potency = 10 +/datum/seed/tomato/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_JUICY,1) + set_trait(TRAIT_MATURATION,8) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,2) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"tomato") + set_trait(TRAIT_PRODUCT_COLOUR,"#D10000") + set_trait(TRAIT_PLANT_ICON,"bush3") /datum/seed/tomato/blood name = "bloodtomato" seed_name = "blood tomato" display_name = "blood tomato plant" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/bloodtomato) mutants = list("killer") - packet_icon = "seed-bloodtomato" - plant_icon = "bloodtomato" chems = list("nutriment" = list(1,10), "blood" = list(1,5)) + splat_type = /obj/effect/decal/cleanable/blood/splatter - yield = 3 +/datum/seed/tomato/blood/New() + ..() + set_trait(TRAIT_YIELD,3) + set_trait(TRAIT_PRODUCT_COLOUR,"#FF0000") /datum/seed/tomato/killer name = "killertomato" seed_name = "killer tomato" display_name = "killer tomato plant" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/killertomato) mutants = null - packet_icon = "seed-killertomato" - plant_icon = "killertomato" + can_self_harvest = 1 + has_mob_product = /mob/living/simple_animal/tomato - yield = 2 - growth_stages = 2 +/datum/seed/tomato/killer/New() + ..() + set_trait(TRAIT_YIELD,2) + set_trait(TRAIT_PRODUCT_COLOUR,"#A86747") /datum/seed/tomato/blue name = "bluetomato" seed_name = "blue tomato" display_name = "blue tomato plant" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/bluetomato) mutants = list("bluespacetomato") - packet_icon = "seed-bluetomato" - plant_icon = "bluetomato" chems = list("nutriment" = list(1,20), "lube" = list(1,5)) +/datum/seed/tomato/blue/New() + ..() + set_trait(TRAIT_PRODUCT_COLOUR,"#4D86E8") + set_trait(TRAIT_PLANT_COLOUR,"#070AAD") + /datum/seed/tomato/blue/teleport name = "bluespacetomato" seed_name = "bluespace tomato" display_name = "bluespace tomato plant" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/bluespacetomato) mutants = null - packet_icon = "seed-bluespacetomato" - plant_icon = "bluespacetomato" chems = list("nutriment" = list(1,20), "singulo" = list(1,5)) +/datum/seed/tomato/blue/teleport/New() + ..() + set_trait(TRAIT_TELEPORTING,1) + set_trait(TRAIT_PRODUCT_COLOUR,"#00E5FF") + set_trait(TRAIT_BIOLUM,1) + set_trait(TRAIT_BIOLUM_COLOUR,"#4DA4A8") + //Eggplants/varieties. /datum/seed/eggplant name = "eggplant" seed_name = "eggplant" display_name = "eggplants" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/eggplant) mutants = list("realeggplant") - packet_icon = "seed-eggplant" - plant_icon = "eggplant" - harvest_repeat = 1 chems = list("nutriment" = list(1,10)) + kitchen_tag = "eggplant" - lifespan = 25 - maturation = 6 - production = 6 - yield = 2 - potency = 20 - -/datum/seed/eggplant/eggs - name = "realeggplant" - seed_name = "egg-plant" - display_name = "egg-plants" - products = list(/obj/item/weapon/reagent_containers/food/snacks/egg) - mutants = null - packet_icon = "seed-eggy" - plant_icon = "eggy" - - lifespan = 75 - production = 12 +/datum/seed/eggplant/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,2) + set_trait(TRAIT_POTENCY,20) + set_trait(TRAIT_PRODUCT_ICON,"eggplant") + set_trait(TRAIT_PRODUCT_COLOUR,"#892694") + set_trait(TRAIT_PLANT_ICON,"bush4") //Apples/varieties. - /datum/seed/apple name = "apple" seed_name = "apple" display_name = "apple tree" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/apple) mutants = list("poisonapple","goldapple") - packet_icon = "seed-apple" - plant_icon = "apple" - harvest_repeat = 1 chems = list("nutriment" = list(1,10)) + kitchen_tag = "apple" - lifespan = 55 - maturation = 6 - production = 6 - yield = 5 - potency = 10 +/datum/seed/apple/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,5) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"apple") + set_trait(TRAIT_PRODUCT_COLOUR,"#FF540A") + set_trait(TRAIT_PLANT_ICON,"tree2") /datum/seed/apple/poison name = "poisonapple" mutants = null - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/apple/poisoned) chems = list("cyanide" = list(1,5)) /datum/seed/apple/gold name = "goldapple" seed_name = "golden apple" display_name = "gold apple tree" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/goldapple) mutants = null - packet_icon = "seed-goldapple" - plant_icon = "goldapple" chems = list("nutriment" = list(1,10), "gold" = list(1,5)) + kitchen_tag = "goldapple" - maturation = 10 - production = 10 - yield = 3 +/datum/seed/apple/gold/New() + ..() + set_trait(TRAIT_MATURATION,10) + set_trait(TRAIT_PRODUCTION,10) + set_trait(TRAIT_YIELD,3) + set_trait(TRAIT_PRODUCT_COLOUR,"#FFDD00") + set_trait(TRAIT_PLANT_COLOUR,"#D6B44D") //Ambrosia/varieties. /datum/seed/ambrosia name = "ambrosia" seed_name = "ambrosia vulgaris" display_name = "ambrosia vulgaris" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris) mutants = list("ambrosiadeus") - packet_icon = "seed-ambrosiavulgaris" - plant_icon = "ambrosiavulgaris" - harvest_repeat = 1 chems = list("nutriment" = list(1), "space_drugs" = list(1,8), "kelotane" = list(1,8,1), "bicaridine" = list(1,10,1), "toxin" = list(1,10)) + kitchen_tag = "ambrosia" - lifespan = 60 - maturation = 6 - production = 6 - yield = 6 - potency = 5 +/datum/seed/ambrosia/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,6) + set_trait(TRAIT_POTENCY,5) + set_trait(TRAIT_PRODUCT_ICON,"ambrosia") + set_trait(TRAIT_PRODUCT_COLOUR,"#9FAD55") + set_trait(TRAIT_PLANT_ICON,"ambrosia") /datum/seed/ambrosia/deus name = "ambrosiadeus" seed_name = "ambrosia deus" display_name = "ambrosia deus" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus) mutants = null - packet_icon = "seed-ambrosiadeus" - plant_icon = "ambrosiadeus" chems = list("nutriment" = list(1), "bicaridine" = list(1,8), "synaptizine" = list(1,8,1), "hyperzine" = list(1,10,1), "space_drugs" = list(1,10)) + kitchen_tag = "ambrosiadeus" + +/datum/seed/ambrosia/deus/New() + ..() + set_trait(TRAIT_PRODUCT_COLOUR,"#A3F0AD") + set_trait(TRAIT_PLANT_COLOUR,"#2A9C61") //Mushrooms/varieties. /datum/seed/mushroom @@ -974,667 +305,799 @@ proc/populate_seed_list() seed_name = "chanterelle" seed_noun = "spores" display_name = "chanterelle mushrooms" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/chanterelle) mutants = list("reishi","amanita","plumphelmet") - packet_icon = "mycelium-chanter" - plant_icon = "chanter" chems = list("nutriment" = list(1,25)) + splat_type = /obj/effect/plant + kitchen_tag = "mushroom" - lifespan = 35 - maturation = 7 - production = 1 - yield = 5 - potency = 1 - growth_stages = 3 +/datum/seed/mushroom/New() + ..() + set_trait(TRAIT_MATURATION,7) + set_trait(TRAIT_PRODUCTION,1) + set_trait(TRAIT_YIELD,5) + set_trait(TRAIT_POTENCY,1) + set_trait(TRAIT_PRODUCT_ICON,"mushroom4") + set_trait(TRAIT_PRODUCT_COLOUR,"#DBDA72") + set_trait(TRAIT_PLANT_COLOUR,"#D9C94E") + set_trait(TRAIT_PLANT_ICON,"mushroom") /datum/seed/mushroom/mold name = "mold" seed_name = "brown mold" display_name = "brown mold" - products = null mutants = null - //mutants = list("wallrot") //TBD. - plant_icon = "mold" - lifespan = 50 - maturation = 10 - yield = -1 +/datum/seed/mushroom/mold/New() + ..() + set_trait(TRAIT_SPREAD,1) + set_trait(TRAIT_MATURATION,10) + set_trait(TRAIT_YIELD,-1) + set_trait(TRAIT_PRODUCT_ICON,"mushroom5") + set_trait(TRAIT_PRODUCT_COLOUR,"#7A5F20") + set_trait(TRAIT_PLANT_COLOUR,"#7A5F20") + set_trait(TRAIT_PLANT_ICON,"mushroom9") /datum/seed/mushroom/plump name = "plumphelmet" seed_name = "plump helmet" display_name = "plump helmet mushrooms" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet) mutants = list("walkingmushroom","towercap") - packet_icon = "mycelium-plump" - plant_icon = "plump" chems = list("nutriment" = list(2,10)) + kitchen_tag = "plumphelmet" - lifespan = 25 - maturation = 8 - yield = 4 - potency = 0 +/datum/seed/mushroom/plump/New() + ..() + set_trait(TRAIT_MATURATION,8) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,0) + set_trait(TRAIT_PRODUCT_ICON,"mushroom10") + set_trait(TRAIT_PRODUCT_COLOUR,"#B57BB0") + set_trait(TRAIT_PLANT_COLOUR,"#9E4F9D") + set_trait(TRAIT_PLANT_ICON,"mushroom2") + +/datum/seed/mushroom/plump/walking + name = "walkingmushroom" + seed_name = "walking mushroom" + display_name = "walking mushrooms" + mutants = null + can_self_harvest = 1 + has_mob_product = /mob/living/simple_animal/mushroom + +/datum/seed/mushroom/plump/walking/New() + ..() + set_trait(TRAIT_MATURATION,5) + set_trait(TRAIT_YIELD,1) + set_trait(TRAIT_PRODUCT_COLOUR,"#FAC0F2") + set_trait(TRAIT_PLANT_COLOUR,"#C4B1C2") /datum/seed/mushroom/hallucinogenic name = "reishi" seed_name = "reishi" display_name = "reishi" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/reishi) mutants = list("libertycap","glowshroom") - packet_icon = "mycelium-reishi" - plant_icon = "reishi" chems = list("nutriment" = list(1,50), "psilocybin" = list(3,5)) - maturation = 10 - production = 5 - yield = 4 - potency = 15 - growth_stages = 4 +/datum/seed/mushroom/hallucinogenic/New() + ..() + set_trait(TRAIT_MATURATION,10) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,15) + set_trait(TRAIT_PRODUCT_ICON,"mushroom11") + set_trait(TRAIT_PRODUCT_COLOUR,"#FFB70F") + set_trait(TRAIT_PLANT_COLOUR,"#F58A18") + set_trait(TRAIT_PLANT_ICON,"mushroom6") /datum/seed/mushroom/hallucinogenic/strong name = "libertycap" seed_name = "liberty cap" display_name = "liberty cap mushrooms" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap) mutants = null - packet_icon = "mycelium-liberty" - plant_icon = "liberty" chems = list("nutriment" = list(1), "stoxin" = list(3,3), "space_drugs" = list(1,25)) - lifespan = 25 - production = 1 - potency = 15 - growth_stages = 3 +/datum/seed/mushroom/hallucinogenic/strong/New() + ..() + set_trait(TRAIT_PRODUCTION,1) + set_trait(TRAIT_POTENCY,15) + set_trait(TRAIT_PRODUCT_ICON,"mushroom8") + set_trait(TRAIT_PRODUCT_COLOUR,"#F2E550") + set_trait(TRAIT_PLANT_COLOUR,"#D1CA82") + set_trait(TRAIT_PLANT_ICON,"mushroom3") /datum/seed/mushroom/poison name = "amanita" seed_name = "fly amanita" display_name = "fly amanita mushrooms" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita) mutants = list("destroyingangel","plastic") - packet_icon = "mycelium-amanita" - plant_icon = "amanita" chems = list("nutriment" = list(1), "amatoxin" = list(3,3), "psilocybin" = list(1,25)) - lifespan = 50 - maturation = 10 - production = 5 - yield = 4 - potency = 10 +/datum/seed/mushroom/poison/New() + ..() + set_trait(TRAIT_MATURATION,10) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"mushroom") + set_trait(TRAIT_PRODUCT_COLOUR,"#FF4545") + set_trait(TRAIT_PLANT_COLOUR,"#E0DDBA") + set_trait(TRAIT_PLANT_ICON,"mushroom4") /datum/seed/mushroom/poison/death name = "destroyingangel" seed_name = "destroying angel" display_name = "destroying angel mushrooms" mutants = null - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/angel) - packet_icon = "mycelium-angel" - plant_icon = "angel" chems = list("nutriment" = list(1,50), "amatoxin" = list(13,3), "psilocybin" = list(1,25)) - maturation = 12 - yield = 2 - potency = 35 +/datum/seed/mushroom/poison/death/New() + ..() + set_trait(TRAIT_MATURATION,12) + set_trait(TRAIT_YIELD,2) + set_trait(TRAIT_POTENCY,35) + set_trait(TRAIT_PRODUCT_ICON,"mushroom3") + set_trait(TRAIT_PRODUCT_COLOUR,"#EDE8EA") + set_trait(TRAIT_PLANT_COLOUR,"#E6D8DD") + set_trait(TRAIT_PLANT_ICON,"mushroom5") /datum/seed/mushroom/towercap name = "towercap" seed_name = "tower cap" display_name = "tower caps" + chems = list("woodpulp" = list(10,1)) mutants = null - products = list(/obj/item/weapon/grown/log) - packet_icon = "mycelium-tower" - plant_icon = "towercap" - lifespan = 80 - maturation = 15 +/datum/seed/mushroom/towercap/New() + ..() + set_trait(TRAIT_MATURATION,15) + set_trait(TRAIT_PRODUCT_ICON,"mushroom7") + set_trait(TRAIT_PRODUCT_COLOUR,"#79A36D") + set_trait(TRAIT_PLANT_COLOUR,"#857F41") + set_trait(TRAIT_PLANT_ICON,"mushroom8") /datum/seed/mushroom/glowshroom name = "glowshroom" seed_name = "glowshroom" display_name = "glowshrooms" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom) mutants = null - packet_icon = "mycelium-glowshroom" - plant_icon = "glowshroom" chems = list("radium" = list(1,20)) - lifespan = 120 - maturation = 15 - yield = 3 - potency = 30 - growth_stages = 4 - biolum = 1 - biolum_colour = "#006622" - -/datum/seed/mushroom/walking - name = "walkingmushroom" - seed_name = "walking mushroom" - display_name = "walking mushrooms" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/walkingmushroom) - mutants = null - packet_icon = "mycelium-walkingmushroom" - plant_icon = "walkingmushroom" - chems = list("nutriment" = list(2,10)) - - lifespan = 30 - maturation = 5 - yield = 1 - potency = 0 - growth_stages = 3 +/datum/seed/mushroom/glowshroom/New() + ..() + set_trait(TRAIT_SPREAD,1) + set_trait(TRAIT_MATURATION,15) + set_trait(TRAIT_YIELD,3) + set_trait(TRAIT_POTENCY,30) + set_trait(TRAIT_BIOLUM,1) + set_trait(TRAIT_BIOLUM_COLOUR,"#006622") + set_trait(TRAIT_PRODUCT_ICON,"mushroom2") + set_trait(TRAIT_PRODUCT_COLOUR,"#DDFAB6") + set_trait(TRAIT_PLANT_COLOUR,"#EFFF8A") + set_trait(TRAIT_PLANT_ICON,"mushroom7") /datum/seed/mushroom/plastic name = "plastic" seed_name = "plastellium" display_name = "plastellium" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/plastellium) mutants = null - packet_icon = "mycelium-plast" - plant_icon = "plastellium" chems = list("plasticide" = list(1,10)) - lifespan = 15 - maturation = 5 - production = 6 - yield = 6 - potency = 20 +/datum/seed/mushroom/plastic/New() + ..() + set_trait(TRAIT_MATURATION,5) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,6) + set_trait(TRAIT_POTENCY,20) + set_trait(TRAIT_PRODUCT_ICON,"mushroom6") + set_trait(TRAIT_PRODUCT_COLOUR,"#E6E6E6") + set_trait(TRAIT_PLANT_COLOUR,"#E6E6E6") + set_trait(TRAIT_PLANT_ICON,"mushroom10") //Flowers/varieties /datum/seed/flower name = "harebells" seed_name = "harebell" display_name = "harebells" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/harebell) - packet_icon = "seed-harebell" - plant_icon = "harebell" chems = list("nutriment" = list(1,20)) - lifespan = 100 - maturation = 7 - production = 1 - yield = 2 - growth_stages = 4 +/datum/seed/flower/New() + ..() + set_trait(TRAIT_MATURATION,7) + set_trait(TRAIT_PRODUCTION,1) + set_trait(TRAIT_YIELD,2) + set_trait(TRAIT_PRODUCT_ICON,"flower5") + set_trait(TRAIT_PRODUCT_COLOUR,"#C492D6") + set_trait(TRAIT_PLANT_COLOUR,"#6B8C5E") + set_trait(TRAIT_PLANT_ICON,"flower") /datum/seed/flower/poppy name = "poppies" seed_name = "poppy" display_name = "poppies" - packet_icon = "seed-poppy" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/poppy) - plant_icon = "poppy" chems = list("nutriment" = list(1,20), "bicaridine" = list(1,10)) + kitchen_tag = "poppy" - lifespan = 25 - potency = 20 - maturation = 8 - production = 6 - yield = 6 - growth_stages = 3 +/datum/seed/flower/poppy/New() + ..() + set_trait(TRAIT_POTENCY,20) + set_trait(TRAIT_MATURATION,8) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,6) + set_trait(TRAIT_PRODUCT_ICON,"flower3") + set_trait(TRAIT_PRODUCT_COLOUR,"#B33715") + set_trait(TRAIT_PLANT_ICON,"flower3") /datum/seed/flower/sunflower name = "sunflowers" seed_name = "sunflower" display_name = "sunflowers" - packet_icon = "seed-sunflower" - products = list(/obj/item/weapon/grown/sunflower) - plant_icon = "sunflower" - lifespan = 25 - maturation = 6 - growth_stages = 3 +/datum/seed/flower/sunflower/New() + ..() + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCT_ICON,"flower2") + set_trait(TRAIT_PRODUCT_COLOUR,"#FFF700") + set_trait(TRAIT_PLANT_ICON,"flower2") //Grapes/varieties /datum/seed/grapes name = "grapes" seed_name = "grape" display_name = "grapevines" - packet_icon = "seed-grapes" mutants = list("greengrapes") - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/grapes) - plant_icon = "grape" - harvest_repeat = 1 - chems = list("nutriment" = list(1,10), "sugar" = list(1,5)) + chems = list("nutriment" = list(1,10), "sugar" = list(1,5), "grapejuice" = list(1,10)) - lifespan = 50 - maturation = 3 - production = 5 - yield = 4 - potency = 10 +/datum/seed/grapes/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,3) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"grapes") + set_trait(TRAIT_PRODUCT_COLOUR,"#BB6AC4") + set_trait(TRAIT_PLANT_COLOUR,"#378F2E") + set_trait(TRAIT_PLANT_ICON,"vine") /datum/seed/grapes/green name = "greengrapes" seed_name = "green grape" display_name = "green grapevines" - packet_icon = "seed-greengrapes" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/greengrapes) mutants = null - plant_icon = "greengrape" - chems = list("nutriment" = list(1,10), "kelotane" = list(3,5)) + chems = list("nutriment" = list(1,10), "kelotane" = list(3,5), "grapejuice" = list(1,10)) + +/datum/seed/grapes/green/New() + ..() + set_trait(TRAIT_PRODUCT_COLOUR,"42ed2f") //Everything else /datum/seed/peanuts name = "peanut" seed_name = "peanut" display_name = "peanut vines" - packet_icon = "seed-peanut" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/peanut) - plant_icon = "peanut" - harvest_repeat = 1 chems = list("nutriment" = list(1,10)) - lifespan = 55 - maturation = 6 - production = 6 - yield = 6 - potency = 10 +/datum/seed/peanuts/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,6) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"potato") + set_trait(TRAIT_PRODUCT_COLOUR,"#C4AE7A") + set_trait(TRAIT_PLANT_ICON,"bush2") /datum/seed/cabbage name = "cabbage" seed_name = "cabbage" display_name = "cabbages" - packet_icon = "seed-cabbage" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage) - plant_icon = "cabbage" - harvest_repeat = 1 chems = list("nutriment" = list(1,10)) + kitchen_tag = "cabbage" - lifespan = 50 - maturation = 3 - production = 5 - yield = 4 - potency = 10 - growth_stages = 1 - -/datum/seed/shand - name = "shand" - seed_name = "S'randar's hand" - display_name = "S'randar's hand leaves" - packet_icon = "seed-shand" - products = list(/obj/item/stack/medical/bruise_pack/tajaran) - plant_icon = "shand" - chems = list("bicaridine" = list(0,10)) - - lifespan = 50 - maturation = 3 - production = 5 - yield = 4 - potency = 10 - growth_stages = 3 - -/datum/seed/mtear - name = "mtear" - seed_name = "Messa's tear" - display_name = "Messa's tear leaves" - packet_icon = "seed-mtear" - products = list(/obj/item/stack/medical/ointment/tajaran) - plant_icon = "mtear" - chems = list("honey" = list(1,10), "kelotane" = list(3,5)) - - lifespan = 50 - maturation = 3 - production = 5 - yield = 4 - potency = 10 - growth_stages = 3 +/datum/seed/cabbage/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,3) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"cabbage") + set_trait(TRAIT_PRODUCT_COLOUR,"#84BD82") + set_trait(TRAIT_PLANT_COLOUR,"#6D9C6B") + set_trait(TRAIT_PLANT_ICON,"vine2") /datum/seed/banana name = "banana" seed_name = "banana" display_name = "banana tree" - packet_icon = "seed-banana" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/banana) - plant_icon = "banana" - harvest_repeat = 1 chems = list("banana" = list(1,10)) + trash_type = /obj/item/weapon/bananapeel + kitchen_tag = "banana" - lifespan = 50 - maturation = 6 - production = 6 - yield = 3 +/datum/seed/banana/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,3) + set_trait(TRAIT_PRODUCT_ICON,"bananas") + set_trait(TRAIT_PRODUCT_COLOUR,"#FFEC1F") + set_trait(TRAIT_PLANT_COLOUR,"#69AD50") + set_trait(TRAIT_PLANT_ICON,"tree4") /datum/seed/corn name = "corn" seed_name = "corn" display_name = "ears of corn" - packet_icon = "seed-corn" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/corn) - plant_icon = "corn" - chems = list("nutriment" = list(1,10)) + chems = list("nutriment" = list(1,10), "cornoil" = list(1,10)) + kitchen_tag = "corn" + trash_type = /obj/item/weapon/corncob - lifespan = 25 - maturation = 8 - production = 6 - yield = 3 - potency = 20 - growth_stages = 3 +/datum/seed/corn/New() + ..() + set_trait(TRAIT_MATURATION,8) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,3) + set_trait(TRAIT_POTENCY,20) + set_trait(TRAIT_PRODUCT_ICON,"corn") + set_trait(TRAIT_PRODUCT_COLOUR,"#FFF23B") + set_trait(TRAIT_PLANT_COLOUR,"#87C969") + set_trait(TRAIT_PLANT_ICON,"corn") /datum/seed/potato name = "potato" seed_name = "potato" display_name = "potatoes" - packet_icon = "seed-potato" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/potato) - plant_icon = "potato" - chems = list("nutriment" = list(1,10)) + chems = list("nutriment" = list(1,10), "potato" = list(1,10)) + kitchen_tag = "potato" - lifespan = 30 - maturation = 10 - production = 1 - yield = 4 - potency = 10 - growth_stages = 4 +/datum/seed/potato/New() + ..() + set_trait(TRAIT_PRODUCES_POWER,1) + set_trait(TRAIT_MATURATION,10) + set_trait(TRAIT_PRODUCTION,1) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"potato") + set_trait(TRAIT_PRODUCT_COLOUR,"#D4CAB4") + set_trait(TRAIT_PLANT_ICON,"bush2") /datum/seed/soybean name = "soybean" seed_name = "soybean" display_name = "soybeans" - packet_icon = "seed-soybean" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans) - plant_icon = "soybean" - harvest_repeat = 1 - chems = list("nutriment" = list(1,20)) + chems = list("nutriment" = list(1,20), "soymilk" = list(1,20)) + kitchen_tag = "soybeans" - lifespan = 25 - maturation = 4 - production = 4 - yield = 3 - potency = 5 +/datum/seed/soybean/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,4) + set_trait(TRAIT_PRODUCTION,4) + set_trait(TRAIT_YIELD,3) + set_trait(TRAIT_POTENCY,5) + set_trait(TRAIT_PRODUCT_ICON,"bean") + set_trait(TRAIT_PRODUCT_COLOUR,"#EBE7C0") + set_trait(TRAIT_PLANT_ICON,"stalk") /datum/seed/wheat name = "wheat" seed_name = "wheat" display_name = "wheat stalks" - packet_icon = "seed-wheat" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/wheat) - plant_icon = "wheat" - chems = list("nutriment" = list(1,25)) + chems = list("nutriment" = list(1,25), "flour" = list(15,15)) + kitchen_tag = "wheat" - lifespan = 25 - maturation = 6 - production = 1 - yield = 4 - potency = 5 +/datum/seed/wheat/New() + ..() + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,1) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,5) + set_trait(TRAIT_PRODUCT_ICON,"wheat") + set_trait(TRAIT_PRODUCT_COLOUR,"#DBD37D") + set_trait(TRAIT_PLANT_COLOUR,"#BFAF82") + set_trait(TRAIT_PLANT_ICON,"stalk2") /datum/seed/rice name = "rice" seed_name = "rice" display_name = "rice stalks" - packet_icon = "seed-rice" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/ricestalk) - plant_icon = "rice" - chems = list("nutriment" = list(1,25)) + chems = list("nutriment" = list(1,25), "rice" = list(10,15)) + kitchen_tag = "rice" - lifespan = 25 - maturation = 6 - production = 1 - yield = 4 - potency = 5 - growth_stages = 4 +/datum/seed/rice/New() + ..() + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,1) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,5) + set_trait(TRAIT_PRODUCT_ICON,"rice") + set_trait(TRAIT_PRODUCT_COLOUR,"#D5E6D1") + set_trait(TRAIT_PLANT_COLOUR,"#8ED17D") + set_trait(TRAIT_PLANT_ICON,"stalk2") /datum/seed/carrots name = "carrot" seed_name = "carrot" display_name = "carrots" - packet_icon = "seed-carrot" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/carrot) - plant_icon = "carrot" - chems = list("nutriment" = list(1,20), "imidazoline" = list(3,5)) + chems = list("nutriment" = list(1,20), "imidazoline" = list(3,5), "carrotjuice" = list(1,20)) + kitchen_tag = "carrot" - lifespan = 25 - maturation = 10 - production = 1 - yield = 5 - potency = 10 - growth_stages = 3 +/datum/seed/carrots/New() + ..() + set_trait(TRAIT_MATURATION,10) + set_trait(TRAIT_PRODUCTION,1) + set_trait(TRAIT_YIELD,5) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"carrot") + set_trait(TRAIT_PRODUCT_COLOUR,"#FFDB4A") + set_trait(TRAIT_PLANT_ICON,"carrot") /datum/seed/weeds name = "weeds" seed_name = "weed" display_name = "weeds" - packet_icon = "seed-ambrosiavulgaris" - plant_icon = "weeds" - lifespan = 100 - maturation = 5 - production = 1 - yield = -1 - potency = -1 - growth_stages = 4 - immutable = -1 +/datum/seed/weeds/New() + ..() + set_trait(TRAIT_MATURATION,5) + set_trait(TRAIT_PRODUCTION,1) + set_trait(TRAIT_YIELD,-1) + set_trait(TRAIT_POTENCY,-1) + set_trait(TRAIT_IMMUTABLE,-1) + set_trait(TRAIT_PRODUCT_ICON,"flower4") + set_trait(TRAIT_PRODUCT_COLOUR,"#FCEB2B") + set_trait(TRAIT_PLANT_COLOUR,"#59945A") + set_trait(TRAIT_PLANT_ICON,"bush6") /datum/seed/whitebeets name = "whitebeet" seed_name = "white-beet" display_name = "white-beets" - packet_icon = "seed-whitebeet" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/whitebeet) - plant_icon = "whitebeet" chems = list("nutriment" = list(0,20), "sugar" = list(1,5)) + kitchen_tag = "whitebeet" - lifespan = 60 - maturation = 6 - production = 6 - yield = 6 - potency = 10 +/datum/seed/whitebeets/New() + ..() + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,6) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"carrot2") + set_trait(TRAIT_PRODUCT_COLOUR,"#EEF5B0") + set_trait(TRAIT_PLANT_COLOUR,"#4D8F53") + set_trait(TRAIT_PLANT_ICON,"carrot2") /datum/seed/sugarcane name = "sugarcane" seed_name = "sugarcane" display_name = "sugarcanes" - packet_icon = "seed-sugarcane" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/sugarcane) - plant_icon = "sugarcane" - harvest_repeat = 1 chems = list("sugar" = list(4,5)) - lifespan = 60 - maturation = 3 - production = 6 - yield = 4 - potency = 10 - growth_stages = 3 +/datum/seed/sugarcane/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,3) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"stalk") + set_trait(TRAIT_PRODUCT_COLOUR,"#B4D6BD") + set_trait(TRAIT_PLANT_COLOUR,"#6BBD68") + set_trait(TRAIT_PLANT_ICON,"stalk3") /datum/seed/watermelon name = "watermelon" seed_name = "watermelon" display_name = "watermelon vine" - packet_icon = "seed-watermelon" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/watermelon) - plant_icon = "watermelon" - harvest_repeat = 1 - chems = list("nutriment" = list(1,6)) + chems = list("nutriment" = list(1,6), "watermelonjuice" = list(1,6)) - lifespan = 50 - maturation = 6 - production = 6 - yield = 3 - potency = 1 +/datum/seed/watermelon/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_JUICY,1) + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,3) + set_trait(TRAIT_POTENCY,1) + set_trait(TRAIT_PRODUCT_ICON,"vine") + set_trait(TRAIT_PRODUCT_COLOUR,"#326B30") + set_trait(TRAIT_PLANT_COLOUR,"#257522") + set_trait(TRAIT_PLANT_ICON,"vine2") /datum/seed/pumpkin name = "pumpkin" seed_name = "pumpkin" display_name = "pumpkin vine" - packet_icon = "seed-pumpkin" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin) - plant_icon = "pumpkin" - harvest_repeat = 1 chems = list("nutriment" = list(1,6)) + kitchen_tag = "pumpkin" - lifespan = 50 - maturation = 6 - production = 6 - yield = 3 - potency = 10 - growth_stages = 3 +/datum/seed/pumpkin/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,3) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"vine") + set_trait(TRAIT_PRODUCT_COLOUR,"#B4D4B9") + set_trait(TRAIT_PLANT_COLOUR,"#BAE8C1") + set_trait(TRAIT_PLANT_ICON,"vine2") -/datum/seed/lime +/datum/seed/citrus name = "lime" seed_name = "lime" display_name = "lime trees" - packet_icon = "seed-lime" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/lime) - plant_icon = "lime" - harvest_repeat = 1 - chems = list("nutriment" = list(1,20)) + chems = list("nutriment" = list(1,20), "limejuice" = list(1,20)) + kitchen_tag = "lime" - lifespan = 55 - maturation = 6 - production = 6 - yield = 4 - potency = 15 +/datum/seed/citrus/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_JUICY,1) + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,15) + set_trait(TRAIT_PRODUCT_ICON,"treefruit") + set_trait(TRAIT_PRODUCT_COLOUR,"#3AF026") + set_trait(TRAIT_PLANT_ICON,"tree") -/datum/seed/lemon +/datum/seed/citrus/lemon name = "lemon" seed_name = "lemon" display_name = "lemon trees" - packet_icon = "seed-lemon" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/lemon) - plant_icon = "lemon" - harvest_repeat = 1 - chems = list("nutriment" = list(1,20)) + chems = list("nutriment" = list(1,20), "lemonjuice" = list(1,20)) + kitchen_tag = "lemon" - lifespan = 55 - maturation = 6 - production = 6 - yield = 4 - potency = 10 +/datum/seed/citrus/lemon/New() + ..() + set_trait(TRAIT_PRODUCES_POWER,1) + set_trait(TRAIT_PRODUCT_COLOUR,"#F0E226") -/datum/seed/orange +/datum/seed/citrus/orange name = "orange" seed_name = "orange" display_name = "orange trees" - packet_icon = "seed-orange" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/orange) - plant_icon = "orange" - harvest_repeat = 1 - chems = list("nutriment" = list(1,20)) + kitchen_tag = "orange" + chems = list("nutriment" = list(1,20), "orangejuice" = list(1,20)) - lifespan = 60 - maturation = 6 - production = 6 - yield = 5 - potency = 1 +/datum/seed/citrus/orange/New() + ..() + set_trait(TRAIT_PRODUCT_COLOUR,"#FFC20A") /datum/seed/grass name = "grass" seed_name = "grass" display_name = "grass" - packet_icon = "seed-grass" - products = list(/obj/item/stack/tile/grass) - plant_icon = "grass" - harvest_repeat = 1 + chems = list("nutriment" = list(1,20)) + kitchen_tag = "grass" - lifespan = 60 - maturation = 2 - production = 5 - yield = 5 - growth_stages = 2 +/datum/seed/grass/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,2) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,5) + set_trait(TRAIT_PRODUCT_ICON,"grass") + set_trait(TRAIT_PRODUCT_COLOUR,"#09FF00") + set_trait(TRAIT_PLANT_COLOUR,"#07D900") + set_trait(TRAIT_PLANT_ICON,"grass") /datum/seed/cocoa name = "cocoa" seed_name = "cacao" display_name = "cacao tree" - packet_icon = "seed-cocoapod" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod) - plant_icon = "cocoapod" - harvest_repeat = 1 chems = list("nutriment" = list(1,10), "coco" = list(4,5)) - lifespan = 20 - maturation = 5 - production = 5 - yield = 2 - potency = 10 - growth_stages = 5 +/datum/seed/cocoa/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_MATURATION,5) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,2) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"treefruit") + set_trait(TRAIT_PRODUCT_COLOUR,"#CCA935") + set_trait(TRAIT_PLANT_ICON,"tree2") /datum/seed/cherries name = "cherry" seed_name = "cherry" seed_noun = "pits" display_name = "cherry tree" - packet_icon = "seed-cherry" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/cherries) - plant_icon = "cherry" - harvest_repeat = 1 - chems = list("nutriment" = list(1,15), "sugar" = list(1,15)) + chems = list("nutriment" = list(1,15), "sugar" = list(1,15), "cherryjelly" = list(1,15)) + kitchen_tag = "cherries" - lifespan = 35 - maturation = 5 - production = 5 - yield = 3 - potency = 10 - growth_stages = 5 +/datum/seed/cherries/New() + ..() + set_trait(TRAIT_HARVEST_REPEAT,1) + set_trait(TRAIT_JUICY,1) + set_trait(TRAIT_MATURATION,5) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,3) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"cherry") + set_trait(TRAIT_PRODUCT_COLOUR,"#A80000") + set_trait(TRAIT_PLANT_ICON,"tree2") + set_trait(TRAIT_PLANT_COLOUR,"#2F7D2D") /datum/seed/kudzu name = "kudzu" seed_name = "kudzu" display_name = "kudzu vines" - packet_icon = "seed-kudzu" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/kudzupod) - plant_icon = "kudzu" - product_colour = "#96D278" chems = list("nutriment" = list(1,50), "anti_toxin" = list(1,25)) - lifespan = 20 - maturation = 6 - production = 6 - yield = 4 - potency = 10 - growth_stages = 4 - spread = 2 +/datum/seed/kudzu/New() + ..() + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_SPREAD,2) + set_trait(TRAIT_PRODUCT_ICON,"treefruit") + set_trait(TRAIT_PRODUCT_COLOUR,"#96D278") + set_trait(TRAIT_PLANT_COLOUR,"#6F7A63") + set_trait(TRAIT_PLANT_ICON,"vine2") /datum/seed/diona name = "diona" seed_name = "diona" seed_noun = "nodes" display_name = "replicant pods" - packet_icon = "seed-replicapod" - products = list(/mob/living/carbon/alien/diona) - plant_icon = "replicapod" - product_requires_player = 1 - immutable = 1 + can_self_harvest = 1 + has_mob_product = /mob/living/carbon/alien/diona - lifespan = 50 - endurance = 8 - maturation = 5 - production = 10 - yield = 1 - potency = 30 +/datum/seed/diona/New() + ..() + set_trait(TRAIT_IMMUTABLE,1) + set_trait(TRAIT_ENDURANCE,8) + set_trait(TRAIT_MATURATION,5) + set_trait(TRAIT_PRODUCTION,10) + set_trait(TRAIT_YIELD,1) + set_trait(TRAIT_POTENCY,30) + set_trait(TRAIT_PRODUCT_ICON,"diona") + set_trait(TRAIT_PRODUCT_COLOUR,"#799957") + set_trait(TRAIT_PLANT_COLOUR,"#66804B") + set_trait(TRAIT_PLANT_ICON,"alien4") -/datum/seed/clown - name = "clown" - seed_name = "clown" - seed_noun = "pods" - display_name = "laughing clowns" - packet_icon = "seed-replicapod" - products = list(/mob/living/simple_animal/hostile/retaliate/clown) - plant_icon = "replicapod" - product_requires_player = 1 +/datum/seed/shand + name = "shand" + seed_name = "S'randar's hand" + display_name = "S'randar's hand leaves" + chems = list("bicaridine" = list(0,10)) + kitchen_tag = "shand" - lifespan = 100 - endurance = 8 - maturation = 1 - production = 1 - yield = 10 - potency = 30 +/datum/seed/shand/New() + ..() + set_trait(TRAIT_MATURATION,3) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"alien3") + set_trait(TRAIT_PRODUCT_COLOUR,"#378C61") + set_trait(TRAIT_PLANT_COLOUR,"#378C61") + set_trait(TRAIT_PLANT_ICON,"tree5") -/datum/seed/test - name = "test" - seed_name = "testing" - seed_noun = "data" - display_name = "runtimes" - packet_icon = "seed-replicapod" - products = list(/mob/living/simple_animal/cat/Runtime) - plant_icon = "replicapod" +/datum/seed/mtear + name = "mtear" + seed_name = "Messa's tear" + display_name = "Messa's tear leaves" + chems = list("honey" = list(1,10), "kelotane" = list(3,5)) + kitchen_tag = "mtear" - requires_nutrients = 0 - nutrient_consumption = 0 - requires_water = 0 - water_consumption = 0 - pest_tolerance = 11 - weed_tolerance = 11 - lifespan = 1000 - endurance = 100 - maturation = 1 - production = 1 - yield = 1 - potency = 1 \ No newline at end of file +/datum/seed/mtear/New() + ..() + set_trait(TRAIT_MATURATION,3) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,10) + set_trait(TRAIT_PRODUCT_ICON,"alien4") + set_trait(TRAIT_PRODUCT_COLOUR,"#4CC5C7") + set_trait(TRAIT_PLANT_COLOUR,"#4CC789") + set_trait(TRAIT_PLANT_ICON,"bush7") + +/datum/seed/telriis + name = "telriis" + seed_name = "telriis" + display_name = "telriis grass" + chems = list("pwine" = list(1,5), "nutriment" = list(1,6)) + +/datum/seed/telriis/New() + ..() + set_trait(TRAIT_PLANT_ICON,"telriis") + set_trait(TRAIT_ENDURANCE,50) + set_trait(TRAIT_MATURATION,5) + set_trait(TRAIT_PRODUCTION,5) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,5) + +/datum/seed/thaadra + name = "thaadra" + seed_name = "thaa'dra" + display_name = "thaa'dra lichen" + chems = list("frostoil" = list(1,5),"nutriment" = list(1,5)) + +/datum/seed/thaadra/New() + ..() + set_trait(TRAIT_PLANT_ICON,"thaadra") + set_trait(TRAIT_ENDURANCE,10) + set_trait(TRAIT_MATURATION,5) + set_trait(TRAIT_PRODUCTION,9) + set_trait(TRAIT_YIELD,2) + set_trait(TRAIT_POTENCY,5) + +/datum/seed/jurlmah + name = "jurlmah" + seed_name = "jurl'mah" + display_name = "jurl'mah reeds" + chems = list("serotrotium" = list(1,5),"nutriment" = list(1,5)) + +/datum/seed/jurlmah/New() + ..() + set_trait(TRAIT_PLANT_ICON,"jurlmah") + set_trait(TRAIT_ENDURANCE,12) + set_trait(TRAIT_MATURATION,8) + set_trait(TRAIT_PRODUCTION,9) + set_trait(TRAIT_YIELD,3) + set_trait(TRAIT_POTENCY,10) + +/datum/seed/amauri + name = "amauri" + seed_name = "amauri" + display_name = "amauri plant" + chems = list("zombiepowder" = list(1,10),"condensedcapsaicin" = list(1,5),"nutriment" = list(1,5)) + +/datum/seed/amauri/New() + ..() + set_trait(TRAIT_PLANT_ICON,"amauri") + set_trait(TRAIT_ENDURANCE,10) + set_trait(TRAIT_MATURATION,8) + set_trait(TRAIT_PRODUCTION,9) + set_trait(TRAIT_YIELD,4) + set_trait(TRAIT_POTENCY,10) + +/datum/seed/gelthi + name = "gelthi" + seed_name = "gelthi" + display_name = "gelthi plant" + chems = list("stoxin" = list(1,5),"capsaicin" = list(1,5),"nutriment" = list(1,5)) + +/datum/seed/gelthi/New() + ..() + set_trait(TRAIT_PLANT_ICON,"gelthi") + set_trait(TRAIT_ENDURANCE,15) + set_trait(TRAIT_MATURATION,6) + set_trait(TRAIT_PRODUCTION,6) + set_trait(TRAIT_YIELD,2) + set_trait(TRAIT_POTENCY,1) + +/datum/seed/vale + name = "vale" + seed_name = "vale" + display_name = "vale bush" + chems = list("paracetamol" = list(1,5),"dexalin" = list(1,2),"nutriment"= list(1,5)) + +/datum/seed/vale/New() + ..() + set_trait(TRAIT_PLANT_ICON,"vale") + set_trait(TRAIT_ENDURANCE,15) + set_trait(TRAIT_MATURATION,8) + set_trait(TRAIT_PRODUCTION,10) + set_trait(TRAIT_YIELD,3) + set_trait(TRAIT_POTENCY,3) + +/datum/seed/surik + name = "surik" + seed_name = "surik" + display_name = "surik vine" + chems = list("impedrezene" = list(1,3),"synaptizine" = list(1,2),"nutriment" = list(1,5)) + +/datum/seed/surik/New() + ..() + set_trait(TRAIT_PLANT_ICON,"surik") + set_trait(TRAIT_ENDURANCE,18) + set_trait(TRAIT_MATURATION,7) + set_trait(TRAIT_PRODUCTION,7) + set_trait(TRAIT_YIELD,3) + set_trait(TRAIT_POTENCY,3) diff --git a/code/modules/hydroponics/seed_machines.dm b/code/modules/hydroponics/seed_machines.dm index 1b5034f417..1160235c9e 100644 --- a/code/modules/hydroponics/seed_machines.dm +++ b/code/modules/hydroponics/seed_machines.dm @@ -1,7 +1,7 @@ /obj/item/weapon/disk/botany name = "flora data disk" desc = "A small disk used for carrying data on plant genetics." - icon = 'icons/obj/hydroponics.dmi' + icon = 'icons/obj/hydroponics_machines.dmi' icon_state = "disk" w_class = 1.0 @@ -16,7 +16,7 @@ /obj/item/weapon/disk/botany/attack_self(var/mob/user as mob) if(genes.len) var/choice = alert(user, "Are you sure you want to wipe the disk?", "Xenobotany Data", "No", "Yes") - if(src && user && genes && choice == "Yes") + if(src && user && genes && choice && choice == "Yes" && user.Adjacent(get_turf(src))) user << "You wipe the disk data." name = initial(name) desc = initial(name) @@ -33,7 +33,7 @@ new /obj/item/weapon/disk/botany(src) /obj/machinery/botany - icon = 'icons/obj/hydroponics.dmi' + icon = 'icons/obj/hydroponics_machines.dmi' icon_state = "hydrotray3" density = 1 anchored = 1 @@ -44,7 +44,7 @@ var/open = 0 var/active = 0 - var/action_time = 50 + var/action_time = 5 var/last_action = 0 var/eject_disk = 0 var/failed_task = 0 @@ -85,7 +85,7 @@ user << "There is already a seed loaded." return var/obj/item/seeds/S =W - if(S.seed && S.seed.immutable > 0) + if(S.seed && S.seed.get_trait(TRAIT_IMMUTABLE) > 0) user << "That seed is not compatible with our genetics technology." else user.remove_from_mob(W) @@ -96,7 +96,7 @@ if(istype(W,/obj/item/weapon/screwdriver)) open = !open - user << "\blue You [open ? "open" : "close"] the maintenance panel." + user << "You [open ? "open" : "close"] the maintenance panel." return if(open) @@ -144,8 +144,8 @@ var/list/data = list() var/list/geneMasks[0] - for(var/gene_tag in gene_tag_masks) - geneMasks.Add(list(list("tag" = gene_tag, "mask" = gene_tag_masks[gene_tag]))) + for(var/gene_tag in plant_controller.gene_tag_masks) + geneMasks.Add(list(list("tag" = gene_tag, "mask" = plant_controller.gene_tag_masks[gene_tag]))) data["geneMasks"] = geneMasks data["activity"] = active @@ -186,10 +186,10 @@ if(!seed) return seed.loc = get_turf(src) - if(seed.seed.name == "new line" || isnull(seed_types[seed.seed.name])) - seed.seed.uid = seed_types.len + 1 + if(seed.seed.name == "new line" || isnull(plant_controller.seeds[seed.seed.name])) + seed.seed.uid = plant_controller.seeds.len + 1 seed.seed.name = "[seed.seed.uid]" - seed_types[seed.seed.name] = seed.seed + plant_controller.seeds[seed.seed.name] = seed.seed seed.update_seed() visible_message("\icon[src] [src] beeps and spits out [seed].") @@ -242,8 +242,8 @@ if(!genetics.roundstart) loaded_disk.genesource += " (variety #[genetics.uid])" - loaded_disk.name += " ([gene_tag_masks[href_list["get_gene"]]], #[genetics.uid])" - loaded_disk.desc += " The label reads \'gene [gene_tag_masks[href_list["get_gene"]]], sampled from [genetics.display_name]\'." + loaded_disk.name += " ([plant_controller.gene_tag_masks[href_list["get_gene"]]], #[genetics.uid])" + loaded_disk.desc += " The label reads \'gene [plant_controller.gene_tag_masks[href_list["get_gene"]]], sampled from [genetics.display_name]\'." eject_disk = 1 degradation += rand(20,60) @@ -288,7 +288,7 @@ for(var/datum/plantgene/P in loaded_disk.genes) if(data["locus"] != "") data["locus"] += ", " - data["locus"] += "[gene_tag_masks[P.genetype]]" + data["locus"] += "[plant_controller.gene_tag_masks[P.genetype]]" else data["disk"] = 0 @@ -318,7 +318,7 @@ last_action = world.time active = 1 - if(!isnull(seed_types[seed.seed.name])) + if(!isnull(plant_controller.seeds[seed.seed.name])) seed.seed = seed.seed.diverge(1) seed.seed_type = seed.seed.name seed.update_seed() diff --git a/code/modules/hydroponics/seed_mobs.dm b/code/modules/hydroponics/seed_mobs.dm index 9fe3702eac..d31f184380 100644 --- a/code/modules/hydroponics/seed_mobs.dm +++ b/code/modules/hydroponics/seed_mobs.dm @@ -1,5 +1,4 @@ /datum/seed - var/product_requires_player // If yes, product will ask for a player among the ghosts. var/list/currently_querying // Used to avoid asking the same ghost repeatedly. // The following procs are used to grab players for mobs produced by a seed (mostly for dionaea). @@ -7,20 +6,21 @@ if(!host || !istype(host)) return - if(product_requires_player) - spawn(0) - request_player(host) - spawn(75) - if(!host.ckey && !host.client) - host.death() // This seems redundant, but a lot of mobs don't - host.stat = 2 // handle death() properly. Better safe than etc. - host.visible_message("\red [host] is malformed and unable to survive. It expires pitifully, leaving behind some seeds.") + spawn(0) + request_player(host) + if(istype(host,/mob/living/simple_animal)) + return + spawn(75) + if(!host.ckey && !host.client) + host.death() // This seems redundant, but a lot of mobs don't + host.stat = 2 // handle death() properly. Better safe than etc. + host.visible_message("[host] is malformed and unable to survive. It expires pitifully, leaving behind some seeds.") - var/total_yield = rand(1,3) - for(var/j = 0;j<=total_yield;j++) - var/obj/item/seeds/S = new(get_turf(host)) - S.seed_type = name - S.update_seed() + var/total_yield = rand(1,3) + for(var/j = 0;j<=total_yield;j++) + var/obj/item/seeds/S = new(get_turf(host)) + S.seed_type = name + S.update_seed() /datum/seed/proc/request_player(var/mob/living/host) if(!host) return diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seed_packets.dm similarity index 66% rename from code/modules/hydroponics/seeds.dm rename to code/modules/hydroponics/seed_packets.dm index 6f1b732849..093c4d7926 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seed_packets.dm @@ -1,8 +1,10 @@ +var/global/list/plant_seed_sprites = list() + //Seed packet object/procs. /obj/item/seeds name = "packet of seeds" icon = 'icons/obj/seeds.dmi' - icon_state = "seed" + icon_state = "blank" w_class = 2.0 var/seed_type @@ -10,21 +12,52 @@ var/modified = 0 /obj/item/seeds/New() + while(!plant_controller) + sleep(30) update_seed() ..() //Grabs the appropriate seed datum from the global list. /obj/item/seeds/proc/update_seed() - if(!seed && seed_type && !isnull(seed_types) && seed_types[seed_type]) - seed = seed_types[seed_type] + if(!seed && seed_type && !isnull(plant_controller.seeds) && plant_controller.seeds[seed_type]) + seed = plant_controller.seeds[seed_type] update_appearance() //Updates strings and icon appropriately based on seed datum. /obj/item/seeds/proc/update_appearance() if(!seed) return - icon_state = seed.packet_icon - src.name = "packet of [seed.seed_name] [seed.seed_noun]" - src.desc = "It has a picture of [seed.display_name] on the front." + + // Update icon. + overlays.Cut() + var/is_seeds = ((seed.seed_noun in list("seeds","pits","nodes")) ? 1 : 0) + var/image/seed_mask + var/seed_base_key = "base-[is_seeds ? seed.get_trait(TRAIT_PLANT_COLOUR) : "spores"]" + if(plant_seed_sprites[seed_base_key]) + seed_mask = plant_seed_sprites[seed_base_key] + else + seed_mask = image('icons/obj/seeds.dmi',"[is_seeds ? "seed" : "spore"]-mask") + if(is_seeds) // Spore glass bits aren't coloured. + seed_mask.color = seed.get_trait(TRAIT_PLANT_COLOUR) + plant_seed_sprites[seed_base_key] = seed_mask + + var/image/seed_overlay + var/seed_overlay_key = "[seed.get_trait(TRAIT_PRODUCT_ICON)]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]" + if(plant_seed_sprites[seed_overlay_key]) + seed_overlay = plant_seed_sprites[seed_overlay_key] + else + seed_overlay = image('icons/obj/seeds.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]") + seed_overlay.color = seed.get_trait(TRAIT_PRODUCT_COLOUR) + plant_seed_sprites[seed_overlay_key] = seed_overlay + + overlays |= seed_mask + overlays |= seed_overlay + + if(is_seeds) + src.name = "packet of [seed.seed_name] [seed.seed_noun]" + src.desc = "It has a picture of [seed.display_name] on the front." + else + src.name = "sample of [seed.seed_name] [seed.seed_noun]" + src.desc = "It's labelled as coming from [seed.display_name]." /obj/item/seeds/examine(mob/user) ..(user) @@ -43,13 +76,8 @@ seed_type = null /obj/item/seeds/random/New() - seed = new() - seed.randomize() - - seed.uid = seed_types.len + 1 - seed.name = "[seed.uid]" - seed_types[seed.name] = seed - + seed = plant_controller.create_random_seed() + seed_type = seed.name update_seed() /obj/item/seeds/replicapod @@ -91,9 +119,6 @@ /obj/item/seeds/eggplantseed seed_type = "eggplant" -/obj/item/seeds/eggyseed - seed_type = "realeggplant" - /obj/item/seeds/bloodtomatoseed seed_type = "bloodtomato" @@ -229,5 +254,29 @@ /obj/item/seeds/cherryseed seed_type = "cherry" +/obj/item/seeds/tobaccoseed + seed_type = "tobacco" + /obj/item/seeds/kudzuseed - seed_type = "kudzu" \ No newline at end of file + seed_type = "kudzu" + +/obj/item/seeds/jurlmah + seed_type = "jurlmah" + +/obj/item/seeds/amauri + seed_type = "amauri" + +/obj/item/seeds/gelthi + seed_type = "gelthi" + +/obj/item/seeds/vale + seed_type = "vale" + +/obj/item/seeds/surik + seed_type = "surik" + +/obj/item/seeds/telriis + seed_type = "telriis" + +/obj/item/seeds/thaadra + seed_type = "thaadra" diff --git a/code/modules/hydroponics/seed_storage.dm b/code/modules/hydroponics/seed_storage.dm new file mode 100644 index 0000000000..469896018e --- /dev/null +++ b/code/modules/hydroponics/seed_storage.dm @@ -0,0 +1,242 @@ +/datum/seed_pile + var/name + var/amount + var/datum/seed/seed_type // Keeps track of what our seed is + var/list/obj/item/seeds/seeds = list() // Tracks actual objects contained in the pile + var/ID + +/datum/seed_pile/New(var/obj/item/seeds/O, var/ID) + name = O.name + amount = 1 + seed_type = O.seed + seeds += O + src.ID = ID + +/datum/seed_pile/proc/matches(var/obj/item/seeds/O) + if (O.seed == seed_type) + return 1 + return 0 + +/obj/machinery/seed_storage + name = "Seed storage" + desc = "It stores, sorts, and dispenses seeds." + icon = 'icons/obj/vending.dmi' + icon_state = "seeds" + density = 1 + anchored = 1 + use_power = 1 + idle_power_usage = 100 + + var/initialized = 0 // Map-placed ones break if seeds are loaded right at the start of the round, so we do it on the first interaction + var/list/datum/seed_pile/piles = list() + var/list/starting_seeds = list() + var/list/scanner = list() // What properties we can view + +/obj/machinery/seed_storage/random // This is mostly for testing, but I guess admins could spawn it + name = "Random seed storage" + scanner = list("stats", "produce", "soil", "temperature", "light") + starting_seeds = list(/obj/item/seeds/random = 50) + +/obj/machinery/seed_storage/garden + name = "Garden seed storage" + scanner = list("stats") + starting_seeds = list(/obj/item/seeds/appleseed = 3, /obj/item/seeds/bananaseed = 3, /obj/item/seeds/berryseed = 3, /obj/item/seeds/cabbageseed = 3, /obj/item/seeds/carrotseed = 3, /obj/item/seeds/chantermycelium = 3, /obj/item/seeds/cherryseed = 3, /obj/item/seeds/chiliseed = 3, /obj/item/seeds/cocoapodseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/grapeseed = 3, /obj/item/seeds/grassseed = 3, /obj/item/seeds/replicapod = 3, /obj/item/seeds/lemonseed = 3, /obj/item/seeds/limeseed = 3, /obj/item/seeds/mtearseed = 2, /obj/item/seeds/orangeseed = 3, /obj/item/seeds/peanutseed = 3, /obj/item/seeds/plumpmycelium = 3, /obj/item/seeds/poppyseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/pumpkinseed = 3, /obj/item/seeds/riceseed = 3, /obj/item/seeds/soyaseed = 3, /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/shandseed = 2, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, /obj/item/seeds/watermelonseed = 3, /obj/item/seeds/wheatseed = 3, /obj/item/seeds/whitebeetseed = 3) + +/obj/machinery/seed_storage/xenobotany + name = "Xenobotany seed storage" + scanner = list("stats", "produce", "soil", "temperature", "light") + starting_seeds = list(/obj/item/seeds/ambrosiavulgarisseed = 3, /obj/item/seeds/appleseed = 3, /obj/item/seeds/amanitamycelium = 2, /obj/item/seeds/bananaseed = 3, /obj/item/seeds/berryseed = 3, /obj/item/seeds/cabbageseed = 3, /obj/item/seeds/carrotseed = 3, /obj/item/seeds/chantermycelium = 3, /obj/item/seeds/cherryseed = 3, /obj/item/seeds/chiliseed = 3, /obj/item/seeds/cocoapodseed = 3, /obj/item/seeds/cornseed = 3, /obj/item/seeds/replicapod = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/glowshroom = 2, /obj/item/seeds/grapeseed = 3, /obj/item/seeds/grassseed = 3, /obj/item/seeds/lemonseed = 3, /obj/item/seeds/libertymycelium = 2, /obj/item/seeds/limeseed = 3, /obj/item/seeds/mtearseed = 2, /obj/item/seeds/nettleseed = 2, /obj/item/seeds/orangeseed = 3, /obj/item/seeds/peanutseed = 3, /obj/item/seeds/plastiseed = 3, /obj/item/seeds/plumpmycelium = 3, /obj/item/seeds/poppyseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/pumpkinseed = 3, /obj/item/seeds/reishimycelium = 2, /obj/item/seeds/riceseed = 3, /obj/item/seeds/soyaseed = 3, /obj/item/seeds/sugarcaneseed = 3, /obj/item/seeds/sunflowerseed = 3, /obj/item/seeds/shandseed = 2, /obj/item/seeds/tobaccoseed = 3, /obj/item/seeds/tomatoseed = 3, /obj/item/seeds/towermycelium = 3, /obj/item/seeds/watermelonseed = 3, /obj/item/seeds/wheatseed = 3, /obj/item/seeds/whitebeetseed = 3) + +/obj/machinery/seed_storage/attack_hand(mob/user as mob) + user.set_machine(src) + interact(user) + +/obj/machinery/seed_storage/interact(mob/user as mob) + if (..()) + return + + if (!initialized) + for(var/typepath in starting_seeds) + var/amount = starting_seeds[typepath] + if(isnull(amount)) amount = 1 + + for (var/i = 1 to amount) + var/O = new typepath + add(O) + initialized = 1 + + var/dat = "

    Seed storage contents

    " + if (piles.len == 0) + dat += "No seeds" + else + dat += "" + dat += "" + if ("stats" in scanner) + dat += "" + if ("temperature" in scanner) + dat += "" + if ("light" in scanner) + dat += "" + if ("soil" in scanner) + dat += "" + dat += "" + for (var/datum/seed_pile/S in piles) + var/datum/seed/seed = S.seed_type + if(!seed) + continue + dat += "" + dat += "" + dat += "" + if ("stats" in scanner) + dat += "" + if(seed.get_trait(TRAIT_HARVEST_REPEAT)) + dat += "" + else + dat += "" + if ("temperature" in scanner) + dat += "" + if ("light" in scanner) + dat += "" + if ("soil" in scanner) + if(seed.get_trait(TRAIT_REQUIRES_NUTRIENTS)) + if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05) + dat += "" + else if(seed.get_trait(TRAIT_REQUIRES_NUTRIENTS) > 0.2) + dat += "" + else + dat += "" + else + dat += "" + if(seed.get_trait(TRAIT_REQUIRES_WATER)) + if(seed.get_trait(TRAIT_WATER_CONSUMPTION) < 1) + dat += "" + else if(seed.get_trait(TRAIT_WATER_CONSUMPTION) > 5) + dat += "" + else + dat += "" + else + dat += "" + + dat += "" + dat += "" + dat += "" + dat += "" + dat += "
    NameVarietyEYMPrPtHarvestTempLightNutriWaterNotesAmount
    [seed.seed_name]#[seed.uid][seed.get_trait(TRAIT_ENDURANCE)][seed.get_trait(TRAIT_YIELD)][seed.get_trait(TRAIT_MATURATION)][seed.get_trait(TRAIT_PRODUCTION)][seed.get_trait(TRAIT_POTENCY)]MultipleSingle[seed.get_trait(TRAIT_IDEAL_HEAT)] K[seed.get_trait(TRAIT_IDEAL_LIGHT)] LLowHighNormNoLowHighNormNo" + switch(seed.get_trait(TRAIT_CARNIVOROUS)) + if(1) + dat += "CARN " + if(2) + dat += "CARN " + switch(seed.get_trait(TRAIT_SPREAD)) + if(1) + dat += "VINE " + if(2) + dat += "VINE " + if ("pressure" in scanner) + if(seed.get_trait(TRAIT_LOWKPA_TOLERANCE) < 20) + dat += "LP " + if(seed.get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220) + dat += "HP " + if ("temperature" in scanner) + if(seed.get_trait(TRAIT_HEAT_TOLERANCE) > 30) + dat += "TEMRES " + else if(seed.get_trait(TRAIT_HEAT_TOLERANCE) < 10) + dat += "TEMSEN " + if ("light" in scanner) + if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) > 10) + dat += "LIGRES " + else if(seed.get_trait(TRAIT_LIGHT_TOLERANCE) < 3) + dat += "LIGSEN " + if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) < 3) + dat += "TOXSEN " + else if(seed.get_trait(TRAIT_TOXINS_TOLERANCE) > 6) + dat += "TOXRES " + if(seed.get_trait(TRAIT_PEST_TOLERANCE) < 3) + dat += "PESTSEN " + else if(seed.get_trait(TRAIT_PEST_TOLERANCE) > 6) + dat += "PESTRES " + if(seed.get_trait(TRAIT_WEED_TOLERANCE) < 3) + dat += "WEEDSEN " + else if(seed.get_trait(TRAIT_WEED_TOLERANCE) > 6) + dat += "WEEDRES " + if(seed.get_trait(TRAIT_PARASITE)) + dat += "PAR " + if ("temperature" in scanner) + if(seed.get_trait(TRAIT_ALTER_TEMP) > 0) + dat += "TEMP+ " + if(seed.get_trait(TRAIT_ALTER_TEMP) < 0) + dat += "TEMP- " + if(seed.get_trait(TRAIT_BIOLUM)) + dat += "LUM " + dat += "[S.amount]Vend Purge
    " + + user << browse(dat, "window=seedstorage") + onclose(user, "seedstorage") + +/obj/machinery/seed_storage/Topic(var/href, var/list/href_list) + if (..()) + return + var/task = href_list["task"] + var/ID = text2num(href_list["id"]) + + for (var/datum/seed_pile/N in piles) + if (N.ID == ID) + if (task == "vend") + var/obj/O = pick(N.seeds) + if (O) + --N.amount + N.seeds -= O + if (N.amount <= 0 || N.seeds.len <= 0) + piles -= N + del(N) + O.loc = src.loc + else + piles -= N + del(N) + else if (task == "purge") + for (var/obj/O in N.seeds) + del(O) + piles -= N + del(N) + break + updateUsrDialog() + +/obj/machinery/seed_storage/attackby(var/obj/item/O as obj, var/mob/user as mob) + if (istype(O, /obj/item/seeds)) + add(O) + user.visible_message("[user] puts \the [O.name] into \the [src].", "You put \the [O] into \the [src].") + return + else if (istype(O, /obj/item/weapon/storage/bag/plants)) + var/obj/item/weapon/storage/P = O + var/loaded = 0 + for(var/obj/item/seeds/G in P.contents) + ++loaded + add(G) + if (loaded) + user.visible_message("[user] puts the seeds from \the [O.name] into \the [src].", "You put the seeds from \the [O.name] into \the [src].") + else + user << "There are no seeds in \the [O.name]." + return + else if(istype(O, /obj/item/weapon/wrench)) + playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) + anchored = !anchored + user << "You [anchored ? "wrench" : "unwrench"] \the [src]." + +/obj/machinery/seed_storage/proc/add(var/obj/item/seeds/O as obj) + if (istype(O.loc, /mob)) + var/mob/user = O.loc + user.drop_item(O) + else if(istype(O.loc,/obj/item/weapon/storage)) + var/obj/item/weapon/storage/S = O.loc + S.remove_from_storage(O, src) + + O.loc = src + + for (var/datum/seed_pile/N in piles) + if (N.matches(O)) + ++N.amount + N.seeds += (O) + return + + piles += new /datum/seed_pile(O, piles.len) + return diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm new file mode 100644 index 0000000000..4f52b82cee --- /dev/null +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -0,0 +1,259 @@ +#define DEFAULT_SEED "glowshroom" +#define VINE_GROWTH_STAGES 5 + +/proc/spacevine_infestation() + spawn() //to stop the secrets panel hanging + var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas + for(var/areapath in typesof(/area/hallway)) + var/area/A = locate(areapath) + for(var/area/B in A.related) + for(var/turf/simulated/floor/F in B.contents) + if(!F.contents.len) + turfs += F + + if(turfs.len) //Pick a turf to spawn at if we can + var/turf/simulated/floor/T = pick(turfs) + var/datum/seed/seed = plant_controller.create_random_seed(1) + seed.set_trait(TRAIT_SPREAD,2) // So it will function properly as vines. + seed.set_trait(TRAIT_POTENCY,rand(70,100)) // Guarantee a wide spread and powerful effects. + new /obj/effect/plant(T,seed) + message_admins("Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])") + +/obj/effect/dead_plant + anchored = 1 + opacity = 0 + density = 0 + color = DEAD_PLANT_COLOUR + +/obj/effect/dead_plant/attack_hand() + del(src) + +/obj/effect/dead_plant/attackby() + ..() + for(var/obj/effect/plant/neighbor in range(1)) + neighbor.update_neighbors() + del(src) + +/obj/effect/plant + name = "plant" + anchored = 1 + opacity = 0 + density = 0 + icon = 'icons/obj/hydroponics_growing.dmi' + icon_state = "bush4-1" + layer = 3 + pass_flags = PASSTABLE + + var/health = 10 + var/max_health = 100 + var/growth_threshold = 0 + var/growth_type = 0 + var/max_growth = 0 + + var/list/neighbors = list() + var/obj/effect/plant/parent + var/datum/seed/seed + var/floor = 0 + var/spread_chance = 40 + var/spread_distance = 3 + var/evolve_chance = 2 + var/last_tick = 0 + var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/plant + +/obj/effect/plant/Del() + if(plant_controller) + plant_controller.remove_plant(src) + for(var/obj/effect/plant/neighbor in range(1,src)) + plant_controller.add_plant(neighbor) + ..() +/obj/effect/plant/single + spread_chance = 0 + +/obj/effect/plant/New(var/newloc, var/datum/seed/newseed, var/obj/effect/plant/newparent) + ..() + + if(!newparent) + parent = src + else + parent = newparent + + if(!plant_controller) + sleep(250) // ugly hack, should mean roundstart plants are fine. + if(!plant_controller) + world << "Plant controller does not exist and [src] requires it. Aborting." + del(src) + return + + if(!istype(newseed)) + newseed = plant_controller.seeds[DEFAULT_SEED] + seed = newseed + if(!seed) + del(src) + return + + name = seed.display_name + max_health = round(seed.get_trait(TRAIT_ENDURANCE)/2) + if(seed.get_trait(TRAIT_SPREAD)==2) + max_growth = VINE_GROWTH_STAGES + growth_threshold = max_health/VINE_GROWTH_STAGES + icon = 'icons/obj/hydroponics_vines.dmi' + growth_type = 2 // Vines by default. + if(seed.get_trait(TRAIT_CARNIVOROUS) == 2) + growth_type = 1 // WOOOORMS. + else if(!(seed.seed_noun in list("seeds","pits"))) + if(seed.seed_noun == "nodes") + growth_type = 3 // Biomass + else + growth_type = 4 // Mold + else + max_growth = seed.growth_stages + growth_threshold = max_health/seed.growth_stages + + if(max_growth > 2 && prob(50)) + max_growth-- //Ensure some variation in final sprite, makes the carpet of crap look less wonky. + + spread_chance = seed.get_trait(TRAIT_POTENCY) + spread_distance = ((growth_type>0) ? round(spread_chance*0.6) : round(spread_chance*0.3)) + update_icon() + + spawn(1) // Plants will sometimes be spawned in the turf adjacent to the one they need to end up in, for the sake of correct dir/etc being set. + set_dir(calc_dir()) + update_icon() + plant_controller.add_plant(src) + // Some plants eat through plating. + if(!isnull(seed.chems["pacid"])) + var/turf/T = get_turf(src) + T.ex_act(prob(80) ? 3 : 2) + +/obj/effect/plant/update_icon() + //TODO: should really be caching this. + refresh_icon() + if(growth_type == 0 && !floor) + src.transform = null + var/matrix/M = matrix() + // should make the plant flush against the wall it's meant to be growing from. + M.Translate(0,-(rand(12,14))) + switch(dir) + if(WEST) + M.Turn(90) + if(NORTH) + M.Turn(180) + if(EAST) + M.Turn(270) + src.transform = M + var/icon_colour = seed.get_trait(TRAIT_PLANT_COLOUR) + if(icon_colour) + color = icon_colour + // Apply colour and light from seed datum. + if(seed.get_trait(TRAIT_BIOLUM)) + SetLuminosity(1+round(seed.get_trait(TRAIT_POTENCY)/20)) + if(seed.get_trait(TRAIT_BIOLUM_COLOUR)) + l_color = seed.get_trait(TRAIT_BIOLUM_COLOUR) + else + l_color = null + return + else + SetLuminosity(0) + +/obj/effect/plant/proc/refresh_icon() + var/growth = min(max_growth,round(health/growth_threshold)) + var/at_fringe = get_dist(src,parent) + if(spread_distance > 5) + if(at_fringe >= (spread_distance-3)) + max_growth-- + if(at_fringe >= (spread_distance-2)) + max_growth-- + max_growth = max(1,max_growth) + if(growth_type > 0) + switch(growth_type) + if(1) + icon_state = "worms" + if(2) + icon_state = "vines-[growth]" + if(3) + icon_state = "mass-[growth]" + if(4) + icon_state = "mold-[growth]" + else + icon_state = "[seed.get_trait(TRAIT_PLANT_ICON)]-[growth]" + + if(growth>2 && growth == max_growth) + layer = 5 + opacity = 1 + if(!isnull(seed.chems["woodpulp"])) + density = 1 + else + layer = 3 + density = 0 + +/obj/effect/plant/proc/calc_dir(turf/location = loc) + set background = 1 + var/direction = 16 + + for(var/wallDir in cardinal) + var/turf/newTurf = get_step(location,wallDir) + if(newTurf.density) + direction |= wallDir + + for(var/obj/effect/plant/shroom in location) + if(shroom == src) + continue + if(shroom.floor) //special + direction &= ~16 + else + direction &= ~shroom.dir + + var/list/dirList = list() + + for(var/i=1,i<=16,i <<= 1) + if(direction & i) + dirList += i + + if(dirList.len) + var/newDir = pick(dirList) + if(newDir == 16) + floor = 1 + newDir = 1 + return newDir + + floor = 1 + return 1 + +/obj/effect/plant/attackby(var/obj/item/weapon/W, var/mob/user) + + plant_controller.add_plant(src) + + if(istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/weapon/scalpel)) + if(!seed) + user << "There is nothing to take a sample from." + return + seed.harvest(user,0,1) + health -= (rand(3,5)*10) + else + ..() + if(W.force) + health -= W.force + check_health() + +/obj/effect/plant/ex_act(severity) + switch(severity) + if(1.0) + die_off() + return + if(2.0) + if (prob(50)) + die_off() + return + if(3.0) + if (prob(5)) + die_off() + return + else + return + +/obj/effect/plant/proc/check_health() + if(health <= 0) + die_off() + +/obj/effect/plant/proc/is_mature() + return (health >= (max_health/3)) \ No newline at end of file diff --git a/code/modules/hydroponics/spreading/spreading_growth.dm b/code/modules/hydroponics/spreading/spreading_growth.dm new file mode 100644 index 0000000000..257d2219ba --- /dev/null +++ b/code/modules/hydroponics/spreading/spreading_growth.dm @@ -0,0 +1,99 @@ +#define NEIGHBOR_REFRESH_TIME 100 + +/obj/effect/plant/proc/get_cardinal_neighbors() + var/list/cardinal_neighbors = list() + for(var/check_dir in cardinal) + var/turf/simulated/T = get_step(get_turf(src), check_dir) + if(istype(T)) + cardinal_neighbors |= T + return cardinal_neighbors + +/obj/effect/plant/proc/update_neighbors() + // Update our list of valid neighboring turfs. + neighbors = list() + for(var/turf/simulated/floor in get_cardinal_neighbors()) + if(get_dist(parent, floor) > spread_distance) + continue + if((locate(/obj/effect/plant) in floor.contents) || (locate(/obj/effect/dead_plant) in floor.contents) ) + continue + if(floor.density) + if(!isnull(seed.chems["pacid"])) + spawn(rand(5,25)) floor.ex_act(3) + continue + if(!Adjacent(floor) || !floor.Enter(src)) + continue + neighbors |= floor + // Update all of our friends. + var/turf/T = get_turf(src) + for(var/obj/effect/plant/neighbor in range(1,src)) + neighbor.neighbors -= T + +/obj/effect/plant/process() + + // Something is very wrong, kill ourselves. + if(!seed) + die_off() + return 0 + + // Handle life. + var/turf/simulated/T = get_turf(src) + if(istype(T)) + health -= seed.handle_environment(T,T.return_air(),null,1) + if(health < max_health) + health += rand(3,5) + refresh_icon() + if(health > max_health) + health = max_health + else if(health == max_health && !plant) + plant = new(T,seed) + plant.dir = src.dir + plant.transform = src.transform + plant.age = seed.get_trait(TRAIT_MATURATION)-1 + plant.update_icon() + if(growth_type==0) //Vines do not become invisible. + invisibility = INVISIBILITY_MAXIMUM + else + plant.layer = layer + 0.1 + + if(buckled_mob) + seed.do_sting(buckled_mob,src) + if(seed.get_trait(TRAIT_CARNIVOROUS)) + seed.do_thorns(buckled_mob,src) + + if(world.time >= last_tick+NEIGHBOR_REFRESH_TIME) + last_tick = world.time + update_neighbors() + + if(is_mature() && neighbors.len && prob(spread_chance)) + for(var/i=1,i<=seed.get_trait(TRAIT_YIELD),i++) + if(prob(spread_chance)) + sleep(rand(3,5)) + if(!neighbors.len) + break + var/turf/target_turf = pick(neighbors) + var/obj/effect/plant/child = new(get_turf(src),seed,parent) + spawn(1) // This should do a little bit of animation. + child.loc = target_turf + child.update_icon() + // Update neighboring squares. + for(var/obj/effect/plant/neighbor in range(1,target_turf)) + neighbor.neighbors -= target_turf + + // We shouldn't have spawned if the controller doesn't exist. + check_health() + if(neighbors.len || health != max_health) + plant_controller.add_plant(src) + +/obj/effect/plant/proc/die_off() + // Kill off our plant. + if(plant) plant.die() + // This turf is clear now, let our buddies know. + for(var/turf/simulated/check_turf in get_cardinal_neighbors()) + if(!istype(check_turf)) + continue + for(var/obj/effect/plant/neighbor in check_turf.contents) + neighbor.neighbors |= check_turf + plant_controller.add_plant(neighbor) + spawn(1) if(src) del(src) + +#undef NEIGHBOR_REFRESH_TIME \ No newline at end of file diff --git a/code/modules/hydroponics/spreading/spreading_response.dm b/code/modules/hydroponics/spreading/spreading_response.dm new file mode 100644 index 0000000000..d175fdda22 --- /dev/null +++ b/code/modules/hydroponics/spreading/spreading_response.dm @@ -0,0 +1,78 @@ +/obj/effect/plant/HasProximity(var/atom/movable/AM) + + if(!is_mature() || seed.get_trait(TRAIT_SPREAD) != 2) + return + + var/mob/living/M = AM + if(!istype(M)) + return + + if(!buckled_mob && !M.buckled && !M.anchored && (M.small || prob(round(seed.get_trait(TRAIT_POTENCY)/2)))) + entangle(M) + +/obj/effect/plant/attack_hand(mob/user as mob) + // Todo, cause damage. + manual_unbuckle(user) + +/obj/effect/plant/proc/trodden_on(var/mob/living/victim) + if(!is_mature()) + return + var/mob/living/carbon/human/H = victim + if(istype(H) && H.shoes) + return + seed.do_thorns(victim,src) + seed.do_sting(victim,src,pick("r_foot","l_foot","r_leg","l_leg")) + +/obj/effect/plant/proc/unbuckle() + if(buckled_mob) + if(buckled_mob.buckled == src) + buckled_mob.buckled = null + buckled_mob.anchored = initial(buckled_mob.anchored) + buckled_mob.update_canmove() + buckled_mob = null + return + +/obj/effect/plant/proc/manual_unbuckle(mob/user as mob) + if(buckled_mob) + if(prob(seed ? min(max(0,100 - seed.get_trait(TRAIT_POTENCY)/2),100) : 50)) + if(buckled_mob.buckled == src) + if(buckled_mob != user) + buckled_mob.visible_message(\ + "[user.name] frees [buckled_mob.name] from \the [src].",\ + "[user.name] frees you from \the [src].",\ + "You hear shredding and ripping.") + else + buckled_mob.visible_message(\ + "[buckled_mob.name] struggles free of \the [src].",\ + "You untangle \the [src] from around yourself.",\ + "You hear shredding and ripping.") + unbuckle() + else + var/text = pick("rip","tear","pull") + user.visible_message(\ + "[user.name] [text]s at \the [src].",\ + "You [text] at \the [src].",\ + "You hear shredding and ripping.") + return + +/obj/effect/plant/proc/entangle(var/mob/living/victim) + + if(buckled_mob) + return + + if(!Adjacent(victim)) + return + + victim.buckled = src + victim.update_canmove() + buckled_mob = victim + if(!victim.anchored && !victim.buckled && victim.loc != get_turf(src)) + var/can_grab = 1 + if(istype(victim, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = victim + if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP)) + can_grab = 0 + if(can_grab) + src.visible_message("Tendrils lash out from \the [src] and drag \the [victim] in!") + victim.loc = src.loc + victim << "Tendrils [pick("wind", "tangle", "tighten")] around you!" diff --git a/code/modules/hydroponics/hydro_tray.dm b/code/modules/hydroponics/trays/tray.dm similarity index 55% rename from code/modules/hydroponics/hydro_tray.dm rename to code/modules/hydroponics/trays/tray.dm index 9ef693a94d..69aa483b03 100644 --- a/code/modules/hydroponics/hydro_tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -1,15 +1,14 @@ -#define HYDRO_SPEED_MULTIPLIER 1 - /obj/machinery/portable_atmospherics/hydroponics name = "hydroponics tray" - icon = 'icons/obj/hydroponics.dmi' + icon = 'icons/obj/hydroponics_machines.dmi' icon_state = "hydrotray3" density = 1 anchored = 1 flags = OPENCONTAINER volume = 100 - var/draw_warnings = 1 //Set to 0 to stop it from drawing the alert lights. + var/mechanical = 1 // Set to 0 to stop it from drawing the alert lights. + var/base_name = "tray" // Plant maintenance vars. var/waterlevel = 100 // Water (max 100) @@ -21,13 +20,14 @@ var/dead = 0 // Is it dead? var/harvest = 0 // Is it ready to harvest? var/age = 0 // Current plant age - var/sampled = 0 // Have wa taken a sample? + var/sampled = 0 // Have we taken a sample? // Harvest/mutation mods. var/yield_mod = 0 // Modifier to yield var/mutation_mod = 0 // Modifier to mutation chance var/toxins = 0 // Toxicity in the tray? var/mutation_level = 0 // When it hits 100, the plant mutates. + var/tray_light = 1 // Supplied lighting. // Mechanical concerns. var/health = 0 // Plant health. @@ -37,6 +37,7 @@ var/closed_system // If set, the tray will attempt to take atmos from a pipe. var/force_update // Set this to bypass the cycle time check. var/obj/temp_chem_holder // Something to hold reagents during process_reagents() + var/labelled // Seed details/line data. var/datum/seed/seed = null // The currently planted seed @@ -122,6 +123,12 @@ "mutagen" = 15 ) +/obj/machinery/portable_atmospherics/hydroponics/AltClick() + if(mechanical && !usr.stat && !usr.lying && Adjacent(usr)) + close_lid(usr) + return + return ..() + /obj/machinery/portable_atmospherics/hydroponics/attack_generic(var/mob/user) if(istype(user,/mob/living/carbon/alien/diona)) var/mob/living/carbon/alien/diona/nymph = user @@ -146,13 +153,14 @@ temp_chem_holder = new() temp_chem_holder.create_reagents(10) create_reagents(200) - connect() + if(mechanical) + connect() update_icon() /obj/machinery/portable_atmospherics/hydroponics/bullet_act(var/obj/item/projectile/Proj) //Don't act on seeds like dionaea that shouldn't change. - if(seed && seed.immutable > 0) + if(seed && seed.get_trait(TRAIT_IMMUTABLE) > 0) return //Override for somatoray projectiles. @@ -173,174 +181,18 @@ else return 0 -/obj/machinery/portable_atmospherics/hydroponics/process() - - //Do this even if we're not ready for a plant cycle. - process_reagents() - - // Update values every cycle rather than every process() tick. - if(force_update) - force_update = 0 - else if(world.time < (lastcycle + cycledelay)) - return - lastcycle = world.time - - // Mutation level drops each main tick. - mutation_level -= rand(2,4) - - // Weeds like water and nutrients, there's a chance the weed population will increase. - // Bonus chance if the tray is unoccupied. - if(waterlevel > 10 && nutrilevel > 2 && prob(isnull(seed) ? 5 : 1)) - weedlevel += 1 * HYDRO_SPEED_MULTIPLIER - - // There's a chance for a weed explosion to happen if the weeds take over. - // Plants that are themselves weeds (weed_tolerance > 10) are unaffected. - if (weedlevel >= 10 && prob(10)) - if(!seed || weedlevel >= seed.weed_tolerance) - weed_invasion() - - // If there is no seed data (and hence nothing planted), - // or the plant is dead, process nothing further. - if(!seed || dead) - if(draw_warnings) update_icon() //Harvesting would fail to set alert icons properly. - return - - // Advance plant age. - if(prob(30)) age += 1 * HYDRO_SPEED_MULTIPLIER - - //Highly mutable plants have a chance of mutating every tick. - if(seed.immutable == -1) - var/mut_prob = rand(1,100) - if(mut_prob <= 5) mutate(mut_prob == 1 ? 2 : 1) - - // Other plants also mutate if enough mutagenic compounds have been added. - if(!seed.immutable) - if(prob(min(mutation_level,100))) - mutate((rand(100) < 15) ? 2 : 1) - mutation_level = 0 - - // Maintain tray nutrient and water levels. - if(seed.nutrient_consumption > 0 && nutrilevel > 0 && prob(25)) - nutrilevel -= max(0,seed.nutrient_consumption * HYDRO_SPEED_MULTIPLIER) - if(seed.water_consumption > 0 && waterlevel > 0 && prob(25)) - waterlevel -= max(0,seed.water_consumption * HYDRO_SPEED_MULTIPLIER) - - // Make sure the plant is not starving or thirsty. Adequate - // water and nutrients will cause a plant to become healthier. - var/healthmod = rand(1,3) * HYDRO_SPEED_MULTIPLIER - if(seed.requires_nutrients && prob(35)) - health += (nutrilevel < 2 ? -healthmod : healthmod) - if(seed.requires_water && prob(35)) - health += (waterlevel < 10 ? -healthmod : healthmod) - - // Check that pressure, heat and light are all within bounds. - // First, handle an open system or an unconnected closed system. - - var/turf/T = loc - var/datum/gas_mixture/environment - - // If we're closed, take from our internal sources. - if(closed_system && (connected_port || holding)) - environment = air_contents - - // If atmos input is not there, grab from turf. - if(!environment) - if(istype(T)) - environment = T.return_air() - - if(!environment) return - - // Handle gas consumption. - if(seed.consume_gasses && seed.consume_gasses.len) - var/missing_gas = 0 - for(var/gas in seed.consume_gasses) - if(environment && environment.gas && environment.gas[gas] && \ - environment.gas[gas] >= seed.consume_gasses[gas]) - environment.adjust_gas(gas,-seed.consume_gasses[gas],1) - else - missing_gas++ - - if(missing_gas > 0) - health -= missing_gas * HYDRO_SPEED_MULTIPLIER - - // Process it. - var/pressure = environment.return_pressure() - if(pressure < seed.lowkpa_tolerance || pressure > seed.highkpa_tolerance) - health -= healthmod - - if(abs(environment.temperature - seed.ideal_heat) > seed.heat_tolerance) - health -= healthmod - - // Handle gas production. - if(seed.exude_gasses && seed.exude_gasses.len) - for(var/gas in seed.exude_gasses) - environment.adjust_gas(gas, max(1,round((seed.exude_gasses[gas]*seed.potency)/seed.exude_gasses.len))) - - // If we're attached to a pipenet, then we should let the pipenet know we might have modified some gasses - if (closed_system && connected_port) - update_connected_network() - - // Handle light requirements. - var/area/A = T.loc - if(A) - var/light_available - if(A.lighting_use_dynamic) - light_available = max(0,min(10,T.lighting_lumcount)-5) - else - light_available = 5 - if(abs(light_available - seed.ideal_light) > seed.light_tolerance) - health -= healthmod - - // Toxin levels beyond the plant's tolerance cause damage, but - // toxins are sucked up each tick and slowly reduce over time. - if(toxins > 0) - var/toxin_uptake = max(1,round(toxins/10)) - if(toxins > seed.toxins_tolerance) - health -= toxin_uptake - toxins -= toxin_uptake - - // Check for pests and weeds. - // Some carnivorous plants happily eat pests. - if(pestlevel > 0) - if(seed.carnivorous) - health += HYDRO_SPEED_MULTIPLIER - pestlevel -= HYDRO_SPEED_MULTIPLIER - else if (pestlevel >= seed.pest_tolerance) - health -= HYDRO_SPEED_MULTIPLIER - - // Some plants thrive and live off of weeds. - if(weedlevel > 0) - if(seed.parasite) - health += HYDRO_SPEED_MULTIPLIER - weedlevel -= HYDRO_SPEED_MULTIPLIER - else if (weedlevel >= seed.weed_tolerance) - health -= HYDRO_SPEED_MULTIPLIER - - // Handle life and death. - // If the plant is too old, it loses health fast. - if(age > seed.lifespan) - health -= rand(3,5) * HYDRO_SPEED_MULTIPLIER - - // When the plant dies, weeds thrive and pests die off. - if(health <= 0) - dead = 1 - mutation_level = 0 - harvest = 0 - weedlevel += 1 * HYDRO_SPEED_MULTIPLIER - pestlevel = 0 - - // If enough time (in cycles, not ticks) has passed since the plant was harvested, we're ready to harvest again. - else if(seed.products && seed.products.len && age > seed.production && \ - (age - lastproduce) > seed.production && (!harvest && !dead)) - harvest = 1 - lastproduce = age - - if(prob(3)) // On each tick, there's a chance the pest population will increase - pestlevel += 0.1 * HYDRO_SPEED_MULTIPLIER - +/obj/machinery/portable_atmospherics/hydroponics/proc/check_health() + if(seed && !dead && health <= 0) + die() check_level_sanity() update_icon() - return + +/obj/machinery/portable_atmospherics/hydroponics/proc/die() + dead = 1 + mutation_level = 0 + harvest = 0 + weedlevel += 1 * HYDRO_SPEED_MULTIPLIER + pestlevel = 0 //Process reagents being input into the tray. /obj/machinery/portable_atmospherics/hydroponics/proc/process_reagents() @@ -391,27 +243,29 @@ toxins -= round(water_added/4) temp_chem_holder.reagents.clear_reagents() - check_level_sanity() - update_icon() + check_health() //Harvests the product of a plant. /obj/machinery/portable_atmospherics/hydroponics/proc/harvest(var/mob/user) //Harvest the product of the plant, - if(!seed || !harvest || !user) + if(!seed || !harvest) return if(closed_system) - user << "You can't harvest from the plant while the lid is shut." + if(user) user << "You can't harvest from the plant while the lid is shut." return - seed.harvest(user,yield_mod) + if(user) + seed.harvest(user,yield_mod) + else + seed.harvest(get_turf(src),yield_mod) // Reset values. harvest = 0 lastproduce = age - if(!seed.harvest_repeat) + if(!seed.get_trait(TRAIT_HARVEST_REPEAT)) yield_mod = 0 seed = null dead = 0 @@ -419,8 +273,7 @@ sampled = 0 mutation_mod = 0 - check_level_sanity() - update_icon() + check_health() return //Clears out a dead plant. @@ -438,85 +291,28 @@ yield_mod = 0 mutation_mod = 0 - user << "You remove the dead plant from the [src]." - check_level_sanity() - update_icon() + user << "You remove the dead plant." + check_health() return -//Refreshes the icon and sets the luminosity -/obj/machinery/portable_atmospherics/hydroponics/update_icon() - - overlays.Cut() - - // Updates the plant overlay. - if(!isnull(seed)) - - if(draw_warnings && health <= (seed.endurance / 2)) - overlays += "over_lowhealth3" - - if(dead) - overlays += "[seed.plant_icon]-dead" - else if(harvest) - overlays += "[seed.plant_icon]-harvest" - else if(age < seed.maturation) - - var/t_growthstate - if(age >= seed.maturation) - t_growthstate = seed.growth_stages - else - t_growthstate = round(seed.maturation / seed.growth_stages) - - overlays += "[seed.plant_icon]-grow[t_growthstate]" - lastproduce = age - else - overlays += "[seed.plant_icon]-grow[seed.growth_stages]" - - //Draw the cover. - if(closed_system) - overlays += "hydrocover" - - //Updated the various alert icons. - if(draw_warnings) - if(waterlevel <= 10) - overlays += "over_lowwater3" - if(nutrilevel <= 2) - overlays += "over_lownutri3" - if(weedlevel >= 5 || pestlevel >= 5 || toxins >= 40) - overlays += "over_alert3" - if(harvest) - overlays += "over_harvest3" - - // Update bioluminescence. - if(seed) - if(seed.biolum) - SetLuminosity(round(seed.potency/10)) - if(seed.biolum_colour) - l_color = seed.biolum_colour - else - l_color = null - return - - SetLuminosity(0) - return - - // If a weed growth is sufficient, this proc is called. +// If a weed growth is sufficient, this proc is called. /obj/machinery/portable_atmospherics/hydroponics/proc/weed_invasion() //Remove the seed if something is already planted. if(seed) seed = null - seed = seed_types[pick(list("reishi","nettles","amanita","mushrooms","plumphelmet","towercap","harebells","weeds"))] + seed = plant_controller.seeds[pick(list("reishi","nettles","amanita","mushrooms","plumphelmet","towercap","harebells","weeds"))] if(!seed) return //Weed does not exist, someone fucked up. dead = 0 age = 0 - health = seed.endurance + health = seed.get_trait(TRAIT_ENDURANCE) lastcycle = world.time harvest = 0 weedlevel = 0 pestlevel = 0 sampled = 0 update_icon() - visible_message("\blue [src] has been overtaken by [seed.display_name].") + visible_message("[src] has been overtaken by [seed.display_name].") return @@ -534,16 +330,40 @@ // We need to make sure we're not modifying one of the global seed datums. // If it's not in the global list, then no products of the line have been // harvested yet and it's safe to assume it's restricted to this tray. - if(!isnull(seed_types[seed.name])) + if(!isnull(plant_controller.seeds[seed.name])) seed = seed.diverge() seed.mutate(severity,get_turf(src)) return +/obj/machinery/portable_atmospherics/hydroponics/verb/remove_label() + + set name = "Remove Label" + set category = "Object" + set src in view(1) + + if(labelled) + usr << "You remove the label." + labelled = null + update_icon() + else + usr << "There is no label to remove." + return + +/obj/machinery/portable_atmospherics/hydroponics/verb/set_light() + set name = "Set Light" + set category = "Object" + set src in view(1) + + var/new_light = input("Specify a light level.") as null|anything in list(0,1,2,3,4,5,6,7,8,9,10) + if(new_light) + tray_light = new_light + usr << "You set the tray to a light level of [tray_light] lumens." + /obj/machinery/portable_atmospherics/hydroponics/proc/check_level_sanity() //Make sure various values are sane. if(seed) - health = max(0,min(seed.endurance,health)) + health = max(0,min(seed.get_trait(TRAIT_ENDURANCE),health)) else health = 0 dead = 0 @@ -559,21 +379,21 @@ var/previous_plant = seed.display_name var/newseed = seed.get_mutant_variant() - if(newseed in seed_types) - seed = seed_types[newseed] + if(newseed in plant_controller.seeds) + seed = plant_controller.seeds[newseed] else return dead = 0 mutate(1) age = 0 - health = seed.endurance + health = seed.get_trait(TRAIT_ENDURANCE) lastcycle = world.time harvest = 0 weedlevel = 0 update_icon() - visible_message("\red The \blue [previous_plant] \red has suddenly mutated into \blue [seed.display_name]!") + visible_message("The [previous_plant] has suddenly mutated into [seed.display_name]!") return @@ -604,7 +424,7 @@ sampled = 1 // Bookkeeping. - check_level_sanity() + check_health() force_update = 1 process() @@ -641,42 +461,28 @@ return user << "You plant the [S.seed.seed_name] [S.seed.seed_noun]." - - if(S.seed.spread == 1) - msg_admin_attack("[key_name(user)] has planted a creeper packet.") - var/obj/effect/plant_controller/creeper/PC = new(get_turf(src)) - if(PC) - PC.seed = S.seed - else if(S.seed.spread == 2) - msg_admin_attack("[key_name(user)] has planted a spreading vine packet.") - var/obj/effect/plant_controller/PC = new(get_turf(src)) - if(PC) - PC.seed = S.seed - else - seed = S.seed //Grab the seed datum. - dead = 0 - age = 1 - //Snowflakey, maybe move this to the seed datum - health = (istype(S, /obj/item/seeds/cutting) ? round(seed.endurance/rand(2,5)) : seed.endurance) - - lastcycle = world.time + seed = S.seed //Grab the seed datum. + dead = 0 + age = 1 + //Snowflakey, maybe move this to the seed datum + health = (istype(S, /obj/item/seeds/cutting) ? round(seed.get_trait(TRAIT_ENDURANCE)/rand(2,5)) : seed.get_trait(TRAIT_ENDURANCE)) + lastcycle = world.time del(O) - check_level_sanity() - update_icon() + check_health() else - user << "\red \The [src] already has seeds in it!" + user << "\The [src] already has seeds in it!" else if (istype(O, /obj/item/weapon/minihoe)) // The minihoe if(weedlevel > 0) - user.visible_message("\red [user] starts uprooting the weeds.", "\red You remove the weeds from the [src].") + user.visible_message("[user] starts uprooting the weeds.", "You remove the weeds from the [src].") weedlevel = 0 update_icon() else - user << "\red This plot is completely devoid of weeds. It doesn't need uprooting." + user << "This plot is completely devoid of weeds. It doesn't need uprooting." else if (istype(O, /obj/item/weapon/storage/bag/plants)) @@ -698,11 +504,9 @@ user << "You spray [src] with [O]." playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6) del(O) + check_health() - check_level_sanity() - update_icon() - - else if(istype(O, /obj/item/weapon/wrench)) + else if(mechanical && istype(O, /obj/item/weapon/wrench)) //If there's a connector here, the portable_atmospherics setup can handle it. if(locate(/obj/machinery/atmospherics/portables_connector/) in loc) @@ -715,7 +519,7 @@ else if(istype(O, /obj/item/apiary)) if(seed) - user << "\red [src] is already occupied!" + user << "[src] is already occupied!" else user.drop_item() del(O) @@ -725,15 +529,18 @@ A.icon_state = src.icon_state A.hydrotray_type = src.type del(src) + else if(O.force && seed) + user.visible_message("\The [seed.display_name] has been attacked by [user] with \the [O]!") + if(!dead) + health -= O.force + check_health() return /obj/machinery/portable_atmospherics/hydroponics/attack_tk(mob/user as mob) - - if(harvest) - harvest(user) - - else if(dead) + if(dead) remove_dead(user) + else if(harvest) + harvest(user) /obj/machinery/portable_atmospherics/hydroponics/attack_hand(mob/user as mob) @@ -745,35 +552,50 @@ else if(dead) remove_dead(user) - else - if(seed && !dead) - usr << "[src] has \blue [seed.display_name] \black planted." - if(health <= (seed.endurance / 2)) - usr << "The plant looks \red unhealthy." +/obj/machinery/portable_atmospherics/hydroponics/examine() + + ..() + + if(!seed) + usr << "[src] is empty." + return + + usr << "[seed.display_name] are growing here." + + if(!Adjacent(usr)) + return + + usr << "Water: [round(waterlevel,0.1)]/100" + usr << "Nutrient: [round(nutrilevel,0.1)]/10" + + if(weedlevel >= 5) + usr << "\The [src] is infested with weeds!" + if(pestlevel >= 5) + usr << "\The [src] is infested with tiny worms!" + + if(dead) + usr << "The plant is dead." + else if(health <= (seed.get_trait(TRAIT_ENDURANCE)/ 2)) + usr << "The plant looks unhealthy." + + if(mechanical) + var/turf/T = loc + var/datum/gas_mixture/environment + + if(closed_system && (connected_port || holding)) + environment = air_contents + + if(!environment) + if(istype(T)) + environment = T.return_air() + + if(!environment) //We're in a crate or nullspace, bail out. + return + + var/light_string + if(closed_system && mechanical) + light_string = "that the internal lights are set to [tray_light] lumens" else - usr << "[src] is empty." - usr << "Water: [round(waterlevel,0.1)]/100" - usr << "Nutrient: [round(nutrilevel,0.1)]/10" - if(weedlevel >= 5) - usr << "[src] is \red filled with weeds!" - if(pestlevel >= 5) - usr << "[src] is \red filled with tiny worms!" - - if(!istype(src,/obj/machinery/portable_atmospherics/hydroponics/soil)) - - var/turf/T = loc - var/datum/gas_mixture/environment - - if(closed_system && (connected_port || holding)) - environment = air_contents - - if(!environment) - if(istype(T)) - environment = T.return_air() - - if(!environment) //We're in a crate or nullspace, bail out. - return - var/area/A = T.loc var/light_available if(A) @@ -781,40 +603,20 @@ light_available = max(0,min(10,T.lighting_lumcount)-5) else light_available = 5 + light_string = "a light level of [light_available] lumens" - usr << "The tray's sensor suite is reporting a light level of [light_available] lumens and a temperature of [environment.temperature]K." + usr << "The tray's sensor suite is reporting [light_string] and a temperature of [environment.temperature]K." -/obj/machinery/portable_atmospherics/hydroponics/verb/close_lid() +/obj/machinery/portable_atmospherics/hydroponics/verb/close_lid_verb() set name = "Toggle Tray Lid" set category = "Object" set src in view(1) + close_lid(usr) - if(!usr || usr.stat || usr.restrained()) +/obj/machinery/portable_atmospherics/hydroponics/proc/close_lid(var/mob/living/user) + if(!user || user.stat || user.restrained()) return closed_system = !closed_system - usr << "You [closed_system ? "close" : "open"] the tray's lid." + user << "You [closed_system ? "close" : "open"] the tray's lid." update_icon() - -/obj/machinery/portable_atmospherics/hydroponics/soil - name = "soil" - icon = 'icons/obj/hydroponics.dmi' - icon_state = "soil" - density = 0 - use_power = 0 - draw_warnings = 0 - -/obj/machinery/portable_atmospherics/hydroponics/soil/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(istype(O, /obj/item/weapon/shovel)) - user << "You clear up [src]!" - del(src) - else if(istype(O,/obj/item/weapon/shovel) || istype(O,/obj/item/weapon/tank)) - return - else - ..() - -/obj/machinery/portable_atmospherics/hydroponics/soil/New() - ..() - verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/close_lid - -#undef HYDRO_SPEED_MULTIPLIER diff --git a/code/game/machinery/bees_apiary.dm b/code/modules/hydroponics/trays/tray_apiary.dm similarity index 94% rename from code/game/machinery/bees_apiary.dm rename to code/modules/hydroponics/trays/tray_apiary.dm index 58e6dd7783..f2098e7481 100644 --- a/code/game/machinery/bees_apiary.dm +++ b/code/modules/hydroponics/trays/tray_apiary.dm @@ -3,7 +3,7 @@ /obj/machinery/apiary name = "apiary tray" - icon = 'icons/obj/hydroponics.dmi' + icon = 'icons/obj/hydroponics_machines.dmi' icon_state = "hydrotray3" density = 1 anchored = 1 @@ -188,13 +188,7 @@ if(prob(10)) H.lastcycle -= 5 if(prob(10)) - if(!isnull(seed_types[H.seed.name])) - H.seed = H.seed.diverge(-1) - H.seed.lifespan = max(initial(H.seed.lifespan) * 1.5, H.seed.lifespan + 1) - if(prob(10)) - if(!isnull(seed_types[H.seed.name])) - H.seed = H.seed.diverge(-1) - H.seed.endurance = max(initial(H.seed.endurance) * 1.5, H.seed.endurance + 1) + H.seed.set_trait(TRAIT_ENDURANCE,max(H.seed.get_trait(TRAIT_ENDURANCE)*1.5,H.seed.get_trait(TRAIT_ENDURANCE)+1)) if(H.toxins && prob(10)) H.toxins = min(0, H.toxins - 1) toxic++ diff --git a/code/modules/hydroponics/trays/tray_process.dm b/code/modules/hydroponics/trays/tray_process.dm new file mode 100644 index 0000000000..280ce9e6d6 --- /dev/null +++ b/code/modules/hydroponics/trays/tray_process.dm @@ -0,0 +1,126 @@ +/obj/machinery/portable_atmospherics/hydroponics/process() + + //Do this even if we're not ready for a plant cycle. + process_reagents() + + // Update values every cycle rather than every process() tick. + if(force_update) + force_update = 0 + else if(world.time < (lastcycle + cycledelay)) + return + lastcycle = world.time + + // Mutation level drops each main tick. + mutation_level -= rand(2,4) + + // Weeds like water and nutrients, there's a chance the weed population will increase. + // Bonus chance if the tray is unoccupied. + if(waterlevel > 10 && nutrilevel > 2 && prob(isnull(seed) ? 5 : 1)) + weedlevel += 1 * HYDRO_SPEED_MULTIPLIER + + // There's a chance for a weed explosion to happen if the weeds take over. + // Plants that are themselves weeds (weed_tolerance > 10) are unaffected. + if (weedlevel >= 10 && prob(10)) + if(!seed || weedlevel >= seed.get_trait(TRAIT_WEED_TOLERANCE)) + weed_invasion() + + // If there is no seed data (and hence nothing planted), + // or the plant is dead, process nothing further. + if(!seed || dead) + if(mechanical) update_icon() //Harvesting would fail to set alert icons properly. + return + + // Advance plant age. + if(prob(30)) age += 1 * HYDRO_SPEED_MULTIPLIER + + //Highly mutable plants have a chance of mutating every tick. + if(seed.get_trait(TRAIT_IMMUTABLE) == -1) + var/mut_prob = rand(1,100) + if(mut_prob <= 5) mutate(mut_prob == 1 ? 2 : 1) + + // Other plants also mutate if enough mutagenic compounds have been added. + if(!seed.get_trait(TRAIT_IMMUTABLE)) + if(prob(min(mutation_level,100))) + mutate((rand(100) < 15) ? 2 : 1) + mutation_level = 0 + + // Maintain tray nutrient and water levels. + if(seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0 && nutrilevel > 0 && prob(25)) + nutrilevel -= max(0,seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) * HYDRO_SPEED_MULTIPLIER) + if(seed.get_trait(TRAIT_WATER_CONSUMPTION) > 0 && waterlevel > 0 && prob(25)) + waterlevel -= max(0,seed.get_trait(TRAIT_WATER_CONSUMPTION) * HYDRO_SPEED_MULTIPLIER) + + // Make sure the plant is not starving or thirsty. Adequate + // water and nutrients will cause a plant to become healthier. + var/healthmod = rand(1,3) * HYDRO_SPEED_MULTIPLIER + if(seed.get_trait(TRAIT_REQUIRES_NUTRIENTS) && prob(35)) + health += (nutrilevel < 2 ? -healthmod : healthmod) + if(seed.get_trait(TRAIT_REQUIRES_WATER) && prob(35)) + health += (waterlevel < 10 ? -healthmod : healthmod) + + // Check that pressure, heat and light are all within bounds. + // First, handle an open system or an unconnected closed system. + var/turf/T = loc + var/datum/gas_mixture/environment + // If we're closed, take from our internal sources. + if(closed_system && (connected_port || holding)) + environment = air_contents + // If atmos input is not there, grab from turf. + if(!environment && istype(T)) environment = T.return_air() + if(!environment) return + + // Seed datum handles gasses, light and pressure. + if(mechanical && closed_system) + health -= seed.handle_environment(T,environment,tray_light) + else + health -= seed.handle_environment(T,environment) + + // If we're attached to a pipenet, then we should let the pipenet know we might have modified some gasses + if (closed_system && connected_port) + update_connected_network() + + // Toxin levels beyond the plant's tolerance cause damage, but + // toxins are sucked up each tick and slowly reduce over time. + if(toxins > 0) + var/toxin_uptake = max(1,round(toxins/10)) + if(toxins > seed.get_trait(TRAIT_TOXINS_TOLERANCE)) + health -= toxin_uptake + toxins -= toxin_uptake + + // Check for pests and weeds. + // Some carnivorous plants happily eat pests. + if(pestlevel > 0) + if(seed.get_trait(TRAIT_CARNIVOROUS)) + health += HYDRO_SPEED_MULTIPLIER + pestlevel -= HYDRO_SPEED_MULTIPLIER + else if (pestlevel >= seed.get_trait(TRAIT_PEST_TOLERANCE)) + health -= HYDRO_SPEED_MULTIPLIER + + // Some plants thrive and live off of weeds. + if(weedlevel > 0) + if(seed.get_trait(TRAIT_PARASITE)) + health += HYDRO_SPEED_MULTIPLIER + weedlevel -= HYDRO_SPEED_MULTIPLIER + else if (weedlevel >= seed.get_trait(TRAIT_WEED_TOLERANCE)) + health -= HYDRO_SPEED_MULTIPLIER + + // Handle life and death. + // When the plant dies, weeds thrive and pests die off. + check_health() + + // If enough time (in cycles, not ticks) has passed since the plant was harvested, we're ready to harvest again. + if((age > seed.get_trait(TRAIT_MATURATION)) && \ + ((age - lastproduce) > seed.get_trait(TRAIT_PRODUCTION)) && \ + (!harvest && !dead)) + harvest = 1 + lastproduce = age + + if(prob(3)) // On each tick, there's a chance the pest population will increase + pestlevel += 0.1 * HYDRO_SPEED_MULTIPLIER + + // Some seeds will self-harvest if you don't keep a lid on them. + if(seed && seed.can_self_harvest && harvest && !closed_system && prob(5)) + harvest() + + check_health() + return diff --git a/code/modules/hydroponics/trays/tray_reagents.dm b/code/modules/hydroponics/trays/tray_reagents.dm new file mode 100644 index 0000000000..3dad0adc45 --- /dev/null +++ b/code/modules/hydroponics/trays/tray_reagents.dm @@ -0,0 +1,138 @@ + +/obj/item/weapon/plantspray + icon = 'icons/obj/hydroponics_machines.dmi' + item_state = "spray" + flags = NOBLUDGEON + slot_flags = SLOT_BELT + throwforce = 4 + w_class = 2.0 + throw_speed = 2 + throw_range = 10 + var/toxicity = 4 + var/pest_kill_str = 0 + var/weed_kill_str = 0 + +/obj/item/weapon/plantspray/weeds // -- Skie + + name = "weed-spray" + desc = "It's a toxic mixture, in spray form, to kill small weeds." + icon_state = "weedspray" + weed_kill_str = 6 + +/obj/item/weapon/plantspray/pests + name = "pest-spray" + desc = "It's some pest eliminator spray! Do not inhale!" + icon_state = "pestspray" + pest_kill_str = 6 + +/obj/item/weapon/plantspray/pests/old + name = "bottle of pestkiller" + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle16" + +/obj/item/weapon/plantspray/pests/old/carbaryl + name = "bottle of carbaryl" + icon_state = "bottle16" + toxicity = 4 + pest_kill_str = 2 + +/obj/item/weapon/plantspray/pests/old/lindane + name = "bottle of lindane" + icon_state = "bottle18" + toxicity = 6 + pest_kill_str = 4 + +/obj/item/weapon/plantspray/pests/old/phosmet + name = "bottle of phosmet" + icon_state = "bottle15" + toxicity = 8 + pest_kill_str = 7 + +/obj/item/weapon/minihoe // -- Numbers + name = "mini hoe" + desc = "It's used for removing weeds or scratching your back." + icon = 'icons/obj/weapons.dmi' + icon_state = "hoe" + item_state = "hoe" + flags = CONDUCT | NOBLUDGEON + force = 5.0 + throwforce = 7.0 + w_class = 2.0 + matter = list("metal" = 50) + attack_verb = list("slashed", "sliced", "cut", "clawed") + + +// ************************************* +// Weedkiller defines for hydroponics +// ************************************* + +/obj/item/weedkiller + name = "bottle of weedkiller" + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle16" + var/toxicity = 0 + var/weed_kill_str = 0 + +/obj/item/weedkiller/triclopyr + name = "bottle of glyphosate" + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle16" + toxicity = 4 + weed_kill_str = 2 + +/obj/item/weedkiller/lindane + name = "bottle of triclopyr" + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle18" + toxicity = 6 + weed_kill_str = 4 + +/obj/item/weedkiller/D24 + name = "bottle of 2,4-D" + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle15" + toxicity = 8 + weed_kill_str = 7 + +// ************************************* +// Nutrient defines for hydroponics +// ************************************* + +/obj/item/weapon/reagent_containers/glass/fertilizer + name = "fertilizer bottle" + desc = "A small glass bottle. Can hold up to 10 units." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle16" + flags = OPENCONTAINER + possible_transfer_amounts = null + w_class = 2.0 + + var/fertilizer //Reagent contained, if any. + + //Like a shot glass! + amount_per_transfer_from_this = 10 + volume = 10 + +/obj/item/weapon/reagent_containers/glass/fertilizer/New() + ..() + + src.pixel_x = rand(-5.0, 5) + src.pixel_y = rand(-5.0, 5) + + if(fertilizer) + reagents.add_reagent(fertilizer,10) + +/obj/item/weapon/reagent_containers/glass/fertilizer/ez + name = "bottle of E-Z-Nutrient" + icon_state = "bottle16" + fertilizer = "eznutrient" + +/obj/item/weapon/reagent_containers/glass/fertilizer/l4z + name = "bottle of Left 4 Zed" + icon_state = "bottle18" + fertilizer = "left4zed" + +/obj/item/weapon/reagent_containers/glass/fertilizer/rh + name = "bottle of Robust Harvest" + icon_state = "bottle15" + fertilizer = "robustharvest" diff --git a/code/modules/hydroponics/trays/tray_soil.dm b/code/modules/hydroponics/trays/tray_soil.dm new file mode 100644 index 0000000000..ff8e3e23df --- /dev/null +++ b/code/modules/hydroponics/trays/tray_soil.dm @@ -0,0 +1,67 @@ +/obj/machinery/portable_atmospherics/hydroponics/soil + name = "soil" + icon_state = "soil" + density = 0 + use_power = 0 + mechanical = 0 + tray_light = 0 + +/obj/machinery/portable_atmospherics/hydroponics/soil/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(istype(O,/obj/item/weapon/tank)) + return + else + ..() + +/obj/machinery/portable_atmospherics/hydroponics/soil/New() + ..() + verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/close_lid_verb + verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/remove_label + verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/set_light + +/obj/machinery/portable_atmospherics/hydroponics/soil/CanPass() + return 1 + +// Holder for vine plants. +// Icons for plants are generated as overlays, so setting it to invisible wouldn't work. +// Hence using a blank icon. +/obj/machinery/portable_atmospherics/hydroponics/soil/invisible + name = "plant" + icon = 'icons/obj/seeds.dmi' + icon_state = "blank" + +/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/New(var/newloc,var/datum/seed/newseed) + ..() + seed = newseed + dead = 0 + age = 1 + health = seed.get_trait(TRAIT_ENDURANCE) + lastcycle = world.time + pixel_y = rand(-5,5) + check_health() + +/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/remove_dead() + ..() + del(src) + +/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/harvest() + ..() + if(!seed) // Repeat harvests are a thing. + del(src) + +/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/die() + del(src) + +/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/process() + if(!seed) + del(src) + return + else if(name=="plant") + name = seed.display_name + ..() + +/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/Del() + // Check if we're masking a decal that needs to be visible again. + for(var/obj/effect/plant/plant in get_turf(src)) + if(plant.invisibility == INVISIBILITY_MAXIMUM) + plant.invisibility = initial(plant.invisibility) + ..() diff --git a/code/modules/hydroponics/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm new file mode 100644 index 0000000000..67d630119a --- /dev/null +++ b/code/modules/hydroponics/trays/tray_tools.dm @@ -0,0 +1,280 @@ +//Analyzer, pestkillers, weedkillers, nutrients, hatchets, cutters. + +/obj/item/weapon/wirecutters/clippers + name = "plant clippers" + desc = "A tool used to take samples from plants." + +/obj/item/device/analyzer/plant_analyzer + name = "plant analyzer" + icon = 'icons/obj/device.dmi' + icon_state = "hydro" + item_state = "analyzer" + var/form_title + var/last_data + +/obj/item/device/analyzer/plant_analyzer/proc/print_report_verb() + set name = "Print Plant Report" + set category = "Object" + set src = usr + + if(usr.stat || usr.restrained() || usr.lying) + return + print_report(usr) + +/obj/item/device/analyzer/plant_analyzer/Topic(href, href_list) + if(..()) + return + if(href_list["print"]) + print_report(usr) + +/obj/item/device/analyzer/plant_analyzer/proc/print_report(var/mob/living/user) + if(!last_data) + user << "There is no scan data to print." + return + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(src)) + P.name = "paper - [form_title]" + P.info = "[last_data]" + if(istype(user,/mob/living/carbon/human) && !(user.l_hand && user.r_hand)) + user.put_in_hands(P) + user.visible_message("\The [src] spits out a piece of paper.") + return + +/obj/item/device/analyzer/plant_analyzer/attack_self(mob/user as mob) + print_report(user) + return 0 + +/obj/item/device/analyzer/plant_analyzer/afterattack(obj/target, mob/user, flag) + if(!flag) return + + var/datum/seed/grown_seed + var/datum/reagents/grown_reagents + if(istype(target,/obj/structure/table)) + return ..() + else if(istype(target,/obj/item/weapon/reagent_containers/food/snacks/grown)) + + var/obj/item/weapon/reagent_containers/food/snacks/grown/G = target + grown_seed = plant_controller.seeds[G.plantname] + grown_reagents = G.reagents + + else if(istype(target,/obj/item/weapon/grown)) + + var/obj/item/weapon/grown/G = target + grown_seed = plant_controller.seeds[G.plantname] + grown_reagents = G.reagents + + else if(istype(target,/obj/item/seeds)) + + var/obj/item/seeds/S = target + grown_seed = S.seed + + else if(istype(target,/obj/machinery/portable_atmospherics/hydroponics)) + + var/obj/machinery/portable_atmospherics/hydroponics/H = target + grown_seed = H.seed + grown_reagents = H.reagents + + if(!grown_seed) + user << "[src] can tell you nothing about \the [target]." + return + + form_title = "[grown_seed.seed_name] (#[grown_seed.uid])" + var/dat = "

    Plant data for [form_title]

    " + user.visible_message("[user] runs the scanner over \the [target].") + + dat += "

    General Data

    " + + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "
    Endurance[grown_seed.get_trait(TRAIT_ENDURANCE)]
    Yield[grown_seed.get_trait(TRAIT_YIELD)]
    Maturation time[grown_seed.get_trait(TRAIT_MATURATION)]
    Production time[grown_seed.get_trait(TRAIT_PRODUCTION)]
    Potency[grown_seed.get_trait(TRAIT_POTENCY)]
    " + + if(grown_reagents && grown_reagents.reagent_list && grown_reagents.reagent_list.len) + dat += "

    Reagent Data

    " + + dat += "
    This sample contains: " + for(var/datum/reagent/R in grown_reagents.reagent_list) + dat += "
    - [R.id], [grown_reagents.get_reagent_amount(R.id)] unit(s)" + + dat += "

    Other Data

    " + + if(grown_seed.get_trait(TRAIT_HARVEST_REPEAT)) + dat += "This plant can be harvested repeatedly.
    " + + if(grown_seed.get_trait(TRAIT_IMMUTABLE) == -1) + dat += "This plant is highly mutable.
    " + else if(grown_seed.get_trait(TRAIT_IMMUTABLE) > 0) + dat += "This plant does not possess genetics that are alterable.
    " + + if(grown_seed.get_trait(TRAIT_REQUIRES_NUTRIENTS)) + if(grown_seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) < 0.05) + dat += "It consumes a small amount of nutrient fluid.
    " + else if(grown_seed.get_trait(TRAIT_NUTRIENT_CONSUMPTION) > 0.2) + dat += "It requires a heavy supply of nutrient fluid.
    " + else + dat += "It requires a supply of nutrient fluid.
    " + + if(grown_seed.get_trait(TRAIT_REQUIRES_WATER)) + if(grown_seed.get_trait(TRAIT_WATER_CONSUMPTION) < 1) + dat += "It requires very little water.
    " + else if(grown_seed.get_trait(TRAIT_WATER_CONSUMPTION) > 5) + dat += "It requires a large amount of water.
    " + else + dat += "It requires a stable supply of water.
    " + + if(grown_seed.mutants && grown_seed.mutants.len) + dat += "It exhibits a high degree of potential subspecies shift.
    " + + dat += "It thrives in a temperature of [grown_seed.get_trait(TRAIT_IDEAL_HEAT)] Kelvin." + + if(grown_seed.get_trait(TRAIT_LOWKPA_TOLERANCE) < 20) + dat += "
    It is well adapted to low pressure levels." + if(grown_seed.get_trait(TRAIT_HIGHKPA_TOLERANCE) > 220) + dat += "
    It is well adapted to high pressure levels." + + if(grown_seed.get_trait(TRAIT_HEAT_TOLERANCE) > 30) + dat += "
    It is well adapted to a range of temperatures." + else if(grown_seed.get_trait(TRAIT_HEAT_TOLERANCE) < 10) + dat += "
    It is very sensitive to temperature shifts." + + dat += "
    It thrives in a light level of [grown_seed.get_trait(TRAIT_IDEAL_LIGHT)] lumen[grown_seed.get_trait(TRAIT_IDEAL_LIGHT) == 1 ? "" : "s"]." + + if(grown_seed.get_trait(TRAIT_LIGHT_TOLERANCE) > 10) + dat += "
    It is well adapted to a range of light levels." + else if(grown_seed.get_trait(TRAIT_LIGHT_TOLERANCE) < 3) + dat += "
    It is very sensitive to light level shifts." + + if(grown_seed.get_trait(TRAIT_TOXINS_TOLERANCE) < 3) + dat += "
    It is highly sensitive to toxins." + else if(grown_seed.get_trait(TRAIT_TOXINS_TOLERANCE) > 6) + dat += "
    It is remarkably resistant to toxins." + + if(grown_seed.get_trait(TRAIT_PEST_TOLERANCE) < 3) + dat += "
    It is highly sensitive to pests." + else if(grown_seed.get_trait(TRAIT_PEST_TOLERANCE) > 6) + dat += "
    It is remarkably resistant to pests." + + if(grown_seed.get_trait(TRAIT_WEED_TOLERANCE) < 3) + dat += "
    It is highly sensitive to weeds." + else if(grown_seed.get_trait(TRAIT_WEED_TOLERANCE) > 6) + dat += "
    It is remarkably resistant to weeds." + + switch(grown_seed.get_trait(TRAIT_SPREAD)) + if(1) + dat += "
    It is able to be planted outside of a tray." + if(2) + dat += "
    It is a robust and vigorous vine that will spread rapidly." + + switch(grown_seed.get_trait(TRAIT_CARNIVOROUS)) + if(1) + dat += "
    It is carniovorous and will eat tray pests for sustenance." + if(2) + dat += "
    It is carnivorous and poses a significant threat to living things around it." + + if(grown_seed.get_trait(TRAIT_PARASITE)) + dat += "
    It is capable of parisitizing and gaining sustenance from tray weeds." + if(grown_seed.get_trait(TRAIT_ALTER_TEMP)) + dat += "
    It will periodically alter the local temperature by [grown_seed.get_trait(TRAIT_ALTER_TEMP)] degrees Kelvin." + + if(grown_seed.get_trait(TRAIT_BIOLUM)) + dat += "
    It is [grown_seed.get_trait(TRAIT_BIOLUM_COLOUR) ? "bio-luminescent" : "bio-luminescent"]." + + if(grown_seed.get_trait(TRAIT_PRODUCES_POWER)) + dat += "
    The fruit will function as a battery if prepared appropriately." + + if(grown_seed.get_trait(TRAIT_STINGS)) + dat += "
    The fruit is covered in stinging spines." + + if(grown_seed.get_trait(TRAIT_JUICY) == 1) + dat += "
    The fruit is soft-skinned and juicy." + else if(grown_seed.get_trait(TRAIT_JUICY) == 2) + dat += "
    The fruit is excessively juicy." + + if(grown_seed.get_trait(TRAIT_EXPLOSIVE)) + dat += "
    The fruit is internally unstable." + + if(grown_seed.get_trait(TRAIT_TELEPORTING)) + dat += "
    The fruit is temporal/spatially unstable." + + if(dat) + last_data = dat + dat += "

    \[print report\]" + user << browse(dat,"window=plant_analyzer") + + return + +/obj/item/weapon/minihoe // -- Numbers + name = "mini hoe" + desc = "It's used for removing weeds or scratching your back." + icon = 'icons/obj/weapons.dmi' + icon_state = "hoe" + item_state = "hoe" + flags = CONDUCT | NOBLUDGEON + force = 5.0 + throwforce = 7.0 + w_class = 2.0 + matter = list("metal" = 50) + attack_verb = list("slashed", "sliced", "cut", "clawed") + +//Hatchets and things to kill kudzu +/obj/item/weapon/hatchet + name = "hatchet" + desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood." + icon = 'icons/obj/weapons.dmi' + icon_state = "hatchet" + flags = CONDUCT + force = 12.0 + w_class = 2.0 + throwforce = 15.0 + throw_speed = 4 + throw_range = 4 + sharp = 1 + edge = 1 + matter = list("metal" = 15000) + origin_tech = "materials=2;combat=1" + attack_verb = list("chopped", "torn", "cut") + +/obj/item/weapon/hatchet/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) + playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1) + return ..() + +//If it's a hatchet it goes here. I guess +/obj/item/weapon/hatchet/unathiknife + name = "duelling knife" + desc = "A length of leather-bound wood studded with razor-sharp teeth. How crude." + icon = 'icons/obj/weapons.dmi' + icon_state = "unathiknife" + attack_verb = list("ripped", "torn", "cut") + +/obj/item/weapon/hatchet/tacknife + name = "tactical knife" + desc = "You'd be killing loads of people if this was Medal of Valor: Heroes of Nyx." + icon = 'icons/obj/weapons.dmi' + icon_state = "tacknife" + item_state = "knife" + attack_verb = list("stabbed", "chopped", "cut") + + +/obj/item/weapon/scythe + icon_state = "scythe0" + name = "scythe" + desc = "A sharp and curved blade on a long fibremetal handle, this tool makes it easy to reap what you sow." + force = 13.0 + throwforce = 5.0 + throw_speed = 1 + throw_range = 3 + w_class = 4.0 + flags = NOSHIELD + slot_flags = SLOT_BACK + origin_tech = "materials=2;combat=2" + attack_verb = list("chopped", "sliced", "cut", "reaped") + +/obj/item/weapon/scythe/afterattack(atom/A, mob/user as mob, proximity) + if(!proximity) return + if(istype(A, /obj/effect/plant)) + for(var/obj/effect/plant/B in orange(A,1)) + if(prob(80)) + B.die_off(1) + del A \ No newline at end of file diff --git a/code/modules/hydroponics/trays/tray_update_icons.dm b/code/modules/hydroponics/trays/tray_update_icons.dm new file mode 100644 index 0000000000..61e19632ea --- /dev/null +++ b/code/modules/hydroponics/trays/tray_update_icons.dm @@ -0,0 +1,84 @@ +//Refreshes the icon and sets the luminosity +/obj/machinery/portable_atmospherics/hydroponics/update_icon() + // Update name. + if(seed) + if(mechanical) + name = "[base_name] (#[seed.uid])" + else + name = "[seed.seed_name]" + else + name = initial(name) + + if(labelled) + name += " ([labelled])" + + overlays.Cut() + // Updates the plant overlay. + if(!isnull(seed)) + + if(mechanical && health <= (seed.get_trait(TRAIT_ENDURANCE) / 2)) + overlays += "over_lowhealth3" + + if(dead) + var/ikey = "[seed.get_trait(TRAIT_PLANT_ICON)]-dead" + var/image/dead_overlay = plant_controller.plant_icon_cache["[ikey]"] + if(!dead_overlay) + dead_overlay = image('icons/obj/hydroponics_growing.dmi', "[ikey]") + dead_overlay.color = DEAD_PLANT_COLOUR + overlays |= dead_overlay + else + if(!seed.growth_stages) + seed.update_growth_stages() + if(!seed.growth_stages) + world << "Seed type [seed.get_trait(TRAIT_PLANT_ICON)] cannot find a growth stage value." + return + var/overlay_stage = 1 + if(age >= seed.get_trait(TRAIT_MATURATION)) + overlay_stage = seed.growth_stages + else + var/maturation = round(seed.get_trait(TRAIT_MATURATION)/seed.growth_stages) + overlay_stage = maturation ? max(1,round(age/maturation)) : 1 + var/ikey = "[seed.get_trait(TRAIT_PLANT_ICON)]-[overlay_stage]" + var/image/plant_overlay = plant_controller.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] + if(!plant_overlay) + plant_overlay = image('icons/obj/hydroponics_growing.dmi', "[ikey]") + plant_overlay.color = seed.get_trait(TRAIT_PLANT_COLOUR) + plant_controller.plant_icon_cache["[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] = plant_overlay + overlays |= plant_overlay + + if(harvest && overlay_stage == seed.growth_stages) + ikey = "[seed.get_trait(TRAIT_PRODUCT_ICON)]" + var/image/harvest_overlay = plant_controller.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PLANT_COLOUR)]"] + if(!harvest_overlay) + harvest_overlay = image('icons/obj/hydroponics_products.dmi', "[ikey]") + harvest_overlay.color = seed.get_trait(TRAIT_PRODUCT_COLOUR) + plant_controller.plant_icon_cache["product-[ikey]-[seed.get_trait(TRAIT_PRODUCT_COLOUR)]"] = harvest_overlay + overlays |= harvest_overlay + + //Draw the cover. + if(closed_system) + overlays += "hydrocover" + + //Updated the various alert icons. + if(mechanical) + if(waterlevel <= 10) + overlays += "over_lowwater3" + if(nutrilevel <= 2) + overlays += "over_lownutri3" + if(weedlevel >= 5 || pestlevel >= 5 || toxins >= 40) + overlays += "over_alert3" + if(harvest) + overlays += "over_harvest3" + + // Update bioluminescence. + if(seed) + if(seed.get_trait(TRAIT_BIOLUM)) + SetLuminosity(round(seed.get_trait(TRAIT_POTENCY)/10)) + if(seed.get_trait(TRAIT_BIOLUM_COLOUR)) + l_color = seed.get_trait(TRAIT_BIOLUM_COLOUR) + else + l_color = null + return + + SetLuminosity(0) + return \ No newline at end of file diff --git a/code/modules/hydroponics/vines.dm b/code/modules/hydroponics/vines.dm deleted file mode 100644 index 699063fec4..0000000000 --- a/code/modules/hydroponics/vines.dm +++ /dev/null @@ -1,385 +0,0 @@ -// SPACE VINES (Note that this code is very similar to Biomass code) -/obj/effect/plantsegment - name = "space vines" - desc = "An extremely expansionistic species of vine." - icon = 'icons/effects/spacevines.dmi' - icon_state = "Light1" - anchored = 1 - density = 0 - layer = 5 - pass_flags = PASSTABLE | PASSGRILLE - - // Vars used by vines with seed data. - var/age = 0 - var/lastproduce = 0 - var/harvest = 0 - var/list/chems - var/plant_damage_noun = "Thorns" - var/limited_growth = 0 - - // Life vars/ - var/energy = 0 - var/obj/effect/plant_controller/master = null - var/mob/living/buckled_mob - var/datum/seed/seed - -/obj/effect/plantsegment/New() - return - -/obj/effect/plantsegment/Del() - if(master) - master.vines -= src - master.growth_queue -= src - ..() - -/obj/effect/plantsegment/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (!W || !user || !W.type) return - switch(W.type) - if(/obj/item/weapon/circular_saw) del src - if(/obj/item/weapon/kitchen/utensil/knife) del src - if(/obj/item/weapon/scalpel) del src - if(/obj/item/weapon/twohanded/fireaxe) del src - if(/obj/item/weapon/hatchet) del src - if(/obj/item/weapon/melee/energy) del src - if(/obj/item/weapon/pickaxe/plasmacutter) del src - - // Less effective weapons - if(/obj/item/weapon/wirecutters) - if(prob(25)) del src - if(/obj/item/weapon/shard) - if(prob(25)) del src - - // Weapons with subtypes - else - if(istype(W, /obj/item/weapon/melee/energy/sword)) del src - else if(istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(WT.remove_fuel(0, user)) del src - else - manual_unbuckle(user) - return - // Plant-b-gone damage is handled in its entry in chemistry-reagents.dm - ..() - - -/obj/effect/plantsegment/attack_hand(mob/user as mob) - - if(user.a_intent == "help" && seed && harvest) - seed.harvest(user,1) - harvest = 0 - lastproduce = age - update() - return - - manual_unbuckle(user) - -/obj/effect/plantsegment/proc/unbuckle() - if(buckled_mob) - if(buckled_mob.buckled == src) //this is probably unneccesary, but it doesn't hurt - buckled_mob.buckled = null - buckled_mob.anchored = initial(buckled_mob.anchored) - buckled_mob.update_canmove() - buckled_mob = null - return - -/obj/effect/plantsegment/proc/manual_unbuckle(mob/user as mob) - if(buckled_mob) - if(prob(seed ? min(max(0,100 - seed.potency),100) : 50)) - if(buckled_mob.buckled == src) - if(buckled_mob != user) - buckled_mob.visible_message(\ - "[user.name] frees [buckled_mob.name] from [src].",\ - "[user.name] frees you from [src].",\ - "You hear shredding and ripping.") - else - buckled_mob.visible_message(\ - "[buckled_mob.name] struggles free of [src].",\ - "You untangle [src] from around yourself.",\ - "You hear shredding and ripping.") - unbuckle() - else - var/text = pick("rips","tears","pulls") - user.visible_message(\ - "[user.name] [text] at [src].",\ - "You [text] at [src].",\ - "You hear shredding and ripping.") - return - -/obj/effect/plantsegment/proc/grow() - - if(!energy) - src.icon_state = pick("Med1", "Med2", "Med3") - energy = 1 - - //Low-lying creepers do not block vision or grow thickly. - if(limited_growth) - energy = 2 - return - - src.opacity = 1 - layer = 5 - else if(!limited_growth) - src.icon_state = pick("Hvy1", "Hvy2", "Hvy3") - energy = 2 - -/obj/effect/plantsegment/proc/entangle_mob() - - if(limited_growth) - return - - if(prob(seed ? seed.potency : 25)) - - if(!buckled_mob) - var/mob/living/carbon/V = locate() in src.loc - if(V && (V.stat != DEAD) && (V.buckled != src)) // If mob exists and is not dead or captured. - V.buckled = src - V.loc = src.loc - V.update_canmove() - src.buckled_mob = V - V << "The vines [pick("wind", "tangle", "tighten")] around you!" - - // FEED ME, SEYMOUR. - if(buckled_mob && seed && (buckled_mob.stat != DEAD)) //Don't bother with a dead mob. - - var/mob/living/M = buckled_mob - if(!istype(M)) return - var/mob/living/carbon/human/H = buckled_mob - - // Drink some blood/cause some brute. - if(seed.carnivorous == 2) - buckled_mob << "\The [src] pierces your flesh greedily!" - - var/damage = rand(round(seed.potency/2),seed.potency) - if(!istype(H)) - H.adjustBruteLoss(damage) - return - - var/datum/organ/external/affecting = H.get_organ(pick("l_foot","r_foot","l_leg","r_leg","l_hand","r_hand","l_arm", "r_arm","head","chest","groin")) - - if(affecting) - affecting.take_damage(damage, 0) - if(affecting.parent) - affecting.parent.add_autopsy_data("[plant_damage_noun]", damage) - else - H.adjustBruteLoss(damage) - - H.UpdateDamageIcon() - H.updatehealth() - - // Inject some chems. - if(seed.chems && seed.chems.len && istype(H)) - H << "You feel something seeping into your skin!" - for(var/rid in seed.chems) - var/injecting = min(5,max(1,seed.potency/5)) - H.reagents.add_reagent(rid,injecting) - -/obj/effect/plantsegment/proc/update() - if(!seed) return - - // Update bioluminescence. - if(seed.biolum) - SetLuminosity(1+round(seed.potency/10)) - if(seed.biolum_colour) - l_color = seed.biolum_colour - else - l_color = null - return - else - SetLuminosity(0) - - // Update flower/product overlay. - overlays.Cut() - if(age >= seed.maturation) - if(prob(20) && seed.products && seed.products.len && !harvest && ((age-lastproduce) > seed.production)) - harvest = 1 - lastproduce = age - - if(harvest) - var/image/fruit_overlay = image('icons/obj/hydroponics.dmi',"") - if(seed.product_colour) - fruit_overlay.color = seed.product_colour - overlays += fruit_overlay - - if(seed.flowers) - var/image/flower_overlay = image('icons/obj/hydroponics.dmi',"[seed.flower_icon]") - if(seed.flower_colour) - flower_overlay.color = seed.flower_colour - overlays += flower_overlay - -/obj/effect/plantsegment/proc/spread() - var/direction = pick(cardinal) - var/step = get_step(src,direction) - if(istype(step,/turf/simulated/floor)) - var/turf/simulated/floor/F = step - if(!locate(/obj/effect/plantsegment,F)) - if(F.Enter(src)) - if(master) - master.spawn_piece( F ) - -// Explosion damage. -/obj/effect/plantsegment/ex_act(severity) - switch(severity) - if(1.0) - die() - return - if(2.0) - if (prob(90)) - die() - return - if(3.0) - if (prob(50)) - die() - return - return - -// Hotspots kill vines. -/obj/effect/plantsegment/fire_act(null, temp, volume) - del src - -/obj/effect/plantsegment/proc/die() - if(seed && harvest && rand(5)) - seed.harvest(src,1) - del(src) - -/obj/effect/plantsegment/proc/life() - - if(!seed) - return - - if(prob(30)) - age++ - - var/turf/T = loc - var/datum/gas_mixture/environment - if(T) environment = T.return_air() - - if(!environment) - return - - var/pressure = environment.return_pressure() - if(pressure < seed.lowkpa_tolerance || pressure > seed.highkpa_tolerance) - die() - return - - if(abs(environment.temperature - seed.ideal_heat) > seed.heat_tolerance) - die() - return - - var/area/A = T.loc - if(A) - var/light_available - if(A.lighting_use_dynamic) - light_available = max(0,min(10,T.lighting_lumcount)-5) - else - light_available = 5 - if(abs(light_available - seed.ideal_light) > seed.light_tolerance) - die() - return - -/obj/effect/plant_controller - - //What this does is that instead of having the grow minimum of 1, required to start growing, the minimum will be 0, - //meaning if you get the spacevines' size to something less than 20 plots, it won't grow anymore. - - var/list/obj/effect/plantsegment/vines = list() - var/list/growth_queue = list() - var/reached_collapse_size - var/reached_slowdown_size - var/datum/seed/seed - - var/collapse_limit = 250 - var/slowdown_limit = 30 - var/limited_growth = 0 - -/obj/effect/plant_controller/creeper - collapse_limit = 6 - slowdown_limit = 3 - limited_growth = 1 - -/obj/effect/plant_controller/New() - if(!istype(src.loc,/turf/simulated/floor)) - del(src) - - spawn(0) - spawn_piece(src.loc) - - processing_objects.Add(src) - -/obj/effect/plant_controller/Del() - processing_objects.Remove(src) - ..() - -/obj/effect/plant_controller/proc/spawn_piece(var/turf/location) - var/obj/effect/plantsegment/SV = new(location) - SV.limited_growth = src.limited_growth - growth_queue += SV - vines += SV - SV.master = src - if(seed) - SV.seed = seed - SV.name = "[seed.seed_name] vines" - SV.update() - -/obj/effect/plant_controller/process() - - // Space vines exterminated. Remove the controller - if(!vines) - del(src) - return - - // Sanity check. - if(!growth_queue) - del(src) - return - - // Check if we're too big for our own good. - if(vines.len >= (seed ? seed.potency * collapse_limit : 250) && !reached_collapse_size) - reached_collapse_size = 1 - if(vines.len >= (seed ? seed.potency * slowdown_limit : 30) && !reached_slowdown_size ) - reached_slowdown_size = 1 - - var/length = 0 - if(reached_collapse_size) - length = 0 - else if(reached_slowdown_size) - if(prob(seed ? seed.potency : 25)) - length = 1 - else - length = 0 - else - length = 1 - - length = min(30, max(length, vines.len/5)) - - // Update as many pieces of vine as we're allowed to. - // Append updated vines to the end of the growth queue. - var/i = 0 - var/list/obj/effect/plantsegment/queue_end = list() - for(var/obj/effect/plantsegment/SV in growth_queue) - i++ - queue_end += SV - growth_queue -= SV - - SV.life() - - if(!SV) continue - - if(SV.energy < 2) //If tile isn't fully grown - var/chance - if(seed) - chance = limited_growth ? round(seed.potency/2,1) : seed.potency - else - chance = 20 - - if(prob(chance)) - SV.grow() - - else if(!seed || !limited_growth) //If tile is fully grown and not just a creeper. - SV.entangle_mob() - - SV.update() - SV.spread() - if(i >= length) - break - - growth_queue = growth_queue + queue_end \ No newline at end of file diff --git a/code/modules/icon generation/Uristrunes.dm b/code/modules/icon generation/Uristrunes.dm index d9c129df8e..8dfe135a72 100644 --- a/code/modules/icon generation/Uristrunes.dm +++ b/code/modules/icon generation/Uristrunes.dm @@ -179,7 +179,7 @@ var/list/rune_animation = list( var/icon/base = icon('icons/effects/uristrunes.dmi', "") for(var/i = 0, i < 10, i++) - if(rune_bits & (1 << i)) + if(BITTEST(rune_bits, i)) base.Blend(icon('icons/effects/uristrunes.dmi', "rune-[1 << i]"), ICON_OVERLAY) var/icon/result @@ -217,7 +217,7 @@ var/list/rune_animation = list( var/icon/I = icon('icons/effects/uristrunes.dmi', "blank") for(var/i = 0, i < 10, i++) - if(rune & (1 << i)) + if(BITTEST(rune, i)) I.Blend(icon('icons/effects/uristrunes.dmi', "rune-[1 << i]"), ICON_OVERLAY) var/obj/o = new(locate(x, y, z)) @@ -229,7 +229,7 @@ var/list/rune_animation = list( var/rune = rand(1, 1023) for(var/i = 0, i < 10, i++) - if(rune & (1 << i)) + if(BITTEST(rune, i)) I.Blend(icon('icons/effects/uristrunes.dmi', "rune-[1 << i]"), ICON_OVERLAY) var/obj/o = new(t) @@ -265,4 +265,4 @@ var/list/rune_animation = list( list(0.250, 1), list(0.125, 1), )) -*/ \ No newline at end of file +*/ diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index cd172b41ee..279be15775 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -31,11 +31,11 @@ O.loc = src update_icon() else if(istype(O, /obj/item/weapon/pen)) - var/newname = stripped_input(usr, "What would you like to title this bookshelf?") + var/newname = sanitizeSafe(input("What would you like to title this bookshelf?"), MAX_MESSAGE_LEN) if(!newname) return else - name = ("bookcase ([sanitize(newname)])") + name = ("bookcase ([newname])") else ..() @@ -174,7 +174,7 @@ var/choice = input("What would you like to change?") in list("Title", "Contents", "Author", "Cancel") switch(choice) if("Title") - var/newtitle = reject_bad_text(stripped_input(usr, "Write a new title:")) + var/newtitle = reject_bad_text(sanitizeSafe(input("Write a new title:"))) if(!newtitle) usr << "The title is invalid." return @@ -182,14 +182,14 @@ src.name = newtitle src.title = newtitle if("Contents") - var/content = strip_html(input(usr, "Write your book's contents (HTML NOT allowed):"),8192) as message|null + var/content = sanitize(input("Write your book's contents (HTML NOT allowed):") as message|null, MAX_BOOK_MESSAGE_LEN) if(!content) usr << "The content is invalid." return else src.dat += content if("Author") - var/newauthor = stripped_input(usr, "Write the author's name:") + var/newauthor = sanitize(input(usr, "Write the author's name:")) if(!newauthor) usr << "The name is invalid." return diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index 8544543531..5d390948a3 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -300,12 +300,12 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f if(checkoutperiod < 1) checkoutperiod = 1 if(href_list["editbook"]) - buffer_book = sanitize(copytext(input("Enter the book's title:") as text|null,1,MAX_MESSAGE_LEN)) + buffer_book = sanitizeSafe(input("Enter the book's title:") as text|null) if(href_list["editmob"]) - buffer_mob = sanitize(copytext(input("Enter the recipient's name:") as text|null,1,MAX_NAME_LEN)) + buffer_mob = sanitize(input("Enter the recipient's name:") as text|null, MAX_NAME_LEN) if(href_list["checkout"]) var/datum/borrowbook/b = new /datum/borrowbook - b.bookname = sanitize(buffer_book) + b.bookname = sanitizeSafe(buffer_book) b.mobname = sanitize(buffer_mob) b.getdate = world.time b.duedate = world.time + (checkoutperiod * 600) @@ -317,7 +317,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f var/obj/item/weapon/book/b = locate(href_list["delbook"]) inventory.Remove(b) if(href_list["setauthor"]) - var/newauthor = sanitize(copytext(input("Enter the author's name: ") as text|null,1,MAX_MESSAGE_LEN)) + var/newauthor = sanitize(input("Enter the author's name: ") as text|null) if(newauthor) scanner.cache.author = newauthor if(href_list["setcategory"]) diff --git a/code/modules/maps/reader.dm b/code/modules/maps/reader.dm index 66ebb13c72..daf34508f5 100644 --- a/code/modules/maps/reader.dm +++ b/code/modules/maps/reader.dm @@ -2,6 +2,9 @@ //SS13 Optimized Map loader ////////////////////////////////////////////////////////////// +//global datum that will preload variables on atoms instanciation +var/global/dmm_suite/preloader/_preloader = null + /** * Construct the model map and control the loading process @@ -163,7 +166,7 @@ //first instance the /area and remove it from the members list index = members.len var/atom/instance - var/dmm_suite/preloader/_preloader = new(members_attributes[index])//preloader for assigning set variables on atom creation + _preloader = new(members_attributes[index])//preloader for assigning set variables on atom creation instance = locate(members[index]) instance.contents.Add(locate(xcrd,ycrd,zcrd)) @@ -191,34 +194,6 @@ T = UT index++ - - //Replace the previous part of the code with this if it's unsafe to assume tiles have ALWAYS an /area AND a /turf - /*while(members.len > 0) - var/length = members.len - var/member = members[length] - - if(ispath(member,/area)) - var/atom/instance - var/dmm_suite/preloader/_preloader = new(members_attributes[length]) - - instance = locate(member) - instance.contents.Add(locate(xcrd,ycrd,zcrd)) - - if(_preloader && instance) - _preloader.load(instance) - - members.Remove(member) - continue - - else if(ispath(member,/turf)) - instance_atom(member,members_attributes[length],xcrd,ycrd,zcrd) - members.Remove(member) - continue - - else - break - */ - //finally instance all remainings objects/mobs for(index=1,index < first_turf_index,index++) instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd) @@ -230,11 +205,11 @@ //Instance an atom at (x,y,z) and gives it the variables in attributes /dmm_suite/proc/instance_atom(var/path,var/list/attributes, var/x, var/y, var/z) var/atom/instance - var/dmm_suite/preloader/_preloader = new(attributes) + _preloader = new(attributes, path) - instance = new path (locate(x,y,z), _preloader)//first preloader pass + instance = new path (locate(x,y,z))//first preloader pass - if(_preloader && instance)//second preloader pass, as some variables may have been reset/changed by New() + if(_preloader && instance)//second preloader pass, for those atoms that don't ..() in New() _preloader.load(instance) return instance @@ -242,9 +217,9 @@ //text trimming (both directions) helper proc //optionally removes quotes before and after the text (for variable name) /dmm_suite/proc/trim_text(var/what as text,var/trim_quotes=0) - while(length(what) && (findtext(what," ",1,2)))// || findtext(what,quote,1,2))) + while(length(what) && (findtext(what," ",1,2))) what=copytext(what,2,0) - while(length(what) && (findtext(what," ",length(what),0)))// || findtext(what,quote,length(what),0))) + while(length(what) && (findtext(what," ",length(what),0))) what=copytext(what,1,length(what)) if(trim_quotes) while(length(what) && (findtext(what,quote,1,2))) @@ -298,14 +273,18 @@ else if(isnum(text2num(trim_right))) trim_right = text2num(trim_right) - //Check for file - else if(copytext(trim_right,1,2) == "'") - trim_right = file(copytext(trim_right,2,length(trim_right))) + //Check for null + else if(trim_right == "null") + trim_right = null //Check for list else if(copytext(trim_right,1,5) == "list") trim_right = text2list(copytext(trim_right,6,length(trim_right))) + //Check for file + else if(copytext(trim_right,1,2) == "'") + trim_right = file(copytext(trim_right,2,length(trim_right))) + to_return[trim_left] = trim_right else//simple var @@ -323,10 +302,11 @@ placed.opacity = 1 placed.underlays += turfs_underlays -//atom creation method that preloads variables before creation -/atom/New(atom/loc, dmm_suite/preloader/_dmm_preloader) - if(istype(_dmm_preloader, /dmm_suite/preloader)) - _dmm_preloader.load(src) +//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() + _preloader.load(src) + . = ..() ////////////////// @@ -336,14 +316,17 @@ /dmm_suite/preloader parent_type = /datum var/list/attributes + var/target_path -/dmm_suite/preloader/New(list/the_attributes) +/dmm_suite/preloader/New(var/list/the_attributes, var/path) .=..() if(!the_attributes.len) Del() + return attributes = the_attributes + target_path = path /dmm_suite/preloader/proc/load(atom/what) for(var/attribute in attributes) what.vars[attribute] = attributes[attribute] - Del() + Del() \ No newline at end of file diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index f71b7f9d35..c26c2eb9cd 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -6,74 +6,155 @@ icon_closed = "securecrate" var/code = null var/lastattempt = null - var/attempts = 3 + var/attempts = 10 + var/codelen = 4 locked = 1 - var/min = 1 - var/max = 10 /obj/structure/closet/crate/secure/loot/New() ..() - code = rand(min,max) - var/loot = rand(1,30) + var/list/digits = list("1", "2", "3", "4", "5", "6", "7", "8", "9", "0") + + code = "" + for(var/i = 0, i < codelen, i++) + var/dig = pick(digits) + code += dig + digits -= dig // Player can enter codes with matching digits, but there are never matching digits in the answer + + var/loot = rand(1, 100) switch(loot) - if(1) + if(1 to 5) // Common things go, 5% new/obj/item/weapon/reagent_containers/food/drinks/bottle/rum(src) - new/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus(src) new/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus(src) new/obj/item/weapon/flame/lighter/zippo(src) - if(2) + if(6 to 10) new/obj/item/weapon/pickaxe/drill(src) new/obj/item/device/taperecorder(src) new/obj/item/clothing/suit/space(src) new/obj/item/clothing/head/helmet/space(src) - if(3) - return - if(4) + if(11 to 15) new/obj/item/weapon/reagent_containers/glass/beaker/bluespace(src) - if(5 to 6) + if(16 to 20) for(var/i = 0, i < 10, i++) new/obj/item/weapon/ore/diamond(src) - if(7) - return - if(8) - return - if(9) + if(21 to 25) for(var/i = 0, i < 3, i++) new/obj/machinery/portable_atmospherics/hydroponics(src) - if(10) + if(26 to 30) for(var/i = 0, i < 3, i++) new/obj/item/weapon/reagent_containers/glass/beaker/noreact(src) - if(11 to 13) - new/obj/item/weapon/melee/classic_baton(src) - if(14) - return - if(15) - new/obj/item/clothing/under/chameleon(src) - for(var/i = 0, i < 7, i++) - new/obj/item/clothing/tie/horrible(src) - if(16) - new/obj/item/clothing/under/shorts(src) + if(31 to 35) + spawn_money(rand(300,800), src) + if(36 to 40) + new/obj/item/weapon/melee/baton(src) + if(41 to 45) new/obj/item/clothing/under/shorts/red(src) new/obj/item/clothing/under/shorts/blue(src) - //Dummy crates start here. - if(17 to 29) - return - //Dummy crates end here. - if(30) - new/obj/item/weapon/melee/baton(src) + if(46 to 50) + new/obj/item/clothing/under/chameleon(src) + for(var/i = 0, i < 7, i++) + new/obj/item/clothing/accessory/horrible(src) + if(51 to 52) // Uncommon, 2% each + new/obj/item/weapon/melee/classic_baton(src) + if(53 to 54) + new/obj/item/latexballon(src) + if(55 to 56) + var/newitem = pick(typesof(/obj/item/toy/prize) - /obj/item/toy/prize) + new newitem(src) + if(57 to 58) + new/obj/item/toy/syndicateballoon(src) + if(59 to 60) + new/obj/item/weapon/rig(src) + if(61 to 62) + for(var/i = 0, i < 12, ++i) + new/obj/item/clothing/head/kitty(src) + if(63 to 64) + var/t = rand(4,7) + for(var/i = 0, i < t, ++i) + 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/phoron, /obj/item/weapon/coin/uranium, /obj/item/weapon/coin/platinum) + new newcoin(src) + if(65 to 66) + new/obj/item/clothing/suit/ianshirt(src) + if(67 to 68) + var/t = rand(4,7) + for(var/i = 0, i < t, ++i) + var/newitem = pick(typesof(/obj/item/weapon/stock_parts) - /obj/item/weapon/stock_parts - /obj/item/weapon/stock_parts/subspace) + new newitem(src) + if(69 to 70) + new/obj/item/weapon/pickaxe/silver(src) + if(71 to 72) + new/obj/item/weapon/pickaxe/drill(src) + if(73 to 74) + new/obj/item/weapon/pickaxe/jackhammer(src) + if(75 to 76) + new/obj/item/weapon/pickaxe/diamond(src) + if(77 to 78) + new/obj/item/weapon/pickaxe/diamonddrill(src) + if(79 to 80) + new/obj/item/weapon/pickaxe/gold(src) + if(81 to 82) + new/obj/item/weapon/pickaxe/plasmacutter(src) + if(83 to 84) + new/obj/item/toy/katana(src) + if(85 to 86) + new/obj/item/seeds/random(src) + if(87) // Rarest things, some are unobtainble otherwise, some are just robust, 1% each + new/obj/item/weed_extract(src) + if(88) + new/obj/item/xenos_claw(src) + if(89) + new/obj/item/organ/xenos/plasmavessel(src) + if(90) + new/obj/item/organ/heart(src) + if(91) + new/obj/item/device/soulstone(src) + if(92) + new/obj/item/weapon/katana(src) + if(93) + new/obj/item/weapon/dnainjector/xraymut(src) // Probably the least OP + if(94) // Why the hell not + new/obj/item/weapon/storage/backpack/clown(src) + new/obj/item/clothing/under/rank/clown(src) + new/obj/item/clothing/shoes/clown_shoes(src) + new/obj/item/device/pda/clown(src) + new/obj/item/clothing/mask/gas/clown_hat(src) + new/obj/item/weapon/bikehorn(src) + //new/obj/item/weapon/stamp/clown(src) I'd add it, but only clowns can use it + new/obj/item/toy/crayon/rainbow(src) + new/obj/item/toy/waterflower(src) + if(95) + new/obj/item/clothing/under/mime(src) + new/obj/item/clothing/shoes/black(src) + new/obj/item/device/pda/mime(src) + new/obj/item/clothing/gloves/white(src) + new/obj/item/clothing/mask/gas/mime(src) + new/obj/item/clothing/head/beret(src) + new/obj/item/clothing/suit/suspenders(src) + new/obj/item/toy/crayon/mime(src) + new/obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing(src) + if(96) + new/obj/item/weapon/vampiric(src) + if(97) + new/obj/item/weapon/archaeological_find(src) + if(98) + new/obj/item/weapon/melee/energy/sword(src) + if(99) + new/obj/item/weapon/storage/belt/champion(src) + new/obj/item/clothing/mask/luchador(src) + if(100) + new/obj/item/clothing/head/bearpelt(src) /obj/structure/closet/crate/secure/loot/togglelock(mob/user as mob) if(locked) user << "The crate is locked with a Deca-code lock." - var/input = input(usr, "Enter digit from [min] to [max].", "Deca-Code Lock", "") as num + var/input = input(usr, "Enter [codelen] digits.", "Deca-Code Lock", "") as text if(in_range(src, user)) - input = Clamp(input, 0, 10) if (input == code) user << "The crate unlocks!" locked = 0 overlays.Cut() overlays += greenlight - else if (input == null || input > max || input < min) + else if (input == null || length(input) != codelen) user << "You leave the crate alone." else user << "A red light flashes." @@ -96,19 +177,26 @@ if (istype(W, /obj/item/weapon/card/emag)) user << "The crate unlocks!" locked = 0 - if (istype(W, /obj/item/device/multitool)) + if (istype(W, /obj/item/device/multitool)) // Greetings Urist McProfessor, how about a nice game of cows and bulls? user << "DECA-CODE LOCK REPORT:" 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) - user << " has been made to open the crate thus far." - return - // hot and cold - if (code > lastattempt) - user << "* Last access attempt lower than expected code." - else - user << "* Last access attempt higher than expected code." + if (lastattempt != null) + var/list/guess = list() + var/bulls = 0 + var/cows = 0 + for(var/i = 1, i < codelen + 1, i++) + var/a = copytext(lastattempt, i, i+1) // Stuff the code into the list + guess += a + guess[a] = i + for(var/i in guess) // Go through list and count matches + var/a = findtext(code, i) + if(a == guess[i]) + ++bulls + else if(a) + ++cows + user << "Last code attempt had [bulls] correct digits at correct positions and [cows] correct digits at incorrect positions." else ..() else ..() diff --git a/code/modules/mining/drilling/distribution.dm b/code/modules/mining/drilling/distribution.dm deleted file mode 100644 index 33654da273..0000000000 --- a/code/modules/mining/drilling/distribution.dm +++ /dev/null @@ -1,233 +0,0 @@ -//If anyone can think of a less shitty way to work out x,y points on a linear string of integers please tell me. -#define MAP_CELL ((y-1)*real_size)+x -#define MAP_CENTRE (((y-1)+size/2)*real_size)+(x+size/2) -#define MAP_TOP_LEFT ((y-1)*real_size)+x -#define MAP_TOP_RIGHT ((y-1)*real_size)+(x+size) -#define MAP_BOTTOM_LEFT (((y+size)-1)*real_size)+x -#define MAP_BOTTOM_RIGHT ((((y+size)-1)*real_size)+(x+size)) -#define MAP_MID_TOP MAP_TOP_LEFT + (size/2) -#define MAP_MID_BOTTOM MAP_BOTTOM_LEFT + (size/2) -#define MAP_MID_LEFT (((y-1)+size/2)*real_size)+x -#define MAP_MID_RIGHT (((y-1)+size/2)*real_size)+(x+size) - -#define MIN_SURFACE_COUNT 1000 -#define MAX_SURFACE_COUNT 5000 -#define MIN_RARE_COUNT 1000 -#define MAX_RARE_COUNT 5000 -#define MIN_DEEP_COUNT 100 -#define MAX_DEEP_COUNT 300 -#define ITERATE_BEFORE_FAIL 200 - -#define RESOURCE_HIGH_MAX 4 -#define RESOURCE_HIGH_MIN 2 -#define RESOURCE_MID_MAX 3 -#define RESOURCE_MID_MIN 1 -#define RESOURCE_LOW_MAX 1 -#define RESOURCE_LOW_MIN 0 - -/* -Surface minerals: - silicates - iron - gold - silver - -Rare minerals: - uranium - diamond - -Deep minerals: - phoron - osmium (platinum) - tritium (hydrogen) -*/ - -/datum/ore_distribution - - var/real_size = 65 //Overall map size ((must be power of 2)+1) - var/chunk_size = 4 //Size each cell represents on map (like hell we're generating up to 100 256^2 grids at roundstart) - var/list/map[4225] //The actual map. real_size squared. - var/range = 255 //Max random range of cells in map. - - var/random_variance_chance = 25 - var/random_element = 0.5 - -/datum/ore_distribution/proc/map_is_sane() - if(!map) return 0 - - var/rare_count = 0 - var/surface_count = 0 - var/deep_count = 0 - - for(var/cell in map) - if(cell>(range*0.60)) - deep_count++ - else if(cell>(range*0.40)) - rare_count++ - else - surface_count++ - - if(surface_count < MIN_SURFACE_COUNT || surface_count > MAX_SURFACE_COUNT) return 0 - if(rare_count < MIN_RARE_COUNT || rare_count > MAX_RARE_COUNT) return 0 - if(deep_count < MIN_DEEP_COUNT || deep_count > MAX_DEEP_COUNT) return 0 - return 1 - -//Halfassed diamond-square algorithm with some fuckery since it's a single dimension array. -/datum/ore_distribution/proc/populate_distribution_map() - - //Seed beginning values. - var/x = 1 - var/y = 1 - var/size = real_size-1 - map[MAP_TOP_LEFT] = (range/3)+rand(range/5) - map[MAP_TOP_RIGHT] = (range/3)+rand(range/5) - map[MAP_BOTTOM_LEFT] = (range/3)+rand(range/5) - map[MAP_BOTTOM_RIGHT] = (range/3)+rand(range/5) - - //Fill in and smooth it out. - var/attempts = 0 - do - attempts++ - generate_distribution_map(1,1,size) - while(attempts < ITERATE_BEFORE_FAIL && !map_is_sane()) - - if(attempts >= ITERATE_BEFORE_FAIL) - world << "Could not generate a sane distribution map. Aborting." - map = null - return - else - apply_to_asteroid() - -/datum/ore_distribution/proc/clear_distribution_map() - for(var/x = 1, x <= real_size, x++) - for(var/y = 1, y <= real_size, y++) - map[MAP_CELL] = 0 - -/datum/ore_distribution/proc/print_distribution_map(var/mob/usr) - var/line = "" - for(var/x = 1, x <= real_size, x++) - for(var/y = 1, y <= real_size, y++) - line += num2text(round(map[MAP_CELL]/25.5)) - if(usr) - usr << line - else - world << line - line = "" - -/datum/ore_distribution/proc/generate_distribution_map(var/x,var/y,var/input_size) - - var/size = input_size - - map[MAP_MID_TOP] = (map[MAP_TOP_LEFT] + map[MAP_TOP_RIGHT])/2 - map[MAP_MID_RIGHT] = (map[MAP_BOTTOM_RIGHT] + map[MAP_TOP_RIGHT])/2 - map[MAP_MID_BOTTOM] = (map[MAP_BOTTOM_LEFT] + map[MAP_BOTTOM_RIGHT])/2 - map[MAP_MID_LEFT] = (map[MAP_TOP_LEFT] + map[MAP_BOTTOM_RIGHT])/2 - map[MAP_CENTRE] = (map[MAP_MID_LEFT]+map[MAP_MID_RIGHT]+map[MAP_MID_BOTTOM]+map[MAP_MID_TOP])/4 - - if(prob(random_variance_chance)) - map[MAP_CENTRE] *= (rand(1) ? (1.0-random_element) : (1.0+random_element)) - map[MAP_CENTRE] = max(0,min(range,map[MAP_CENTRE])) - - if(size>3) - generate_distribution_map(x,y,input_size/2) - generate_distribution_map(x+(input_size/2),y,input_size/2) - generate_distribution_map(x,y+(input_size/2),input_size/2) - generate_distribution_map(x+(input_size/2),y+(input_size/2),input_size/2) - -/datum/ore_distribution/proc/apply_to_asteroid() - - // THESE VALUES DETERMINE THE AREA THAT THE DISTRIBUTION MAP IS APPLIED TO. - // IF YOU DO NOT RUN OFFICIAL BAYCODE ASTEROID MAP YOU NEED TO CHANGE THEM. - // ORIGIN IS THE BOTTOM LEFT CORNER OF THE SQUARE CONTAINING ALL ASTEROID - // TILES YOU WISH TO APPLY THE DISTRIBUTION MAP TO. - - var/origin_x = 13 //We start here... - var/origin_y = 32 //...and here... - var/limit_x = 217 //...and iterate until here... - var/limit_y = 223 //...and here... - var/asteroid_z = 5 //...on this Z-level. - - var/tx = origin_x - var/ty = origin_y - - for(var/y = 1, y <= real_size, y++) - - for(var/x = 1, x <= real_size, x++) - - var/turf/target_turf - - for(var/i=0,i limit_x || ty+i > limit_y) - continue - - target_turf = locate(tx+j, ty+i, asteroid_z) - - if(target_turf && target_turf.has_resources) - target_turf.resources = list() - target_turf.resources["silicates"] = rand(3,5) - target_turf.resources["carbonaceous rock"] = rand(3,5) - - switch(map[MAP_CELL]) - if(0 to 100) - target_turf.resources["iron"] = rand(RESOURCE_HIGH_MIN,RESOURCE_HIGH_MAX) - target_turf.resources["gold"] = rand(RESOURCE_LOW_MIN,RESOURCE_LOW_MAX) - target_turf.resources["silver"] = rand(RESOURCE_LOW_MIN,RESOURCE_LOW_MAX) - target_turf.resources["uranium"] = rand(RESOURCE_LOW_MIN,RESOURCE_LOW_MAX) - target_turf.resources["diamond"] = 0 - target_turf.resources["phoron"] = 0 - target_turf.resources["osmium"] = 0 - target_turf.resources["hydrogen"] = 0 - if(100 to 124) - target_turf.resources["iron"] = 0 - target_turf.resources["gold"] = rand(RESOURCE_MID_MIN,RESOURCE_MID_MAX) - target_turf.resources["silver"] = rand(RESOURCE_MID_MIN,RESOURCE_MID_MAX) - target_turf.resources["uranium"] = rand(RESOURCE_MID_MIN,RESOURCE_MID_MAX) - target_turf.resources["diamond"] = 0 - target_turf.resources["phoron"] = rand(RESOURCE_MID_MIN,RESOURCE_MID_MAX) - target_turf.resources["osmium"] = rand(RESOURCE_MID_MIN,RESOURCE_MID_MAX) - target_turf.resources["hydrogen"] = 0 - if(125 to 255) - target_turf.resources["iron"] = 0 - target_turf.resources["gold"] = 0 - target_turf.resources["silver"] = 0 - target_turf.resources["uranium"] = rand(RESOURCE_LOW_MIN,RESOURCE_LOW_MAX) - target_turf.resources["diamond"] = rand(RESOURCE_LOW_MIN,RESOURCE_LOW_MAX) - target_turf.resources["phoron"] = rand(RESOURCE_HIGH_MIN,RESOURCE_HIGH_MAX) - target_turf.resources["osmium"] = rand(RESOURCE_HIGH_MIN,RESOURCE_HIGH_MAX) - target_turf.resources["hydrogen"] = rand(RESOURCE_MID_MIN,RESOURCE_MID_MAX) - - tx += chunk_size - tx = origin_x - ty += chunk_size - - world << "Resource map generation complete." - return - -#undef MAP_CELL -#undef MAP_CENTRE -#undef MAP_TOP_LEFT -#undef MAP_TOP_RIGHT -#undef MAP_BOTTOM_LEFT -#undef MAP_BOTTOM_RIGHT -#undef MAP_MID_TOP -#undef MAP_MID_BOTTOM -#undef MAP_MID_LEFT -#undef MAP_MID_RIGHT - -#undef MIN_SURFACE_COUNT -#undef MAX_SURFACE_COUNT -#undef MIN_RARE_COUNT -#undef MAX_RARE_COUNT -#undef MIN_DEEP_COUNT -#undef MAX_DEEP_COUNT -#undef ITERATE_BEFORE_FAIL - -#undef RESOURCE_HIGH_MAX -#undef RESOURCE_HIGH_MIN -#undef RESOURCE_MID_MAX -#undef RESOURCE_MID_MIN -#undef RESOURCE_LOW_MAX -#undef RESOURCE_LOW_MIN diff --git a/code/modules/mining/drilling/drill.dm b/code/modules/mining/drilling/drill.dm index 7f9d331aac..5d25adb78d 100644 --- a/code/modules/mining/drilling/drill.dm +++ b/code/modules/mining/drilling/drill.dm @@ -14,7 +14,6 @@ var/supported = 0 var/active = 0 var/list/resource_field = list() - var/open = 0 var/ore_types = list( "iron" = /obj/item/weapon/ore/iron, @@ -30,10 +29,10 @@ ) //Upgrades - var/obj/item/weapon/stock_parts/matter_bin/storage - var/obj/item/weapon/stock_parts/micro_laser/cutter - var/obj/item/weapon/stock_parts/capacitor/cellmount - var/obj/item/weapon/cell/cell + var/harvest_speed + var/capacity + var/charge_use + var/obj/item/weapon/cell/cell = null //Flags var/need_update_field = 0 @@ -43,13 +42,14 @@ ..() - storage = new(src) - cutter = new(src) - cellmount = new(src) + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/miningdrill(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/capacitor(src) + component_parts += new /obj/item/weapon/stock_parts/micro_laser(src) + component_parts += new /obj/item/weapon/cell/high(src) - cell = new(src) - cell.maxcharge = 10000 - cell.charge = cell.maxcharge + RefreshParts() /obj/machinery/mining/drill/process() @@ -74,11 +74,11 @@ return //Drill through the flooring, if any. - if(istype(get_turf(src),/turf/simulated/floor/plating/airless/asteroid)) + if(istype(get_turf(src), /turf/simulated/floor/plating/airless/asteroid)) var/turf/simulated/floor/plating/airless/asteroid/T = get_turf(src) if(!T.dug) T.gets_dug() - else if(istype(get_turf(src),/turf/simulated/floor)) + else if(istype(get_turf(src), /turf/simulated/floor)) var/turf/simulated/floor/T = get_turf(src) T.ex_act(2.0) @@ -94,20 +94,20 @@ if(!harvesting) return - var/total_harvest = get_harvest_capacity() //Ore harvest-per-tick. + var/total_harvest = harvest_speed //Ore harvest-per-tick. var/found_resource = 0 //If this doesn't get set, the area is depleted and the drill errors out. for(var/metal in ore_types) - if(contents.len >= get_storage_capacity()) + if(contents.len >= capacity) system_error("insufficient storage space") active = 0 need_player_check = 1 update_icon() return - if(contents.len + total_harvest >= get_storage_capacity()) - total_harvest = get_storage_capacity() - contents.len + if(contents.len + total_harvest >= capacity) + total_harvest = capacity - contents.len if(total_harvest <= 0) break if(harvesting.resources[metal]) @@ -124,7 +124,7 @@ create_ore = harvesting.resources[metal] harvesting.resources[metal] = 0 - for(var/i=1,i<=create_ore,i++) + for(var/i=1, i <= create_ore, i++) var/oretype = ore_types[metal] new oretype(src) @@ -140,93 +140,56 @@ /obj/machinery/mining/drill/attack_ai(var/mob/user as mob) return src.attack_hand(user) -/obj/machinery/mining/drill/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W,/obj/item/weapon/screwdriver)) - if(active) return - open = !open - user << "\blue You [open ? "open" : "close"] the maintenance panel." //TODO: Sprite. +/obj/machinery/mining/drill/attackby(obj/item/O as obj, mob/user as mob) + if(!active) + if(default_deconstruction_screwdriver(user, O)) + return + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) + return + if(!panel_open || active) return ..() + + if(istype(O, /obj/item/weapon/cell)) + if(cell) + user << "The drill already has a cell installed." + else + user.drop_item() + O.loc = src + cell = O + component_parts += O + user << "You install \the [O]." return - else - if(!open || active) return ..() - if(istype(W,/obj/item/weapon/crowbar)) - if(cell) - user << "You pry out \the [cell]." - cell.loc = get_turf(src) - cell = null - else if(storage) - user << "You slip the bolt and pry out \the [storage]." - storage.loc = get_turf(src) - storage = null - else if(cutter) - user << "You carefully detatch and pry out \the [cutter]." - cutter.loc = get_turf(src) - cutter = null - else if(cellmount) - user << "You yank out a few wires and pry out \the [cellmount]." - cellmount.loc = get_turf(src) - cellmount = null - else - user << "There's nothing inside the drilling rig to remove." - return - else if(istype(W,/obj/item/weapon/stock_parts/matter_bin)) - if(storage) - user << "The drill already has a matter bin installed." - else - user.drop_item() - W.loc = src - storage = W - user << "You install \the [W]." - return - else if(istype(W,/obj/item/weapon/stock_parts/micro_laser)) - if(cutter) - user << "The drill already has a cutting head installed." - else - user.drop_item() - W.loc = src - cutter = W - user << "You install \the [W]." - return - else if(istype(W,/obj/item/weapon/stock_parts/capacitor)) - if(cellmount) - user << "The drill already has a cell capacitor installed." - else - user.drop_item() - W.loc = src - cellmount = W - user << "You install \the [W]." - return - else if(istype(W,/obj/item/weapon/cell)) - if(cell) - user << "The drill already has a cell installed." - else - user.drop_item() - W.loc = src - cell = W - user << "You install \the [W]." - return ..() + /obj/machinery/mining/drill/attack_hand(mob/user as mob) check_supports() - if(need_player_check) + if (panel_open && cell) + user << "You take out \the [cell]." + cell.loc = get_turf(user) + component_parts -= cell + cell = null + return + else if(need_player_check) user << "You hit the manual override and reset the drill's error checking." need_player_check = 0 - if(anchored) get_resource_field() + if(anchored) + get_resource_field() update_icon() return - - else if(supported) + else if(supported && !panel_open) if(use_cell_power()) active = !active if(active) - user << "\blue You engage \the [src] and it lurches downwards, grinding noisily." + visible_message("\The [src] lurches downwards, grinding noisily.") need_update_field = 1 else - user << "\blue You disengage \the [src] and it shudders to a grinding halt." + visible_message("\The [src] shudders to a grinding halt.") else - user << "\blue The drill is unpowered." + user << "The drill is unpowered." else - user << "\blue Turning on a piece of industrial machinery without sufficient bracing is a bad idea." + user << "Turning on a piece of industrial machinery without sufficient bracing or wires exposed is a bad idea." update_icon() @@ -241,6 +204,21 @@ icon_state = "mining_drill" return +/obj/machinery/mining/drill/RefreshParts() + ..() + harvest_speed = 0 + capacity = 0 + charge_use = 50 + + for(var/obj/item/weapon/stock_parts/P in component_parts) + if(istype(P, /obj/item/weapon/stock_parts/micro_laser)) + harvest_speed = P.rating + if(istype(P, /obj/item/weapon/stock_parts/matter_bin)) + capacity = 200 * P.rating + if(istype(P, /obj/item/weapon/stock_parts/capacitor)) + charge_use -= 10 * P.rating + cell = locate(/obj/item/weapon/cell) in component_parts + /obj/machinery/mining/drill/proc/check_supports() supported = 0 @@ -259,20 +237,12 @@ /obj/machinery/mining/drill/proc/system_error(var/error) - if(error) src.visible_message("\red \The [src] flashes a '[error]' warning.") + if(error) + src.visible_message("\The [src] flashes a '[error]' warning.") need_player_check = 1 active = 0 update_icon() -/obj/machinery/mining/drill/proc/get_harvest_capacity() - return (cutter ? cutter.rating : 0) - -/obj/machinery/mining/drill/proc/get_storage_capacity() - return 200 * (storage ? storage.rating : 0) - -/obj/machinery/mining/drill/proc/get_charge_use() - return 50 - (10 * (cellmount ? cellmount.rating : 0)) - /obj/machinery/mining/drill/proc/get_resource_field() resource_field = list() @@ -281,13 +251,13 @@ var/turf/T = get_turf(src) if(!istype(T)) return - var/tx = T.x-2 - var/ty = T.y-2 + var/tx = T.x - 2 + var/ty = T.y - 2 var/turf/mine_turf - for(var/iy=0,iy<5,iy++) - for(var/ix=0,ix<5,ix++) - mine_turf = locate(tx+ix,ty+iy,T.z) - if(mine_turf && istype(mine_turf) && mine_turf.has_resources) + for(var/iy = 0,iy < 5, iy++) + for(var/ix = 0, ix < 5, ix++) + mine_turf = locate(tx + ix, ty + iy, T.z) + if(mine_turf && mine_turf.has_resources) resource_field += mine_turf if(!resource_field.len) @@ -295,9 +265,8 @@ /obj/machinery/mining/drill/proc/use_cell_power() if(!cell) return 0 - var/req = get_charge_use() - if(cell.charge >= req) - cell.use(req) + if(cell.charge >= charge_use) + cell.use(charge_use) return 1 return 0 @@ -312,9 +281,9 @@ if(B) for(var/obj/item/weapon/ore/O in contents) O.loc = B - usr << "\red You unload the drill's storage cache into the ore box." + usr << "You unload the drill's storage cache into the ore box." else - usr << "\red You must move an ore box up to the drill before you can unload it." + usr << "You must move an ore box up to the drill before you can unload it." /obj/machinery/mining/brace @@ -326,16 +295,16 @@ /obj/machinery/mining/brace/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W,/obj/item/weapon/wrench)) - if(istype(get_turf(src),/turf/space)) - user << "\blue You can't anchor something to empty space. Idiot." + if(istype(get_turf(src), /turf/space)) + user << "You can't anchor something to empty space. Idiot." return if(connected && connected.active) - user << "\blue You can't unanchor the brace of a running drill!" + user << "You can't unanchor the brace of a running drill!" return playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) - user << "\blue You [anchored ? "un" : ""]anchor the brace." + user << "You [anchored ? "un" : ""]anchor the brace." anchored = !anchored if(anchored) @@ -347,18 +316,16 @@ var/turf/T = get_step(get_turf(src), src.dir) - if(!T.has_resources) - src.visible_message("\red The terrain near the brace is unsuitable!") - return - for(var/thing in T.contents) - if(istype(thing,/obj/machinery/mining/drill)) + if(istype(thing, /obj/machinery/mining/drill)) connected = thing break - if(!connected) return + if(!connected) + return - if(!connected.supports) connected.supports = list() + if(!connected.supports) + connected.supports = list() icon_state = "mining_brace_active" diff --git a/code/modules/mining/drilling/scanner.dm b/code/modules/mining/drilling/scanner.dm index a770aa791d..510172d795 100644 --- a/code/modules/mining/drilling/scanner.dm +++ b/code/modules/mining/drilling/scanner.dm @@ -5,16 +5,13 @@ icon_state = "forensic0-old" //GET A BETTER SPRITE. item_state = "electronic" matter = list("metal" = 150) - origin_tech = "magnets=1;engineering=1" /obj/item/weapon/mining_scanner/attack_self(mob/user as mob) - user << "You begin sweeping \the [src] about, scanning for metal deposits." - if(!do_after(user,50)) return - - if(!user || !src) return + if(!do_after(user, 50)) + return var/list/metals = list( "surface minerals" = 0, @@ -23,32 +20,30 @@ "exotic matter" = 0 ) - for(var/turf/T in range(3,get_turf(user))) + for(var/turf/T in range(2, get_turf(user))) if(!T.has_resources) continue for(var/metal in T.resources) - var/ore_type switch(metal) - if("silicates" || "carbonaceous rock" || "iron") ore_type = "surface minerals" - if("gold" || "silver" || "diamond") ore_type = "precious metals" - if("uranium") ore_type = "nuclear fuel" - if("phoron" || "osmium" || "hydrogen") ore_type = "exotic matter" + if("silicates", "carbonaceous rock", "iron") ore_type = "surface minerals" + if("gold", "silver", "diamond") ore_type = "precious metals" + if("uranium") ore_type = "nuclear fuel" + if("phoron", "osmium", "hydrogen") ore_type = "exotic matter" if(ore_type) metals[ore_type] += T.resources[metal] - user << "\icon[src] \blue The scanner beeps and displays a readout." + user << "\icon[src] The scanner beeps and displays a readout." for(var/ore_type in metals) - var/result = "no sign" switch(metals[ore_type]) - if(1 to 50) result = "trace amounts" - if(51 to 150) result = "significant amounts" - if(151 to INFINITY) result = "huge quantities" + if(1 to 25) result = "trace amounts" + if(26 to 75) result = "significant amounts" + if(76 to INFINITY) result = "huge quantities" user << "- [result] of [ore_type]." \ No newline at end of file diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 2a029b42ee..ee043b1441 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -67,7 +67,7 @@ /obj/machinery/mineral/processing_unit_console/Topic(href, href_list) if(..()) - return + return 1 usr.set_machine(src) src.add_fingerprint(usr) diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm index b974a57aaf..9dc23503ec 100644 --- a/code/modules/mining/machine_stacking.dm +++ b/code/modules/mining/machine_stacking.dm @@ -43,7 +43,7 @@ /obj/machinery/mineral/stacking_unit_console/Topic(href, href_list) if(..()) - return + return 1 if(href_list["change_stack"]) var/choice = input("What would you like to set the stack amount to?") as null|anything in list(1,5,10,20,50) diff --git a/code/modules/mining/mine_areas.dm b/code/modules/mining/mine_areas.dm deleted file mode 100644 index c1fa4f3ddb..0000000000 --- a/code/modules/mining/mine_areas.dm +++ /dev/null @@ -1,54 +0,0 @@ -/**********************Mine areas**************************/ - -/area/mine - icon_state = "mining" - music = 'sound/ambience/song_game.ogg' - -/area/mine/explored - name = "Mine" - icon_state = "explored" - ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg') - -/area/mine/unexplored - name = "Mine" - icon_state = "unexplored" - ambience = list('sound/ambience/ambimine.ogg', 'sound/ambience/song_game.ogg') - -/area/mine/lobby - name = "Mining station" - -/area/mine/storage - name = "Mining station Storage" - -/area/mine/production - name = "Mining Station Starboard Wing" - icon_state = "mining_production" - -/area/mine/abandoned - name = "Abandoned Mining Station" - -/area/mine/living_quarters - name = "Mining Station Port Wing" - icon_state = "mining_living" - -/area/mine/eva - name = "Mining Station EVA" - icon_state = "mining_eva" - -/area/mine/maintenance - name = "Mining Station Communications" - -/area/mine/cafeteria - name = "Mining station Cafeteria" - -/area/mine/hydroponics - name = "Mining station Hydroponics" - -/area/mine/sleeper - name = "Mining station Emergency Sleeper" - -/area/mine/north_outpost - name = "North Mining Outpost" - -/area/mine/west_outpost - name = "West Mining Outpost" \ No newline at end of file diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index be76b4c126..a3b601ebce 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -49,21 +49,22 @@ /*****************************Pickaxe********************************/ /obj/item/weapon/pickaxe - name = "pickaxe" + name = "mining drill" + desc = "The most basic of mining drills, for short excavations and small mineral extractions." icon = 'icons/obj/items.dmi' - icon_state = "pickaxe" flags = CONDUCT slot_flags = SLOT_BELT force = 15.0 throwforce = 4.0 - item_state = "pickaxe" + icon_state = "pickaxe" + item_state = "jackhammer" w_class = 4.0 matter = list("metal" = 3750) var/digspeed = 40 //moving the delay to an item var so R&D can make improved picks. --NEO origin_tech = "materials=1;engineering=1" - attack_verb = list("hit", "pierced", "sliced", "attacked") + attack_verb = list("hit", "pierced", "sliced", "attacked", "drilled") var/drill_sound = 'sound/weapons/Genhit.ogg' - var/drill_verb = "picking" + var/drill_verb = "drilling" sharp = 1 var/excavation_amount = 100 @@ -82,7 +83,7 @@ desc = "This makes no metallurgic sense." /obj/item/weapon/pickaxe/drill - name = "mining drill" // Can dig sand as well! + name = "advanced mining drill" // Can dig sand as well! icon_state = "handdrill" item_state = "jackhammer" digspeed = 30 diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index 095fe8045f..c56bcde642 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -29,7 +29,8 @@ /turf/simulated/mineral/New() - MineralSpread() + spawn(0) + MineralSpread() spawn(2) var/list/step_overlays = list("s" = NORTH, "n" = SOUTH, "w" = EAST, "e" = WEST) @@ -86,7 +87,7 @@ if(mineral && mineral.spread) for(var/trydir in cardinal) if(prob(mineral.spread_chance)) - var/turf/simulated/mineral/random/target_turf = get_step(src, trydir) + var/turf/simulated/mineral/target_turf = get_step(src, trydir) if(istype(target_turf) && !target_turf.mineral) target_turf.mineral = mineral target_turf.UpdateMineral() @@ -363,7 +364,7 @@ /turf/simulated/mineral/random name = "Mineral deposit" var/mineralSpawnChanceList = list("Uranium" = 5, "Platinum" = 5, "Iron" = 35, "Coal" = 35, "Diamond" = 1, "Gold" = 5, "Silver" = 5, "Phoron" = 10) - var/mineralChance = 10 //means 10% chance of this plot changing to a mineral deposit + var/mineralChance = 100 //10 //means 10% chance of this plot changing to a mineral deposit /turf/simulated/mineral/random/New() if (prob(mineralChance) && !mineral) @@ -379,7 +380,7 @@ . = ..() /turf/simulated/mineral/random/high_chance - mineralChance = 25 + mineralChance = 100 //25 mineralSpawnChanceList = list("Uranium" = 10, "Platinum" = 10, "Iron" = 20, "Coal" = 20, "Diamond" = 2, "Gold" = 10, "Silver" = 10, "Phoron" = 20) diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm index 59857424e6..bcf46bb292 100644 --- a/code/modules/mining/mint.dm +++ b/code/modules/mining/mint.dm @@ -116,7 +116,7 @@ /obj/machinery/mineral/mint/Topic(href, href_list) if(..()) - return + return 1 usr.set_machine(src) src.add_fingerprint(usr) if(processing==1) diff --git a/code/modules/mining/money_bag.dm b/code/modules/mining/money_bag.dm index d49ccc222f..7409859af2 100644 --- a/code/modules/mining/money_bag.dm +++ b/code/modules/mining/money_bag.dm @@ -62,7 +62,7 @@ /obj/item/weapon/moneybag/Topic(href, href_list) if(..()) - return + return 1 usr.set_machine(src) src.add_fingerprint(usr) if(href_list["remove"]) diff --git a/code/modules/mining/ore.dm b/code/modules/mining/ore.dm index a637c45626..30385d49a5 100644 --- a/code/modules/mining/ore.dm +++ b/code/modules/mining/ore.dm @@ -2,6 +2,7 @@ name = "rock" icon = 'icons/obj/mining.dmi' icon_state = "ore2" + w_class = 2 var/datum/geosample/geologic_data var/oretag diff --git a/code/modules/mob/dead/observer/login.dm b/code/modules/mob/dead/observer/login.dm index ce0dbe3d57..bf9b607a38 100644 --- a/code/modules/mob/dead/observer/login.dm +++ b/code/modules/mob/dead/observer/login.dm @@ -1,2 +1,5 @@ /mob/dead/observer/Login() - ..() \ No newline at end of file + ..() + if (ghostimage) + ghostimage.icon_state = src.icon_state + updateghostimages() diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 825754c0d4..7b5f740135 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -1,3 +1,6 @@ +var/global/list/image/ghost_darkness_images = list() //this is a list of images for things ghosts should still be able to see when they toggle darkness +var/global/list/image/ghost_sightless_images = list() //this is a list of images for things ghosts should still be able to see even without ghost sight + /mob/dead/observer name = "ghost" desc = "It's a g-g-g-g-ghooooost!" //jinkies! @@ -23,6 +26,9 @@ var/atom/movable/following = null var/admin_ghosted = 0 var/anonsay = 0 + var/image/ghostimage = null //this mobs ghost image, for deleting and stuff + var/ghostvision = 1 //is the ghost able to see things humans can't? + var/seedarkness = 1 /mob/dead/observer/New(mob/body) sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF @@ -32,6 +38,10 @@ stat = DEAD + ghostimage = image(src.icon,src,src.icon_state) + ghost_darkness_images |= ghostimage + updateallghostimages() + var/turf/T if(ismob(body)) T = get_turf(body) //Where is the body located? @@ -70,7 +80,13 @@ real_name = name ..() - +/mob/dead/observer/Del() + if (ghostimage) + ghost_darkness_images -= ghostimage + del(ghostimage) + ghostimage = null + updateallghostimages() + ..() /mob/dead/observer/Topic(href, href_list) if (href_list["track"]) @@ -213,8 +229,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp //world << "DEBUG: ticker not null" if(ticker.mode.name == "AI malfunction") //world << "DEBUG: malf mode ticker test" - if(ticker.mode:malf_mode_declared) - stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]") + if(malf.revealed) + stat(null, "Time left: [max(malf.hack_time/(malf.hacked_apcs.len/3), 0)]") if(emergency_shuttle) var/eta_status = emergency_shuttle.get_status_panel_eta() if(eta_status) @@ -403,16 +419,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp src << "\blue Temperature: [round(environment.temperature-T0C,0.1)]°C ([round(environment.temperature,0.1)]K)" src << "\blue Heat Capacity: [round(environment.heat_capacity(),0.1)]" - -/mob/dead/observer/verb/toggle_darkness() - set name = "Toggle Darkness" - set category = "Ghost" - - if (see_invisible == SEE_INVISIBLE_OBSERVER_NOLIGHTING) - see_invisible = SEE_INVISIBLE_OBSERVER - else - see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING - /mob/dead/observer/verb/become_mouse() set name = "Become mouse" set category = "Ghost" @@ -486,8 +492,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/ghosts_can_write if(ticker.mode.name == "cult") - var/datum/game_mode/cult/C = ticker.mode - if(C.cult.len > config.cult_ghostwriter_req_cultists) + if(cult.current_antagonists.len > config.cult_ghostwriter_req_cultists) ghosts_can_write = 1 if(!ghosts_can_write) @@ -528,7 +533,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/max_length = 50 - var/message = stripped_input(src,"Write a message. It cannot be longer than [max_length] characters.","Blood writing", "") + var/message = sanitize(input("Write a message. It cannot be longer than [max_length] characters.","Blood writing", "")) if (message) @@ -614,3 +619,43 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/canface() return 1 + +/mob/dead/observer/verb/toggle_ghostsee() + set name = "Toggle Ghost Vision" + set desc = "Toggles your ability to see things only ghosts can see, like other ghosts" + set category = "Ghost" + ghostvision = !(ghostvision) + updateghostsight() + usr << "You [(ghostvision?"now":"no longer")] have ghost vision." + +/mob/dead/observer/verb/toggle_darkness() + set name = "Toggle Darkness" + set category = "Ghost" + seedarkness = !(seedarkness) + updateghostsight() + +/mob/dead/observer/proc/updateghostsight() + if (!seedarkness) + see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING + else + see_invisible = SEE_INVISIBLE_OBSERVER + if (!ghostvision) + see_invisible = SEE_INVISIBLE_LIVING; + updateghostimages() + +/proc/updateallghostimages() + for (var/mob/dead/observer/O in player_list) + O.updateghostimages() + +/mob/dead/observer/proc/updateghostimages() + if (!client) + return + if (seedarkness || !ghostvision) + client.images -= ghost_darkness_images + client.images |= ghost_sightless_images + else + //add images for the 60inv things ghosts can normally see when darkness is enabled so they can see them now + client.images -= ghost_sightless_images + client.images |= ghost_darkness_images + if (ghostimage) + client.images -= ghostimage //remove ourself diff --git a/code/modules/mob/dead/observer/say.dm b/code/modules/mob/dead/observer/say.dm index b5b819950c..be9f1615e0 100644 --- a/code/modules/mob/dead/observer/say.dm +++ b/code/modules/mob/dead/observer/say.dm @@ -1,5 +1,5 @@ /mob/dead/observer/say(var/message) - message = strip_html_properly(message) + message = sanitize(message) if (!message) return @@ -18,7 +18,7 @@ /mob/dead/observer/emote(var/act, var/type, var/message) - message = trim_strip_html_properly(message) + message = sanitize(message) if(!message) return diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm index 3d96e3d9c0..a97d616dee 100644 --- a/code/modules/mob/death.dm +++ b/code/modules/mob/death.dm @@ -52,6 +52,8 @@ if(stat == DEAD) return 0 + facing_dir = null + if(!gibbed && deathmessage != "no message") // This is gross, but reliable. Only brains use it. src.visible_message("\The [src.name] [deathmessage]") diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm index 8862479b2a..5645773ea0 100644 --- a/code/modules/mob/emote.dm +++ b/code/modules/mob/emote.dm @@ -12,7 +12,7 @@ var/input if(!message) - input = sanitize(copytext(input(src,"Choose an emote to display.") as text|null,1,MAX_MESSAGE_LEN)) + input = sanitize(input(src,"Choose an emote to display.") as text|null) else input = message if(input) @@ -108,7 +108,7 @@ var/input if(!message) - input = sanitize(copytext(input(src, "Choose an emote to display.") as text|null, 1, MAX_MESSAGE_LEN)) + input = sanitize(input(src, "Choose an emote to display.") as text|null) else input = message diff --git a/code/modules/mob/freelook/chunk.dm b/code/modules/mob/freelook/chunk.dm new file mode 100644 index 0000000000..8c6c7d043a --- /dev/null +++ b/code/modules/mob/freelook/chunk.dm @@ -0,0 +1,146 @@ +#define UPDATE_BUFFER 25 // 2.5 seconds + +// CHUNK +// +// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed. +// Allows the Eye to stream these chunks and know what it can and cannot see. + +/datum/obfuscation + var/icon = 'icons/effects/cameravis.dmi' + var/icon_state = "black" + +/datum/chunk + var/list/obscuredTurfs = list() + var/list/visibleTurfs = list() + var/list/obscured = list() + var/list/turfs = list() + var/list/seenby = list() + var/visible = 0 + var/changed = 0 + var/updating = 0 + var/x = 0 + var/y = 0 + var/z = 0 + var/datum/obfuscation/obfuscation = new() + +// Add an eye to the chunk, then update if changed. + +/datum/chunk/proc/add(mob/eye/eye) + if(!eye.owner) + return + eye.visibleChunks += src + if(eye.owner.client) + eye.owner.client.images += obscured + visible++ + seenby += eye + if(changed && !updating) + update() + +// Remove an eye from the chunk, then update if changed. + +/datum/chunk/proc/remove(mob/eye/eye) + if(!eye.owner) + return + eye.visibleChunks -= src + if(eye.owner.client) + eye.owner.client.images -= obscured + seenby -= eye + if(visible > 0) + visible-- + +// Called when a chunk has changed. I.E: A wall was deleted. + +/datum/chunk/proc/visibilityChanged(turf/loc) + if(!visibleTurfs[loc]) + return + hasChanged() + +// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will +// instead be flagged to update the next time an AI Eye moves near it. + +/datum/chunk/proc/hasChanged(var/update_now = 0) + if(visible || update_now) + if(!updating) + updating = 1 + spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once + update() + updating = 0 + else + changed = 1 + +// The actual updating. + +/datum/chunk/proc/update() + + set background = 1 + + var/list/newVisibleTurfs = new() + acquireVisibleTurfs(newVisibleTurfs) + + // Removes turf that isn't in turfs. + newVisibleTurfs &= turfs + + var/list/visAdded = newVisibleTurfs - visibleTurfs + var/list/visRemoved = visibleTurfs - newVisibleTurfs + + visibleTurfs = newVisibleTurfs + obscuredTurfs = turfs - newVisibleTurfs + + for(var/turf in visAdded) + var/turf/t = turf + if(t.obfuscations[obfuscation.type]) + obscured -= t.obfuscations[obfuscation.type] + for(var/eye in seenby) + var/mob/eye/m = eye + if(!m || !m.owner) + continue + if(m.owner.client) + m.owner.client.images -= t.obfuscations[obfuscation.type] + + for(var/turf in visRemoved) + var/turf/t = turf + if(obscuredTurfs[t]) + if(!t.obfuscations[obfuscation.type]) + t.obfuscations[obfuscation.type] = image(obfuscation.icon, t, obfuscation.icon_state, 15) + + obscured += t.obfuscations[obfuscation.type] + for(var/eye in seenby) + var/mob/eye/m = eye + if(!m || !m.owner) + seenby -= m + continue + if(m.owner.client) + m.owner.client.images += t.obfuscations[obfuscation.type] + +/datum/chunk/proc/acquireVisibleTurfs(var/list/visible) + +// Create a new camera chunk, since the chunks are made as they are needed. + +/datum/chunk/New(loc, x, y, z) + + // 0xf = 15 + x &= ~0xf + y &= ~0xf + + src.x = x + src.y = y + src.z = z + + for(var/turf/t in range(10, locate(x + 8, y + 8, z))) + if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16) + turfs[t] = t + + acquireVisibleTurfs(visibleTurfs) + + // Removes turf that isn't in turfs. + visibleTurfs &= turfs + + obscuredTurfs = turfs - visibleTurfs + + for(var/turf in obscuredTurfs) + var/turf/t = turf + if(!t.obfuscations[obfuscation.type]) + t.obfuscations[obfuscation.type] = image(obfuscation.icon, t, obfuscation.icon_state, 15) + obscured += t.obfuscations[obfuscation.type] + +#undef UPDATE_BUFFER diff --git a/code/modules/mob/freelook/eye.dm b/code/modules/mob/freelook/eye.dm new file mode 100644 index 0000000000..70ae8cb700 --- /dev/null +++ b/code/modules/mob/freelook/eye.dm @@ -0,0 +1,103 @@ +// EYE +// +// A mob that another mob controls to look around the station with. +// It streams chunks as it moves around, which will show it what the controller can and cannot see. + +/mob/eye + name = "Eye" + icon = 'icons/mob/eye.dmi' + icon_state = "default-eye" + alpha = 127 + + var/sprint = 10 + var/cooldown = 0 + var/acceleration = 1 + + see_in_dark = 7 + status_flags = GODMODE + invisibility = INVISIBILITY_EYE + + var/mob/owner = null + var/list/visibleChunks = list() + + var/ghostimage = null + var/datum/visualnet/visualnet + +/mob/eye/New() + ghostimage = image(src.icon,src,src.icon_state) + ghost_darkness_images |= ghostimage //so ghosts can see the eye when they disable darkness + ghost_sightless_images |= ghostimage //so ghosts can see the eye when they disable ghost sight + updateallghostimages() + ..() + +mob/eye/Del() + if (ghostimage) + ghost_darkness_images -= ghostimage + ghost_sightless_images -= ghostimage + del(ghostimage) + ghostimage = null; + updateallghostimages() + ..() + +// Movement code. Returns 0 to stop air movement from moving it. +/mob/eye/Move() + return 0 + +/mob/eye/examinate() + set popup_menu = 0 + set src = usr.contents + return 0 + +/mob/eye/pointed() + set popup_menu = 0 + set src = usr.contents + return 0 + +/mob/eye/examine(mob/user) + +// Use this when setting the eye's location. +// It will also stream the chunk that the new loc is in. +/mob/eye/proc/setLoc(var/T) + if(owner) + T = get_turf(T) + loc = T + + if(owner.client) + owner.client.eye = src + + visualnet.visibility(src) + return 1 + return 0 + +/mob/eye/EyeMove(n, direct) + var/initial = initial(sprint) + var/max_sprint = 50 + + if(cooldown && cooldown < world.timeofday) + sprint = initial + + for(var/i = 0; i < max(sprint, initial); i += 20) + var/turf/step = get_turf(get_step(src, direct)) + if(step) + setLoc(step) + + cooldown = world.timeofday + 5 + if(acceleration) + sprint = min(sprint + 0.5, max_sprint) + else + sprint = initial + +/mob/eye/proc/getLoc() + if(owner) + if(!isturf(owner.loc) || !owner.client) + return + return loc + +/mob + var/mob/eye/eyeobj + +/mob/proc/EyeMove(n, direct) + if(!eyeobj) + return + + return eyeobj.EyeMove(n, direct) diff --git a/code/modules/mob/freelook/update_triggers.dm b/code/modules/mob/freelook/update_triggers.dm new file mode 100644 index 0000000000..9bba162c40 --- /dev/null +++ b/code/modules/mob/freelook/update_triggers.dm @@ -0,0 +1,53 @@ +//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update. + +// TURFS + +/proc/updateVisibility(atom/A, var/opacity_check = 1) + if(ticker) + for(var/datum/visualnet/VN in visual_nets) + VN.updateVisibility(A, opacity_check) + +/turf + var/list/image/obfuscations = new() + +/turf/drain_power() + return -1 + +/turf/simulated/Del() + updateVisibility(src) + ..() + +/turf/simulated/New() + ..() + updateVisibility(src) + + +// STRUCTURES + +/obj/structure/Del() + updateVisibility(src) + ..() + +/obj/structure/New() + ..() + updateVisibility(src) + +// EFFECTS + +/obj/effect/Del() + updateVisibility(src) + ..() + +/obj/effect/New() + ..() + updateVisibility(src) + +// DOORS + +// Simply updates the visibility of the area when it opens/closes/destroyed. +/obj/machinery/door/update_nearby_tiles(need_rebuild) + . = ..(need_rebuild) + // Glass door glass = 1 + // don't check then? + if(!glass) + updateVisibility(src, 0) \ No newline at end of file diff --git a/code/modules/mob/freelook/visualnet.dm b/code/modules/mob/freelook/visualnet.dm new file mode 100644 index 0000000000..dedc23ab2d --- /dev/null +++ b/code/modules/mob/freelook/visualnet.dm @@ -0,0 +1,133 @@ +// VISUAL NET +// +// The datum containing all the chunks. + +var/global/list/visual_nets = new() + +/datum/visualnet + // The chunks of the map, mapping the areas that an object can see. + var/list/chunks = list() + var/ready = 0 + var/chunk_type = /datum/chunk + +/datum/visualnet/New() + ..() + visual_nets += src + +/datum/visualnet/Del() + visual_nets -= src + ..() + +// Checks if a chunk has been Generated in x, y, z. +/datum/visualnet/proc/chunkGenerated(x, y, z) + x &= ~0xf + y &= ~0xf + var/key = "[x],[y],[z]" + return (chunks[key]) + +// Returns the chunk in the x, y, z. +// If there is no chunk, it creates a new chunk and returns that. +/datum/visualnet/proc/getChunk(x, y, z) + x &= ~0xf + y &= ~0xf + var/key = "[x],[y],[z]" + if(!chunks[key]) + chunks[key] = new chunk_type(null, x, y, z) + + return chunks[key] + +// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set. + +/datum/visualnet/proc/visibility(mob/eye/eye) + // 0xf = 15 + var/x1 = max(0, eye.x - 16) & ~0xf + var/y1 = max(0, eye.y - 16) & ~0xf + var/x2 = min(world.maxx, eye.x + 16) & ~0xf + var/y2 = min(world.maxy, eye.y + 16) & ~0xf + + var/list/visibleChunks = list() + + for(var/x = x1; x <= x2; x += 16) + for(var/y = y1; y <= y2; y += 16) + visibleChunks += getChunk(x, y, eye.z) + + var/list/remove = eye.visibleChunks - visibleChunks + var/list/add = visibleChunks - eye.visibleChunks + + for(var/chunk in remove) + var/datum/chunk/c = chunk + c.remove(eye) + + for(var/chunk in add) + var/datum/chunk/c = chunk + c.add(eye) + +// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. + +/datum/visualnet/proc/updateVisibility(atom/A, var/opacity_check = 1) + + if(!ticker || (opacity_check && !A.opacity)) + return + majorChunkChange(A, 2) + +/datum/visualnet/proc/updateChunk(x, y, z) + // 0xf = 15 + if(!chunkGenerated(x, y, z)) + return + var/datum/chunk/chunk = getChunk(x, y, z) + chunk.hasChanged() + +// Never access this proc directly!!!! +// This will update the chunk and all the surrounding chunks. +// It will also add the atom to the cameras list if you set the choice to 1. +// Setting the choice to 0 will remove the camera from the chunks. +// If you want to update the chunks around an object, without adding/removing a camera, use choice 2. + +/datum/visualnet/proc/majorChunkChange(atom/c, var/choice) + // 0xf = 15 + if(!c) + return + + var/turf/T = get_turf(c) + if(T) + var/x1 = max(0, T.x - 8) & ~0xf + var/y1 = max(0, T.y - 8) & ~0xf + var/x2 = min(world.maxx, T.x + 8) & ~0xf + var/y2 = min(world.maxy, T.y + 8) & ~0xf + + //world << "X1: [x1] - Y1: [y1] - X2: [x2] - Y2: [y2]" + + for(var/x = x1; x <= x2; x += 16) + for(var/y = y1; y <= y2; y += 16) + if(chunkGenerated(x, y, T.z)) + var/datum/chunk/chunk = getChunk(x, y, T.z) + onMajorChunkChange(c, choice, chunk) + chunk.hasChanged() + +/datum/visualnet/proc/onMajorChunkChange(atom/c, var/choice, var/datum/chunk/chunk) + +// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0. + +/datum/visualnet/proc/checkVis(mob/living/target as mob) + // 0xf = 15 + var/turf/position = get_turf(target) + return checkTurfVis(position) + +/datum/visualnet/proc/checkTurfVis(var/turf/position) + var/datum/chunk/chunk = getChunk(position.x, position.y, position.z) + if(chunk) + if(chunk.changed) + chunk.hasChanged(1) // Update now, no matter if it's visible or not. + if(chunk.visibleTurfs[position]) + return 1 + return 0 + +// Debug verb for VVing the chunk that the turf is in. +/* +/turf/verb/view_chunk() + set src in world + + if(cameranet.chunkGenerated(x, y, z)) + var/datum/chunk/chunk = cameranet.getCameraChunk(x, y, z) + usr.client.debug_variables(chunk) +*/ diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index f63566a048..e5e91c4bdc 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -67,13 +67,19 @@ src << "[speaker_name][alt_name] talks but you cannot hear \him." else if(language) - src << "[speaker_name][alt_name] [track][language.format_message(message, verb)]" + on_hear_say("[speaker_name][alt_name] [track][language.format_message(message, verb)]") else - src << "[speaker_name][alt_name] [track][verb], \"[message]\"" + on_hear_say("[speaker_name][alt_name] [track][verb], \"[message]\"") if (speech_sound && (get_dist(speaker, src) <= world.view && src.z == speaker.z)) var/turf/source = speaker? get_turf(speaker) : get_turf(src) src.playsound_local(source, speech_sound, sound_vol, 1) +/mob/proc/on_hear_say(var/message) + src << message + +/mob/living/silicon/on_hear_say(var/message) + var/time = say_timestamp() + src << "[time] [message]" /mob/proc/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="") @@ -125,17 +131,26 @@ if(istype(src, /mob/living/silicon/ai) && !hard_to_hear) var/jobname // the mob's "job" - var/mob/living/carbon/human/impersonating //The crewmember being impersonated, if any. + var/mob/living/carbon/human/impersonating //The crew member being impersonated, if any. if (ishuman(speaker)) var/mob/living/carbon/human/H = speaker - if((H.wear_id && istype(H.wear_id,/obj/item/weapon/card/id/syndicate)) && (H.wear_mask && istype(H.wear_mask,/obj/item/clothing/mask/gas/voice))) - + if(H.wear_mask && istype(H.wear_mask,/obj/item/clothing/mask/gas/voice)) changed_voice = 1 - var/mob/living/carbon/human/I = locate(speaker_name) + var/list/impersonated = new() + var/mob/living/carbon/human/I = impersonated[speaker_name] - if(I) + if(!I) + for(var/mob/living/carbon/human/M in mob_list) + if(M.real_name == speaker_name) + I = M + impersonated[speaker_name] = I + break + + // If I's display name is currently different from the voice name and using an agent ID then don't impersonate + // as this would allow the AI to track I and realize the mismatch. + if(I && !(I.name != speaker_name && I.wear_id && istype(I.wear_id,/obj/item/weapon/card/id/syndicate))) impersonating = I jobname = impersonating.get_assignment() else @@ -175,10 +190,25 @@ if(sdisabilities & DEAF || ear_deaf) if(prob(20)) src << "You feel your headset vibrate but can hear nothing from it!" - else if(track) - src << "[part_a][track][part_b][formatted]" else - src << "[part_a][speaker_name][part_b][formatted]" + on_hear_radio(part_a, speaker_name, track, part_b, formatted) + +/proc/say_timestamp() + return "\[[worldtime2text()]\]" + +/mob/proc/on_hear_radio(part_a, speaker_name, track, part_b, formatted) + src << "[part_a][speaker_name][part_b][formatted]" + +/mob/dead/observer/on_hear_radio(part_a, speaker_name, track, part_b, formatted) + src << "[part_a][track][part_b][formatted]" + +/mob/living/silicon/on_hear_radio(part_a, speaker_name, track, part_b, formatted) + var/time = say_timestamp() + src << "[time][part_a][speaker_name][part_b][formatted]" + +/mob/living/silicon/ai/on_hear_radio(part_a, speaker_name, track, part_b, formatted) + var/time = say_timestamp() + src << "[time][part_a][track][part_b][formatted]" /mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null) if(!client) diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index 96eb6f11a3..5e7fbe438d 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -78,4 +78,24 @@ name = "cortical borer" desc = "It's a slimy brain slug. Gross." icon_state = "borer" - origin_tech = "biotech=6" \ No newline at end of file + origin_tech = "biotech=6" + +/obj/item/weapon/holder/monkey + name = "monkey" + desc = "It's a monkey. Ook." + icon_state = "monkey" + +/obj/item/weapon/holder/monkey/farwa + name = "farwa" + desc = "It's a farwa." + icon_state = "farwa" + +/obj/item/weapon/holder/monkey/stok + name = "stok" + desc = "It's a stok. stok." + icon_state = "stok" + +/obj/item/weapon/holder/monkey/neaera + name = "neaera" + desc = "It's a neaera." + icon_state = "neara" diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm deleted file mode 100644 index 86d407cff8..0000000000 --- a/code/modules/mob/language.dm +++ /dev/null @@ -1,454 +0,0 @@ -#define SCRAMBLE_CACHE_LEN 20 - -/* - Datum based languages. Easily editable and modular. -*/ - -/datum/language - var/name = "an unknown language" // Fluff name of language if any. - var/desc = "A language." // Short description for 'Check Languages'. - var/speech_verb = "says" // 'says', 'hisses', 'farts'. - var/ask_verb = "asks" // Used when sentence ends in a ? - var/exclaim_verb = "exclaims" // Used when sentence ends in a ! - var/whisper_verb // Optional. When not specified speech_verb + quietly/softly is used instead. - var/signlang_verb = list() // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags - var/colour = "body" // CSS style to use for strings in this language. - var/key = "x" // Character used to speak in language eg. :o for Unathi. - var/flags = 0 // Various language flags. - var/native // If set, non-native speakers will have trouble speaking. - var/list/syllables // Used when scrambling text for a non-speaker. - var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string. - -/datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4) - if(!syllables || !syllables.len) - if(gender==FEMALE) - return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) - else - return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) - - var/full_name = "" - var/new_name = "" - - for(var/i = 0;i0;x--) - new_name += pick(syllables) - full_name += " [capitalize(lowertext(new_name))]" - - return "[trim(full_name)]" - -/datum/language - var/list/scramble_cache = list() - -/datum/language/proc/scramble(var/input) - - if(!syllables || !syllables.len) - return stars(input) - - // If the input is cached already, move it to the end of the cache and return it - if(input in scramble_cache) - var/n = scramble_cache[input] - scramble_cache -= input - scramble_cache[input] = n - return n - - var/input_size = length(input) - var/scrambled_text = "" - var/capitalize = 1 - - while(length(scrambled_text) < input_size) - var/next = pick(syllables) - if(capitalize) - next = capitalize(next) - capitalize = 0 - scrambled_text += next - var/chance = rand(100) - if(chance <= 5) - scrambled_text += ". " - capitalize = 1 - else if(chance > 5 && chance <= space_chance) - scrambled_text += " " - - scrambled_text = trim(scrambled_text) - var/ending = copytext(scrambled_text, length(scrambled_text)) - if(ending == ".") - scrambled_text = copytext(scrambled_text,1,length(scrambled_text)-1) - var/input_ending = copytext(input, input_size) - if(input_ending in list("!","?",".")) - scrambled_text += input_ending - - // Add it to cache, cutting old entries if the list is too long - scramble_cache[input] = scrambled_text - if(scramble_cache.len > SCRAMBLE_CACHE_LEN) - scramble_cache.Cut(1, scramble_cache.len-SCRAMBLE_CACHE_LEN-1) - - - return scrambled_text - -/datum/language/proc/format_message(message, verb) - return "[verb], \"[capitalize(message)]\"" - -/datum/language/proc/format_message_plain(message, verb) - return "[verb], \"[capitalize(message)]\"" - -/datum/language/proc/format_message_radio(message, verb) - return "[verb], \"[capitalize(message)]\"" - -/datum/language/proc/get_talkinto_msg_range(message) - // if you yell, you'll be heard from two tiles over instead of one - return (copytext(message, length(message)) == "!") ? 2 : 1 - -/datum/language/proc/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) - log_say("[key_name(speaker)] : ([name]) [message]") - - if(!speaker_mask) speaker_mask = speaker.name - var/msg = "[name], [speaker_mask] [format_message(message, get_spoken_verb(message))]" - - for(var/mob/player in player_list) - if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player))) - player << msg - -/datum/language/proc/check_special_condition(var/mob/other) - return 1 - -/datum/language/proc/get_spoken_verb(var/msg_end) - switch(msg_end) - if("!") - return exclaim_verb - if("?") - return ask_verb - return speech_verb - -// Noise "language", for audible emotes. -/datum/language/noise - name = "Noise" - desc = "Noises" - key = "" - flags = RESTRICTED|NONGLOBAL|INNATE|NO_TALK_MSG|NO_STUTTER - -/datum/language/noise/format_message(message, verb) - return "[message]" - -/datum/language/noise/format_message_plain(message, verb) - return message - -/datum/language/noise/format_message_radio(message, verb) - return "[message]" - -/datum/language/noise/get_talkinto_msg_range(message) - // if you make a loud noise (screams etc), you'll be heard from 4 tiles over instead of two - return (copytext(message, length(message)) == "!") ? 4 : 2 - -/datum/language/unathi - name = "Sinta'unathi" - desc = "The common language of Moghes, composed of sibilant hisses and rattles. Spoken natively by Unathi." - speech_verb = "hisses" - ask_verb = "hisses" - exclaim_verb = "roars" - colour = "soghun" - key = "o" - flags = WHITELISTED - syllables = list("ss","ss","ss","ss","skak","seeki","resh","las","esi","kor","sh") - -/datum/language/unathi/get_random_name() - - var/new_name = ..() - while(findtextEx(new_name,"sss",1,null)) - new_name = replacetext(new_name, "sss", "ss") - return capitalize(new_name) - -/datum/language/tajaran - name = "Siik'tajr" - desc = "The traditionally employed tongue of Ahdomai, composed of expressive yowls and chirps. Native to the Tajaran." - speech_verb = "mrowls" - ask_verb = "mrowls" - exclaim_verb = "yowls" - colour = "tajaran" - key = "j" - flags = WHITELISTED - syllables = list("rr","rr","tajr","kir","raj","kii","mir","kra","ahk","nal","vah","khaz","jri","ran","darr", \ - "mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r", \ - "ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah", \ - "hal","ket","jurl","mah","tul","cresh","azu","ragh") - -/datum/language/tajaran/get_random_name(var/gender) - - var/new_name = ..(gender,1) - if(prob(80)) - new_name += " [pick(list("Hadii","Kaytam","Zhan-Khazan","Hharar","Njarir'Akhan"))]" - else - new_name += ..(gender,1) - return new_name - -/datum/language/skrell - name = "Skrellian" - desc = "A melodic and complex language spoken by the Skrell of Qerrbalak. Some of the notes are inaudible to humans." - speech_verb = "warbles" - ask_verb = "warbles" - exclaim_verb = "warbles" - colour = "skrell" - key = "k" - flags = WHITELISTED - syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!") - -/datum/language/vox - name = "Vox-pidgin" - desc = "The common tongue of the various Vox ships making up the Shoal. It sounds like chaotic shrieking to everyone else." - speech_verb = "shrieks" - ask_verb = "creels" - exclaim_verb = "SHRIEKS" - colour = "vox" - key = "5" - flags = WHITELISTED - syllables = list("ti","ti","ti","hi","hi","ki","ki","ki","ki","ya","ta","ha","ka","ya","chi","cha","kah", \ - "SKRE","AHK","EHK","RAWK","KRA","AAA","EEE","KI","II","KRI","KA") - -/datum/language/vox/get_random_name() - return ..(FEMALE,1,6) - -/datum/language/diona - name = "Rootspeak" - desc = "A creaking, subvocal language spoken instinctively by the Dionaea. Due to the unique makeup of the average Diona, a phrase of Rootspeak can be a combination of anywhere from one to twelve individual voices and notes." - speech_verb = "creaks and rustles" - ask_verb = "creaks" - exclaim_verb = "rustles" - colour = "soghun" - key = "q" - flags = RESTRICTED - syllables = list("hs","zt","kr","st","sh") - -/datum/language/diona/get_random_name() - var/new_name = "[pick(list("To Sleep Beneath","Wind Over","Embrace of","Dreams of","Witnessing","To Walk Beneath","Approaching the"))]" - new_name += " [pick(list("the Void","the Sky","Encroaching Night","Planetsong","Starsong","the Wandering Star","the Empty Day","Daybreak","Nightfall","the Rain"))]" - return new_name - -/datum/language/common - name = "Galactic Common" - desc = "The common galactic tongue." - speech_verb = "says" - whisper_verb = "whispers" - key = "0" - flags = RESTRICTED - syllables = list("blah","blah","blah","bleh","meh","neh","nah","wah") - -//TODO flag certain languages to use the mob-type specific say_quote and then get rid of these. -/datum/language/common/get_spoken_verb(var/msg_end) - switch(msg_end) - if("!") - return pick("exclaims","shouts","yells") //TODO: make the basic proc handle lists of verbs. - if("?") - return ask_verb - return speech_verb - -/datum/language/human - name = "Sol Common" - desc = "A bastardized hybrid of informal English and elements of Mandarin Chinese; the common language of the Sol system." - speech_verb = "says" - whisper_verb = "whispers" - colour = "solcom" - key = "1" - flags = RESTRICTED - syllables = list("tao","shi","tzu","yi","com","be","is","i","op","vi","ed","lec","mo","cle","te","dis","e") - -/datum/language/human/get_spoken_verb(var/msg_end) - switch(msg_end) - if("!") - return pick("exclaims","shouts","yells") //TODO: make the basic proc handle lists of verbs. - if("?") - return ask_verb - return speech_verb - -// Galactic common languages (systemwide accepted standards). -/datum/language/trader - name = "Tradeband" - desc = "Maintained by the various trading cartels in major systems, this elegant, structured language is used for bartering and bargaining." - speech_verb = "enunciates" - colour = "say_quote" - key = "2" - space_chance = 100 - syllables = list("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit", - "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", - "magna", "aliqua", "ut", "enim", "ad", "minim", "veniam", "quis", "nostrud", - "exercitation", "ullamco", "laboris", "nisi", "ut", "aliquip", "ex", "ea", "commodo", - "consequat", "duis", "aute", "irure", "dolor", "in", "reprehenderit", "in", - "voluptate", "velit", "esse", "cillum", "dolore", "eu", "fugiat", "nulla", - "pariatur", "excepteur", "sint", "occaecat", "cupidatat", "non", "proident", "sunt", - "in", "culpa", "qui", "officia", "deserunt", "mollit", "anim", "id", "est", "laborum") - -/datum/language/gutter - name = "Gutter" - desc = "Much like Standard, this crude pidgin tongue descended from numerous languages and serves as Tradeband for criminal elements." - speech_verb = "growls" - colour = "rough" - key = "3" - syllables = list ("gra","ba","ba","breh","bra","rah","dur","ra","ro","gro","go","ber","bar","geh","heh", "gra") - -/datum/language/xenocommon - name = "Xenomorph" - colour = "alien" - desc = "The common tongue of the xenomorphs." - speech_verb = "hisses" - ask_verb = "hisses" - exclaim_verb = "hisses" - key = "4" - flags = RESTRICTED - syllables = list("sss","sSs","SSS") - -/datum/language/xenos - name = "Hivemind" - desc = "Xenomorphs have the strange ability to commune over a psychic hivemind." - speech_verb = "hisses" - ask_verb = "hisses" - exclaim_verb = "hisses" - colour = "alien" - key = "a" - flags = RESTRICTED | HIVEMIND - -/datum/language/xenos/check_special_condition(var/mob/other) - - var/mob/living/carbon/M = other - if(!istype(M)) - return 1 - if(locate(/datum/organ/internal/xenos/hivenode) in M.internal_organs) - return 1 - - return 0 - -/datum/language/ling - name = "Changeling" - desc = "Although they are normally wary and suspicious of each other, changelings can commune over a distance." - speech_verb = "says" - colour = "changeling" - key = "g" - flags = RESTRICTED | HIVEMIND - -/datum/language/ling/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) - - if(speaker.mind && speaker.mind.changeling) - ..(speaker,message,speaker.mind.changeling.changelingID) - else - ..(speaker,message) - -/datum/language/corticalborer - name = "Cortical Link" - desc = "Cortical borers possess a strange link between their tiny minds." - speech_verb = "sings" - ask_verb = "sings" - exclaim_verb = "sings" - colour = "alien" - key = "x" - flags = RESTRICTED | HIVEMIND - -/datum/language/corticalborer/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) - - var/mob/living/simple_animal/borer/B - - if(istype(speaker,/mob/living/carbon)) - var/mob/living/carbon/M = speaker - B = M.has_brain_worms() - else if(istype(speaker,/mob/living/simple_animal/borer)) - B = speaker - - if(B) - speaker_mask = B.truename - ..(speaker,message,speaker_mask) - -/datum/language/binary - name = "Robot Talk" - desc = "Most human stations support free-use communications protocols and routing hubs for synthetic use." - colour = "say_quote" - speech_verb = "states" - ask_verb = "queries" - exclaim_verb = "declares" - key = "b" - flags = RESTRICTED | HIVEMIND - var/drone_only - -/datum/language/binary/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) - - if(!speaker.binarycheck()) - return - - if (!message) - return - - var/message_start = "[name], [speaker.name]" - var/message_body = "[speaker.say_quote(message)], \"[message]\"" - - for (var/mob/M in dead_mob_list) - if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping - M.show_message("[message_start] [message_body]", 2) - - for (var/mob/living/S in living_mob_list) - - if(drone_only && !istype(S,/mob/living/silicon/robot/drone)) - continue - else if(istype(S , /mob/living/silicon/ai)) - message_start = "[name], [speaker.name]" - else if (!S.binarycheck()) - continue - - S.show_message("[message_start] [message_body]", 2) - - var/list/listening = hearers(1, src) - listening -= src - - for (var/mob/living/M in listening) - if(istype(M, /mob/living/silicon) || M.binarycheck()) - continue - M.show_message("synthesised voice beeps, \"beep beep beep\"",2) - - //robot binary xmitter component power usage - if (isrobot(speaker)) - var/mob/living/silicon/robot/R = speaker - var/datum/robot_component/C = R.components["comms"] - R.cell_use_power(C.active_usage) - -/datum/language/binary/drone - name = "Drone Talk" - desc = "A heavily encoded damage control coordination stream." - speech_verb = "transmits" - ask_verb = "transmits" - exclaim_verb = "transmits" - colour = "say_quote" - key = "d" - flags = RESTRICTED | HIVEMIND - drone_only = 1 - -// Language handling. -/mob/proc/add_language(var/language) - - var/datum/language/new_language = all_languages[language] - - if(!istype(new_language) || new_language in languages) - return 0 - - languages.Add(new_language) - return 1 - -/mob/proc/remove_language(var/rem_language) - var/datum/language/L = all_languages[rem_language] - . = (L in languages) - languages.Remove(L) - -// Can we speak this language, as opposed to just understanding it? -/mob/proc/can_speak(datum/language/speaking) - - return (universal_speak || (speaking && speaking.flags & INNATE) || speaking in src.languages) - -//TBD -/mob/verb/check_languages() - set name = "Check Known Languages" - set category = "IC" - set src = usr - - var/dat = "Known Languages

    " - - for(var/datum/language/L in languages) - if(!(L.flags & NONGLOBAL)) - dat += "[L.name] (:[L.key])
    [L.desc]

    " - - src << browse(dat, "window=checklanguage") - return - -#undef SCRAMBLE_CACHE_LEN diff --git a/code/modules/mob/language/generic.dm b/code/modules/mob/language/generic.dm new file mode 100644 index 0000000000..d93edf3ac2 --- /dev/null +++ b/code/modules/mob/language/generic.dm @@ -0,0 +1,64 @@ +// Noise "language", for audible emotes. +/datum/language/noise + name = "Noise" + desc = "Noises" + key = "" + flags = RESTRICTED|NONGLOBAL|INNATE|NO_TALK_MSG|NO_STUTTER + +/datum/language/noise/format_message(message, verb) + return "[message]" + +/datum/language/noise/format_message_plain(message, verb) + return message + +/datum/language/noise/format_message_radio(message, verb) + return "[message]" + +/datum/language/noise/get_talkinto_msg_range(message) + // if you make a loud noise (screams etc), you'll be heard from 4 tiles over instead of two + return (copytext(message, length(message)) == "!") ? 4 : 2 + +// 'basic' language; spoken by default. +/datum/language/common + name = "Galactic Common" + desc = "The common galactic tongue." + speech_verb = "says" + whisper_verb = "whispers" + key = "0" + flags = RESTRICTED + syllables = list("blah","blah","blah","bleh","meh","neh","nah","wah") + +//TODO flag certain languages to use the mob-type specific say_quote and then get rid of these. +/datum/language/common/get_spoken_verb(var/msg_end) + switch(msg_end) + if("!") + return pick("exclaims","shouts","yells") //TODO: make the basic proc handle lists of verbs. + if("?") + return ask_verb + return speech_verb + +// Galactic common languages (systemwide accepted standards). +/datum/language/trader + name = "Tradeband" + desc = "Maintained by the various trading cartels in major systems, this elegant, structured language is used for bartering and bargaining." + speech_verb = "enunciates" + colour = "say_quote" + key = "2" + space_chance = 100 + syllables = list("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit", + "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", + "magna", "aliqua", "ut", "enim", "ad", "minim", "veniam", "quis", "nostrud", + "exercitation", "ullamco", "laboris", "nisi", "ut", "aliquip", "ex", "ea", "commodo", + "consequat", "duis", "aute", "irure", "dolor", "in", "reprehenderit", "in", + "voluptate", "velit", "esse", "cillum", "dolore", "eu", "fugiat", "nulla", + "pariatur", "excepteur", "sint", "occaecat", "cupidatat", "non", "proident", "sunt", + "in", "culpa", "qui", "officia", "deserunt", "mollit", "anim", "id", "est", "laborum") + +// Criminal language. +/datum/language/gutter + name = "Gutter" + desc = "Much like Standard, this crude pidgin tongue descended from numerous languages and serves as Tradeband for criminal elements." + speech_verb = "growls" + colour = "rough" + key = "3" + syllables = list ("gra","ba","ba","breh","bra","rah","dur","ra","ro","gro","go","ber","bar","geh","heh", "gra") diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm new file mode 100644 index 0000000000..d2cb8a82ab --- /dev/null +++ b/code/modules/mob/language/language.dm @@ -0,0 +1,157 @@ +#define SCRAMBLE_CACHE_LEN 20 + +/* + Datum based languages. Easily editable and modular. +*/ + +/datum/language + var/name = "an unknown language" // Fluff name of language if any. + var/desc = "A language." // Short description for 'Check Languages'. + var/speech_verb = "says" // 'says', 'hisses', 'farts'. + var/ask_verb = "asks" // Used when sentence ends in a ? + var/exclaim_verb = "exclaims" // Used when sentence ends in a ! + var/whisper_verb // Optional. When not specified speech_verb + quietly/softly is used instead. + var/signlang_verb = list() // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags + var/colour = "body" // CSS style to use for strings in this language. + var/key = "x" // Character used to speak in language eg. :o for Unathi. + var/flags = 0 // Various language flags. + var/native // If set, non-native speakers will have trouble speaking. + var/list/syllables // Used when scrambling text for a non-speaker. + var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string. + +/datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4) + if(!syllables || !syllables.len) + if(gender==FEMALE) + return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) + else + return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) + + var/full_name = "" + var/new_name = "" + + for(var/i = 0;i0;x--) + new_name += pick(syllables) + full_name += " [capitalize(lowertext(new_name))]" + + return "[trim(full_name)]" + +/datum/language + var/list/scramble_cache = list() + +/datum/language/proc/scramble(var/input) + + if(!syllables || !syllables.len) + return stars(input) + + // If the input is cached already, move it to the end of the cache and return it + if(input in scramble_cache) + var/n = scramble_cache[input] + scramble_cache -= input + scramble_cache[input] = n + return n + + var/input_size = length(input) + var/scrambled_text = "" + var/capitalize = 1 + + while(length(scrambled_text) < input_size) + var/next = pick(syllables) + if(capitalize) + next = capitalize(next) + capitalize = 0 + scrambled_text += next + var/chance = rand(100) + if(chance <= 5) + scrambled_text += ". " + capitalize = 1 + else if(chance > 5 && chance <= space_chance) + scrambled_text += " " + + scrambled_text = trim(scrambled_text) + var/ending = copytext(scrambled_text, length(scrambled_text)) + if(ending == ".") + scrambled_text = copytext(scrambled_text,1,length(scrambled_text)-1) + var/input_ending = copytext(input, input_size) + if(input_ending in list("!","?",".")) + scrambled_text += input_ending + + // Add it to cache, cutting old entries if the list is too long + scramble_cache[input] = scrambled_text + if(scramble_cache.len > SCRAMBLE_CACHE_LEN) + scramble_cache.Cut(1, scramble_cache.len-SCRAMBLE_CACHE_LEN-1) + + return scrambled_text + +/datum/language/proc/format_message(message, verb) + return "[verb], \"[capitalize(message)]\"" + +/datum/language/proc/format_message_plain(message, verb) + return "[verb], \"[capitalize(message)]\"" + +/datum/language/proc/format_message_radio(message, verb) + return "[verb], \"[capitalize(message)]\"" + +/datum/language/proc/get_talkinto_msg_range(message) + // if you yell, you'll be heard from two tiles over instead of one + return (copytext(message, length(message)) == "!") ? 2 : 1 + +/datum/language/proc/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) + log_say("[key_name(speaker)] : ([name]) [message]") + + if(!speaker_mask) speaker_mask = speaker.name + var/msg = "[name], [speaker_mask] [format_message(message, get_spoken_verb(message))]" + + for(var/mob/player in player_list) + if(istype(player,/mob/dead) || ((src in player.languages) && check_special_condition(player))) + player << msg + +/datum/language/proc/check_special_condition(var/mob/other) + return 1 + +/datum/language/proc/get_spoken_verb(var/msg_end) + switch(msg_end) + if("!") + return exclaim_verb + if("?") + return ask_verb + return speech_verb + +// Language handling. +/mob/proc/add_language(var/language) + + var/datum/language/new_language = all_languages[language] + + if(!istype(new_language) || new_language in languages) + return 0 + + languages.Add(new_language) + return 1 + +/mob/proc/remove_language(var/rem_language) + var/datum/language/L = all_languages[rem_language] + . = (L in languages) + languages.Remove(L) + +// Can we speak this language, as opposed to just understanding it? +/mob/proc/can_speak(datum/language/speaking) + + return (universal_speak || (speaking && speaking.flags & INNATE) || speaking in src.languages) + +//TBD +/mob/verb/check_languages() + set name = "Check Known Languages" + set category = "IC" + set src = usr + + var/dat = "Known Languages

    " + + for(var/datum/language/L in languages) + if(!(L.flags & NONGLOBAL)) + dat += "[L.name] (:[L.key])
    [L.desc]

    " + + src << browse(dat, "window=checklanguage") + return + +#undef SCRAMBLE_CACHE_LEN diff --git a/code/modules/mob/language/monkey.dm b/code/modules/mob/language/monkey.dm new file mode 100644 index 0000000000..f40a276bbc --- /dev/null +++ b/code/modules/mob/language/monkey.dm @@ -0,0 +1,22 @@ +/datum/language/human/monkey + name = "Chimpanzee" + desc = "Ook ook ook." + speech_verb = "chimpers" + ask_verb = "chimpers" + exclaim_verb = "screeches" + key = "6" + +/datum/language/skrell/monkey + name = "Neara" + desc = "Squik squik squik." + key = "8" + +/datum/language/unathi/monkey + name = "Stok" + desc = "Hiss hiss hiss." + key = "7" + +/datum/language/tajaran/monkey + name = "Farwa" + desc = "Meow meow meow." + key = "9" diff --git a/code/modules/mob/language/outsider.dm b/code/modules/mob/language/outsider.dm new file mode 100644 index 0000000000..cd12ead385 --- /dev/null +++ b/code/modules/mob/language/outsider.dm @@ -0,0 +1,112 @@ +/datum/language/xenocommon + name = "Xenomorph" + colour = "alien" + desc = "The common tongue of the xenomorphs." + speech_verb = "hisses" + ask_verb = "hisses" + exclaim_verb = "hisses" + key = "4" + flags = RESTRICTED + syllables = list("sss","sSs","SSS") + +/datum/language/xenos + name = "Hivemind" + desc = "Xenomorphs have the strange ability to commune over a psychic hivemind." + speech_verb = "hisses" + ask_verb = "hisses" + exclaim_verb = "hisses" + colour = "alien" + key = "a" + flags = RESTRICTED | HIVEMIND + +/datum/language/xenos/check_special_condition(var/mob/other) + + var/mob/living/carbon/M = other + if(!istype(M)) + return 1 + if(locate(/datum/organ/internal/xenos/hivenode) in M.internal_organs) + return 1 + + return 0 + +/datum/language/ling + name = "Changeling" + desc = "Although they are normally wary and suspicious of each other, changelings can commune over a distance." + speech_verb = "says" + colour = "changeling" + key = "g" + flags = RESTRICTED | HIVEMIND + +/datum/language/ling/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) + + if(speaker.mind && speaker.mind.changeling) + ..(speaker,message,speaker.mind.changeling.changelingID) + else + ..(speaker,message) + +/datum/language/corticalborer + name = "Cortical Link" + desc = "Cortical borers possess a strange link between their tiny minds." + speech_verb = "sings" + ask_verb = "sings" + exclaim_verb = "sings" + colour = "alien" + key = "x" + flags = RESTRICTED | HIVEMIND + +/datum/language/corticalborer/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) + + var/mob/living/simple_animal/borer/B + + if(istype(speaker,/mob/living/carbon)) + var/mob/living/carbon/M = speaker + B = M.has_brain_worms() + else if(istype(speaker,/mob/living/simple_animal/borer)) + B = speaker + + if(B) + speaker_mask = B.truename + ..(speaker,message,speaker_mask) + +/datum/language/vox + name = "Vox-pidgin" + desc = "The common tongue of the various Vox ships making up the Shoal. It sounds like chaotic shrieking to everyone else." + speech_verb = "shrieks" + ask_verb = "creels" + exclaim_verb = "SHRIEKS" + colour = "vox" + key = "5" + flags = WHITELISTED + syllables = list("ti","ti","ti","hi","hi","ki","ki","ki","ki","ya","ta","ha","ka","ya","chi","cha","kah", \ + "SKRE","AHK","EHK","RAWK","KRA","AAA","EEE","KI","II","KRI","KA") + +/datum/language/vox/get_random_name() + return ..(FEMALE,1,6) + +/datum/language/cultcommon + name = "Cult" + desc = "The chants of the occult, the incomprehensible." + speech_verb = "intones" + ask_verb = "intones" + exclaim_verb = "chants" + colour = "cult" + key = "n" + flags = RESTRICTED + space_chance = 100 + syllables = list("ire","ego","nahlizet","certum","veri","jatkaa","mgar","balaq", "karazet", "geeri", \ + "orkan", "allaq", "sas'so", "c'arta", "forbici", "tarem", "n'ath", "reth", "sh'yro", "eth", "d'raggathnor", \ + "mah'weyh", "pleggh", "at", "e'ntrath", "tok-lyr", "rqa'nap", "g'lt-ulotf", "ta'gh", "fara'qha", "fel", "d'amar det", \ + "yu'gular", "faras", "desdae", "havas", "mithum", "javara", "umathar", "uf'kal", "thenar", "rash'tla", \ + "sektath", "mal'zua", "zasan", "therium", "viortia", "kla'atu", "barada", "nikt'o", "fwe'sh", "mah", "erl", "nyag", "r'ya", \ + "gal'h'rfikk", "harfrandid", "mud'gib", "fuu", "ma'jin", "dedo", "ol'btoh", "n'ath", "reth", "sh'yro", "eth", \ + "d'rekkathnor", "khari'd", "gual'te", "nikka", "nikt'o", "barada", "kla'atu", "barhah", "hra" ,"zar'garis") + +/datum/language/cult + name = "Occult" + desc = "The initiated can share their thoughts by means defying all reason." + speech_verb = "intones" + ask_verb = "intones" + exclaim_verb = "chants" + colour = "cult" + key = "m" + flags = RESTRICTED | HIVEMIND diff --git a/code/modules/mob/language/station.dm b/code/modules/mob/language/station.dm new file mode 100644 index 0000000000..d5900769b3 --- /dev/null +++ b/code/modules/mob/language/station.dm @@ -0,0 +1,156 @@ +/datum/language/diona + name = "Rootspeak" + desc = "A creaking, subvocal language spoken instinctively by the Dionaea. Due to the unique makeup of the average Diona, a phrase of Rootspeak can be a combination of anywhere from one to twelve individual voices and notes." + speech_verb = "creaks and rustles" + ask_verb = "creaks" + exclaim_verb = "rustles" + colour = "soghun" + key = "q" + flags = RESTRICTED + syllables = list("hs","zt","kr","st","sh") + +/datum/language/diona/get_random_name() + var/new_name = "[pick(list("To Sleep Beneath","Wind Over","Embrace of","Dreams of","Witnessing","To Walk Beneath","Approaching the"))]" + new_name += " [pick(list("the Void","the Sky","Encroaching Night","Planetsong","Starsong","the Wandering Star","the Empty Day","Daybreak","Nightfall","the Rain"))]" + return new_name + +/datum/language/unathi + name = "Sinta'unathi" + desc = "The common language of Moghes, composed of sibilant hisses and rattles. Spoken natively by Unathi." + speech_verb = "hisses" + ask_verb = "hisses" + exclaim_verb = "roars" + colour = "soghun" + key = "o" + flags = WHITELISTED + syllables = list("ss","ss","ss","ss","skak","seeki","resh","las","esi","kor","sh") + +/datum/language/unathi/get_random_name() + + var/new_name = ..() + while(findtextEx(new_name,"sss",1,null)) + new_name = replacetext(new_name, "sss", "ss") + return capitalize(new_name) + +/datum/language/tajaran + name = "Siik'tajr" + desc = "The traditionally employed tongue of Ahdomai, composed of expressive yowls and chirps. Native to the Tajaran." + speech_verb = "mrowls" + ask_verb = "mrowls" + exclaim_verb = "yowls" + colour = "tajaran" + key = "j" + flags = WHITELISTED + syllables = list("rr","rr","tajr","kir","raj","kii","mir","kra","ahk","nal","vah","khaz","jri","ran","darr", \ + "mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r", \ + "ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah", \ + "hal","ket","jurl","mah","tul","cresh","azu","ragh", "mro", "mra") + +/datum/language/tajaran/get_random_name(var/gender) + + var/new_name = ..(gender,1) + if(prob(80)) + new_name += " [pick(list("Hadii","Kaytam","Zhan-Khazan","Hharar","Njarir'Akhan"))]" + else + new_name += ..(gender,1) + return new_name + +/datum/language/skrell + name = "Skrellian" + desc = "A melodic and complex language spoken by the Skrell of Qerrbalak. Some of the notes are inaudible to humans." + speech_verb = "warbles" + ask_verb = "warbles" + exclaim_verb = "warbles" + colour = "skrell" + key = "k" + flags = WHITELISTED + syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!") + +/datum/language/human + name = "Sol Common" + desc = "A bastardized hybrid of informal English and elements of Mandarin Chinese; the common language of the Sol system." + speech_verb = "says" + whisper_verb = "whispers" + colour = "solcom" + key = "1" + flags = RESTRICTED + + //syllables are at the bottom of the file + +/datum/language/human/get_spoken_verb(var/msg_end) + switch(msg_end) + if("!") + return pick("exclaims","shouts","yells") //TODO: make the basic proc handle lists of verbs. + if("?") + return ask_verb + return speech_verb + +/datum/language/human/get_random_name(var/gender) + if (prob(80)) + if(gender==FEMALE) + return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) + else + return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) + else + return ..() + +//Syllable Lists +/* + This list really long, mainly because I can't make up my mind about which mandarin syllables should be removed, + and the english syllables had to be duplicated so that there is roughly a 50-50 weighting. + + Sources: + http://www.sttmedia.com/syllablefrequency-english + http://www.chinahighlights.com/travelguide/learning-chinese/pinyin-syllables.htm +*/ +/datum/language/human/syllables = list( +"a", "ai", "an", "ang", "ao", "ba", "bai", "ban", "bang", "bao", "bei", "ben", "beng", "bi", "bian", "biao", +"bie", "bin", "bing", "bo", "bu", "ca", "cai", "can", "cang", "cao", "ce", "cei", "cen", "ceng", "cha", "chai", +"chan", "chang", "chao", "che", "chen", "cheng", "chi", "chong", "chou", "chu", "chua", "chuai", "chuan", "chuang", "chui", "chun", +"chuo", "ci", "cong", "cou", "cu", "cuan", "cui", "cun", "cuo", "da", "dai", "dan", "dang", "dao", "de", "dei", +"den", "deng", "di", "dian", "diao", "die", "ding", "diu", "dong", "dou", "du", "duan", "dui", "dun", "duo", "e", +"ei", "en", "er", "fa", "fan", "fang", "fei", "fen", "feng", "fo", "fou", "fu", "ga", "gai", "gan", "gang", +"gao", "ge", "gei", "gen", "geng", "gong", "gou", "gu", "gua", "guai", "guan", "guang", "gui", "gun", "guo", "ha", +"hai", "han", "hang", "hao", "he", "hei", "hen", "heng", "hm", "hng", "hong", "hou", "hu", "hua", "huai", "huan", +"huang", "hui", "hun", "huo", "ji", "jia", "jian", "jiang", "jiao", "jie", "jin", "jing", "jiong", "jiu", "ju", "juan", +"jue", "jun", "ka", "kai", "kan", "kang", "kao", "ke", "kei", "ken", "keng", "kong", "kou", "ku", "kua", "kuai", +"kuan", "kuang", "kui", "kun", "kuo", "la", "lai", "lan", "lang", "lao", "le", "lei", "leng", "li", "lia", "lian", +"liang", "liao", "lie", "lin", "ling", "liu", "long", "lou", "lu", "luan", "lun", "luo", "ma", "mai", "man", "mang", +"mao", "me", "mei", "men", "meng", "mi", "mian", "miao", "mie", "min", "ming", "miu", "mo", "mou", "mu", "na", +"nai", "nan", "nang", "nao", "ne", "nei", "nen", "neng", "ng", "ni", "nian", "niang", "niao", "nie", "nin", "ning", +"niu", "nong", "nou", "nu", "nuan", "nuo", "o", "ou", "pa", "pai", "pan", "pang", "pao", "pei", "pen", "peng", +"pi", "pian", "piao", "pie", "pin", "ping", "po", "pou", "pu", "qi", "qia", "qian", "qiang", "qiao", "qie", "qin", +"qing", "qiong", "qiu", "qu", "quan", "que", "qun", "ran", "rang", "rao", "re", "ren", "reng", "ri", "rong", "rou", +"ru", "rua", "ruan", "rui", "run", "ruo", "sa", "sai", "san", "sang", "sao", "se", "sei", "sen", "seng", "sha", +"shai", "shan", "shang", "shao", "she", "shei", "shen", "sheng", "shi", "shou", "shu", "shua", "shuai", "shuan", "shuang", "shui", +"shun", "shuo", "si", "song", "sou", "su", "suan", "sui", "sun", "suo", "ta", "tai", "tan", "tang", "tao", "te", +"teng", "ti", "tian", "tiao", "tie", "ting", "tong", "tou", "tu", "tuan", "tui", "tun", "tuo", "wa", "wai", "wan", +"wang", "wei", "wen", "weng", "wo", "wu", "xi", "xia", "xian", "xiang", "xiao", "xie", "xin", "xing", "xiong", "xiu", +"xu", "xuan", "xue", "xun", "ya", "yan", "yang", "yao", "ye", "yi", "yin", "ying", "yong", "you", "yu", "yuan", +"yue", "yun", "za", "zai", "zan", "zang", "zao", "ze", "zei", "zen", "zeng", "zha", "zhai", "zhan", "zhang", "zhao", +"zhe", "zhei", "zhen", "zheng", "zhi", "zhong", "zhou", "zhu", "zhua", "zhuai", "zhuan", "zhuang", "zhui", "zhun", "zhuo", "zi", +"zong", "zou", "zuan", "zui", "zun", "zuo", "zu", +"al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it", +"le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to", +"ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin", +"his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi", +"al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it", +"le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to", +"ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin", +"his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi", +"al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it", +"le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to", +"ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin", +"his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi", +"al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it", +"le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to", +"ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin", +"his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi", +"al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it", +"le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to", +"ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin", +"his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi", +"al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it", +"le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to", +"ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin", +"his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi") diff --git a/code/modules/mob/language/synthetic.dm b/code/modules/mob/language/synthetic.dm new file mode 100644 index 0000000000..3355a1e5c8 --- /dev/null +++ b/code/modules/mob/language/synthetic.dm @@ -0,0 +1,61 @@ +/datum/language/binary + name = "Robot Talk" + desc = "Most human stations support free-use communications protocols and routing hubs for synthetic use." + colour = "say_quote" + speech_verb = "states" + ask_verb = "queries" + exclaim_verb = "declares" + key = "b" + flags = RESTRICTED | HIVEMIND + var/drone_only + +/datum/language/binary/broadcast(var/mob/living/speaker,var/message,var/speaker_mask) + + if(!speaker.binarycheck()) + return + + if (!message) + return + + var/message_start = "[name], [speaker.name]" + var/message_body = "[speaker.say_quote(message)], \"[message]\"" + + for (var/mob/M in dead_mob_list) + if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping + M.show_message("[message_start] [message_body]", 2) + + for (var/mob/living/S in living_mob_list) + + if(drone_only && !istype(S,/mob/living/silicon/robot/drone)) + continue + else if(istype(S , /mob/living/silicon/ai)) + message_start = "[name], [speaker.name]" + else if (!S.binarycheck()) + continue + + S.show_message("[message_start] [message_body]", 2) + + var/list/listening = hearers(1, src) + listening -= src + + for (var/mob/living/M in listening) + if(istype(M, /mob/living/silicon) || M.binarycheck()) + continue + M.show_message("synthesised voice beeps, \"beep beep beep\"",2) + + //robot binary xmitter component power usage + if (isrobot(speaker)) + var/mob/living/silicon/robot/R = speaker + var/datum/robot_component/C = R.components["comms"] + R.cell_use_power(C.active_usage) + +/datum/language/binary/drone + name = "Drone Talk" + desc = "A heavily encoded damage control coordination stream." + speech_verb = "transmits" + ask_verb = "transmits" + exclaim_verb = "transmits" + colour = "say_quote" + key = "d" + flags = RESTRICTED | HIVEMIND + drone_only = 1 diff --git a/code/modules/mob/living/carbon/alien/alien_attacks.dm b/code/modules/mob/living/carbon/alien/alien_attacks.dm index 4285f91c3f..62768945a3 100644 --- a/code/modules/mob/living/carbon/alien/alien_attacks.dm +++ b/code/modules/mob/living/carbon/alien/alien_attacks.dm @@ -20,10 +20,10 @@ switch(M.a_intent) - if ("help") + if (I_HELP) help_shake_act(M) - if ("grab") + if (I_GRAB) if (M == src) return var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src ) diff --git a/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm b/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm index a379af21c7..58aba691dd 100644 --- a/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm +++ b/code/modules/mob/living/carbon/alien/diona/diona_attacks.dm @@ -2,7 +2,7 @@ if(istype(M)) //Let people pick the little buggers up. - if(M.a_intent == "help") + if(M.a_intent == I_HELP) if(M.species && M.species.name == "Diona") M << "You feel your being twine with that of [src] as it merges with your biomass." src << "You feel your being twine with that of [M] as you merge with its biomass." diff --git a/code/modules/mob/living/carbon/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm index 038c77fcde..28ae01391f 100644 --- a/code/modules/mob/living/carbon/alien/say.dm +++ b/code/modules/mob/living/carbon/alien/say.dm @@ -7,7 +7,7 @@ src << "\red You cannot speak in IC (Muted)." return - message = trim_strip_html_properly(message) + message = sanitize(message) if(stat == 2) return say_dead(message) diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm index e602916d8c..d5ac4f756d 100644 --- a/code/modules/mob/living/carbon/brain/say.dm +++ b/code/modules/mob/living/carbon/brain/say.dm @@ -32,5 +32,5 @@ if(istype(container, /obj/item/device/mmi/radio_enabled)) var/obj/item/device/mmi/radio_enabled/R = container if(R.radio) - spawn(0) R.radio.hear_talk(src, trim(sanitize(message)), verb, speaking) + spawn(0) R.radio.hear_talk(src, sanitize(message), verb, speaking) ..(trim(message), speaking, verb) diff --git a/code/modules/mob/living/carbon/breathe.dm b/code/modules/mob/living/carbon/breathe.dm new file mode 100644 index 0000000000..38e1efa71b --- /dev/null +++ b/code/modules/mob/living/carbon/breathe.dm @@ -0,0 +1,80 @@ +//Common breathing procs + +/mob/living/carbon/proc/breathe() + //if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return + if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return + + var/datum/gas_mixture/breath = null + + //First, check if we can breathe at all + if(health < config.health_threshold_crit && !reagents.has_reagent("inaprovaline")) //crit aka circulatory shock + losebreath++ + + if(losebreath>0) //Suffocating so do not take a breath + losebreath-- + if (prob(10)) //Gasp per 10 ticks? Sounds about right. + spawn emote("gasp") + else + //Okay, we can breathe, now check if we can get air + breath = get_breath_from_internal() //First, check for air from internals + if(!breath) + breath = get_breath_from_environment() //No breath from internals so let's try to get air from our location + + handle_breath(breath) + handle_post_breath(breath) + +/mob/living/carbon/proc/get_breath_from_internal(var/volume_needed=BREATH_VOLUME) //hopefully this will allow overrides to specify a different default volume without breaking any cases where volume is passed in. + if(internal) + if (!contents.Find(internal)) + internal = null + if (!(wear_mask && (wear_mask.flags & AIRTIGHT))) + internal = null + if(internal) + if (internals) + internals.icon_state = "internal1" + return internal.remove_air_volume(volume_needed) + else + if (internals) + internals.icon_state = "internal0" + return null + +/mob/living/carbon/proc/get_breath_from_environment(var/volume_needed=BREATH_VOLUME) + var/datum/gas_mixture/breath = null + + var/datum/gas_mixture/environment + if(loc) + environment = loc.return_air_for_internal_lifeform() + + if(environment) + breath = environment.remove_volume(volume_needed) + handle_chemical_smoke(environment) //handle chemical smoke while we're at it + + if(breath) + //handle mask filtering + if(istype(wear_mask, /obj/item/clothing/mask) && breath) + var/obj/item/clothing/mask/M = wear_mask + var/datum/gas_mixture/filtered = M.filter_air(breath) + loc.assume_air(filtered) + return breath + return null + +//Handle possble chem smoke effect +/mob/living/carbon/proc/handle_chemical_smoke(var/datum/gas_mixture/environment) + if(wear_mask && (wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT)) + return + + for(var/obj/effect/effect/smoke/chem/smoke in view(1, src)) + if(smoke.reagents.total_volume) + smoke.reagents.reaction(src, INGEST) + spawn(5) + if(smoke) + //maybe check air pressure here or something to see if breathing in smoke is even possible. + smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs? + break // If they breathe in the nasty stuff once, no need to continue checking + +/mob/living/carbon/proc/handle_breath(datum/gas_mixture/breath) + return + +/mob/living/carbon/proc/handle_post_breath(datum/gas_mixture/breath) + if(breath) + loc.assume_air(breath) //by default, exhale diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 7db6a2fe29..215d98cf9a 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1,6 +1,8 @@ /mob/living/carbon/Life() ..() + handle_viruses() + // Increase germ_level regularly if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level germ_level++ @@ -19,12 +21,11 @@ if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8)) germ_level++ -/mob/living/carbon/relaymove(var/mob/user, direction) - if(user in src.stomach_contents) - if(prob(40)) - for(var/mob/M in hearers(4, src)) - if(M.client) - M.show_message(text("\red You hear something rumbling inside [src]'s stomach..."), 2) +/mob/living/carbon/relaymove(var/mob/living/user, direction) + if((user in src.stomach_contents) && istype(user)) + if(user.last_special <= world.time) + user.last_special = world.time + 50 + src.visible_message("You hear something rumbling inside [src]'s stomach...") var/obj/item/I = user.get_active_hand() if(I && I.force) var/d = rand(round(I.force / 4), I.force) @@ -38,9 +39,7 @@ H.updatehealth() else src.take_organ_damage(d) - for(var/mob/M in viewers(user, null)) - if(M.client) - M.show_message(text("\red [user] attacks [src]'s stomach wall with the [I.name]!"), 2) + user.visible_message("[user] attacks [src]'s stomach wall with the [I.name]!") playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1) if(prob(src.getBruteLoss() - 50)) @@ -190,6 +189,29 @@ src.show_message(text("\t []My [] is [].",status=="OK"?"\blue ":"\red ",org.display_name,status),1) if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit)) H.play_xylophone() + else if (on_fire) + playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + if (M.on_fire) + M.visible_message("[M] tries to pat out [src]'s flames, but to no avail!", \ + "You try to pat out [src]'s flames, but to no avail! Put yourself out first!") + else + M.visible_message("[M] tries to pat out [src]'s flames!", \ + "You try to pat out [src]'s flames! Hot!") + if(do_mob(M, src, 15)) + if (prob(10) && (M.fire_stacks <= 0)) + src.fire_stacks -= 2 + M.fire_stacks += 1 + M.IgniteMob() + if (M.on_fire) + M.visible_message("The fire spreads from [src] to [M]!", \ + "The fire spreads to you as well!") + else + src.fire_stacks -= 3 //Less effective than stop, drop, and roll + if (src.fire_stacks <= 0) + M.visible_message("[M] successfully pats out [src]'s flames.", \ + "You successfully pat out [src]'s flames.") + src.ExtinguishMob() + src.fire_stacks = 0 else var/t_him = "it" if (src.gender == MALE) @@ -216,7 +238,11 @@ else M.visible_message("[M] hugs [src] to make [t_him] feel better!", \ "You hug [src] to make [t_him] feel better!") - + if(M.fire_stacks >= (src.fire_stacks + 3)) + src.fire_stacks += 1 + M.fire_stacks -= 1 + if(M.on_fire) + src.IgniteMob() AdjustParalysis(-3) AdjustStunned(-3) AdjustWeakened(-3) @@ -332,7 +358,7 @@ /mob/living/carbon/can_use_hands() if(handcuffed) return 0 - if(buckled && ! istype(buckled, /obj/structure/stool/bed/chair)) // buckling does not restrict hands + if(buckled && ! istype(buckled, /obj/structure/bed/chair)) // buckling does not restrict hands return 0 return 1 @@ -347,6 +373,8 @@ else if (W == handcuffed) handcuffed = null update_inv_handcuffed() + if(buckled && buckled.buckle_require_restraints) + buckled.unbuckle_mob() else if (W == legcuffed) legcuffed = null @@ -407,102 +435,12 @@ if(alert(src,"You sure you want to sleep for a while?","Sleep","Yes","No") == "Yes") usr.sleeping = 20 //Short nap -/mob/living/carbon/Bump(atom/movable/AM as mob|obj, yes) - - spawn( 0 ) - if ((!( yes ) || now_pushing)) - return - now_pushing = 1 - if(ismob(AM)) - var/mob/tmob = AM - - if( istype(tmob, /mob/living/carbon) && prob(10) ) - src.spread_disease_to(AM, "Contact") - - if(istype(tmob, /mob/living/carbon/human)) - - if(HULK in tmob.mutations) - if(prob(70)) - usr << "\red You fail to push [tmob]'s fat ass out of the way." - now_pushing = 0 - return - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - - for(var/mob/M in range(tmob, 1)) - if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) ) - if ( !(world.time % 5) ) - src << "\red [tmob] is restrained, you cannot push past" - now_pushing = 0 - return - if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) ) - if ( !(world.time % 5) ) - src << "\red [tmob] is restraining [M], you cannot push past" - now_pushing = 0 - return - - //Leaping mobs just land on the tile, no pushing, no anything. - if(status_flags & LEAPING) - loc = tmob.loc - status_flags &= ~LEAPING - now_pushing = 0 - return - - // Step over drones. - // I have no idea why the hell this isn't already happening. How do mice do it? - if(istype(tmob,/mob/living/silicon/robot/drone)) - loc = tmob.loc - now_pushing = 0 - return - - if((tmob.a_intent == "help" || tmob.restrained()) && (a_intent == "help" || src.restrained()) && tmob.canmove && !tmob.buckled && canmove) // mutual brohugs all around! - var/turf/oldloc = loc - loc = tmob.loc - tmob.loc = oldloc - now_pushing = 0 - for(var/mob/living/carbon/slime/slime in view(1,tmob)) - if(slime.Victim == tmob) - slime.UpdateFeed() - return - - if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) - if(prob(40) && !(FAT in src.mutations)) - src << "\red You fail to push [tmob]'s fat ass out of the way." - now_pushing = 0 - return - if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot)) - if(prob(99)) - now_pushing = 0 - return - if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot)) - if(prob(99)) - now_pushing = 0 - return - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - - tmob.LAssailant = src - - now_pushing = 0 - ..() - if (!( istype(AM, /atom/movable) )) - return - if (!( now_pushing )) - now_pushing = 1 - if (!( AM.anchored )) - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - var/obj/structure/window/W = AM - if(W.is_full_window()) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - now_pushing = 0 +/mob/living/carbon/Bump(var/atom/movable/AM, yes) + if(now_pushing || !yes) return - return + ..() + if(istype(AM, /mob/living/carbon) && prob(10)) + src.spread_disease_to(AM, "Contact") /mob/living/carbon/can_use_vents() return @@ -515,4 +453,9 @@ playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) Stun(stun_duration) Weaken(Floor(stun_duration/2)) - return 1 \ No newline at end of file + return 1 + +/mob/living/carbon/get_default_language() + if(!species) + return null + return species.default_language ? all_languages[species.default_language] : null diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index bf72360399..55b33324fb 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -3,7 +3,7 @@ var/datum/species/species //Contains icon generation and language information, set during New(). var/list/stomach_contents = list() var/list/datum/disease2/disease/virus2 = list() - var/antibodies = 0 + var/list/antibodies = list() var/last_eating = 0 //Not sure what this does... I found it hidden in food.dm var/life_tick = 0 // The amount of life ticks that have processed on this mob. diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm index 47e4282424..107e660d39 100644 --- a/code/modules/mob/living/carbon/give.dm +++ b/code/modules/mob/living/carbon/give.dm @@ -1,18 +1,14 @@ -/mob/living/carbon/verb/give() +mob/living/carbon/verb/give(var/mob/living/carbon/target in view(1)-usr) set category = "IC" set name = "Give" - set src in view(1) - if(src.stat == 2 || usr.stat == 2 || src.client == null) - return - if(src == usr) - usr << "\red I feel stupider, suddenly." + if(target.stat == 2 || usr.stat == 2|| target.client == null) return var/obj/item/I if(!usr.hand && usr.r_hand == null) - usr << "\red You don't have anything in your right hand to give to [src.name]" + usr << "You don't have anything in your right hand to give to [target.name]" return if(usr.hand && usr.l_hand == null) - usr << "\red You don't have anything in your left hand to give to [src.name]" + usr << "You don't have anything in your left hand to give to [target.name]" return if(usr.hand) I = usr.l_hand @@ -20,38 +16,38 @@ I = usr.r_hand if(!I) return - if(src.r_hand == null || src.l_hand == null) - switch(alert(src,"[usr] wants to give you \a [I]?",,"Yes","No")) + if(target.r_hand == null || target.l_hand == null) + switch(alert(target,"[usr] wants to give you \a [I]?",,"Yes","No")) if("Yes") if(!I) return if(!Adjacent(usr)) - usr << "\red You need to stay in reaching distance while giving an object." - src << "\red [usr.name] moved too far away." + usr << "You need to stay in reaching distance while giving an object." + target << "[usr.name] moved too far away." return if((usr.hand && usr.l_hand != I) || (!usr.hand && usr.r_hand != I)) - usr << "\red You need to keep the item in your active hand." - src << "\red [usr.name] seem to have given up on giving \the [I.name] to you." + usr << "You need to keep the item in your active hand." + target << "[usr.name] seem to have given up on giving \the [I.name] to you." return - if(src.r_hand != null && src.l_hand != null) - src << "\red Your hands are full." - usr << "\red Their hands are full." + if(target.r_hand != null && target.l_hand != null) + target << "Your hands are full." + usr << "Their hands are full." return else usr.drop_item() - if(src.r_hand == null) - src.r_hand = I + if(target.r_hand == null) + target.r_hand = I else - src.l_hand = I - I.loc = src + target.l_hand = I + I.loc = target I.layer = 20 - I.add_fingerprint(src) - src.update_inv_l_hand() - src.update_inv_r_hand() + I.add_fingerprint(target) + target.update_inv_l_hand() + target.update_inv_r_hand() usr.update_inv_l_hand() usr.update_inv_r_hand() - src.visible_message("\blue [usr.name] handed \the [I.name] to [src.name].") + target.visible_message("[usr.name] handed \the [I.name] to [target.name].") if("No") - src.visible_message("\red [usr.name] tried to hand [I.name] to [src.name] but [src.name] didn't want it.") + target.visible_message("[usr.name] tried to hand [I.name] to [target.name] but [target.name] didn't want it.") else - usr << "\red [src.name]'s hands are full." + usr << "[target.name]'s hands are full." diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm new file mode 100644 index 0000000000..4976cba4fb --- /dev/null +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -0,0 +1,187 @@ +/mob/living/carbon/human/proc/change_appearance(var/flags = APPEARANCE_ALL_HAIR, var/location = src, var/mob/user = src, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list()) + var/obj/nano_module/appearance_changer/AC = new(location, src, check_species_whitelist, species_whitelist, species_blacklist) + AC.flags = flags + AC.ui_interact(user) + +/mob/living/carbon/human/proc/change_species(var/new_species) + if(!new_species) + return + + if(species == new_species) + return + + if(!(new_species in all_species)) + return + + set_species(new_species) + reset_hair() + return 1 + +/mob/living/carbon/human/proc/change_gender(var/gender) + if(src.gender == gender) + return + + src.gender = gender + reset_hair() + update_body() + update_dna() + return 1 + +/mob/living/carbon/human/proc/change_hair(var/hair_style) + if(!hair_style) + return + + if(h_style == hair_style) + return + + if(!(hair_style in hair_styles_list)) + return + + h_style = hair_style + + update_hair() + return 1 + +/mob/living/carbon/human/proc/change_facial_hair(var/facial_hair_style) + if(!facial_hair_style) + return + + if(f_style == facial_hair_style) + return + + if(!(facial_hair_style in facial_hair_styles_list)) + return + + f_style = facial_hair_style + + update_hair() + return 1 + +/mob/living/carbon/human/proc/reset_hair() + var/list/valid_hairstyles = generate_valid_hairstyles() + var/list/valid_facial_hairstyles = generate_valid_facial_hairstyles() + + if(valid_hairstyles.len) + h_style = pick(valid_hairstyles) + else + //this shouldn't happen + h_style = "Bald" + + if(valid_facial_hairstyles.len) + f_style = pick(valid_facial_hairstyles) + else + //this shouldn't happen + f_style = "Shaved" + + update_hair() + +/mob/living/carbon/human/proc/change_eye_color(var/red, var/green, var/blue) + if(red == r_eyes && green == g_eyes && blue == b_eyes) + return + + r_eyes = red + g_eyes = green + b_eyes = blue + + update_body() + return 1 + +/mob/living/carbon/human/proc/change_hair_color(var/red, var/green, var/blue) + if(red == r_eyes && green == g_eyes && blue == b_eyes) + return + + r_hair = red + g_hair = green + b_hair = blue + + update_hair() + return 1 + +/mob/living/carbon/human/proc/change_facial_hair_color(var/red, var/green, var/blue) + if(red == r_facial && green == g_facial && blue == b_facial) + return + + r_facial = red + g_facial = green + b_facial = blue + + update_hair() + return 1 + +/mob/living/carbon/human/proc/change_skin_color(var/red, var/green, var/blue) + if(red == r_skin && green == g_skin && blue == b_skin || !(species.flags & HAS_SKIN_COLOR)) + return + + r_skin = red + g_skin = green + b_skin = blue + + update_body() + return 1 + +/mob/living/carbon/human/proc/change_skin_tone(var/tone) + if(s_tone == tone || !(species.flags & HAS_SKIN_TONE)) + return + + s_tone = tone + + update_body() + return 1 + +/mob/living/carbon/human/proc/update_dna() + check_dna() + dna.ready_dna(src) + +/mob/living/carbon/human/proc/generate_valid_species(var/check_whitelist = 1, var/list/whitelist = list(), var/list/blacklist = list()) + var/list/valid_species = new() + for(var/current_species_name in all_species) + var/datum/species/current_species = all_species[current_species_name] + + if(check_whitelist && config.usealienwhitelist && !check_rights(R_ADMIN, 0, src)) //If we're using the whitelist, make sure to check it! + if(!(current_species.flags & CAN_JOIN)) + continue + if(whitelist.len && !(current_species_name in whitelist)) + continue + if(blacklist.len && (current_species_name in blacklist)) + continue + if((current_species.flags & IS_WHITELISTED) && !is_alien_whitelisted(src, current_species_name)) + continue + + valid_species += current_species_name + + return valid_species + +/mob/living/carbon/human/proc/generate_valid_hairstyles() + var/list/valid_hairstyles = new() + for(var/hairstyle in hair_styles_list) + var/datum/sprite_accessory/S = hair_styles_list[hairstyle] + + if(gender == MALE && S.gender == FEMALE) + continue + if(gender == FEMALE && S.gender == MALE) + continue + if(!(species.name in S.species_allowed)) + continue + valid_hairstyles += hairstyle + + return valid_hairstyles + +/mob/living/carbon/human/proc/generate_valid_facial_hairstyles() + var/list/valid_facial_hairstyles = new() + for(var/facialhairstyle in facial_hair_styles_list) + var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle] + + if(gender == MALE && S.gender == FEMALE) + continue + if(gender == FEMALE && S.gender == MALE) + continue + if(!(species.name in S.species_allowed)) + continue + + valid_facial_hairstyles += facialhairstyle + + return valid_facial_hairstyles + +/proc/q() + var/mob/living/carbon/human/H = usr + H.change_appearance(APPEARANCE_ALL) diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 9ed050b5ae..6b40a64198 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -28,8 +28,10 @@ if(stat == DEAD) return - hud_updateflag |= 1 << HEALTH_HUD - hud_updateflag |= 1 << STATUS_HUD + BITSET(hud_updateflag, HEALTH_HUD) + BITSET(hud_updateflag, STATUS_HUD) + BITSET(hud_updateflag, LIFE_HUD) + handle_hud_list() //Handle species-specific deaths. @@ -63,8 +65,6 @@ if(ticker && ticker.mode) sql_report_death(src) ticker.mode.check_win() - if(istype(ticker.mode,/datum/game_mode/heist)) - vox_kills++ //Bad vox. Shouldn't be killing humans. return ..(gibbed,species.death_message) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 2140fe22b3..258c8cbcd1 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -50,7 +50,7 @@ m_type = 1 if ("custom") - var/input = sanitize(copytext(input("Choose an emote to display.") as text|null,1,MAX_MESSAGE_LEN)) + var/input = sanitize(input("Choose an emote to display.") as text|null) if (!input) return var/input2 = input("Is this a visible or hearable emote?") in list("Visible","Hearable") @@ -577,7 +577,7 @@ set desc = "Sets a description which will be shown when someone examines you." set category = "IC" - pose = sanitize(copytext(input(usr, "This is [src]. \He is...", "Pose", null) as text, 1, MAX_MESSAGE_LEN)) + pose = sanitize(input(usr, "This is [src]. \He is...", "Pose", null) as text) /mob/living/carbon/human/verb/set_flavor() set name = "Set Flavour Text" diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 777c17fdbc..73f8fc90ee 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -63,8 +63,8 @@ var/tie_msg if(istype(w_uniform,/obj/item/clothing/under)) var/obj/item/clothing/under/U = w_uniform - if(U.hastie) - tie_msg += " with \icon[U.hastie] \a [U.hastie]" + if(U.accessories.len) + tie_msg += ". Attached to it is [lowertext(english_list(U.accessories))]" if(w_uniform.blood_DNA) msg += "[t_He] [t_is] wearing \icon[w_uniform] [w_uniform.gender==PLURAL?"some":"a"] [(w_uniform.blood_color != "#030303") ? "blood" : "oil"]-stained [w_uniform.name][tie_msg]!\n" @@ -131,6 +131,10 @@ else msg += "[t_He] [t_is] \icon[handcuffed] handcuffed!\n" + //buckled + if(buckled) + msg += "[t_He] [t_is] \icon[buckled] buckled to [buckled]!\n" + //belt if(belt) if(belt.blood_DNA) @@ -209,7 +213,7 @@ distance = 1 if (src.stat) msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n" - if((stat == 2 || src.health < config.health_threshold_crit) && distance <= 3) + if((stat == 2 || src.losebreath) && distance <= 3) msg += "[t_He] does not appear to be breathing.\n" if(istype(usr, /mob/living/carbon/human) && !usr.stat && Adjacent(usr)) usr.visible_message("[usr] checks [src]'s pulse.", "You check [src]'s pulse.") @@ -219,7 +223,10 @@ usr << "[t_He] has no pulse[src.client ? "" : " and [t_his] soul has departed"]..." else usr << "[t_He] has a pulse!" - + if(fire_stacks) + msg += "[t_He] [t_is] covered in some liquid.\n" + if(on_fire) + msg += "[t_He] [t_is] on fire!.\n" msg += "" if(nutrition < 100) @@ -235,7 +242,7 @@ if(getBrainLoss() >= 60) msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n" - if((!species.has_organ["brain"] || has_brain()) && stat != DEAD) + if(species.show_ssd && (!species.has_organ["brain"] || has_brain()) && stat != DEAD) if(!key) msg += "[t_He] [t_is] fast asleep. It doesn't look like they are waking up anytime soon.\n" else if(!client) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 2e194ca7cd..b6f1a67597 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -5,7 +5,7 @@ icon = 'icons/mob/human.dmi' icon_state = "body_m_s" - var/list/hud_list[9] + var/list/hud_list[10] var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us. /mob/living/carbon/human/New(var/new_loc, var/new_species = null) @@ -26,6 +26,7 @@ hud_list[HEALTH_HUD] = image('icons/mob/hud.dmi', src, "hudhealth100") hud_list[STATUS_HUD] = image('icons/mob/hud.dmi', src, "hudhealthy") + hud_list[LIFE_HUD] = image('icons/mob/hud.dmi', src, "hudhealthy") hud_list[ID_HUD] = image('icons/mob/hud.dmi', src, "hudunknown") hud_list[WANTED_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[IMPLOYAL_HUD] = image('icons/mob/hud.dmi', src, "hudblank") @@ -47,8 +48,8 @@ stat(null, "Intent: [a_intent]") stat(null, "Move Mode: [m_intent]") if(ticker && ticker.mode && ticker.mode.name == "AI malfunction") - if(ticker.mode:malf_mode_declared) - stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]") + if(malf.revealed) + stat(null, "Time left: [max(malf.hack_time/(malf.hacked_apcs/3), 0)]") if(emergency_shuttle) var/eta_status = emergency_shuttle.get_status_panel_eta() if(eta_status) @@ -195,6 +196,7 @@ var/datum/organ/external/affected = M.organs_by_name["head"] affected.implants += L L.part = affected + L.implanted(src) /mob/living/carbon/human/proc/is_loyalty_implanted(mob/living/carbon/human/M) for(var/L in M.contents) @@ -241,7 +243,7 @@
    Suit Storage: [(s_store ? s_store : "Nothing")] [((istype(wear_mask, /obj/item/clothing/mask) && istype(s_store, /obj/item/weapon/tank) && !( internal )) ? text(" Set Internal", src) : "")]
    [(handcuffed ? text("Handcuffed") : text("Not Handcuffed"))]
    [(legcuffed ? text("Legcuffed") : text(""))] -
    [(suit) ? ((suit.hastie) ? text(" Remove Accessory", src) : "") :] +
    [(suit) ? ((suit.accessories.len) ? text(" Remove Accessory", src) : "") :]
    [(internal ? text("Remove Internal") : "")]
    Remove Splints
    Empty Pockets @@ -412,7 +414,7 @@ modified = 1 spawn() - hud_updateflag |= 1 << WANTED_HUD + BITSET(hud_updateflag, WANTED_HUD) if(istype(usr,/mob/living/carbon/human)) var/mob/living/carbon/human/U = usr U.handle_regular_hud_updates() @@ -499,7 +501,7 @@ for (var/datum/data/record/R in data_core.security) if (R.fields["id"] == E.fields["id"]) if(hasHUD(usr,"security")) - var/t1 = sanitize(copytext(input("Add Comment:", "Sec. records", null, null) as message,1,MAX_MESSAGE_LEN)) + var/t1 = sanitize(input("Add Comment:", "Sec. records", null, null) as message) if ( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"security")) ) return var/counter = 1 @@ -628,7 +630,7 @@ for (var/datum/data/record/R in data_core.medical) if (R.fields["id"] == E.fields["id"]) if(hasHUD(usr,"medical")) - var/t1 = sanitize(copytext(input("Add Comment:", "Med. records", null, null) as message,1,MAX_MESSAGE_LEN)) + var/t1 = sanitize(input("Add Comment:", "Med. records", null, null) as message) if ( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"medical")) ) return var/counter = 1 @@ -655,17 +657,11 @@ src << browse(null, "window=flavor_changes") return if("general") - var/msg = input(usr,"Update the general description of your character. This will be shown regardless of clothing, and may include OOC notes and preferences.","Flavor Text",html_decode(flavor_texts[href_list["flavor_change"]])) as message - if(msg != null) - msg = copytext(msg, 1, MAX_MESSAGE_LEN) - msg = html_encode(msg) + var/msg = sanitize(input(usr,"Update the general description of your character. This will be shown regardless of clothing, and may include OOC notes and preferences.","Flavor Text",html_decode(flavor_texts[href_list["flavor_change"]])) as message, extra = 0) flavor_texts[href_list["flavor_change"]] = msg return else - var/msg = input(usr,"Update the flavor text for your [href_list["flavor_change"]].","Flavor Text",html_decode(flavor_texts[href_list["flavor_change"]])) as message - if(msg != null) - msg = copytext(msg, 1, MAX_MESSAGE_LEN) - msg = html_encode(msg) + var/msg = sanitize(input(usr,"Update the flavor text for your [href_list["flavor_change"]].","Flavor Text",html_decode(flavor_texts[href_list["flavor_change"]])) as message, extra = 0) flavor_texts[href_list["flavor_change"]] = msg set_flavor() return @@ -696,6 +692,8 @@ number += 2 if(istype(src.head, /obj/item/clothing/head/helmet/space)) number += 2 + if(istype(src.head, /obj/item/clothing/head/helmet/space/emergency)) + number -= 2 if(istype(src.glasses, /obj/item/clothing/glasses/thermal)) number -= 1 if(istype(src.glasses, /obj/item/clothing/glasses/sunglasses)) @@ -710,7 +708,7 @@ if(species.has_fine_manipulation) return 1 if(!silent) - src << "You don't have the dexterity to use [src]!" + src << "You don't have the dexterity to use that!" return 0 /mob/living/carbon/human/abiotic(var/full_body = 0) @@ -1162,6 +1160,10 @@ else return 0 + mob_bump_flag = species.bump_flag + mob_swap_flags = species.swap_flags + mob_push_flags = species.push_flags + /mob/living/carbon/human/proc/bloody_doodle() set category = "IC" set name = "Write in blood" @@ -1201,7 +1203,7 @@ var/max_length = bloody_hands * 30 //tweeter style - var/message = stripped_input(src,"Write a message. It cannot be longer than [max_length] characters.","Blood writing", "") + var/message = sanitize(input("Write a message. It cannot be longer than [max_length] characters.","Blood writing", "")) if (message) var/used_blood_amount = round(length(message) / 30, 1) @@ -1220,10 +1222,11 @@ /mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone) . = 1 - if(!user) - target_zone = pick("chest","chest","chest","left leg","right leg","left arm", "right arm", "head") - else if(!target_zone) - target_zone = user.zone_sel.selecting + if(!target_zone) + if(!user) + target_zone = pick("chest","chest","chest","left leg","right leg","left arm", "right arm", "head") + else + target_zone = user.zone_sel.selecting switch(target_zone) if("head") @@ -1236,7 +1239,7 @@ // Might need re-wording. user << "There is no exposed flesh or thin material [target_zone == "head" ? "on their head" : "on their body"] to inject into." -/mob/living/carbon/human/print_flavor_text() +/mob/living/carbon/human/print_flavor_text(var/shrink = 1) var/list/equipment = list(src.head,src.wear_mask,src.glasses,src.w_uniform,src.wear_suit,src.gloves,src.shoes) var/head_exposed = 1 var/face_exposed = 1 @@ -1272,7 +1275,10 @@ if((T == "head" && head_exposed) || (T == "face" && face_exposed) || (T == "eyes" && eyes_exposed) || (T == "torso" && torso_exposed) || (T == "arms" && arms_exposed) || (T == "hands" && hands_exposed) || (T == "legs" && legs_exposed) || (T == "feet" && feet_exposed)) flavor_text += flavor_texts[T] flavor_text += "\n\n" - return ..() + if(!shrink) + return flavor_text + else + return ..() /mob/living/carbon/human/getDNA() if(species.flags & NO_SCAN) @@ -1301,4 +1307,4 @@ /mob/living/carbon/human/slip(var/slipped_on, stun_duration=8) if((species.flags & NO_SLIP) || (shoes && (shoes.flags & NOSLIP))) return 0 - ..(slipped_on,stun_duration) \ No newline at end of file + ..(slipped_on,stun_duration) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 5029c283ec..82c03a181f 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -45,7 +45,7 @@ M.spread_disease_to(src, "Contact") switch(M.a_intent) - if("help") + if(I_HELP) if(istype(H) && health < config.health_threshold_crit) @@ -69,7 +69,7 @@ help_shake_act(M) return 1 - if("grab") + if(I_GRAB) if(M == src || anchored) return 0 if(w_uniform) @@ -88,7 +88,7 @@ visible_message("[M] has grabbed [src] passively!") return 1 - if("hurt") + if(I_HURT) if(!istype(H)) attack_generic(H,rand(1,3),"punched") @@ -101,11 +101,11 @@ var/datum/organ/external/affecting = get_organ(hit_zone) switch(src.a_intent) - if("help") + if(I_HELP) // We didn't see this coming, so we get the full blow rand_damage = 5 accurate = 1 - if("hurt", "grab") + if(I_HURT, I_GRAB) // We're in a fighting stance, there's a chance we block if(src.canmove && src!=H && prob(20)) block = 1 @@ -200,7 +200,7 @@ // Finally, apply damage to target apply_damage(real_damage, BRUTE, affecting, armour, sharp=attack.sharp, edge=attack.edge) - if("disarm") + if(I_DISARM) M.attack_log += text("\[[time_stamp()]\] Disarmed [src.name] ([src.ckey])") src.attack_log += text("\[[time_stamp()]\] Has been disarmed by [M.name] ([M.ckey])") @@ -210,7 +210,7 @@ w_uniform.add_fingerprint(M) var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting)) - if (istype(r_hand,/obj/item/weapon/gun) || istype(l_hand,/obj/item/weapon/gun)) + if(istype(r_hand,/obj/item/weapon/gun) || istype(l_hand,/obj/item/weapon/gun)) var/obj/item/weapon/gun/W = null var/chance = 0 @@ -232,9 +232,13 @@ var/randn = rand(1, 100) if(!(species.flags & NO_SLIP) && randn <= 25) - apply_effect(3, WEAKEN, run_armor_check(affecting, "melee")) + var/armor_check = run_armor_check(affecting, "melee") + apply_effect(3, WEAKEN, armor_check) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - visible_message("\red [M] has pushed [src]!") + if(armor_check < 2) + visible_message("[M] has pushed [src]!") + else + visible_message("[M] attempted to push [src]!") return var/talked = 0 // BubbleWrap diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 60f1f8a3a2..561659a27a 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -87,7 +87,7 @@ take_overall_damage(amount, 0) else heal_overall_damage(-amount, 0) - hud_updateflag |= 1 << HEALTH_HUD + BITSET(hud_updateflag, HEALTH_HUD) /mob/living/carbon/human/adjustFireLoss(var/amount) if(species && species.burn_mod) @@ -97,7 +97,7 @@ take_overall_damage(0, amount) else heal_overall_damage(0, -amount) - hud_updateflag |= 1 << HEALTH_HUD + BITSET(hud_updateflag, HEALTH_HUD) /mob/living/carbon/human/proc/adjustBruteLossByPart(var/amount, var/organ_name, var/obj/damage_source = null) if(species && species.brute_mod) @@ -112,7 +112,7 @@ //if you don't want to heal robot organs, they you will have to check that yourself before using this proc. O.heal_damage(-amount, 0, internal=0, robo_repair=(O.status & ORGAN_ROBOT)) - hud_updateflag |= 1 << HEALTH_HUD + BITSET(hud_updateflag, HEALTH_HUD) /mob/living/carbon/human/proc/adjustFireLossByPart(var/amount, var/organ_name, var/obj/damage_source = null) if(species && species.burn_mod) @@ -127,7 +127,7 @@ //if you don't want to heal robot organs, they you will have to check that yourself before using this proc. O.heal_damage(0, -amount, internal=0, robo_repair=(O.status & ORGAN_ROBOT)) - hud_updateflag |= 1 << HEALTH_HUD + BITSET(hud_updateflag, HEALTH_HUD) /mob/living/carbon/human/Stun(amount) if(HULK in mutations) return @@ -185,7 +185,7 @@ if (O.status & ORGAN_MUTATED) O.unmutate() src << "Your [O.display_name] is shaped normally again." - hud_updateflag |= 1 << HEALTH_HUD + BITSET(hud_updateflag, HEALTH_HUD) // Defined here solely to take species flags into account without having to recast at mob/living level. /mob/living/carbon/human/getOxyLoss() @@ -249,7 +249,7 @@ var/datum/organ/external/picked = pick(parts) if(picked.heal_damage(brute,burn)) UpdateDamageIcon() - hud_updateflag |= 1 << HEALTH_HUD + BITSET(hud_updateflag, HEALTH_HUD) updatehealth() @@ -265,7 +265,7 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t var/datum/organ/external/picked = pick(parts) if(picked.take_damage(brute,burn,sharp,edge)) UpdateDamageIcon() - hud_updateflag |= 1 << HEALTH_HUD + BITSET(hud_updateflag, HEALTH_HUD) updatehealth() speech_problem_flag = 1 @@ -288,7 +288,7 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t parts -= picked updatehealth() - hud_updateflag |= 1 << HEALTH_HUD + BITSET(hud_updateflag, HEALTH_HUD) speech_problem_flag = 1 if(update) UpdateDamageIcon() @@ -309,7 +309,7 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t parts -= picked updatehealth() - hud_updateflag |= 1 << HEALTH_HUD + BITSET(hud_updateflag, HEALTH_HUD) if(update) UpdateDamageIcon() @@ -336,7 +336,7 @@ This function restores all organs. if(istype(E, /datum/organ/external)) if (E.heal_damage(brute, burn)) UpdateDamageIcon() - hud_updateflag |= 1 << HEALTH_HUD + BITSET(hud_updateflag, HEALTH_HUD) else return 0 return @@ -393,5 +393,5 @@ This function restores all organs. // Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life(). updatehealth() - hud_updateflag |= 1 << HEALTH_HUD + BITSET(hud_updateflag, HEALTH_HUD) return 1 diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index ebe84fa6d1..c95accd40c 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -24,7 +24,7 @@ emp_act if(!(def_zone in list("chest", "groin"))) reflectchance /= 2 if(prob(reflectchance)) - visible_message("\red The [P.name] gets reflected by [src]'s [wear_suit.name]!") + visible_message("\red \The [P] gets reflected by \the [src]'s [wear_suit.name]!") // Find a turf near or on the original location to bounce to if(P.starting) @@ -33,23 +33,18 @@ emp_act var/turf/curloc = get_turf(src) // redirect the projectile - P.original = locate(new_x, new_y, P.z) - P.starting = curloc - P.current = curloc - P.firer = src - P.yo = new_y - curloc.y - P.xo = new_x - curloc.x + P.redirect(new_x, new_y, curloc, src) return -1 // complete projectile permutation //Shrapnel - if (P.damage_type == BRUTE) + if(P.can_embed()) var/armor = getarmor_organ(organ, "bullet") - if((P.embed && prob(20 + max(P.damage - armor, -10)))) + if(prob(20 + max(P.damage - armor, -10))) var/obj/item/weapon/shard/shrapnel/SP = new() - (SP.name) = "[P.name] shrapnel" - (SP.desc) = "[SP.desc] It looks like it was fired from [P.shot_from]." - (SP.loc) = organ + SP.name = (P.name != "shrapnel")? "[P.name] shrapnel" : "shrapnel" + SP.desc = "[SP.desc] It looks like it was fired from [P.shot_from]." + SP.loc = organ organ.embed(SP) return (..(P , def_zone)) @@ -256,9 +251,6 @@ emp_act if(prob(I.force)) apply_effect(20, PARALYZE, armor) visible_message("\red [src] has been knocked unconscious!") - if(src != user && I.damtype == BRUTE) - ticker.mode.remove_revolutionary(mind) - if(bloody)//Apply blood if(wear_mask) wear_mask.add_blood(src) @@ -297,11 +289,11 @@ emp_act return 1 //this proc handles being hit by a thrown atom -/mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = 5) +/mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR) if(istype(AM,/obj/)) var/obj/O = AM - if(in_throw_mode && !get_active_hand() && speed <= 5) //empty active hand and we're in throw mode + if(in_throw_mode && !get_active_hand() && speed <= THROWFORCE_SPEED_DIVISOR) //empty active hand and we're in throw mode if(canmove && !restrained()) if(isturf(O.loc)) put_in_active_hand(O) @@ -309,11 +301,8 @@ emp_act throw_mode_off() return - var/dtype = BRUTE - if(istype(O,/obj/item/weapon)) - var/obj/item/weapon/W = O - dtype = W.damtype - var/throw_damage = O.throwforce*(speed/5) + var/dtype = O.damtype + var/throw_damage = O.throwforce*(speed/THROWFORCE_SPEED_DIVISOR) var/zone if (istype(O.thrower, /mob/living)) @@ -323,11 +312,11 @@ emp_act zone = ran_zone("chest",75) //Hits a random part of the body, geared towards the chest //check if we hit + var/miss_chance = 15 if (O.throw_source) var/distance = get_dist(O.throw_source, loc) - zone = get_zone_with_miss_chance(zone, src, min(15*(distance-2), 0)) - else - zone = get_zone_with_miss_chance(zone, src, 15) + miss_chance = max(15*(distance-2), 0) + zone = get_zone_with_miss_chance(zone, src, miss_chance, ranged_attack=1) if(!zone) visible_message("\blue \The [O] misses [src] narrowly!") @@ -375,17 +364,21 @@ emp_act affecting.embed(I) // Begin BS12 momentum-transfer code. - if(O.throw_source && speed >= 15) - var/obj/item/weapon/W = O - var/momentum = speed/2 + var/mass = 1.5 + if(istype(O, /obj/item)) + var/obj/item/I = O + mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR + var/momentum = speed*mass + + if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED) var/dir = get_dir(O.throw_source, src) visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!") src.throw_at(get_edge_target_turf(src,dir),1,momentum) - if(!W || !src) return + if(!O || !src) return - if(W.loc == src && W.sharp) //Projectile is embedded and suitable for pinning. + if(O.loc == src && O.sharp) //Projectile is embedded and suitable for pinning. var/turf/T = near_wall(dir,2) if(T) @@ -394,6 +387,13 @@ emp_act src.anchored = 1 src.pinned += O +/mob/living/carbon/human/embed(var/obj/O, var/def_zone=null) + if(!def_zone) ..() + + var/datum/organ/external/affecting = get_organ(def_zone) + if(affecting) + affecting.embed(O) + /mob/living/carbon/human/proc/bloody_hands(var/mob/living/source, var/amount = 2) if (gloves) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 064819b2cd..4546fab050 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -82,3 +82,7 @@ var/hand_blood_color var/list/flavor_texts = list() + + mob_bump_flag = HUMAN + mob_push_flags = ALLMOBS + mob_swap_flags = ALLMOBS diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 256fb11138..155492a36b 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -26,7 +26,7 @@ if(wear_suit) tally += wear_suit.slowdown - if(istype(buckled, /obj/structure/stool/bed/chair/wheelchair)) + if(istype(buckled, /obj/structure/bed/chair/wheelchair)) for(var/organ_name in list("l_hand","r_hand","l_arm","r_arm")) var/datum/organ/external/E = get_organ(organ_name) if(!E || (E.status & ORGAN_DESTROYED)) @@ -47,7 +47,7 @@ tally += 0.5 else if(E.status & ORGAN_BROKEN) tally += 1.5 - + if(shock_stage >= 10) tally += 3 if(FAT in src.mutations) diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 1150a52e71..10988afb92 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -175,7 +175,7 @@ text = input("What would you like to say?", "Speak to creature", null, null) - text = trim(sanitize(copytext(text, 1, MAX_MESSAGE_LEN))) + text = sanitize(text) if(!text) return @@ -213,7 +213,7 @@ set desc = "Whisper silently to someone over a distance." set category = "Abilities" - var/msg = sanitize(copytext(input("Message:", "Psychic Whisper") as text|null, 1, MAX_MESSAGE_LEN)) + var/msg = sanitize(input("Message:", "Psychic Whisper") as text|null) if(msg) log_say("PsychicWhisper: [key_name(src)]->[M.key] : [msg]") M << "\green You hear a strange, alien voice in your head... \italic [msg]" diff --git a/code/modules/mob/living/carbon/human/human_species.dm b/code/modules/mob/living/carbon/human/human_species.dm index 051ef214f4..f7a644646d 100644 --- a/code/modules/mob/living/carbon/human/human_species.dm +++ b/code/modules/mob/living/carbon/human/human_species.dm @@ -1,7 +1,3 @@ -// These may have some say.dm bugs regarding understanding common, -// might be worth adapting the bugs into a feature and using these -// subtypes as a basis for non-common-speaking alien foreigners. ~ Z - /mob/living/carbon/human/dummy real_name = "Test Dummy" status_flags = GODMODE|CANPUSH @@ -22,13 +18,21 @@ h_style = "Short Vox Quills" ..(new_loc, "Vox") -/mob/living/carbon/human/voxarmalis/New(var/new_loc) - h_style = "Bald" - ..(new_loc, "Vox Armalis") - /mob/living/carbon/human/diona/New(var/new_loc) ..(new_loc, "Diona") /mob/living/carbon/human/machine/New(var/new_loc) h_style = "blue IPC screen" - ..(new_loc, "Machine") \ No newline at end of file + ..(new_loc, "Machine") + +/mob/living/carbon/human/monkey/New(var/new_loc) + ..(new_loc, "Monkey") + +/mob/living/carbon/human/farwa/New(var/new_loc) + ..(new_loc, "Farwa") + +/mob/living/carbon/human/neara/New(var/new_loc) + ..(new_loc, "Neara") + +/mob/living/carbon/human/stok/New(var/new_loc) + ..(new_loc, "Stok") diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 43b66d9ccc..d35162c2fe 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -1,3 +1,16 @@ +/* +Add fingerprints to items when we put them in our hands. +This saves us from having to call add_fingerprint() any time something is put in a human's hands programmatically. + +*/ +/mob/living/carbon/human/put_in_l_hand(var/obj/item/W) + . = ..() + if(.) W.add_fingerprint(src) + +/mob/living/carbon/human/put_in_r_hand(var/obj/item/W) + . = ..() + if(.) W.add_fingerprint(src) + /mob/living/carbon/human/verb/quick_equip() set name = "quick-equip" set hidden = 1 @@ -155,7 +168,9 @@ back = null update_inv_back() else if (W == handcuffed) - handcuffed = null + handcuffed = null + if(buckled && buckled.buckle_require_restraints) + buckled.unbuckle_mob() update_inv_handcuffed() else if (W == legcuffed) legcuffed = null @@ -317,10 +332,6 @@ name = "human" var/mob/living/carbon/human/target = null -/obj/effect/equip_e/monkey - name = "monkey" - var/mob/living/carbon/monkey/target = null - /obj/effect/equip_e/process() return @@ -476,15 +487,17 @@ message = "\red [source] is trying to unlegcuff [target]!" if("tie") var/obj/item/clothing/under/suit = target.w_uniform - target.attack_log += text("\[[time_stamp()]\] Has had their accessory ([suit.hastie]) removed by [source.name] ([source.ckey])") - source.attack_log += text("\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) accessory ([suit.hastie])") - if(istype(suit.hastie, /obj/item/clothing/tie/holobadge) || istype(suit.hastie, /obj/item/clothing/tie/medal)) - for(var/mob/M in viewers(target, null)) - M.show_message("\red [source] tears off \the [suit.hastie] from [target]'s suit!" , 1) - done() - return - else - message = "\red [source] is trying to take off \a [suit.hastie] from [target]'s suit!" + if(suit.accessories.len) + var/obj/item/clothing/accessory/A = suit.accessories[1] + target.attack_log += "\[[time_stamp()]\] Has had their accessory ([A]) removed by [source.name] ([source.ckey])" + source.attack_log += "\[[time_stamp()]\] Attempted to remove [target.name]'s ([target.ckey]) accessory ([A])" + if(istype(A, /obj/item/clothing/accessory/holobadge) || istype(A, /obj/item/clothing/accessory/medal)) + for(var/mob/M in viewers(target, null)) + M.show_message("\red [source] tears off \the [A] from [target]'s [suit]!" , 1) + done() + return + else + message = "\red [source] is trying to take off \a [A] from [target]'s [suit]!" if("pockets") target.attack_log += text("\[[time_stamp()]\] Has had their pockets emptied by [source.name] ([source.ckey])") source.attack_log += text("\[[time_stamp()]\] Attempted to empty [target.name]'s ([target.ckey]) pockets") @@ -613,17 +626,18 @@ It can still be worn/put on as normal. strip_item = target.wear_suit if("tie") var/obj/item/clothing/under/suit = target.w_uniform - //var/obj/item/clothing/tie/tie = suit.hastie + //var/obj/item/clothing/accessory/tie = suit.hastie /*if(tie) - if (istype(tie,/obj/item/clothing/tie/storage)) - var/obj/item/clothing/tie/storage/W = tie + if (istype(tie,/obj/item/clothing/accessory/storage)) + var/obj/item/clothing/accessory/storage/W = tie if (W.hold) W.hold.close(usr) usr.put_in_hands(tie) suit.hastie = null*/ - if(suit && suit.hastie) - suit.hastie.on_removed(usr) - suit.hastie = null + if(suit && suit.accessories.len) + var/obj/item/clothing/accessory/A = suit.accessories[1] + A.on_removed(usr) + suit.accessories -= A target.update_inv_w_uniform() if("id") slot_to_process = slot_wear_id diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 4c265d520e..9c03a6c378 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -2,7 +2,7 @@ //NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick! #define HUMAN_MAX_OXYLOSS 1 //Defines how much oxyloss humans can get per tick. A tile with no air at all (such as space) applies this value, otherwise it's a percentage of it. -#define HUMAN_CRIT_MAX_OXYLOSS ( (last_tick_duration) /6) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 50HP to get through, so (1/6)*last_tick_duration per second. Breaths however only happen every 4 ticks. +#define HUMAN_CRIT_MAX_OXYLOSS ( (tickerProcess.getLastTickerTimeDuration()) / 6) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 50HP to get through, so (1/6)*last_tick_duration per second. Breaths however only happen every 4 ticks. #define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point #define HEAT_DAMAGE_LEVEL_2 4 //Amount of damage applied when your body temperature passes the 400K point @@ -31,6 +31,7 @@ var/pressure_alert = 0 var/temperature_alert = 0 var/in_stasis = 0 + var/heartbeat = 0 /mob/living/carbon/human/Life() @@ -68,11 +69,6 @@ if(air_master.current_cycle%4==2 || failed_last_breath || (health < config.health_threshold_crit)) //First, resolve location and get a breath breathe() //Only try to take a breath every 4 ticks, unless suffocating - else //Still give containing object the chance to interact - if(istype(loc, /obj/)) - var/obj/location_as_object = loc - location_as_object.handle_internal_lifeform(src, 0) - //Updates the number of stored chemicals for powers handle_changeling() @@ -93,8 +89,6 @@ //Random events (vomiting etc) handle_random_events() - handle_virus_updates() - //stuff in the stomach handle_stomach() @@ -104,6 +98,11 @@ handle_medical_side_effects() + handle_heartbeat() + + if(!client) + species.handle_npc(src) + handle_stasis_bag() if(life_tick > 5 && timeofdeath && (timeofdeath < 5 || world.time - timeofdeath > 6000)) //We are long dead, or we're junk mobs spawned like the clowns on the clown shuttle @@ -112,6 +111,9 @@ //Handle temperature/pressure differences between body and environment handle_environment(environment) //Optimized a good bit. + //Check if we're on fire + handle_fire() + //Status updates, death etc. handle_regular_status_updates() //Optimized a bit update_canmove() @@ -134,7 +136,7 @@ var/pressure_adjustment_coefficient = 1 // Assume no protection at first. - if(wear_suit && (wear_suit.flags & STOPSPRESSUREDMAGE) && head && (head.flags & STOPSPRESSUREDMAGE)) // Complete set of pressure-proof suit worn, assume fully sealed. + if(wear_suit && (wear_suit.flags & STOPPRESSUREDAMAGE) && head && (head.flags & STOPPRESSUREDAMAGE)) // Complete set of pressure-proof suit worn, assume fully sealed. pressure_adjustment_coefficient = 0 // Handles breaches in your space suit. 10 suit damage equals a 100% loss of pressure protection. @@ -324,96 +326,26 @@ var/datum/organ/external/O = pick(organs) if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage) - proc/breathe() - if(reagents.has_reagent("lexorin")) return - if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return - if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return + /** breathing **/ - var/datum/gas_mixture/environment = loc.return_air() - var/datum/gas_mixture/breath + handle_chemical_smoke(var/datum/gas_mixture/environment) + if(wear_mask && (wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT)) + return + if(glasses && (glasses.flags & BLOCK_GAS_SMOKE_EFFECT)) + return + if(head && (head.flags & BLOCK_GAS_SMOKE_EFFECT)) + return + ..() - // HACK NEED CHANGING LATER - if(health < config.health_threshold_crit && !reagents.has_reagent("inaprovaline")) - losebreath++ - - if(losebreath>0) //Suffocating so do not take a breath - losebreath-- - if (prob(10)) //Gasp per 10 ticks? Sounds about right. - spawn emote("gasp") - if(istype(loc, /obj/)) - var/obj/location_as_object = loc - location_as_object.handle_internal_lifeform(src, 0) - else - //First, check for air from internal atmosphere (using an air tank and mask generally) - breath = get_breath_from_internal(BREATH_VOLUME) // Super hacky -- TLE - //breath = get_breath_from_internal(0.5) // Manually setting to old BREATH_VOLUME amount -- TLE - - //No breath from internal atmosphere so get breath from location - if(!breath) - if(isobj(loc)) - var/obj/location_as_object = loc - breath = location_as_object.handle_internal_lifeform(src, BREATH_MOLES) - else if(isturf(loc)) - var/breath_moles = 0 - /*if(environment.return_pressure() > ONE_ATMOSPHERE) - // Loads of air around (pressure effect will be handled elsewhere), so lets just take a enough to fill our lungs at normal atmos pressure (using n = Pv/RT) - breath_moles = (ONE_ATMOSPHERE*BREATH_VOLUME/R_IDEAL_GAS_EQUATION*environment.temperature) - else*/ - // Not enough air around, take a percentage of what's there to model this properly - breath_moles = environment.total_moles*BREATH_PERCENTAGE - - breath = loc.remove_air(breath_moles) - - if(istype(wear_mask, /obj/item/clothing/mask) && breath) - var/obj/item/clothing/mask/M = wear_mask - var/datum/gas_mixture/filtered = M.filter_air(breath) - loc.assume_air(filtered) - - if(!is_lung_ruptured()) - if(!breath || breath.total_moles < BREATH_MOLES / 5 || breath.total_moles > BREATH_MOLES * 5) - if(prob(5)) - rupture_lung() - - // Handle filtering - var/block = 0 - if(wear_mask) - if(wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT) - block = 1 - if(glasses) - if(glasses.flags & BLOCK_GAS_SMOKE_EFFECT) - block = 1 - if(head) - if(head.flags & BLOCK_GAS_SMOKE_EFFECT) - block = 1 - - if(!block) - - for(var/obj/effect/effect/smoke/chem/smoke in view(1, src)) - if(smoke.reagents.total_volume) - smoke.reagents.reaction(src, INGEST) - spawn(5) - if(smoke) - smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs? - break // If they breathe in the nasty stuff once, no need to continue checking - - else //Still give containing object the chance to interact - if(istype(loc, /obj/)) - var/obj/location_as_object = loc - location_as_object.handle_internal_lifeform(src, 0) - - handle_breath(breath) - - if(breath) - loc.assume_air(breath) - - //spread some viruses while we are at it - if (virus2.len > 0 && prob(10)) -// log_debug("[src] : Exhaling some viruses") - for(var/mob/living/carbon/M in view(1,src)) - src.spread_disease_to(M) + handle_post_breath(datum/gas_mixture/breath) + ..() + //spread some viruses while we are at it + if(breath && virus2.len > 0 && prob(10)) + for(var/mob/living/carbon/M in view(1,src)) + src.spread_disease_to(M) - proc/get_breath_from_internal(volume_needed) + get_breath_from_internal(volume_needed=BREATH_VOLUME) if(internal) var/obj/item/weapon/tank/rig_supply @@ -432,23 +364,21 @@ return null - proc/handle_breath(datum/gas_mixture/breath) + handle_breath(datum/gas_mixture/breath) if(status_flags & GODMODE) return if(!breath || (breath.total_moles == 0) || suiciding) + failed_last_breath = 1 if(suiciding) adjustOxyLoss(2)//If you are suiciding, you should die a little bit faster - failed_last_breath = 1 oxygen_alert = max(oxygen_alert, 1) return 0 if(health > config.health_threshold_crit) adjustOxyLoss(HUMAN_MAX_OXYLOSS) - failed_last_breath = 1 else adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS) - failed_last_breath = 1 oxygen_alert = max(oxygen_alert, 1) @@ -598,8 +528,9 @@ failed_last_breath = 0 adjustOxyLoss(-5) + // Hot air hurts :( - if( (breath.temperature <= species.cold_level_1 || breath.temperature >= species.heat_level_1) && !(COLD_RESISTANCE in mutations)) + if((breath.temperature < species.cold_level_1 || breath.temperature > species.heat_level_1) && !(COLD_RESISTANCE in mutations)) if(breath.temperature <= species.cold_level_1) if(prob(20)) @@ -618,7 +549,7 @@ else apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat") fire_alert = max(fire_alert, 2) - + else if(breath.temperature <= species.cold_level_1) if(breath.temperature > species.cold_level_2) apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, "head", used_weapon = "Excessive Cold") @@ -646,6 +577,10 @@ //world << "Breath: [breath.temperature], [src]: [bodytemperature], Adjusting: [temp_adj]" bodytemperature += temp_adj + else if(breath.temperature >= species.heat_discomfort_level) + species.get_environment_discomfort(src,"heat") + else if(breath.temperature <= species.cold_discomfort_level) + species.get_environment_discomfort(src,"cold") breath.update_values() return 1 @@ -702,7 +637,7 @@ //Body temperature is too hot. fire_alert = max(fire_alert, 1) if(status_flags & GODMODE) return 1 //godmode - + if(bodytemperature < species.heat_level_2) take_overall_damage(burn=HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature") fire_alert = max(fire_alert, 2) @@ -716,7 +651,7 @@ else if(bodytemperature <= species.cold_level_1) fire_alert = max(fire_alert, 1) if(status_flags & GODMODE) return 1 //godmode - + if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) if(bodytemperature > species.cold_level_2) take_overall_damage(burn=COLD_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature") @@ -781,6 +716,8 @@ if (abs(body_temperature_difference) < 0.5) return //fuck this precision + if (on_fire) + return //too busy for pesky convection if(bodytemperature < species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects. if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up. @@ -1024,6 +961,10 @@ fake_attack(src) if(!handling_hal) spawn handle_hallucinations() //The not boring kind! + if(client && prob(5)) + client.dir = pick(2,4,8) + spawn(rand(20,50)) + client.dir = 1 if(hallucination<=2) hallucination = 0 @@ -1037,8 +978,7 @@ if(halloss > 100) src << "You're in too much pain to keep going..." - for(var/mob/O in oviewers(src, null)) - O.show_message("[src] slumps to the ground, too weak to continue fighting.", 1) + src.visible_message("[src] slumps to the ground, too weak to continue fighting.") Paralyse(10) setHalLoss(99) @@ -1234,7 +1174,7 @@ if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO if(healths) healths.icon_state = "health7" //DEAD healthmeter if(client) - if(client.view != world.view) // If mob moves while zoomed in with device, unzoom them. + if(client.view != world.view) // If mob dies while zoomed in with device, unzoom them. for(var/obj/item/item in contents) if(item.zoom) item.zoom() @@ -1264,7 +1204,7 @@ if(seer==1) var/obj/effect/rune/R = locate() in loc if(R && R.word1 == cultwords["see"] && R.word2 == cultwords["hell"] && R.word3 == cultwords["join"]) - see_invisible = SEE_INVISIBLE_OBSERVER + see_invisible = SEE_INVISIBLE_CULT else see_invisible = SEE_INVISIBLE_LIVING seer = 0 @@ -1281,6 +1221,8 @@ glasses_processed = 1 process_glasses(glasses) + if(!glasses_processed && (species.vision_flags > 0)) + sight |= species.vision_flags if(!seer && !glasses_processed) see_invisible = SEE_INVISIBLE_LIVING @@ -1403,6 +1345,12 @@ if(machine) if(!machine.check_eye(src)) reset_view(null) + else if(eyeobj) + if(eyeobj.owner != src) + + reset_view(null) + else + src.sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS else var/isRemoteObserve = 0 if((mRemote in mutations) && remoteview_target) @@ -1446,47 +1394,6 @@ if(!currentTurf.lighting_lumcount) playsound_local(src,pick(scarySounds),50, 1, -1) - proc/handle_virus_updates() - if(status_flags & GODMODE) return 0 //godmode - if(bodytemperature > 406) - for(var/datum/disease/D in viruses) - D.cure() - for (var/ID in virus2) - var/datum/disease2/disease/V = virus2[ID] - V.cure(src) - if(life_tick % 3) //don't spam checks over all objects in view every tick. - for(var/obj/effect/decal/cleanable/O in view(1,src)) - if(istype(O,/obj/effect/decal/cleanable/blood)) - var/obj/effect/decal/cleanable/blood/B = O - if(B.virus2.len) - for (var/ID in B.virus2) - var/datum/disease2/disease/V = B.virus2[ID] - infect_virus2(src,V.getcopy()) - - else if(istype(O,/obj/effect/decal/cleanable/mucus)) - var/obj/effect/decal/cleanable/mucus/M = O - if(M.virus2.len) - for (var/ID in M.virus2) - var/datum/disease2/disease/V = M.virus2[ID] - infect_virus2(src,V.getcopy()) - - - if(virus2.len) - for (var/ID in virus2) - var/datum/disease2/disease/V = virus2[ID] - if(isnull(V)) // Trying to figure out a runtime error that keeps repeating - CRASH("virus2 nulled before calling activate()") - else - V.activate(src) - // activate may have deleted the virus - if(!V) continue - - // check if we're immune - if(V.antigen & src.antibodies) - V.dead = 1 - - return - proc/handle_stomach() spawn(0) for(var/mob/living/M in stomach_contents) @@ -1592,6 +1499,27 @@ return temp + proc/handle_heartbeat() + if(pulse == PULSE_NONE || !species.has_organ["heart"]) + return + + var/datum/organ/internal/heart/H = internal_organs_by_name["heart"] + + if(!H || H.robotic >=2 ) + return + + if(pulse >= PULSE_2FAST || shock_stage >= 10 || istype(get_turf(src), /turf/space)) + //PULSE_THREADY - maximum value for pulse, currently it 5. + //High pulse value corresponds to a fast rate of heartbeat. + //Divided by 2, otherwise it is too slow. + var/rate = (PULSE_THREADY - pulse)/2 + + if(heartbeat >= rate) + heartbeat = 0 + src << sound('sound/effects/singlebeat.ogg',0,0,0,50) + else + heartbeat++ + /* Called by life(), instead of having the individual hud items update icons each tick and check for status changes we only set those statuses and icons upon changes. Then those HUD items will simply add those pre-made images. @@ -1600,8 +1528,7 @@ /mob/living/carbon/human/proc/handle_hud_list() - - if(hud_updateflag & 1 << HEALTH_HUD) + if (BITTEST(hud_updateflag, HEALTH_HUD)) var/image/holder = hud_list[HEALTH_HUD] if(stat == 2) holder.icon_state = "hudhealth-100" // X_X @@ -1610,7 +1537,14 @@ holder.icon_state = "hud[percentage_health]" hud_list[HEALTH_HUD] = holder - if(hud_updateflag & 1 << STATUS_HUD) + if (BITTEST(hud_updateflag, LIFE_HUD)) + var/image/holder = hud_list[STATUS_HUD] + if(stat == DEAD) + holder.icon_state = "huddead" + else + holder.icon_state = "hudhealthy" + + if (BITTEST(hud_updateflag, STATUS_HUD)) var/foundVirus = 0 for(var/datum/disease/D in viruses) if(!D.hidden[SCANNER]) @@ -1647,7 +1581,7 @@ hud_list[STATUS_HUD] = holder hud_list[STATUS_HUD_OOC] = holder2 - if(hud_updateflag & 1 << ID_HUD) + if (BITTEST(hud_updateflag, ID_HUD)) var/image/holder = hud_list[ID_HUD] if(wear_id) var/obj/item/weapon/card/id/I = wear_id.GetID() @@ -1661,7 +1595,7 @@ hud_list[ID_HUD] = holder - if(hud_updateflag & 1 << WANTED_HUD) + if (BITTEST(hud_updateflag, WANTED_HUD)) var/image/holder = hud_list[WANTED_HUD] holder.icon_state = "hudblank" var/perpname = name @@ -1687,7 +1621,10 @@ break hud_list[WANTED_HUD] = holder - if(hud_updateflag & 1 << IMPLOYAL_HUD || hud_updateflag & 1 << IMPCHEM_HUD || hud_updateflag & 1 << IMPTRACK_HUD) + if ( BITTEST(hud_updateflag, IMPLOYAL_HUD) \ + || BITTEST(hud_updateflag, IMPCHEM_HUD) \ + || BITTEST(hud_updateflag, IMPTRACK_HUD)) + var/image/holder1 = hud_list[IMPTRACK_HUD] var/image/holder2 = hud_list[IMPLOYAL_HUD] var/image/holder3 = hud_list[IMPCHEM_HUD] @@ -1707,9 +1644,9 @@ hud_list[IMPTRACK_HUD] = holder1 hud_list[IMPLOYAL_HUD] = holder2 - hud_list[IMPCHEM_HUD] = holder3 + hud_list[IMPCHEM_HUD] = holder3 - if(hud_updateflag & 1 << SPECIALROLE_HUD) + if (BITTEST(hud_updateflag, SPECIALROLE_HUD)) var/image/holder = hud_list[SPECIALROLE_HUD] holder.icon_state = "hudblank" if(mind) @@ -1766,5 +1703,15 @@ speech_problem_flag = 1 return stuttering +/mob/living/carbon/human/handle_fire() + if(..()) + return + + var/burn_temperature = fire_burn_temperature() + var/thermal_protection = get_heat_protection(burn_temperature) + + if (thermal_protection < 1 && bodytemperature < burn_temperature) + bodytemperature += round(BODYTEMP_HEATING_MAX*(1-thermal_protection), 1) + #undef HUMAN_MAX_OXYLOSS #undef HUMAN_CRIT_MAX_OXYLOSS diff --git a/code/modules/mob/living/carbon/human/login.dm b/code/modules/mob/living/carbon/human/login.dm index d18d503502..7d507c62cb 100644 --- a/code/modules/mob/living/carbon/human/login.dm +++ b/code/modules/mob/living/carbon/human/login.dm @@ -1,6 +1,5 @@ /mob/living/carbon/human/Login() ..() update_hud() - ticker.mode.update_all_synd_icons() //This proc only sounds CPU-expensive on paper. It is O(n^2), but the outer for-loop only iterates through syndicates, which are only prsenet in nuke rounds and even when they exist, there's usually 6 of them. if(species) species.handle_login_special(src) return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/npcs.dm b/code/modules/mob/living/carbon/human/npcs.dm new file mode 100644 index 0000000000..290c81723e --- /dev/null +++ b/code/modules/mob/living/carbon/human/npcs.dm @@ -0,0 +1,13 @@ +/obj/item/clothing/under/punpun + name = "fancy uniform" + desc = "It looks like it was tailored for a monkey." + icon_state = "punpun" + item_color = "punpun" + species_restricted = list("Monkey") + +/mob/living/carbon/human/monkey/punpun/New() + ..() + spawn(1) + name = "Pun Pun" + real_name = name + w_uniform = new /obj/item/clothing/under/punpun(src) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index b0eeaf4146..221fbc1224 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -1,155 +1,14 @@ /mob/living/carbon/human/say(var/message) - - var/verb = "says" var/alt_name = "" - var/message_range = world.view - var/italics = 0 - - if(client) - if(client.prefs.muted & MUTE_IC) - src << "\red You cannot speak in IC (Muted)." - return - - message = trim_strip_html_properly(message) - - if(stat) - if(stat == 2) - return say_dead(message) - return + if(name != GetVoice()) + alt_name = "(as [get_id_name("Unknown")])" if (istype(src.wear_mask, /obj/item/clothing/mask/muzzle)) src << "You're muzzled and cannot speak!" return - var/message_mode = parse_message_mode(message, "headset") - - if(copytext(message,1,2) == "*") - return emote(copytext(message,2)) - - if(name != GetVoice()) - alt_name = "(as [get_id_name("Unknown")])" - - //parse the radio code and consume it - if (message_mode) - if (message_mode == "headset") - message = copytext(message,2) //it would be really nice if the parse procs could do this for us. - else - message = copytext(message,3) - - message = trim_left(message) - - //parse the language code and consume it - var/datum/language/speaking = parse_language(message) - if(speaking) - message = copytext(message,2+length(speaking.key)) - else if(species.default_language) - speaking = all_languages[species.default_language] - - var/ending = copytext(message, length(message)) - if (speaking) - // This is broadcast to all mobs with the language, - // irrespective of distance or anything else. - if(speaking.flags & HIVEMIND) - speaking.broadcast(src,trim(message)) - return - //If we've gotten this far, keep going! - verb = speaking.get_spoken_verb(ending) - else - if(ending=="!") - verb=pick("exclaims","shouts","yells") - if(ending=="?") - verb="asks" - - message = trim(message) - - if(speech_problem_flag) - if(!speaking || !(speaking.flags & NO_STUTTER)) - var/list/handle_r = handle_speech_problems(message) - message = handle_r[1] - verb = handle_r[2] - speech_problem_flag = handle_r[3] - - if(!message || message == "") - return - - var/list/obj/item/used_radios = new - - switch (message_mode) - if("headset") - if(l_ear && istype(l_ear,/obj/item/device/radio)) - var/obj/item/device/radio/R = l_ear - R.talk_into(src,message,null,verb,speaking) - used_radios += l_ear - else if(r_ear && istype(r_ear,/obj/item/device/radio)) - var/obj/item/device/radio/R = r_ear - R.talk_into(src,message,null,verb,speaking) - used_radios += r_ear - - if("right ear") - var/obj/item/device/radio/R - var/has_radio = 0 - if(r_ear && istype(r_ear,/obj/item/device/radio)) - R = r_ear - has_radio = 1 - if(r_hand && istype(r_hand, /obj/item/device/radio)) - R = r_hand - has_radio = 1 - if(has_radio) - R.talk_into(src,message,null,verb,speaking) - used_radios += R - - - if("left ear") - var/obj/item/device/radio/R - var/has_radio = 0 - if(l_ear && istype(l_ear,/obj/item/device/radio)) - R = l_ear - has_radio = 1 - if(l_hand && istype(l_hand,/obj/item/device/radio)) - R = l_hand - has_radio = 1 - if(has_radio) - R.talk_into(src,message,null,verb,speaking) - used_radios += R - - if("intercom") - for(var/obj/item/device/radio/intercom/I in view(1, null)) - I.talk_into(src, message, verb, speaking) - used_radios += I - if("whisper") - whisper_say(message, speaking, alt_name) - return - else - if(message_mode) - if(l_ear && istype(l_ear,/obj/item/device/radio)) - l_ear.talk_into(src,message, message_mode, verb, speaking) - used_radios += l_ear - else if(r_ear && istype(r_ear,/obj/item/device/radio)) - r_ear.talk_into(src,message, message_mode, verb, speaking) - used_radios += r_ear - - var/sound/speech_sound - var/sound_vol - if(species.speech_sounds && prob(species.speech_chance)) - speech_sound = sound(pick(species.speech_sounds)) - sound_vol = 50 - - //speaking into radios - if(used_radios.len) - italics = 1 - message_range = 1 - if(speaking) - message_range = speaking.get_talkinto_msg_range(message) - var/msg - if(!speaking || !(speaking.flags & NO_TALK_MSG)) - msg = "\The [src] talks into \the [used_radios[1]]" - for(var/mob/living/M in hearers(5, src)) - if((M != src) && msg) - M.show_message(msg) - if (speech_sound) - sound_vol *= 0.5 - - ..(message, speaking, verb, alt_name, italics, message_range, speech_sound, sound_vol) //ohgod we should really be passing a datum here. + message = sanitize(message) + ..(message, alt_name = alt_name) //ohgod we should really be passing a datum here. /mob/living/carbon/human/proc/forcesay(list/append) if(stat == CONSCIOUS) @@ -270,39 +129,33 @@ return verb -/mob/living/carbon/human/proc/handle_speech_problems(var/message) +/mob/living/carbon/human/handle_speech_problems(var/message, var/verb) + if(!speech_problem_flag) + return ..() var/list/returns[3] - var/verb = "says" - var/handled = 0 + speech_problem_flag = 0 if(silent || (sdisabilities & MUTE)) message = "" - handled = 1 + speech_problem_flag = 1 if(istype(wear_mask, /obj/item/clothing/mask/horsehead)) var/obj/item/clothing/mask/horsehead/hoers = wear_mask if(hoers.voicechange) if(mind && mind.changeling && department_radio_keys[copytext(message, 1, 3)] != "changeling") message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!") verb = pick("whinnies","neighs", "says") - handled = 1 + speech_problem_flag = 1 if(message != "") - if((HULK in mutations) && health >= 25 && length(message)) - message = "[uppertext(message)]!!!" - verb = pick("yells","roars","hollers") - handled = 1 - if(slurring) - message = slur(message) - verb = pick("slobbers","slurs") - handled = 1 - if(stuttering) - message = stutter(message) - verb = pick("stammers","stutters") - handled = 1 + var/list/parent = ..() + message = parent[1] + verb = parent[2] + if(parent[3]) + speech_problem_flag = 1 var/braindam = getBrainLoss() if(braindam >= 60) - handled = 1 + speech_problem_flag = 1 if(prob(braindam/4)) message = stutter(message) verb = pick("stammers", "stutters") @@ -312,5 +165,63 @@ returns[1] = message returns[2] = verb - returns[3] = handled + returns[3] = speech_problem_flag return returns + +/mob/living/carbon/human/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name) + switch(message_mode) + if("intercom") + for(var/obj/item/device/radio/intercom/I in view(1, null)) + I.talk_into(src, message, verb, speaking) + used_radios += I + if("headset") + if(l_ear && istype(l_ear,/obj/item/device/radio)) + var/obj/item/device/radio/R = l_ear + R.talk_into(src,message,null,verb,speaking) + used_radios += l_ear + else if(r_ear && istype(r_ear,/obj/item/device/radio)) + var/obj/item/device/radio/R = r_ear + R.talk_into(src,message,null,verb,speaking) + used_radios += r_ear + if("right ear") + var/obj/item/device/radio/R + var/has_radio = 0 + if(r_ear && istype(r_ear,/obj/item/device/radio)) + R = r_ear + has_radio = 1 + if(r_hand && istype(r_hand, /obj/item/device/radio)) + R = r_hand + has_radio = 1 + if(has_radio) + R.talk_into(src,message,null,verb,speaking) + used_radios += R + if("left ear") + var/obj/item/device/radio/R + var/has_radio = 0 + if(l_ear && istype(l_ear,/obj/item/device/radio)) + R = l_ear + has_radio = 1 + if(l_hand && istype(l_hand,/obj/item/device/radio)) + R = l_hand + has_radio = 1 + if(has_radio) + R.talk_into(src,message,null,verb,speaking) + used_radios += R + if("whisper") + whisper_say(message, speaking, alt_name) + return 1 + else + if(message_mode) + if(l_ear && istype(l_ear,/obj/item/device/radio)) + l_ear.talk_into(src,message, message_mode, verb, speaking) + used_radios += l_ear + else if(r_ear && istype(r_ear,/obj/item/device/radio)) + r_ear.talk_into(src,message, message_mode, verb, speaking) + used_radios += r_ear + +/mob/living/carbon/human/handle_speech_sound() + if(species.speech_sounds && prob(species.speech_chance)) + var/list/returns[2] + returns[1] = sound(pick(species.speech_sounds)) + returns[2] = 50 + return ..() diff --git a/code/modules/mob/living/carbon/human/species/outsider/vox.dm b/code/modules/mob/living/carbon/human/species/outsider/vox.dm index bf007450e3..ff99a53995 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm @@ -54,44 +54,3 @@ /datum/species/vox/get_random_name(var/gender) var/datum/language/species_language = all_languages[default_language] return species_language.get_random_name(gender) - -/datum/species/vox/armalis - name = "Vox Armalis" - name_plural = "Vox" - icobase = 'icons/mob/human_races/r_armalis.dmi' - deform = 'icons/mob/human_races/r_armalis.dmi' - rarity_value = 10 - - warning_low_pressure = 50 - hazard_low_pressure = 0 - - cold_level_1 = 80 - cold_level_2 = 50 - cold_level_3 = 0 - - heat_level_1 = 2000 - heat_level_2 = 3000 - heat_level_3 = 4000 - - brute_mod = 0.2 - burn_mod = 0.2 - - eyes = "blank_eyes" - breath_type = "nitrogen" - poison_type = "oxygen" - - flags = IS_RESTRICTED | NO_SCAN | NO_BLOOD | NO_PAIN | HAS_EYE_COLOR - - blood_color = "#2299FC" - flesh_color = "#808D11" - - tail = "armalis_tail" - icon_template = 'icons/mob/human_races/r_armalis.dmi' - - reagent_tag = IS_VOX - - inherent_verbs = list( - /mob/living/carbon/human/proc/leap, - /mob/living/carbon/human/proc/gut, - /mob/living/carbon/human/proc/commune - ) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 8bdfa8a59d..ea03c44e45 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -12,6 +12,12 @@ // Icon/appearance vars. var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set. var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set. + + // Damage overlay and masks. + var/damage_overlays = 'icons/mob/human_races/masks/dam_human.dmi' + var/damage_mask = 'icons/mob/human_races/masks/dam_mask_human.dmi' + var/blood_mask = 'icons/mob/human_races/masks/blood_human.dmi' + var/prone_icon // If set, draws this from icobase when mob is prone. var/eyes = "eyes_s" // Icon for eyes. var/blood_color = "#A10808" // Red. @@ -20,6 +26,8 @@ var/tail // Name of tail image in species effects icon file. var/race_key = 0 // Used for mob icon cache string. var/icon/icon_template // Used for mob icon generation for non-32x32 species. + var/is_small + var/show_ssd = 1 // Language/culture vars. var/default_language = "Galactic Common" // Default language is used when 'say' is used without modifiers. @@ -35,10 +43,12 @@ /datum/unarmed_attack/bite ) var/list/unarmed_attacks = null // For empty hand harm-intent attack - var/brute_mod = null // Physical damage reduction/malus. - var/burn_mod = null // Burn damage reduction/malus. + var/brute_mod = 1 // Physical damage multiplier. + var/burn_mod = 1 // Burn damage multiplier. + var/vision_flags = 0 // Same flags as glasses. // Death vars. + var/meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/human var/gibber_type = /obj/effect/gibspawner/human var/remains_type = /obj/effect/decal/remains/xeno var/gibbed_anim = "gibbed-h" @@ -56,7 +66,7 @@ var/cold_level_3 = 120 // Cold damage level 3 below this point. var/heat_level_1 = 360 // Heat damage level 1 above this point. var/heat_level_2 = 400 // Heat damage level 2 above this point. - var/heat_level_3 = 1000 // Heat damage level 2 above this point. + var/heat_level_3 = 1000 // Heat damage level 3 above this point. var/synth_temp_gain = 0 // IS_SYNTHETIC species will gain this much temperature every second var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure. var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning. @@ -65,6 +75,20 @@ var/light_dam // If set, mob will be damaged in light over this value and heal in light below its negative. var/body_temperature = 310.15 // Non-IS_SYNTHETIC species will try to stabilize at this temperature. // (also affects temperature processing) + + var/heat_discomfort_level = 315 // Aesthetic messages about feeling warm. + var/cold_discomfort_level = 285 // Aesthetic messages about feeling chilly. + var/list/heat_discomfort_strings = list( + "You feel sweat drip down your neck.", + "You feel uncomfortably warm.", + "Your skin prickles in the heat." + ) + var/list/cold_discomfort_strings = list( + "You feel chilly.", + "You shiver suddely.", + "Your chilly flesh stands out in goosebumps." + ) + // HUD data vars. var/datum/hud_data/hud var/hud_type @@ -76,7 +100,8 @@ var/darksight = 2 // Native darksight distance. var/flags = 0 // Various specific features. var/slowdown = 0 // Passive movement speed malus (or boost, if negative) - var/primitive // Lesser form, if any (ie. monkey for humans) + var/primitive_form // Lesser form, if any (ie. monkey for humans) + var/greater_form // Greater form, if any, ie. human for monkeys. var/gluttonous // Can eat some mobs. 1 for monkeys, 2 for people. var/rarity_value = 1 // Relative rarity/collector value for this species. // Determines the organs that the species spawns with and @@ -90,6 +115,11 @@ "eyes" = /datum/organ/internal/eyes ) + // Bump vars + var/bump_flag = HUMAN // What are we considered to be when bumped? + var/push_flags = ALLMOBS // What can we push? + var/swap_flags = ALLMOBS // What can we swap place with? + /datum/species/New() if(hud_type) hud = new hud_type() @@ -100,6 +130,27 @@ for(var/u_type in unarmed_types) unarmed_attacks += new u_type() +/datum/species/proc/get_environment_discomfort(var/mob/living/carbon/human/H, var/msg_type) + + if(!prob(5)) + return + + var/covered = 0 // Basic coverage can help. + for(var/obj/item/clothing/clothes in H) + if(H.l_hand == clothes|| H.r_hand == clothes) + continue + if((clothes.body_parts_covered & UPPER_TORSO) && (clothes.body_parts_covered & LOWER_TORSO)) + covered = 1 + break + + switch(msg_type) + if("cold") + if(!covered) + H << "[pick(cold_discomfort_strings)]" + if("heat") + if(covered) + H << "[pick(heat_discomfort_strings)]" + /datum/species/proc/get_random_name(var/gender) var/datum/language/species_language = all_languages[language] return species_language.get_random_name(gender) @@ -204,7 +255,7 @@ // Called when using the shredding behavior. /datum/species/proc/can_shred(var/mob/living/carbon/human/H, var/ignore_intent) - if(!ignore_intent && H.a_intent != "hurt") + if(!ignore_intent && H.a_intent != I_HURT) return 0 for(var/datum/unarmed_attack/attack in unarmed_attacks) @@ -215,3 +266,6 @@ return 0 +// Called in life() when the mob has no client. +/datum/species/proc/handle_npc(var/mob/living/carbon/human/H) + return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/species_hud.dm b/code/modules/mob/living/carbon/human/species/species_hud.dm index b7b05f48c9..2bb26ca3da 100644 --- a/code/modules/mob/living/carbon/human/species/species_hud.dm +++ b/code/modules/mob/living/carbon/human/species/species_hud.dm @@ -65,4 +65,10 @@ "storage1" = list("loc" = ui_storage1, "slot" = slot_l_store, "state" = "pocket"), "storage2" = list("loc" = ui_storage2, "slot" = slot_r_store, "state" = "pocket"), "belt" = list("loc" = ui_belt, "slot" = slot_belt, "state" = "belt") + ) + +/datum/hud_data/monkey + gear = list( + "mask" = list("loc" = ui_shoes, "slot" = slot_wear_mask, "state" = "equip", "toggle" = 1, "dir" = NORTH), + "back" = list("loc" = ui_sstore1, "slot" = slot_back, "state" = "back", "dir" = NORTH), ) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/station/golem.dm b/code/modules/mob/living/carbon/human/species/station/golem.dm index 7d7b364f5d..f04a8cb367 100644 --- a/code/modules/mob/living/carbon/human/species/station/golem.dm +++ b/code/modules/mob/living/carbon/human/species/station/golem.dm @@ -7,7 +7,7 @@ language = "Sol Common" //todo? unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch) - flags = IS_RESTRICTED | NO_BREATHE | NO_PAIN | NO_BLOOD | IS_SYNTHETIC | NO_SCAN | NO_POISON + flags = IS_RESTRICTED | NO_BREATHE | NO_PAIN | NO_BLOOD | NO_SCAN | NO_POISON siemens_coefficient = 0 breath_type = null diff --git a/code/modules/mob/living/carbon/human/species/station/monkey.dm b/code/modules/mob/living/carbon/human/species/station/monkey.dm new file mode 100644 index 0000000000..0166900a0f --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/station/monkey.dm @@ -0,0 +1,93 @@ +/datum/species/monkey + name = "Monkey" + name_plural = "Monkeys" + blurb = "Ook." + + icobase = 'icons/mob/human_races/monkeys/r_monkey.dmi' + deform = 'icons/mob/human_races/monkeys/r_monkey.dmi' + damage_overlays = 'icons/mob/human_races/masks/dam_monkey.dmi' + damage_mask = 'icons/mob/human_races/masks/dam_mask_monkey.dmi' + blood_mask = 'icons/mob/human_races/masks/blood_monkey.dmi' + language = null + default_language = "Chimpanzee" + greater_form = "Human" + is_small = 1 + has_fine_manipulation = 0 + show_ssd = 0 + eyes = "blank_eyes" + + gibbed_anim = "gibbed-m" + dusted_anim = "dust-m" + death_message = "lets out a faint chimper as it collapses and stops moving..." + tail = "chimptail" + + unarmed_types = list(/datum/unarmed_attack/bite, /datum/unarmed_attack/claws) + inherent_verbs = list(/mob/living/proc/ventcrawl) + hud_type = /datum/hud_data/monkey + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/monkey + + rarity_value = 0.1 + total_health = 75 + brute_mod = 1.5 + burn_mod = 1.5 + + flags = IS_RESTRICTED + + bump_flag = MONKEY + swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL + push_flags = MONKEY|SLIME|SIMPLE_ANIMAL|ALIEN + +/datum/species/monkey/handle_npc(var/mob/living/carbon/human/H) + if(H.stat != CONSCIOUS) + return + if(prob(33) && H.canmove && isturf(H.loc) && !H.pulledby) //won't move if being pulled + step(H, pick(cardinal)) + if(prob(1)) + H.emote(pick("scratch","jump","roll","tail")) + +/datum/species/monkey/handle_post_spawn(var/mob/living/carbon/human/H) + H.real_name = "[lowertext(name)] ([rand(100,999)])" + H.name = H.real_name + + ..() + +/datum/species/monkey/tajaran + name = "Farwa" + name_plural = "Farwa" + + icobase = 'icons/mob/human_races/monkeys/r_farwa.dmi' + deform = 'icons/mob/human_races/monkeys/r_farwa.dmi' + + greater_form = "Tajaran" + default_language = "Farwa" + flesh_color = "#AFA59E" + base_color = "#333333" + tail = "farwatail" + +/datum/species/monkey/skrell + name = "Neara" + name_plural = "Neara" + + icobase = 'icons/mob/human_races/monkeys/r_neara.dmi' + deform = 'icons/mob/human_races/monkeys/r_neara.dmi' + + greater_form = "Skrell" + default_language = "Neara" + flesh_color = "#8CD7A3" + blood_color = "#1D2CBF" + reagent_tag = IS_SKRELL + tail = null + +/datum/species/monkey/unathi + name = "Stok" + name_plural = "Stok" + + icobase = 'icons/mob/human_races/monkeys/r_stok.dmi' + deform = 'icons/mob/human_races/monkeys/r_stok.dmi' + + tail = "stoktail" + greater_form = "Unathi" + default_language = "Stok" + flesh_color = "#34AF10" + base_color = "#066000" + reagent_tag = IS_UNATHI diff --git a/code/modules/mob/living/carbon/human/species/station/slime.dm b/code/modules/mob/living/carbon/human/species/station/slime.dm index d573558143..0e148b0236 100644 --- a/code/modules/mob/living/carbon/human/species/station/slime.dm +++ b/code/modules/mob/living/carbon/human/species/station/slime.dm @@ -1,6 +1,7 @@ /datum/species/slime name = "Slime" name_plural = "slimes" + is_small = 1 icobase = 'icons/mob/human_races/r_slime.dmi' deform = 'icons/mob/human_races/r_slime.dmi' @@ -24,7 +25,11 @@ breath_type = null poison_type = null + bump_flag = SLIME + swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL + push_flags = MONKEY|SLIME|SIMPLE_ANIMAL + /datum/species/slime/handle_death(var/mob/living/carbon/human/H) spawn(1) if(H) - H.gib() \ No newline at end of file + H.gib() diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm index b7b66d2fd4..8cf07fc8d5 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -2,7 +2,7 @@ name = "Human" name_plural = "Humans" language = "Sol Common" - primitive = /mob/living/carbon/monkey + primitive_form = "Monkey" unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite) blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \ colonies across a wide swathe of space. They hold a wide range of forms and creeds.

    \ @@ -20,7 +20,7 @@ language = "Sinta'unathi" tail = "sogtail" unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp) - primitive = /mob/living/carbon/monkey/unathi + primitive_form = "Stok" darksight = 3 gluttonous = 1 @@ -45,6 +45,20 @@ reagent_tag = IS_UNATHI base_color = "#066000" + heat_discomfort_level = 295 + heat_discomfort_strings = list( + "You feel soothingly warm.", + "You feel the heat sink into your bones.", + "You feel warm enough to take a nap." + ) + + cold_discomfort_level = 292 + cold_discomfort_strings = list( + "You feel chilly.", + "You feel sluggish and cold.", + "Your scales bristle against the cold." + ) + /datum/species/tajaran name = "Tajara" name_plural = "Tajaran" @@ -54,6 +68,9 @@ tail = "tajtail" unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp) darksight = 8 + slowdown = -1 + brute_mod = 1.2 + blurb = "The Tajaran race is a species of feline-like bipeds hailing from the planet of Ahdomai in the \ S'randarr system. They have been brought up into the space age by the Humans and Skrell, and have been \ influenced heavily by their long history of Slavemaster rule. They have a structured, clan-influenced way \ @@ -68,13 +85,21 @@ heat_level_2 = 380 //Default 400 heat_level_3 = 800 //Default 1000 - primitive = /mob/living/carbon/monkey/tajara + primitive_form = "Farwa" flags = CAN_JOIN | IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR flesh_color = "#AFA59E" base_color = "#333333" + heat_discomfort_level = 292 + heat_discomfort_strings = list( + "Your fur prickles in the heat.", + "You feel uncomfortably warm.", + "Your overheated skin itches." + ) + cold_discomfort_level = 275 + /datum/species/skrell name = "Skrell" name_plural = "Skrell" @@ -82,7 +107,7 @@ deform = 'icons/mob/human_races/r_def_skrell.dmi' eyes = "skrell_eyes_s" language = "Skrellian" - primitive = /mob/living/carbon/monkey/skrell + primitive_form = "Neara" unarmed_types = list(/datum/unarmed_attack/punch) blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \ the royals' or 'Light of the Crown'.

    Skrell are a highly advanced and logical race who live under the rule \ @@ -105,7 +130,7 @@ deform = 'icons/mob/human_races/r_def_plant.dmi' language = "Rootspeak" unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/diona) - primitive = /mob/living/carbon/alien/diona + //primitive_form = "Nymph" slowdown = 7 rarity_value = 3 hud_type = /datum/hud_data/diona diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm index 167271aef9..2fc44af935 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm @@ -209,5 +209,5 @@ if("resin membrane") new /obj/effect/alien/resin/membrane(loc) if("resin nest") - new /obj/structure/stool/bed/nest(loc) + new /obj/structure/bed/nest(loc) return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm index 15cf1ce728..4265f1b39a 100644 --- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm @@ -42,6 +42,8 @@ breath_type = null poison_type = null + vision_flags = SEE_MOBS + has_organ = list( "heart" = /datum/organ/internal/heart, "brain" = /datum/organ/internal/brain/xeno, @@ -50,6 +52,10 @@ "nutrient vessel" = /datum/organ/internal/diona/nutrients ) + bump_flag = ALIEN + swap_flags = ALLMOBS + push_flags = ALLMOBS ^ ROBOT + var/alien_number = 0 var/caste_name = "creature" // Used to update alien name. var/weeds_heal_rate = 1 // Health regen on weeds. diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index bb19583119..570ee3fa62 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -107,27 +107,29 @@ Please contact me on #coderbus IRC. ~Carn x //Human Overlays Indexes///////// #define MUTATIONS_LAYER 1 #define DAMAGE_LAYER 2 -#define UNIFORM_LAYER 3 -#define TAIL_LAYER 4 //bs12 specific. this hack is probably gonna come back to haunt me +#define SURGERY_LEVEL 3 //bs12 specific. +#define UNIFORM_LAYER 4 #define ID_LAYER 5 #define SHOES_LAYER 6 #define GLOVES_LAYER 7 #define SUIT_LAYER 8 -#define GLASSES_LAYER 9 -#define BELT_LAYER 10 //Possible make this an overlay of somethign required to wear a belt? -#define SUIT_STORE_LAYER 11 -#define BACK_LAYER 12 -#define HAIR_LAYER 13 //TODO: make part of head layer? -#define EARS_LAYER 14 -#define FACEMASK_LAYER 15 -#define HEAD_LAYER 16 -#define COLLAR_LAYER 17 -#define HANDCUFF_LAYER 18 -#define LEGCUFF_LAYER 19 -#define L_HAND_LAYER 20 -#define R_HAND_LAYER 21 -#define TARGETED_LAYER 22 //BS12: Layer for the target overlay from weapon targeting system -#define TOTAL_LAYERS 22 +#define TAIL_LAYER 9 //bs12 specific. this hack is probably gonna come back to haunt me +#define GLASSES_LAYER 10 +#define BELT_LAYER 11 //Possible make this an overlay of somethign required to wear a belt? +#define SUIT_STORE_LAYER 12 +#define BACK_LAYER 13 +#define HAIR_LAYER 14 //TODO: make part of head layer? +#define EARS_LAYER 15 +#define FACEMASK_LAYER 16 +#define HEAD_LAYER 17 +#define COLLAR_LAYER 18 +#define HANDCUFF_LAYER 19 +#define LEGCUFF_LAYER 20 +#define L_HAND_LAYER 21 +#define R_HAND_LAYER 22 +#define FIRE_LAYER 23 //If you're on fire +#define TARGETED_LAYER 24 //BS12: Layer for the target overlay from weapon targeting system +#define TOTAL_LAYERS 24 ////////////////////////////////// /mob/living/carbon/human @@ -173,15 +175,6 @@ Please contact me on #coderbus IRC. ~Carn x src.transform = M var/global/list/damage_icon_parts = list() -proc/get_damage_icon_part(damage_state, body_part) - if(damage_icon_parts["[damage_state]/[body_part]"] == null) - var/icon/DI = new /icon('icons/mob/dam_human.dmi', damage_state) // the damage icon for whole human - // TODO: Convert dam_human.dmi to greyscale and blend in species.blood_colour here. - DI.Blend(new /icon('icons/mob/dam_mask.dmi', body_part), ICON_MULTIPLY) // mask with this organ's pixels - damage_icon_parts["[damage_state]/[body_part]"] = DI - return DI - else - return damage_icon_parts["[damage_state]/[body_part]"] //DAMAGE OVERLAYS //constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists @@ -200,7 +193,7 @@ proc/get_damage_icon_part(damage_state, body_part) previous_damage_appearance = damage_appearance - var/icon/standing = new /icon('icons/mob/dam_human.dmi', "00") + var/icon/standing = new /icon(species.damage_overlays, "00") var/image/standing_image = new /image("icon" = standing) @@ -209,8 +202,15 @@ proc/get_damage_icon_part(damage_state, body_part) if(!(O.status & ORGAN_DESTROYED)) O.update_icon() if(O.damage_state == "00") continue - - var/icon/DI = get_damage_icon_part(O.damage_state, O.icon_name) + var/icon/DI + var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.name]" + if(damage_icon_parts[cache_index] == null) + DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human + DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels + DI.Blend(species.blood_color, ICON_MULTIPLY) + damage_icon_parts[cache_index] = DI + else + DI = damage_icon_parts[cache_index] standing_image.overlays += DI @@ -334,7 +334,7 @@ proc/get_damage_icon_part(damage_state, body_part) base_icon.MapColors(rgb(tone[1],0,0),rgb(0,tone[2],0),rgb(0,0,tone[3])) //Handle husk overlay. - if(husk) + if(husk && ("overlay_husk" in icon_states(race_icon))) var/icon/mask = new(base_icon) var/icon/husk_over = new(race_icon,"overlay_husk") mask.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0) @@ -375,12 +375,11 @@ proc/get_damage_icon_part(damage_state, body_part) stand_icon.Blend(new/icon('icons/mob/human_face.dmi', "lips_[lip_style]_s"), ICON_OVERLAY) //Underwear - if(underwear >0 && underwear < 12 && species.flags & HAS_UNDERWEAR) - if(!fat && !skeleton) - stand_icon.Blend(new /icon('icons/mob/human.dmi', "underwear[underwear]_[g]_s"), ICON_OVERLAY) + if(underwear && species.flags & HAS_UNDERWEAR) + stand_icon.Blend(new /icon('icons/mob/human.dmi', underwear), ICON_OVERLAY) - if(undershirt>0 && undershirt < 5 && species.flags & HAS_UNDERWEAR) - stand_icon.Blend(new /icon('icons/mob/human.dmi', "undershirt[undershirt]_s"), ICON_OVERLAY) + if(undershirt && species.flags & HAS_UNDERWEAR) + stand_icon.Blend(new /icon('icons/mob/human.dmi', undershirt), ICON_OVERLAY) if(update_icons) update_icons() @@ -508,6 +507,8 @@ proc/get_damage_icon_part(damage_state, body_part) update_inv_handcuffed(0) update_inv_legcuffed(0) update_inv_pockets(0) + update_fire(0) + update_surgery(0) UpdateDamageIcon() update_icons() //Hud Stuff @@ -531,14 +532,15 @@ proc/get_damage_icon_part(damage_state, body_part) standing.icon = 'icons/mob/uniform.dmi' if(w_uniform.blood_DNA) - var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "uniformblood") + var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "uniformblood") bloodsies.color = w_uniform.blood_color standing.overlays += bloodsies - if(w_uniform:hastie) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE. - var/tie_color = w_uniform:hastie.item_color - if(!tie_color) tie_color = w_uniform:hastie.icon_state - standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]") + if(w_uniform:accessories.len) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE. + for(var/obj/item/clothing/accessory/A in w_uniform:accessories) + var/tie_color = A.item_color + if(!tie_color) tie_color = A.icon_state + standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]") overlays_standing[UNIFORM_LAYER] = standing else @@ -560,8 +562,8 @@ proc/get_damage_icon_part(damage_state, body_part) else overlays_standing[ID_LAYER] = null - hud_updateflag |= 1 << ID_HUD - hud_updateflag |= 1 << WANTED_HUD + BITSET(hud_updateflag, ID_HUD) + BITSET(hud_updateflag, WANTED_HUD) if(update_icons) update_icons() @@ -579,14 +581,14 @@ proc/get_damage_icon_part(damage_state, body_part) standing = image("icon" = 'icons/mob/hands.dmi', "icon_state" = "[t_state]") if(gloves.blood_DNA) - var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands") + var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "bloodyhands") bloodsies.color = gloves.blood_color standing.overlays += bloodsies gloves.screen_loc = ui_gloves overlays_standing[GLOVES_LAYER] = standing else if(blood_DNA) - var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands") + var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "bloodyhands") bloodsies.color = hand_blood_color overlays_standing[GLOVES_LAYER] = bloodsies else @@ -655,13 +657,13 @@ proc/get_damage_icon_part(damage_state, body_part) standing = image("icon" = 'icons/mob/feet.dmi', "icon_state" = "[shoes.icon_state]") if(shoes.blood_DNA) - var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "shoeblood") + var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "shoeblood") bloodsies.color = shoes.blood_color standing.overlays += bloodsies overlays_standing[SHOES_LAYER] = standing else if(feet_blood_DNA) - var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "shoeblood") + var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "shoeblood") bloodsies.color = feet_blood_color overlays_standing[SHOES_LAYER] = bloodsies else @@ -694,7 +696,7 @@ proc/get_damage_icon_part(damage_state, body_part) standing = image("icon" = 'icons/mob/head.dmi', "icon_state" = "[head.icon_state]") if(head.blood_DNA) - var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood") + var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "helmetblood") bloodsies.color = head.blood_color standing.overlays += bloodsies @@ -714,13 +716,22 @@ proc/get_damage_icon_part(damage_state, body_part) belt.screen_loc = ui_belt //TODO var/t_state = belt.item_state if(!t_state) t_state = belt.icon_state + var/image/standing = image("icon_state" = "[t_state]") if(belt.icon_override) - overlays_standing[BELT_LAYER] = image("icon" = belt.icon_override, "icon_state" = "[t_state]") + standing.icon = belt.icon_override else if(belt.sprite_sheets && belt.sprite_sheets[species.name]) - overlays_standing[BELT_LAYER] = image("icon" = belt.sprite_sheets[species.name], "icon_state" = "[t_state]") + standing.icon = belt.sprite_sheets[species.name] else - overlays_standing[BELT_LAYER] = image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[t_state]") + standing.icon = 'icons/mob/belt.dmi' + + if(belt.contents.len && istype(belt, /obj/item/weapon/storage/belt)) + for(var/obj/item/i in belt.contents) + var/i_state = i.item_state + if(!i_state) i_state = i.icon_state + standing.overlays += image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[i_state]") + + overlays_standing[BELT_LAYER] = standing else overlays_standing[BELT_LAYER] = null if(update_icons) update_icons() @@ -747,7 +758,7 @@ proc/get_damage_icon_part(damage_state, body_part) if(wear_suit.blood_DNA) var/obj/item/clothing/suit/S = wear_suit - var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[S.blood_overlay_type]blood") + var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "[S.blood_overlay_type]blood") bloodsies.color = wear_suit.blood_color standing.overlays += bloodsies @@ -770,7 +781,7 @@ proc/get_damage_icon_part(damage_state, body_part) /mob/living/carbon/human/update_inv_wear_mask(var/update_icons=1) - if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/tie) ) && !(head && head.flags_inv & HIDEMASK)) + if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/accessory) ) && !(head && head.flags_inv & HIDEMASK)) wear_mask.screen_loc = ui_mask //TODO var/image/standing @@ -781,8 +792,8 @@ proc/get_damage_icon_part(damage_state, body_part) else standing = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state]") - if( !istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA ) - var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "maskblood") + if( !istype(wear_mask, /obj/item/clothing/mask/smokable/cigarette) && wear_mask.blood_DNA ) + var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "maskblood") bloodsies.color = wear_mask.blood_color standing.overlays += bloodsies overlays_standing[FACEMASK_LAYER] = standing @@ -842,37 +853,47 @@ proc/get_damage_icon_part(damage_state, body_part) /mob/living/carbon/human/update_inv_r_hand(var/update_icons=1) if(r_hand) r_hand.screen_loc = ui_rhand //TODO + + var/t_icon = INV_R_HAND_DEF_ICON + if(r_hand.item_icons && (icon_r_hand in r_hand.item_icons)) + t_icon = r_hand.item_icons[icon_r_hand] + var/t_state = r_hand.item_state //useful for clothing that changes icon_state but retains the same sprite on the mob when held in hand if(!t_state) t_state = r_hand.icon_state - if(r_hand.icon_override) t_state = "[t_state]_r" overlays_standing[R_HAND_LAYER] = image("icon" = r_hand.icon_override, "icon_state" = "[t_state]") else - overlays_standing[R_HAND_LAYER] = image("icon" = 'icons/mob/items_righthand.dmi', "icon_state" = "[t_state]") + overlays_standing[R_HAND_LAYER] = image("icon" = t_icon, "icon_state" = "[t_state]") if (handcuffed) drop_r_hand() else overlays_standing[R_HAND_LAYER] = null - if(update_icons) update_icons() + + if(update_icons) update_icons() /mob/living/carbon/human/update_inv_l_hand(var/update_icons=1) if(l_hand) l_hand.screen_loc = ui_lhand //TODO + + var/t_icon = INV_L_HAND_DEF_ICON + if(l_hand.item_icons && (icon_l_hand in l_hand.item_icons)) + t_icon = l_hand.item_icons[icon_l_hand] + var/t_state = l_hand.item_state //useful for clothing that changes icon_state but retains the same sprite on the mob when held in hand if(!t_state) t_state = l_hand.icon_state - if(l_hand.icon_override) t_state = "[t_state]_l" overlays_standing[L_HAND_LAYER] = image("icon" = l_hand.icon_override, "icon_state" = "[t_state]") else - overlays_standing[L_HAND_LAYER] = image("icon" = 'icons/mob/items_lefthand.dmi', "icon_state" = "[t_state]") + overlays_standing[L_HAND_LAYER] = image("icon" = t_icon, "icon_state" = "[t_state]") if (handcuffed) drop_l_hand() else overlays_standing[L_HAND_LAYER] = null - if(update_icons) update_icons() + + if(update_icons) update_icons() /mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1) overlays_standing[TAIL_LAYER] = null @@ -903,6 +924,23 @@ proc/get_damage_icon_part(damage_state, body_part) if(update_icons) update_icons() +/mob/living/carbon/human/update_fire(var/update_icons=1) + overlays_standing[FIRE_LAYER] = null + if(on_fire) + overlays_standing[FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing", "layer"=FIRE_LAYER) + + if(update_icons) update_icons() + +/mob/living/carbon/human/proc/update_surgery(var/update_icons=1) + overlays_standing[SURGERY_LEVEL] = null + var/image/total = new + for(var/datum/organ/external/E in organs) + if(E.open) + var/image/I = image("icon"='icons/mob/surgery.dmi', "icon_state"="[E.name][round(E.open)]", "layer"=-SURGERY_LEVEL) + total.overlays += I + overlays_standing[SURGERY_LEVEL] = total + if(update_icons) update_icons() + // Used mostly for creating head items /mob/living/carbon/human/proc/generate_head_icon() //gender no longer matters for the mouth, although there should probably be seperate base head icons. @@ -941,13 +979,14 @@ proc/get_damage_icon_part(damage_state, body_part) //Human Overlays Indexes///////// #undef MUTATIONS_LAYER #undef DAMAGE_LAYER +#undef SURGERY_LEVEL #undef UNIFORM_LAYER -#undef TAIL_LAYER #undef ID_LAYER #undef SHOES_LAYER #undef GLOVES_LAYER #undef EARS_LAYER #undef SUIT_LAYER +#undef TAIL_LAYER #undef GLASSES_LAYER #undef FACEMASK_LAYER #undef BELT_LAYER @@ -961,4 +1000,5 @@ proc/get_damage_icon_part(damage_state, body_part) #undef L_HAND_LAYER #undef R_HAND_LAYER #undef TARGETED_LAYER +#undef FIRE_LAYER #undef TOTAL_LAYERS diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm index 0c9882b215..2f67cbec85 100644 --- a/code/modules/mob/living/carbon/human/whisper.dm +++ b/code/modules/mob/living/carbon/human/whisper.dm @@ -6,7 +6,7 @@ usr << "\red Speech is currently admin-disabled." return - message = trim_strip_html_properly(message) + message = sanitize(message) log_whisper("[src.name]/[src.key] : [message]") if (src.client) diff --git a/code/modules/mob/living/carbon/metroid/death.dm b/code/modules/mob/living/carbon/metroid/death.dm index 2ebc5c576b..022726b00a 100644 --- a/code/modules/mob/living/carbon/metroid/death.dm +++ b/code/modules/mob/living/carbon/metroid/death.dm @@ -1,22 +1,23 @@ /mob/living/carbon/slime/death(gibbed) if(stat == DEAD) return - stat = DEAD - if(!gibbed) - if(is_adult) - var/mob/living/carbon/slime/M = new /mob/living/carbon/slime(loc) - M.colour = colour - M.rabid = 1 - is_adult = 0 - maxHealth = 150 - revive() - regenerate_icons() - number = rand(1, 1000) - name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])" - return + if(!gibbed && is_adult) + var/mob/living/carbon/slime/M = new /mob/living/carbon/slime(loc, colour) + M.rabid = 1 + M.Friends = Friends.Copy() + step_away(M, src) + is_adult = 0 + maxHealth = 150 + revive() + regenerate_icons() + if (!client) rabid = 1 + number = rand(1, 1000) + name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])" + return - icon_state = "[colour] baby slime dead" - overlays.Cut() + . = ..(gibbed, "seizes up and falls limp...") - return ..(gibbed) \ No newline at end of file + regenerate_icons() + + return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/emote.dm b/code/modules/mob/living/carbon/metroid/emote.dm index 2cbc139f5a..a6ea5498cd 100644 --- a/code/modules/mob/living/carbon/metroid/emote.dm +++ b/code/modules/mob/living/carbon/metroid/emote.dm @@ -1,6 +1,5 @@ /mob/living/carbon/slime/emote(var/act, var/m_type=1, var/message = null) - if (findtext(act, "-", 1, null)) var/t1 = findtext(act, "-", 1, null) //param = copytext(act, t1 + 1, length(act) + 1) @@ -9,6 +8,8 @@ if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' act = copytext(act,1,length(act)) + var/updateicon = 0 + switch(act) //Alphabetical please if ("me") if(silent) @@ -59,8 +60,32 @@ message = "The [src.name] vibrates!" m_type = 1 + if("nomood") + mood = null + updateicon = 1 + + if("pout") + mood = "pout" + updateicon = 1 + + if("sad") + mood = "sad" + updateicon = 1 + + if("angry") + mood = "angry" + updateicon = 1 + + if("frown") + mood = "mischevous" + updateicon = 1 + + if("smile") + mood = ":3" + updateicon = 1 + if ("help") //This is an exception - src << "Help for slime emotes. You can use these emotes with say \"*emote\":\n\nbounce, custom, jiggle, light, moan, shiver, sway, twitch, vibrate" + src << "Help for slime emotes. You can use these emotes with say \"*emote\":\n\nbounce, custom, jiggle, light, moan, shiver, sway, twitch, vibrate. You can also set your face with: \n\nnomood, pout, sad, angry, frown, smile" else src << "\blue Unusable emote '[act]'. Say *help for a list." @@ -68,9 +93,9 @@ if (m_type & 1) for(var/mob/O in viewers(src, null)) O.show_message(message, m_type) - //Foreach goto(703) else for(var/mob/O in hearers(src, null)) O.show_message(message, m_type) - //Foreach goto(746) + if(updateicon) + regenerate_icons() return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/items.dm b/code/modules/mob/living/carbon/metroid/items.dm new file mode 100644 index 0000000000..9f10399112 --- /dev/null +++ b/code/modules/mob/living/carbon/metroid/items.dm @@ -0,0 +1,367 @@ +/obj/item/slime_extract + name = "slime extract" + desc = "Goo extracted from a slime. Legends claim these to have \"magical powers\"." + icon = 'icons/mob/slimes.dmi' + icon_state = "grey slime extract" + force = 1.0 + w_class = 1.0 + throwforce = 0 + throw_speed = 3 + throw_range = 6 + origin_tech = "biotech=4" + var/Uses = 1 // uses before it goes inert + var/enhanced = 0 //has it been enhanced before? + + attackby(obj/item/O as obj, mob/user as mob) + if(istype(O, /obj/item/weapon/slimesteroid2)) + if(enhanced == 1) + user << " This extract has already been enhanced!" + return ..() + if(Uses == 0) + user << " You can't enhance a used extract!" + return ..() + user <<"You apply the enhancer. It now has triple the amount of uses." + Uses = 3 + enhanced = 1 + del(O) + +/obj/item/slime_extract/New() + ..() + create_reagents(100) + reagents.add_reagent("slimejelly", 30) + +/obj/item/slime_extract/grey + name = "grey slime extract" + icon_state = "grey slime extract" + +/obj/item/slime_extract/gold + name = "gold slime extract" + icon_state = "gold slime extract" + +/obj/item/slime_extract/silver + name = "silver slime extract" + icon_state = "silver slime extract" + +/obj/item/slime_extract/metal + name = "metal slime extract" + icon_state = "metal slime extract" + +/obj/item/slime_extract/purple + name = "purple slime extract" + icon_state = "purple slime extract" + +/obj/item/slime_extract/darkpurple + name = "dark purple slime extract" + icon_state = "dark purple slime extract" + +/obj/item/slime_extract/orange + name = "orange slime extract" + icon_state = "orange slime extract" + +/obj/item/slime_extract/yellow + name = "yellow slime extract" + icon_state = "yellow slime extract" + +/obj/item/slime_extract/red + name = "red slime extract" + icon_state = "red slime extract" + +/obj/item/slime_extract/blue + name = "blue slime extract" + icon_state = "blue slime extract" + +/obj/item/slime_extract/darkblue + name = "dark blue slime extract" + icon_state = "dark blue slime extract" + +/obj/item/slime_extract/pink + name = "pink slime extract" + icon_state = "pink slime extract" + +/obj/item/slime_extract/green + name = "green slime extract" + icon_state = "green slime extract" + +/obj/item/slime_extract/lightpink + name = "light pink slime extract" + icon_state = "light pink slime extract" + +/obj/item/slime_extract/black + name = "black slime extract" + icon_state = "black slime extract" + +/obj/item/slime_extract/oil + name = "oil slime extract" + icon_state = "oil slime extract" + +/obj/item/slime_extract/adamantine + name = "adamantine slime extract" + icon_state = "adamantine slime extract" + +/obj/item/slime_extract/bluespace + name = "bluespace slime extract" + icon_state = "bluespace slime extract" + +/obj/item/slime_extract/pyrite + name = "pyrite slime extract" + icon_state = "pyrite slime extract" + +/obj/item/slime_extract/cerulean + name = "cerulean slime extract" + icon_state = "cerulean slime extract" + +/obj/item/slime_extract/sepia + name = "sepia slime extract" + icon_state = "sepia slime extract" + +/obj/item/slime_extract/rainbow + name = "rainbow slime extract" + icon_state = "rainbow slime extract" + +////Pet Slime Creation/// + +/obj/item/weapon/slimepotion + name = "docility potion" + desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle19" + + attack(mob/living/carbon/slime/M as mob, mob/user as mob) + if(!istype(M, /mob/living/carbon/slime))//If target is not a slime. + user << " The potion only works on baby slimes!" + return ..() + if(M.is_adult) //Can't tame adults + user << " Only baby slimes can be tamed!" + return..() + if(M.stat) + user << " The slime is dead!" + return..() + if(M.mind) + user << " The slime resists!" + return ..() + var/mob/living/simple_animal/slime/pet = new /mob/living/simple_animal/slime(M.loc) + pet.icon_state = "[M.colour] baby slime" + pet.icon_living = "[M.colour] baby slime" + pet.icon_dead = "[M.colour] baby slime dead" + pet.colour = "[M.colour]" + user <<"You feed the slime the potion, removing it's powers and calming it." + del(M) + var/newname = sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text, MAX_NAME_LEN) + + if (!newname) + newname = "pet slime" + pet.name = newname + pet.real_name = newname + del(src) + +/obj/item/weapon/slimepotion2 + name = "advanced docility potion" + desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame. This one is meant for adult slimes" + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle19" + + attack(mob/living/carbon/slime/M as mob, mob/user as mob) + if(!istype(M, /mob/living/carbon/slime/))//If target is not a slime. + user << " The potion only works on slimes!" + return ..() + if(M.stat) + user << " The slime is dead!" + return..() + if(M.mind) + user << " The slime resists!" + return ..() + var/mob/living/simple_animal/adultslime/pet = new /mob/living/simple_animal/adultslime(M.loc) + pet.icon_state = "[M.colour] adult slime" + pet.icon_living = "[M.colour] adult slime" + pet.icon_dead = "[M.colour] baby slime dead" + pet.colour = "[M.colour]" + user <<"You feed the slime the potion, removing it's powers and calming it." + del(M) + var/newname = sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text, MAX_NAME_LEN) + + if (!newname) + newname = "pet slime" + pet.name = newname + pet.real_name = newname + del(src) + + +/obj/item/weapon/slimesteroid + name = "slime steroid" + desc = "A potent chemical mix that will cause a slime to generate more extract." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle16" + + attack(mob/living/carbon/slime/M as mob, mob/user as mob) + if(!istype(M, /mob/living/carbon/slime))//If target is not a slime. + user << " The steroid only works on baby slimes!" + return ..() + if(M.is_adult) //Can't tame adults + user << " Only baby slimes can use the steroid!" + return..() + if(M.stat) + user << " The slime is dead!" + return..() + if(M.cores == 3) + user <<" The slime already has the maximum amount of extract!" + return..() + + user <<"You feed the slime the steroid. It now has triple the amount of extract." + M.cores = 3 + del(src) + +/obj/item/weapon/slimesteroid2 + name = "extract enhancer" + desc = "A potent chemical mix that will give a slime extract three uses." + icon = 'icons/obj/chemical.dmi' + icon_state = "bottle17" + + /*afterattack(obj/target, mob/user , flag) + if(istype(target, /obj/item/slime_extract)) + if(target.enhanced == 1) + user << " This extract has already been enhanced!" + return ..() + if(target.Uses == 0) + user << " You can't enhance a used extract!" + return ..() + user <<"You apply the enhancer. It now has triple the amount of uses." + target.Uses = 3 + target.enahnced = 1 + del(src)*/ + +/obj/effect/golemrune + anchored = 1 + desc = "a strange rune used to create golems. It glows when spirits are nearby." + name = "rune" + icon = 'icons/obj/rune.dmi' + icon_state = "golem" + unacidable = 1 + layer = TURF_LAYER + + New() + ..() + processing_objects.Add(src) + + process() + var/mob/dead/observer/ghost + for(var/mob/dead/observer/O in src.loc) + if(!O.client) continue + if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue + ghost = O + break + if(ghost) + icon_state = "golem2" + else + icon_state = "golem" + + attack_hand(mob/living/user as mob) + var/mob/dead/observer/ghost + for(var/mob/dead/observer/O in src.loc) + if(!O.client) continue + if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue + ghost = O + break + if(!ghost) + user << "The rune fizzles uselessly. There is no spirit nearby." + return + var/mob/living/carbon/human/G = new(src.loc) + G.set_species("Golem") + G.key = ghost.key + G << "You are an adamantine golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. Serve [user], and assist them in completing their goals at any cost." + del (src) + + + proc/announce_to_ghosts() + for(var/mob/dead/observer/G in player_list) + if(G.client) + var/area/A = get_area(src) + if(A) + G << "Golem rune created in [A.name]." + +/mob/living/carbon/slime/has_eyes() + return 0 + +//////////////////////////////Old shit from metroids/RoRos, and the old cores, would not take much work to re-add them//////////////////////// + +/* +// Basically this slime Core catalyzes reactions that normally wouldn't happen anywhere +/obj/item/slime_core + name = "slime extract" + desc = "Goo extracted from a slime. Legends claim these to have \"magical powers\"." + icon = 'icons/mob/slimes.dmi' + icon_state = "slime extract" + force = 1.0 + w_class = 1.0 + throwforce = 1.0 + throw_speed = 2 + throw_range = 6 + origin_tech = "biotech=4" + var/POWERFLAG = 0 // sshhhhhhh + var/Flush = 30 + var/Uses = 5 // uses before it goes inert + +/obj/item/slime_core/New() + ..() + create_reagents(100) + POWERFLAG = rand(1,10) + Uses = rand(7, 25) + //flags |= NOREACT +/* + spawn() + Life() + + proc/Life() + while(src) + sleep(25) + Flush-- + if(Flush <= 0) + reagents.clear_reagents() + Flush = 30 +*/ + + + +/obj/item/weapon/reagent_containers/food/snacks/egg/slime + name = "slime egg" + desc = "A small, gelatinous egg." + icon = 'icons/mob/mob.dmi' + icon_state = "slime egg-growing" + bitesize = 12 + origin_tech = "biotech=4" + var/grown = 0 + +/obj/item/weapon/reagent_containers/food/snacks/egg/slime/New() + ..() + reagents.add_reagent("nutriment", 4) + reagents.add_reagent("slimejelly", 1) + spawn(rand(1200,1500))//the egg takes a while to "ripen" + Grow() + +/obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Grow() + grown = 1 + icon_state = "slime egg-grown" + processing_objects.Add(src) + return + +/obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Hatch() + processing_objects.Remove(src) + var/turf/T = get_turf(src) + src.visible_message(" The [name] pulsates and quivers!") + spawn(rand(50,100)) + src.visible_message(" The [name] bursts open!") + new/mob/living/carbon/slime(T) + del(src) + + +/obj/item/weapon/reagent_containers/food/snacks/egg/slime/process() + var/turf/location = get_turf(src) + var/datum/gas_mixture/environment = location.return_air() + if (environment.phoron > MOLES_PHORON_VISIBLE)//phoron exposure causes the egg to hatch + src.Hatch() + +/obj/item/weapon/reagent_containers/food/snacks/egg/slime/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype( W, /obj/item/toy/crayon )) + return + else + ..() +*/ diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm index de34d74afa..f122830c76 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/metroid/life.dm @@ -1,10 +1,3 @@ -/mob/living/carbon/slime - var/AIproc = 0 // determines if the AI loop is activated - var/Atkcool = 0 // attack cooldown - var/Tempstun = 0 // temporary temperature stuns - var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while - var/SStun = 0 // stun variable - /mob/living/carbon/slime/Life() set invisibility = 0 set background = 1 @@ -15,113 +8,27 @@ ..() if(stat != DEAD) - //Chemicals in the body handle_chemicals_in_body() - handle_nutrition() - handle_targets() - - if (!ckey) + if (!client) + handle_targets() + if (!AIproc) + spawn() + handle_AI() handle_speech_and_mood() var/datum/gas_mixture/environment if(src.loc) environment = loc.return_air() - //Apparently, the person who wrote this code designed it so that - //blinded get reset each cycle and then get activated later in the - //code. Very ugly. I dont care. Moving this stuff here so its easy - //to find it. - src.blinded = null - - regular_hud_updates() // Basically just deletes any screen objects :< + regular_hud_updates() if(environment) handle_environment(environment) // Handle temperature/pressure differences between body and environment handle_regular_status_updates() // Status updates, death etc. -/mob/living/carbon/slime/proc/AIprocess() // the master AI process - - if(AIproc || stat == DEAD || client) return - - var/hungry = 0 - if (nutrition < get_starve_nutrition()) - hungry = 2 - else if (nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition()) - hungry = 1 - - AIproc = 1 - - while(AIproc && stat != 2 && (attacked || hungry || rabid || Victim)) - if(Victim) // can't eat AND have this little process at the same time - break - - if(!Target || client) - break - - if(Target.health <= -70 || Target.stat == 2) - Target = null - AIproc = 0 - break - - if(Target) - for(var/mob/living/carbon/slime/M in view(1,Target)) - if(M.Victim == Target) - Target = null - AIproc = 0 - break - if(!AIproc) - break - - if(Target in view(1,src)) - if(istype(Target, /mob/living/silicon)) - if(!Atkcool) - Atkcool = 1 - spawn(45) - Atkcool = 0 - - if(Target.Adjacent(src)) - UnarmedAttack(Target) - return - if(!Target.lying && prob(80)) - - if(Target.client && Target.health >= 20) - if(!Atkcool) - Atkcool = 1 - spawn(45) - Atkcool = 0 - - if(Target.Adjacent(src)) - UnarmedAttack(Target) - - else - if(!Atkcool && Target.Adjacent(src)) - Feedon(Target) - - else - if(!Atkcool && Target.Adjacent(src)) - Feedon(Target) - - else - if(Target in view(7, src)) - if(!Target.Adjacent(src)) // Bug of the month candidate: slimes were attempting to move to target only if it was directly next to them, which caused them to target things, but not approach them - step_to(src, Target) - sleep(5) - - else - Target = null - AIproc = 0 - break - - var/sleeptime = movement_delay() - if(sleeptime <= 0) sleeptime = 1 - - sleep(sleeptime + 2) // this is about as fast as a player slime can go - - AIproc = 0 - /mob/living/carbon/slime/proc/handle_environment(datum/gas_mixture/environment) if(!environment) adjustToxLoss(rand(10,20)) @@ -146,8 +53,6 @@ //Account for massive pressure differences if(bodytemperature < (T0C + 5)) // start calculating temperature damage etc - if(bodytemperature <= (T0C - 40)) // stun temperature - Tempstun = 1 if(bodytemperature <= (T0C - 50)) // hurt temperature if(bodytemperature <= 50) // sqrting negative numbers is bad @@ -155,9 +60,6 @@ else adjustToxLoss(round(sqrt(bodytemperature)) * 2) - else - Tempstun = 0 - updatehealth() return //TODO: DEFERRED @@ -189,22 +91,16 @@ /mob/living/carbon/slime/proc/handle_regular_status_updates() - if(is_adult) - health = 200 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) - else - health = 150 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) + src.blinded = null - if(health < config.health_threshold_dead && stat != 2) + health = maxHealth - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) + + if(health < 0 && stat != DEAD) death() return - else if(src.health < config.health_threshold_crit) - - if(!src.reagents.has_reagent("inaprovaline")) - src.adjustOxyLoss(10) - - if(src.stat != DEAD) - src.stat = UNCONSCIOUS + if (halloss) + halloss = 0 if(prob(30)) adjustOxyLoss(-1) @@ -267,27 +163,16 @@ if(nutrition <= 0) nutrition = 0 - if(prob(75)) - adjustToxLoss(rand(0,5)) + adjustToxLoss(rand(1,3)) + if (client && prob(5)) + src << "You are starving!" else if (nutrition >= get_grow_nutrition() && amount_grown < 10) nutrition -= 20 amount_grown++ - if(amount_grown >= 10 && !Victim && !Target && !ckey) - if(is_adult) - Reproduce() - else - Evolve() - /mob/living/carbon/slime/proc/handle_targets() - if(Tempstun) - if(!Victim) // not while they're eating! - canmove = 0 - else - canmove = 1 - - if(attacked > 50) attacked = 50 + if(attacked > 50) attacked = 50 // Let's not get into absurdly long periods of rage if(attacked > 0) attacked-- @@ -300,106 +185,180 @@ if(prob(10)) Discipline-- - if(!client) - if(!canmove) return + if(!canmove) return - if(Victim) return // if it's eating someone already, continue eating! + if(Victim) return // if it's eating someone already, continue eating! - if(Target) - --target_patience - if (target_patience <= 0 || SStun || Discipline || attacked) // Tired of chasing or something draws out attention - target_patience = 0 - Target = null + if(Target) + --target_patience + if (target_patience <= 0 || SStun || Discipline || attacked) // Tired of chasing or something draws out attention + target_patience = 0 + Target = null - if(AIproc && SStun) return + var/hungry = 0 // determines if the slime is hungry - var/hungry = 0 // determines if the slime is hungry + if (nutrition < get_starve_nutrition()) + hungry = 2 + else if (nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition()) + hungry = 1 - if (nutrition < get_starve_nutrition()) - hungry = 2 - else if (nutrition < get_grow_nutrition() && prob(25) || nutrition < get_hunger_nutrition()) - hungry = 1 + if(hungry == 2 && !client) // if a slime is starving, it starts losing its friends + if(Friends.len > 0 && prob(1)) + var/mob/nofriend = pick(Friends) + --Friends[nofriend] + if (Friends[nofriend] <= 0) + Friends -= nofriend - if(hungry == 2 && !client) // if a slime is starving, it starts losing its friends - if(Friends.len > 0 && prob(1)) - var/mob/nofriend = pick(Friends) - --Friends[nofriend] + if(!Target) + if(will_hunt(hungry) || attacked || rabid) // Only add to the list if we need to + var/list/targets = list() - if(!Target) - if(will_hunt() && hungry || attacked || rabid) // Only add to the list if we need to - var/list/targets = list() + for(var/mob/living/L in view(7,src)) - for(var/mob/living/L in view(7,src)) + if(isslime(L) || L.stat == DEAD) // Ignore other slimes and dead mobs + continue - if(isslime(L) || L.stat == DEAD) // Ignore other slimes and dead mobs - continue - - if(L in Friends) // No eating friends! - continue - - if(issilicon(L) && (rabid || attacked)) // They can't eat silicons, but they can glomp them in defence - targets += L // Possible target found! - - if(istype(L, /mob/living/carbon/human) && dna) //Ignore slime(wo)men - var/mob/living/carbon/human/H = L - if(H.species.name == "Slime") - continue - - if(!L.canmove) // Only one slime can latch on at a time. - var/notarget = 0 - for(var/mob/living/carbon/slime/M in view(1,L)) - if(M.Victim == L) - notarget = 1 - if(notarget) - continue + if(L in Friends) // No eating friends! + continue + if(issilicon(L) && (rabid || attacked)) // They can't eat silicons, but they can glomp them in defence targets += L // Possible target found! - if(targets.len > 0) - if(attacked || rabid || hungry == 2) - Target = targets[1] // I am attacked and am fighting back or so hungry I don't even care - else - for(var/mob/living/carbon/C in targets) - if(!Discipline && prob(5)) - if(ishuman(C)) - Target = C - break + if(istype(L, /mob/living/carbon/human) && dna) //Ignore slime(wo)men + var/mob/living/carbon/human/H = L + if(H.species.name == "Slime") + continue - if(isalien(C) || ismonkey(C)) - Target = C - break + if(!L.canmove) // Only one slime can latch on at a time. + var/notarget = 0 + for(var/mob/living/carbon/slime/M in view(1,L)) + if(M.Victim == L) + notarget = 1 + if(notarget) + continue - if (Target) - target_patience = rand(5,7) - if (is_adult) - target_patience += 3 + targets += L // Possible target found! - if(!Target) // If we have no target, we are wandering or following orders - if (Leader) - if (holding_still) - holding_still = max(holding_still - 1, 0) - else if(canmove && isturf(loc)) - step_to(src, Leader) + if(targets.len > 0) + if(attacked || rabid || hungry == 2) + Target = targets[1] // I am attacked and am fighting back or so hungry I don't even care + else + for(var/mob/living/carbon/C in targets) + if(ishuman(C) && !Discipline && prob(5)) + Target = C + break - else if(hungry) - if (holding_still) - holding_still = max(holding_still - hungry, 0) - else if(canmove && isturf(loc) && prob(50)) - step(src, pick(cardinal)) + if(isalien(C) || issmall(C) || isanimal(C)) + Target = C + break + + if (Target) + target_patience = rand(5,7) + if (is_adult) + target_patience += 3 + + if(!Target) // If we have no target, we are wandering or following orders + if (Leader) + if (holding_still) + holding_still = max(holding_still - 1, 0) + else if(canmove && isturf(loc)) + step_to(src, Leader) + + else if(hungry) + if (holding_still) + holding_still = max(holding_still - 1 - hungry, 0) + else if(canmove && isturf(loc) && prob(50)) + step(src, pick(cardinal)) + + else + if (holding_still) + holding_still = max(holding_still - 1, 0) + else if(canmove && isturf(loc) && prob(33)) + step(src, pick(cardinal)) + +/mob/living/carbon/slime/proc/handle_AI() // the master AI process + + if(stat == DEAD || client || Victim) return // If we're dead or have a client, we don't need AI, if we're feeding, we continue feeding + AIproc = 1 + + if(amount_grown >= 10 && !Target) + if(is_adult) + Reproduce() + else + Evolve() + AIproc = 0 + return + + if(Target) // We're chasing the target + if(Target.stat == DEAD) + Target = null + AIproc = 0 + return + + for(var/mob/living/carbon/slime/M in view(1, Target)) + if(M.Victim == Target) + Target = null + AIproc = 0 + return + + if(Target.Adjacent(src)) + if(istype(Target, /mob/living/silicon)) // Glomp the silicons + if(!Atkcool) + a_intent = I_HURT + UnarmedAttack(Target) + Atkcool = 1 + spawn(45) + Atkcool = 0 + AIproc = 0 + return + + if(Target.client && !Target.lying && prob(60 + powerlevel * 4)) // Try to take down the target first + if(!Atkcool) + Atkcool = 1 + spawn(45) + Atkcool = 0 + + a_intent = I_DISARM + UnarmedAttack(Target) else - if (holding_still) - holding_still = max(holding_still - 1, 0) - else if(canmove && isturf(loc) && prob(33)) - step(src, pick(cardinal)) - else if(!AIproc) - spawn() - AIprocess() + if(!Atkcool) + a_intent = I_GRAB + UnarmedAttack(Target) + + else if(Target in view(7, src)) + step_to(src, Target) + + else + Target = null + AIproc = 0 + return + + else + var/mob/living/carbon/slime/frenemy + for (var/mob/living/carbon/slime/S in view(1, src)) + if (S != src) + frenemy = S + if (frenemy && prob(1)) + if (frenemy.colour == colour) + a_intent = I_HELP + else + a_intent = I_HURT + UnarmedAttack(frenemy) + + var/sleeptime = movement_delay() + if(sleeptime <= 5) sleeptime = 5 // Maximum one action per half a second + spawn (sleeptime) + handle_AI() + return /mob/living/carbon/slime/proc/handle_speech_and_mood() //Mood starts here var/newmood = "" - if (rabid || attacked) newmood = "angry" + a_intent = I_HELP + if (rabid || attacked) + newmood = "angry" + a_intent = I_HURT else if (Target) newmood = "mischevous" if (!newmood) @@ -569,11 +528,13 @@ if (is_adult) return 300 else return 200 -/mob/living/carbon/slime/proc/will_hunt(var/hunger = -1) // Check for being stopped from feeding and chasing +/mob/living/carbon/slime/proc/will_hunt(var/hunger) // Check for being stopped from feeding and chasing if (hunger == 2 || rabid || attacked) return 1 if (Leader) return 0 if (holding_still) return 0 - return 1 + if (hunger == 1 || prob(25)) + return 1 + return 0 /mob/living/carbon/slime/slip() //Can't slip something without legs. return 0 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index 14a963cfdc..0e2a237372 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -4,10 +4,9 @@ icon_state = "grey baby slime" pass_flags = PASSTABLE var/is_adult = 0 - speak_emote = list("telepathically chirps") + speak_emote = list("chirps") layer = 5 - maxHealth = 150 health = 150 gender = NEUTER @@ -25,7 +24,7 @@ var/cores = 1 // the number of /obj/item/slime_extract's the slime has left inside var/mutation_chance = 30 // Chance of mutating, should be between 25 and 35 - var/powerlevel = 0 // 1-10 controls how much electricity they are generating + var/powerlevel = 0 // 0-10 controls how much electricity they are generating var/amount_grown = 0 // controls how long the slime has been overfed, if 10, grows or reproduces var/number = 0 // Used to understand when someone is talking to it @@ -45,6 +44,11 @@ var/mood = "" // To show its face + var/AIproc = 0 // If it's 0, we need to launch an AI proc + var/Atkcool = 0 // attack cooldown + var/SStun = 0 // NPC stun variable. Used to calm them down when they are attacked while feeding, or they will immediately re-attach + var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while. The part about freeze gun is a lie + ///////////TIME FOR SUBSPECIES var/colour = "grey" @@ -53,28 +57,21 @@ var/core_removal_stage = 0 //For removing cores. -/mob/living/carbon/slime/New() +/mob/living/carbon/slime/New(var/location, var/colour="grey") verbs += /mob/living/proc/ventcrawl create_reagents(100) - spawn (0) - number = rand(1, 1000) - name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])" - icon_state = "[colour] [is_adult ? "adult" : "baby"] slime" - real_name = name - slime_mutation = mutation_table(colour) - mutation_chance = rand(25, 35) - var/sanitizedcolour = replacetext(colour, " ", "") - coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]") - ..() -/mob/living/carbon/slime/regenerate_icons() - icon_state = "[colour] [is_adult ? "adult" : "baby"] slime" - overlays.len = 0 - if (mood) - overlays += image('icons/mob/slimes.dmi', icon_state = "aslime-[mood]") - ..() + src.colour = colour + number = rand(1, 1000) + name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])" + real_name = name + slime_mutation = mutation_table(colour) + mutation_chance = rand(25, 35) + var/sanitizedcolour = replacetext(colour, " ", "") + coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]") + ..(location) /mob/living/carbon/slime/movement_delay() if (bodytemperature >= 330.23) // 135 F @@ -82,8 +79,8 @@ var/tally = 0 - var/health_deficiency = (100 - health) - if(health_deficiency >= 45) tally += (health_deficiency / 25) + var/health_deficiency = (maxHealth - health) + if(health_deficiency >= 30) tally += (health_deficiency / 25) if (bodytemperature < 183.222) tally += (283.222 - bodytemperature) / 10 * 1.75 @@ -105,25 +102,23 @@ return now_pushing = 1 - if(isobj(AM)) - if(!client && powerlevel > 0) - var/probab = 10 - switch(powerlevel) - if(1 to 2) probab = 20 - if(3 to 4) probab = 30 - if(5 to 6) probab = 40 - if(7 to 8) probab = 60 - if(9) probab = 70 - if(10) probab = 95 - if(prob(probab)) - if(istype(AM, /obj/structure/window) || istype(AM, /obj/structure/grille)) - if(nutrition <= get_hunger_nutrition() && !Atkcool) - if (is_adult || prob(5)) - UnarmedAttack(AM) - spawn() - Atkcool = 1 - sleep(45) - Atkcool = 0 + if(isobj(AM) && !client && powerlevel > 0) + var/probab = 10 + switch(powerlevel) + if(1 to 2) probab = 20 + if(3 to 4) probab = 30 + if(5 to 6) probab = 40 + if(7 to 8) probab = 60 + if(9) probab = 70 + if(10) probab = 95 + if(prob(probab)) + if(istype(AM, /obj/structure/window) || istype(AM, /obj/structure/grille)) + if(nutrition <= get_hunger_nutrition() && !Atkcool) + if (is_adult || prob(5)) + UnarmedAttack(AM) + Atkcool = 1 + spawn(45) + Atkcool = 0 if(ismob(AM)) var/mob/tmob = AM @@ -139,21 +134,8 @@ return now_pushing = 0 + ..() - if (!istype(AM, /atom/movable)) - return - if (!( now_pushing )) - now_pushing = 1 - if (!( AM.anchored )) - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - var/obj/structure/window/W = AM - if(W.is_full_window()) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - now_pushing = null /mob/living/carbon/slime/Process_Spacemove() return 2 @@ -162,10 +144,8 @@ ..() statpanel("Status") - if(is_adult) - stat(null, "Health: [round((health / 200) * 100)]%") - else - stat(null, "Health: [round((health / 150) * 100)]%") + stat(null, "Health: [round((health / maxHealth) * 100)]%") + stat(null, "Intent: [a_intent]") if (client.statpanel == "Status") stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]") @@ -227,9 +207,7 @@ if(shielded) damage /= 4 - //paralysis += 1 - - show_message(" The blob attacks you!") + show_message(" The blob attacks you!") adjustFireLoss(damage) @@ -244,14 +222,12 @@ return /mob/living/carbon/slime/meteorhit(O as obj) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message(text("\red [] has been hit by []", src, O), 1) - if (health > 0) - adjustBruteLoss((istype(O, /obj/effect/meteor/small) ? 10 : 25)) - adjustFireLoss(30) + visible_message("[src] has been hit by [O]") - updatehealth() + adjustBruteLoss((istype(O, /obj/effect/meteor/small) ? 10 : 25)) + adjustFireLoss(30) + + updatehealth() return /mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M as mob) @@ -271,11 +247,9 @@ if(prob(90) && !client) Discipline++ - spawn() - SStun = 1 - sleep(rand(45,60)) - if(src) - SStun = 0 + SStun = 1 + spawn(rand(45,60)) + SStun = 0 Victim = null anchored = 0 @@ -299,11 +273,9 @@ if(Discipline == 1) attacked = 0 - spawn() - SStun = 1 - sleep(rand(55,65)) - if(src) - SStun = 0 + SStun = 1 + spawn(rand(55,65)) + SStun = 0 Victim = null anchored = 0 @@ -313,10 +285,10 @@ switch(M.a_intent) - if ("help") + if (I_HELP) help_shake_act(M) - if ("grab") + if (I_GRAB) if (M == src || anchored) return var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src) @@ -345,15 +317,13 @@ if(prob(80) && !client) Discipline++ spawn(0) - step_away(src,M,15) sleep(3) step_away(src,M,15) - playsound(loc, "punch", 25, 1, -1) visible_message("[M] has punched [src]!", \ - "[M] has punched [src]!") + "[M] has punched [src]!") adjustBruteLoss(damage) updatehealth() @@ -381,9 +351,8 @@ Target = null anchored = 0 - spawn() - SStun = 1 - sleep(rand(5,20)) + SStun = 1 + spawn(rand(5,20)) SStun = 0 spawn(0) @@ -403,9 +372,8 @@ Discipline++ if(Discipline == 1) attacked = 0 - spawn() - SStun = 1 - sleep(rand(5,20)) + SStun = 1 + spawn(rand(5,20)) SStun = 0 Victim = null @@ -426,8 +394,8 @@ /mob/living/carbon/slime/restrained() return 0 -mob/living/carbon/slime/var/co2overloadtime = null -mob/living/carbon/slime/var/temperature_resistance = T0C+75 +/mob/living/carbon/slime/var/co2overloadtime = null +/mob/living/carbon/slime/var/temperature_resistance = T0C+75 /mob/living/carbon/slime/show_inv(mob/user) return @@ -435,8 +403,17 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 /mob/living/carbon/slime/toggle_throw_mode() return -/mob/living/carbon/slime/proc/apply_water() - adjustToxLoss(rand(15,20)) +/mob/living/carbon/slime/proc/gain_nutrition(var/amount) + nutrition += amount + if(prob(amount * 2)) // Gain around one level per 50 nutrition + powerlevel++ + if(powerlevel > 10) + powerlevel = 10 + adjustToxLoss(-10) + nutrition = max(nutrition, get_max_nutrition()) + +/mob/living/carbon/slime/proc/apply_water(var/amount) + adjustToxLoss(15 + amount) if (!client) if (Target) // Like cats Target = null @@ -446,371 +423,4 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 /mob/living/carbon/slime/can_use_vents() if(Victim) return "You cannot ventcrawl while feeding." - ..() - -/obj/item/slime_extract - name = "slime extract" - desc = "Goo extracted from a slime. Legends claim these to have \"magical powers\"." - icon = 'icons/mob/slimes.dmi' - icon_state = "grey slime extract" - force = 1.0 - w_class = 1.0 - throwforce = 0 - throw_speed = 3 - throw_range = 6 - origin_tech = "biotech=4" - var/Uses = 1 // uses before it goes inert - var/enhanced = 0 //has it been enhanced before? - - attackby(obj/item/O as obj, mob/user as mob) - if(istype(O, /obj/item/weapon/slimesteroid2)) - if(enhanced == 1) - user << " This extract has already been enhanced!" - return ..() - if(Uses == 0) - user << " You can't enhance a used extract!" - return ..() - user <<"You apply the enhancer. It now has triple the amount of uses." - Uses = 3 - enhanced = 1 - del(O) - -/obj/item/slime_extract/New() - ..() - create_reagents(100) - -/obj/item/slime_extract/grey - name = "grey slime extract" - icon_state = "grey slime extract" - -/obj/item/slime_extract/gold - name = "gold slime extract" - icon_state = "gold slime extract" - -/obj/item/slime_extract/silver - name = "silver slime extract" - icon_state = "silver slime extract" - -/obj/item/slime_extract/metal - name = "metal slime extract" - icon_state = "metal slime extract" - -/obj/item/slime_extract/purple - name = "purple slime extract" - icon_state = "purple slime extract" - -/obj/item/slime_extract/darkpurple - name = "dark purple slime extract" - icon_state = "dark purple slime extract" - -/obj/item/slime_extract/orange - name = "orange slime extract" - icon_state = "orange slime extract" - -/obj/item/slime_extract/yellow - name = "yellow slime extract" - icon_state = "yellow slime extract" - -/obj/item/slime_extract/red - name = "red slime extract" - icon_state = "red slime extract" - -/obj/item/slime_extract/blue - name = "blue slime extract" - icon_state = "blue slime extract" - -/obj/item/slime_extract/darkblue - name = "dark blue slime extract" - icon_state = "dark blue slime extract" - -/obj/item/slime_extract/pink - name = "pink slime extract" - icon_state = "pink slime extract" - -/obj/item/slime_extract/green - name = "green slime extract" - icon_state = "green slime extract" - -/obj/item/slime_extract/lightpink - name = "light pink slime extract" - icon_state = "light pink slime extract" - -/obj/item/slime_extract/black - name = "black slime extract" - icon_state = "black slime extract" - -/obj/item/slime_extract/oil - name = "oil slime extract" - icon_state = "oil slime extract" - -/obj/item/slime_extract/adamantine - name = "adamantine slime extract" - icon_state = "adamantine slime extract" - -/obj/item/slime_extract/bluespace - name = "bluespace slime extract" - icon_state = "bluespace slime extract" - -/obj/item/slime_extract/pyrite - name = "pyrite slime extract" - icon_state = "pyrite slime extract" - -/obj/item/slime_extract/cerulean - name = "cerulean slime extract" - icon_state = "cerulean slime extract" - -/obj/item/slime_extract/sepia - name = "sepia slime extract" - icon_state = "sepia slime extract" - -/obj/item/slime_extract/rainbow - name = "rainbow slime extract" - icon_state = "rainbow slime extract" - -////Pet Slime Creation/// - -/obj/item/weapon/slimepotion - name = "docility potion" - desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle19" - - attack(mob/living/carbon/slime/M as mob, mob/user as mob) - if(!istype(M, /mob/living/carbon/slime))//If target is not a slime. - user << " The potion only works on baby slimes!" - return ..() - if(M.is_adult) //Can't tame adults - user << " Only baby slimes can be tamed!" - return..() - if(M.stat) - user << " The slime is dead!" - return..() - if(M.mind) - user << " The slime resists!" - return ..() - var/mob/living/simple_animal/slime/pet = new /mob/living/simple_animal/slime(M.loc) - pet.icon_state = "[M.colour] baby slime" - pet.icon_living = "[M.colour] baby slime" - pet.icon_dead = "[M.colour] baby slime dead" - pet.colour = "[M.colour]" - user <<"You feed the slime the potion, removing it's powers and calming it." - del(M) - var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN)) - - if (!newname) - newname = "pet slime" - pet.name = newname - pet.real_name = newname - del(src) - -/obj/item/weapon/slimepotion2 - name = "advanced docility potion" - desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame. This one is meant for adult slimes" - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle19" - - attack(mob/living/carbon/slime/M as mob, mob/user as mob) - if(!istype(M, /mob/living/carbon/slime/))//If target is not a slime. - user << " The potion only works on slimes!" - return ..() - if(M.stat) - user << " The slime is dead!" - return..() - if(M.mind) - user << " The slime resists!" - return ..() - var/mob/living/simple_animal/adultslime/pet = new /mob/living/simple_animal/adultslime(M.loc) - pet.icon_state = "[M.colour] adult slime" - pet.icon_living = "[M.colour] adult slime" - pet.icon_dead = "[M.colour] baby slime dead" - pet.colour = "[M.colour]" - user <<"You feed the slime the potion, removing it's powers and calming it." - del(M) - var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN)) - - if (!newname) - newname = "pet slime" - pet.name = newname - pet.real_name = newname - del(src) - - -/obj/item/weapon/slimesteroid - name = "slime steroid" - desc = "A potent chemical mix that will cause a slime to generate more extract." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" - - attack(mob/living/carbon/slime/M as mob, mob/user as mob) - if(!istype(M, /mob/living/carbon/slime))//If target is not a slime. - user << " The steroid only works on baby slimes!" - return ..() - if(M.is_adult) //Can't tame adults - user << " Only baby slimes can use the steroid!" - return..() - if(M.stat) - user << " The slime is dead!" - return..() - if(M.cores == 3) - user <<" The slime already has the maximum amount of extract!" - return..() - - user <<"You feed the slime the steroid. It now has triple the amount of extract." - M.cores = 3 - del(src) - -/obj/item/weapon/slimesteroid2 - name = "extract enhancer" - desc = "A potent chemical mix that will give a slime extract three uses." - icon = 'icons/obj/chemical.dmi' - icon_state = "bottle17" - - /*afterattack(obj/target, mob/user , flag) - if(istype(target, /obj/item/slime_extract)) - if(target.enhanced == 1) - user << " This extract has already been enhanced!" - return ..() - if(target.Uses == 0) - user << " You can't enhance a used extract!" - return ..() - user <<"You apply the enhancer. It now has triple the amount of uses." - target.Uses = 3 - target.enahnced = 1 - del(src)*/ - -/obj/effect/golemrune - anchored = 1 - desc = "a strange rune used to create golems. It glows when spirits are nearby." - name = "rune" - icon = 'icons/obj/rune.dmi' - icon_state = "golem" - unacidable = 1 - layer = TURF_LAYER - - New() - ..() - processing_objects.Add(src) - - process() - var/mob/dead/observer/ghost - for(var/mob/dead/observer/O in src.loc) - if(!O.client) continue - if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue - ghost = O - break - if(ghost) - icon_state = "golem2" - else - icon_state = "golem" - - attack_hand(mob/living/user as mob) - var/mob/dead/observer/ghost - for(var/mob/dead/observer/O in src.loc) - if(!O.client) continue - if(O.mind && O.mind.current && O.mind.current.stat != DEAD) continue - ghost = O - break - if(!ghost) - user << "The rune fizzles uselessly. There is no spirit nearby." - return - var/mob/living/carbon/human/G = new(src.loc) - G.set_species("Golem") - G.key = ghost.key - G << "You are an adamantine golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. Serve [user], and assist them in completing their goals at any cost." - del (src) - - - proc/announce_to_ghosts() - for(var/mob/dead/observer/G in player_list) - if(G.client) - var/area/A = get_area(src) - if(A) - G << "Golem rune created in [A.name]." - -/mob/living/carbon/slime/has_eyes() - return 0 - -//////////////////////////////Old shit from metroids/RoRos, and the old cores, would not take much work to re-add them//////////////////////// - -/* -// Basically this slime Core catalyzes reactions that normally wouldn't happen anywhere -/obj/item/slime_core - name = "slime extract" - desc = "Goo extracted from a slime. Legends claim these to have \"magical powers\"." - icon = 'icons/mob/slimes.dmi' - icon_state = "slime extract" - force = 1.0 - w_class = 1.0 - throwforce = 1.0 - throw_speed = 2 - throw_range = 6 - origin_tech = "biotech=4" - var/POWERFLAG = 0 // sshhhhhhh - var/Flush = 30 - var/Uses = 5 // uses before it goes inert - -/obj/item/slime_core/New() - ..() - create_reagents(100) - POWERFLAG = rand(1,10) - Uses = rand(7, 25) - //flags |= NOREACT -/* - spawn() - Life() - - proc/Life() - while(src) - sleep(25) - Flush-- - if(Flush <= 0) - reagents.clear_reagents() - Flush = 30 -*/ - - - -/obj/item/weapon/reagent_containers/food/snacks/egg/slime - name = "slime egg" - desc = "A small, gelatinous egg." - icon = 'icons/mob/mob.dmi' - icon_state = "slime egg-growing" - bitesize = 12 - origin_tech = "biotech=4" - var/grown = 0 - -/obj/item/weapon/reagent_containers/food/snacks/egg/slime/New() - ..() - reagents.add_reagent("nutriment", 4) - reagents.add_reagent("slimejelly", 1) - spawn(rand(1200,1500))//the egg takes a while to "ripen" - Grow() - -/obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Grow() - grown = 1 - icon_state = "slime egg-grown" - processing_objects.Add(src) - return - -/obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Hatch() - processing_objects.Remove(src) - var/turf/T = get_turf(src) - src.visible_message(" The [name] pulsates and quivers!") - spawn(rand(50,100)) - src.visible_message(" The [name] bursts open!") - new/mob/living/carbon/slime(T) - del(src) - - -/obj/item/weapon/reagent_containers/food/snacks/egg/slime/process() - var/turf/location = get_turf(src) - var/datum/gas_mixture/environment = location.return_air() - if (environment.phoron > MOLES_PHORON_VISIBLE)//phoron exposure causes the egg to hatch - src.Hatch() - -/obj/item/weapon/reagent_containers/food/snacks/egg/slime/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype( W, /obj/item/toy/crayon )) - return - else - ..() -*/ + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/powers.dm b/code/modules/mob/living/carbon/metroid/powers.dm index 23ca8acbf6..b2f8c2588f 100644 --- a/code/modules/mob/living/carbon/metroid/powers.dm +++ b/code/modules/mob/living/carbon/metroid/powers.dm @@ -1,75 +1,46 @@ -/mob/living/carbon/slime/verb/Feed() - set category = "Slime" - set desc = "This will let you feed on any valid creature in the surrounding area. This should also be used to halt the feeding process." - if(Victim) +/mob/living/carbon/slime/proc/Wrap(var/mob/living/M) // This is a proc for the clicks + if (Victim == M || src == M) Feedstop() return - if(stat) - src << "I must be conscious to do this..." + if (Victim) + src << "I am already feeding..." return - var/list/choices = list() - for(var/mob/living/C in view(1,src)) - if(C!=src && !istype(C,/mob/living/carbon/slime) && Adjacent(C)) - choices += C - - var/mob/living/M = input(src,"Who do you wish to feed on?") in null|choices - if(!M) return - if(Adjacent(M)) - - if(!istype(src, /mob/living/carbon/brain)) - if(!istype(M, /mob/living/carbon/slime)) - if(stat != 2) - if(health > -70) - - for(var/mob/living/carbon/slime/met in view()) - if(met.Victim == M && met != src) - src << "The [met.name] is already feeding on this subject..." - return - src << "\blue I have latched onto the subject and begun feeding..." - M << "\red The [src.name] has latched onto your head!" - Feedon(M) - - else - src << "This subject does not have a strong enough life energy..." - else - src << "This subject does not have an edible life energy..." - else - src << "I must not feed on my brothers..." - else - src << "This subject does not have an edible life energy..." + var t = invalidFeedTarget(M) + if (t) + src << t + return + Feedon(M) +/mob/living/carbon/slime/proc/invalidFeedTarget(var/mob/living/M) + if (!M || !istype(M)) + return "This subject is incomparable..." + if (istype(M, /mob/living/carbon/slime)) // No cannibalism... yet + return "I cannot feed on other slimes..." + if (!Adjacent(M)) + return "This subject is too far away..." + if (istype(M, /mob/living/carbon) && M.getCloneLoss() > 150 || istype(M, /mob/living/simple_animal) && M.stat == DEAD) + return "This subject does not have an edible life energy..." + for(var/mob/living/carbon/slime/met in view()) + if(met.Victim == M && met != src) + return "The [met.name] is already feeding on this subject..." + return 0 /mob/living/carbon/slime/proc/Feedon(var/mob/living/M) Victim = M - src.loc = M.loc + loc = M.loc canmove = 0 anchored = 1 - var/lastnut = nutrition - var/fed_succesfully = 0 - if(is_adult) - icon_state = "[colour] adult slime eat" - else - icon_state = "[colour] baby slime eat" - while(Victim && M.health > -70 && stat != 2) + regenerate_icons() + + while(Victim && !invalidFeedTarget(M) && stat != 2) canmove = 0 if(Adjacent(M)) - loc = M.loc - - if(prob(15) && M.client && istype(M, /mob/living/carbon)) - var/mob/living/carbon/C = M - if (!(C.species && (C.species.flags & NO_PAIN))) - M << "[pick("You can feel your body becoming weak!", \ - "You feel like you're about to die!", \ - "You feel every part of your body screaming in agony!", \ - "A low, rolling pain passes through your body!", \ - "Your body feels as if it's falling apart!", \ - "You feel extremely weak!", \ - "A sharp, deep pain bathes every inch of your body!")]" + UpdateFeed(M) if(istype(M, /mob/living/carbon)) Victim.adjustCloneLoss(rand(5,6)) @@ -77,83 +48,51 @@ if(Victim.health <= 0) Victim.adjustToxLoss(rand(2,4)) - fed_succesfully = 1 - else if(istype(M, /mob/living/simple_animal)) Victim.adjustBruteLoss(is_adult ? rand(7, 15) : rand(4, 12)) - fed_succesfully = 1 else - if(prob(25)) - src << "[pick("This subject is incompatable", \ - "This subject does not have a life energy", "This subject is empty", \ - "I am not satisified", "I can not feed from this subject", \ - "I do not feel nourished", "This subject is not food")]..." + src << "[pick("This subject is incompatable", "This subject does not have a life energy", "This subject is empty", "I am not satisified", "I can not feed from this subject", "I do not feel nourished", "This subject is not food")]..." + Feedstop() + break - if(fed_succesfully) - //I have no idea why this is not in handle_nutrition() - nutrition += rand(15,30) - if(nutrition >= lastnut + 50) - if(prob(80)) - lastnut = nutrition - powerlevel++ - if(powerlevel > 10) - powerlevel = 10 - adjustToxLoss(-10) + if(prob(15) && M.client && istype(M, /mob/living/carbon)) + var/painMes = pick("You can feel your body becoming weak!", "You feel like you're about to die!", "You feel every part of your body screaming in agony!", "A low, rolling pain passes through your body!", "Your body feels as if it's falling apart!", "You feel extremely weak!", "A sharp, deep pain bathes every inch of your body!") + if (ishuman(M)) + var/mob/living/carbon/human/H = M + H.custom_pain(painMes) + else if (istype(M, /mob/living/carbon)) + var/mob/living/carbon/C = M + if (!(C.species && (C.species.flags & NO_PAIN))) + M << "[painMes]" - //Heal yourself. - adjustOxyLoss(-10) - adjustBruteLoss(-10) - adjustFireLoss(-10) - adjustCloneLoss(-10) + gain_nutrition(rand(20,25)) - updatehealth() - if(Victim) - Victim.updatehealth() - - sleep(rand(15,45)) + adjustOxyLoss(-10) //Heal yourself + adjustBruteLoss(-10) + adjustFireLoss(-10) + adjustCloneLoss(-10) + updatehealth() + if(Victim) + Victim.updatehealth() + sleep(30) // Deal damage every 3 seconds else break - if(stat == 2) - if(!is_adult) - icon_state = "[colour] baby slime dead" - - else - if(is_adult) - icon_state = "[colour] adult slime" - else - icon_state = "[colour] baby slime" - canmove = 1 anchored = 0 - if(M) - if(M.health <= -70) - M.canmove = 0 - if(!client) - if(Victim && !rabid && !attacked) - if(Victim.LAssailant && Victim.LAssailant != Victim) - if(prob(50)) - if(!(Victim.LAssailant in Friends)) - Friends[Victim.LAssailant] = 1 - //Friends.Add(Victim.LAssailant) // no idea why i was using the |= operator - else - ++Friends[Victim.LAssailant] + if(M && invalidFeedTarget(M)) // This means that the slime drained the victim + if(!client) + if(Victim && !rabid && !attacked && Victim.LAssailant && Victim.LAssailant != Victim && prob(50)) + if(!(Victim.LAssailant in Friends)) + Friends[Victim.LAssailant] = 1 + else + ++Friends[Victim.LAssailant] - - if(M.client && istype(src, /mob/living/carbon/human)) - if(prob(85)) - rabid = 1 // UUUNNBGHHHH GONNA EAT JUUUUUU - - if(client) src << "This subject does not have a strong enough life energy anymore..." else - M.canmove = 1 - - if(client) src << "I have stopped feeding..." - else - if(client) src << "I have stopped feeding..." + src << "This subject does not have a strong enough life energy anymore..." Victim = null @@ -167,14 +106,14 @@ if(Victim == M) loc = M.loc // simple "attach to head" effect! - /mob/living/carbon/slime/verb/Evolve() set category = "Slime" set desc = "This will let you evolve from baby to adult slime." if(stat) - src << "I must be conscious to do this..." + src << "I must be conscious to do this..." return + if(!is_adult) if(amount_grown >= 10) is_adult = 1 @@ -183,36 +122,35 @@ regenerate_icons() name = text("[colour] [is_adult ? "adult" : "baby"] slime ([number])") else - src << "I am not ready to evolve yet..." + src << "I am not ready to evolve yet..." else - src << "I have already evolved..." + src << "I have already evolved..." /mob/living/carbon/slime/verb/Reproduce() set category = "Slime" set desc = "This will make you split into four Slimes." if(stat) - src << "I must be conscious to do this..." + src << "I must be conscious to do this..." return if(is_adult) if(amount_grown >= 10) if(stat) - src << "I must be conscious to do this..." + src << "I must be conscious to do this..." return var/list/babies = list() var/new_nutrition = round(nutrition * 0.9) var/new_powerlevel = round(powerlevel / 4) - for(var/i=1,i<=4,i++) - var/mob/living/carbon/slime/M = new /mob/living/carbon/slime/(loc) + for(var/i = 1, i <= 4, i++) + var/t = colour if(prob(mutation_chance)) - M.colour = slime_mutation[rand(1,4)] - else - M.colour = colour + t = slime_mutation[rand(1,4)] + var/mob/living/carbon/slime/M = new /mob/living/carbon/slime/(loc, t) if(ckey) M.nutrition = new_nutrition //Player slimes are more robust at spliting. Once an oversight of poor copypasta, now a feature! M.powerlevel = new_powerlevel - if(i != 1) step_away(M,src) + if(i != 1) step_away(M, src) M.Friends = Friends.Copy() babies += M feedback_add_details("slime_babies_born","slimebirth_[replacetext(M.colour," ","_")]") @@ -225,6 +163,6 @@ new_slime.key = src.key del(src) else - src << "I am not ready to reproduce yet..." + src << "I am not ready to reproduce yet..." else - src << "I am not old enough to reproduce yet..." \ No newline at end of file + src << "I am not old enough to reproduce yet..." \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/say.dm b/code/modules/mob/living/carbon/metroid/say.dm index f4de10ceb7..f1a1761908 100644 --- a/code/modules/mob/living/carbon/metroid/say.dm +++ b/code/modules/mob/living/carbon/metroid/say.dm @@ -10,11 +10,11 @@ var/ending = copytext(text, length(text)) if (ending == "?") - return "telepathically asks"; + return "asks"; else if (ending == "!") - return "telepathically cries"; + return "cries"; - return "telepathically chirps"; + return "chirps"; /mob/living/carbon/slime/say_understands(var/other) if (istype(other, /mob/living/carbon/slime)) diff --git a/code/modules/mob/living/carbon/metroid/subtypes.dm b/code/modules/mob/living/carbon/metroid/subtypes.dm index 9db9e7b02f..6aa75990ac 100644 --- a/code/modules/mob/living/carbon/metroid/subtypes.dm +++ b/code/modules/mob/living/carbon/metroid/subtypes.dm @@ -1,4 +1,4 @@ -proc/mutation_table(var/colour) +/mob/living/carbon/slime/proc/mutation_table(var/colour) var/list/slime_mutation[4] switch(colour) //Tier 1 diff --git a/code/modules/mob/living/carbon/metroid/update_icons.dm b/code/modules/mob/living/carbon/metroid/update_icons.dm index 8902770055..847dcaeb18 100644 --- a/code/modules/mob/living/carbon/metroid/update_icons.dm +++ b/code/modules/mob/living/carbon/metroid/update_icons.dm @@ -1 +1,9 @@ -//no special icon processing +/mob/living/carbon/slime/regenerate_icons() + if (stat == DEAD) + icon_state = "[colour] baby slime dead" + else + icon_state = "[colour] [is_adult ? "adult" : "baby"] slime[Victim ? "" : " eat"]" + overlays.len = 0 + if (mood) + overlays += image('icons/mob/slimes.dmi', icon_state = "aslime-[mood]") + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/monkey/death.dm b/code/modules/mob/living/carbon/monkey/death.dm deleted file mode 100644 index 6d0c48c804..0000000000 --- a/code/modules/mob/living/carbon/monkey/death.dm +++ /dev/null @@ -1,8 +0,0 @@ -/mob/living/carbon/monkey/gib() - ..(null,1) - -/mob/living/carbon/monkey/dust() - ..("dust-m") - -/mob/living/carbon/monkey/death(gibbed) - ..(gibbed,"lets out a faint chimper as it collapses and stops moving...") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/monkey/emote.dm b/code/modules/mob/living/carbon/monkey/emote.dm deleted file mode 100644 index 92493b6d38..0000000000 --- a/code/modules/mob/living/carbon/monkey/emote.dm +++ /dev/null @@ -1,132 +0,0 @@ -/mob/living/carbon/monkey/emote(var/act,var/m_type=1,var/message = null) - - var/param = null - if (findtext(act, "-", 1, null)) - var/t1 = findtext(act, "-", 1, null) - param = copytext(act, t1 + 1, length(act) + 1) - act = copytext(act, 1, t1) - - if(findtext(act,"s",-1) && !findtext(act,"_",-2))//Removes ending s's unless they are prefixed with a '_' - act = copytext(act,1,length(act)) - - var/muzzled = istype(src.wear_mask, /obj/item/clothing/mask/muzzle) - - switch(act) - if ("me") - if(silent) - return - if (src.client) - if (client.prefs.muted & MUTE_IC) - src << "\red You cannot send IC messages (muted)." - return - if (src.client.handle_spam_prevention(message,MUTE_IC)) - return - if (stat) - return - if(!(message)) - return - return custom_emote(m_type, message) - - - if ("custom") - return custom_emote(m_type, message) - - if("sign") - if (!src.restrained()) - message = text("The monkey signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null)) - m_type = 1 - if("scratch") - if (!src.restrained()) - message = "The [src.name] scratches." - m_type = 1 - if("whimper") - if (!muzzled) - message = "The [src.name] whimpers." - m_type = 2 - if("roar") - if (!muzzled) - message = "The [src.name] roars." - m_type = 2 - if("tail") - message = "The [src.name] waves his tail." - m_type = 1 - if("gasp") - message = "The [src.name] gasps." - m_type = 2 - if("shiver") - message = "The [src.name] shivers." - m_type = 2 - if("drool") - message = "The [src.name] drools." - m_type = 1 - if("paw") - if (!src.restrained()) - message = "The [src.name] flails his paw." - m_type = 1 - if("scretch") - if (!muzzled) - message = "The [src.name] scretches." - m_type = 2 - if("choke") - message = "The [src.name] chokes." - m_type = 2 - if("moan") - message = "The [src.name] moans!" - m_type = 2 - if("nod") - message = "The [src.name] nods his head." - m_type = 1 - if("sit") - message = "The [src.name] sits down." - m_type = 1 - if("sway") - message = "The [src.name] sways around dizzily." - m_type = 1 - if("sulk") - message = "The [src.name] sulks down sadly." - m_type = 1 - if("twitch") - message = "The [src.name] twitches violently." - m_type = 1 - if("dance") - if (!src.restrained()) - message = "The [src.name] dances around happily." - m_type = 1 - if("roll") - if (!src.restrained()) - message = "The [src.name] rolls." - m_type = 1 - if("shake") - message = "The [src.name] shakes his head." - m_type = 1 - if("gnarl") - if (!muzzled) - message = "The [src.name] gnarls and shows his teeth.." - m_type = 2 - if("jump") - message = "The [src.name] jumps!" - m_type = 1 - if("collapse") - Paralyse(2) - message = text("[] collapses!", src) - m_type = 2 - if("deathgasp") - message = "The [src.name] lets out a faint chimper as it collapses and stops moving..." - m_type = 1 - if("help") - text += "choke, collapse, dance, deathgasp, drool, gasp, shiver, gnarl, jump, paw, moan, nod, roar, roll, scratch,\nscretch, shake, sign-#, sit, sulk, sway, tail, twitch, whimper" - src << text - else - src << text("Invalid Emote: []", act) - if ((message && src.stat == 0)) - if(src.client) - log_emote("[name]/[key] : [message]") - if (m_type & 1) - for(var/mob/O in viewers(src, null)) - O.show_message(message, m_type) - //Foreach goto(703) - else - for(var/mob/O in hearers(src, null)) - O.show_message(message, m_type) - //Foreach goto(746) - return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/monkey/examine.dm b/code/modules/mob/living/carbon/monkey/examine.dm deleted file mode 100644 index 9385787841..0000000000 --- a/code/modules/mob/living/carbon/monkey/examine.dm +++ /dev/null @@ -1,39 +0,0 @@ -/mob/living/carbon/monkey/examine(mob/user) - ..(user) - - var/msg = "" - if (src.handcuffed) - msg += "It is \icon[src.handcuffed] handcuffed!\n" - if (src.wear_mask) - msg += "It has \icon[src.wear_mask] \a [src.wear_mask] on its head.\n" - if (src.l_hand) - msg += "It has \icon[src.l_hand] \a [src.l_hand] in its left hand.\n" - if (src.r_hand) - msg += "It has \icon[src.r_hand] \a [src.r_hand] in its right hand.\n" - if (src.back) - msg += "It has \icon[src.back] \a [src.back] on its back.\n" - if (src.stat == DEAD) - msg += "It is limp and unresponsive, with no signs of life.\n" - else - msg += "" - if (src.getBruteLoss()) - if (src.getBruteLoss() < 30) - msg += "It has minor bruising.\n" - else - msg += "It has severe bruising!\n" - if (src.getFireLoss()) - if (src.getFireLoss() < 30) - msg += "It has minor burns.\n" - else - msg += "It has severe burns!\n" - if (src.stat == UNCONSCIOUS) - msg += "It isn't responding to anything around it; it seems to be asleep.\n" - msg += "" - - if (src.digitalcamo) - msg += "It is repulsively uncanny!\n" - - msg += "*---------*
    " - - user << msg - return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm deleted file mode 100644 index d6e1ea2d00..0000000000 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ /dev/null @@ -1,628 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - -/mob/living/carbon/monkey - var/oxygen_alert = 0 - var/phoron_alert = 0 - var/fire_alert = 0 - var/pressure_alert = 0 - - var/temperature_alert = 0 - - -/mob/living/carbon/monkey/Life() - set invisibility = 0 - set background = 1 - if (monkeyizing) return - if (update_muts) - update_muts=0 - domutcheck(src,null,MUTCHK_FORCED) - ..() - - var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE - if(loc) - environment = loc.return_air() - - if (stat != DEAD) - //First, resolve location and get a breath - if(air_master.current_cycle%4==2) - //Only try to take a breath every 4 seconds, unless suffocating - breathe() - else //Still give containing object the chance to interact - if(istype(loc, /obj/)) - var/obj/location_as_object = loc - location_as_object.handle_internal_lifeform(src, 0) - - //Updates the number of stored chemicals for powers - handle_changeling() - - //Mutations and radiation - handle_mutations_and_radiation() - - //Chemicals in the body - handle_chemicals_in_body() - - //Disabilities - handle_disabilities() - - //Virus updates, duh - handle_virus_updates() - - //Apparently, the person who wrote this code designed it so that - //blinded get reset each cycle and then get activated later in the - //code. Very ugly. I dont care. Moving this stuff here so its easy - //to find it. - blinded = null - - //Handle temperature/pressure differences between body and environment - if(environment) // More error checking -- TLE - handle_environment(environment) - - //Status updates, death etc. - handle_regular_status_updates() - update_canmove() - - if(client) - handle_regular_hud_updates() - - // Grabbing - for(var/obj/item/weapon/grab/G in src) - G.process() - - if(!client && stat == CONSCIOUS) - - if(prob(33) && canmove && isturf(loc) && !pulledby) //won't move if being pulled - - step(src, pick(cardinal)) - - if(prob(1)) - emote(pick("scratch","jump","roll","tail")) - updatehealth() - -/mob/living/carbon/monkey - - proc/handle_disabilities() - - if (disabilities & EPILEPSY) - if ((prob(1) && paralysis < 10)) - src << "\red You have a seizure!" - Paralyse(10) - if (disabilities & COUGHING) - if ((prob(5) && paralysis <= 1)) - drop_item() - spawn( 0 ) - emote("cough") - return - if (disabilities & TOURETTES) - if ((prob(10) && paralysis <= 1)) - Stun(10) - spawn( 0 ) - emote("twitch") - return - if (disabilities & NERVOUS) - if (prob(10)) - stuttering = max(10, stuttering) - - proc/handle_mutations_and_radiation() - - if(getFireLoss()) - if((COLD_RESISTANCE in mutations) || prob(50)) - switch(getFireLoss()) - if(1 to 50) - adjustFireLoss(-1) - if(51 to 100) - adjustFireLoss(-5) - - if ((HULK in mutations) && health <= 25) - mutations.Remove(HULK) - src << "\red You suddenly feel very weak." - Weaken(3) - emote("collapse") - - if (radiation) - - if (radiation > 100) - radiation = 100 - Weaken(10) - if(!lying) - src << "\red You feel weak." - emote("collapse") - - switch(radiation) - if(1 to 49) - radiation-- - if(prob(25)) - adjustToxLoss(1) - - if(50 to 74) - radiation -= 2 - adjustToxLoss(1) - if(prob(5)) - radiation -= 5 - Weaken(3) - if(!lying) - src << "\red You feel weak." - emote("collapse") - - if(75 to 100) - radiation -= 3 - adjustToxLoss(3) - if(prob(1)) - src << "\red You mutate!" - randmutb(src) - domutcheck(src,null) - emote("gasp") - - proc/handle_virus_updates() - if(status_flags & GODMODE) return 0 //godmode - if(bodytemperature > 406) - for(var/datum/disease/D in viruses) - D.cure() - for (var/ID in virus2) - var/datum/disease2/disease/V = virus2[ID] - V.cure(src) - - for(var/obj/effect/decal/cleanable/O in view(1,src)) - if(istype(O,/obj/effect/decal/cleanable/blood)) - var/obj/effect/decal/cleanable/blood/B = O - if(B.virus2.len) - for (var/ID in B.virus2) - var/datum/disease2/disease/V = B.virus2[ID] - infect_virus2(src,V) - - else if(istype(O,/obj/effect/decal/cleanable/mucus)) - var/obj/effect/decal/cleanable/mucus/M = O - - if(M.virus2.len) - for (var/ID in M.virus2) - var/datum/disease2/disease/V = M.virus2[ID] - infect_virus2(src,V) - - if(virus2.len) - for (var/ID in virus2) - var/datum/disease2/disease/V = virus2[ID] - if(isnull(V)) // Trying to figure out a runtime error that keeps repeating - CRASH("virus2 nulled before calling activate()") - else - V.activate(src) - // activate may have deleted the virus - if(!V) continue - - // check if we're immune - if(V.antigen & src.antibodies) - V.dead = 1 - - return - - proc/breathe() - if(reagents) - - if(reagents.has_reagent("lexorin")) return - - if(!loc) return //probably ought to make a proper fix for this, but :effort: --NeoFite - - var/datum/gas_mixture/environment = loc.return_air() - var/datum/gas_mixture/breath - if(health < 0) - losebreath++ - if(losebreath>0) //Suffocating so do not take a breath - losebreath-- - if (prob(75)) //High chance of gasping for air - spawn emote("gasp") - if(istype(loc, /obj/)) - var/obj/location_as_object = loc - location_as_object.handle_internal_lifeform(src, 0) - else - //First, check for air from internal atmosphere (using an air tank and mask generally) - breath = get_breath_from_internal(BREATH_VOLUME) - - //No breath from internal atmosphere so get breath from location - if(!breath) - if(istype(loc, /obj/)) - var/obj/location_as_object = loc - breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME) - else if(istype(loc, /turf/)) - var/breath_moles = environment.total_moles*BREATH_PERCENTAGE - breath = loc.remove_air(breath_moles) - - if(istype(wear_mask, /obj/item/clothing/mask) && breath) - var/obj/item/clothing/mask/M = wear_mask - var/datum/gas_mixture/filtered = M.filter_air(breath) - loc.assume_air(filtered) - - // Handle chem smoke effect -- Doohl - var/block = 0 - if(wear_mask) - if(istype(wear_mask, /obj/item/clothing/mask/gas)) - block = 1 - - if(!block) - for(var/obj/effect/effect/smoke/chem/smoke in view(1, src)) - if(smoke.reagents.total_volume) - smoke.reagents.reaction(src, INGEST) - spawn(5) - if(smoke) - smoke.reagents.copy_to(src, 10) // I dunno, maybe the reagents enter the blood stream through the lungs? - break // If they breathe in the nasty stuff once, no need to continue checking - - - else //Still give containing object the chance to interact - if(istype(loc, /obj/)) - var/obj/location_as_object = loc - location_as_object.handle_internal_lifeform(src, 0) - - handle_breath(breath) - - if(breath) - loc.assume_air(breath) - - - proc/get_breath_from_internal(volume_needed) - if(internal) - if (!contents.Find(internal)) - internal = null - if (!(wear_mask && (wear_mask.flags & AIRTIGHT))) - internal = null - if(internal) - if (internals) - internals.icon_state = "internal1" - return internal.remove_air_volume(volume_needed) - else - if (internals) - internals.icon_state = "internal0" - return null - - proc/handle_breath(datum/gas_mixture/breath) - if(status_flags & GODMODE) - return - - if(!breath || (breath.total_moles == 0)) - adjustOxyLoss(7) - - oxygen_alert = max(oxygen_alert, 1) - - return 0 - - var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa - //var/safe_oxygen_max = 140 // Maximum safe partial pressure of O2, in kPa (Not used for now) - var/safe_co2_max = 10 // Yes it's an arbitrary value who cares? - var/safe_phoron_max = 0.5 - var/SA_para_min = 0.5 - var/SA_sleep_min = 5 - var/oxygen_used = 0 - var/breath_pressure = (breath.total_moles * R_IDEAL_GAS_EQUATION * breath.temperature) / BREATH_VOLUME - - //Partial pressure of the O2 in our breath - var/O2_pp = (breath.gas["oxygen"] / breath.total_moles) * breath_pressure - // Same, but for the phoron - var/Toxins_pp = (breath.gas["phoron"] / breath.total_moles) * breath_pressure - // And CO2, lets say a PP of more than 10 will be bad (It's a little less really, but eh, being passed out all round aint no fun) - var/CO2_pp = (breath.gas["carbon_dioxide"] / breath.total_moles) * breath_pressure - - if(O2_pp < safe_oxygen_min) // Too little oxygen - if(prob(20)) - spawn(0) emote("gasp") - if (O2_pp == 0) - O2_pp = 0.01 - var/ratio = safe_oxygen_min/O2_pp - adjustOxyLoss(min(5*ratio, 7)) // Don't fuck them up too fast (space only does 7 after all!) - oxygen_used = breath.gas["oxygen"] * ratio / 6 - oxygen_alert = max(oxygen_alert, 1) - /*else if (O2_pp > safe_oxygen_max) // Too much oxygen (commented this out for now, I'll deal with pressure damage elsewhere I suppose) - spawn(0) emote("cough") - var/ratio = O2_pp/safe_oxygen_max - oxyloss += 5*ratio - oxygen_used = breath.oxygen*ratio/6 - oxygen_alert = max(oxygen_alert, 1)*/ - else // We're in safe limits - adjustOxyLoss(-5) - oxygen_used = breath.gas["oxygen"] / 6 - oxygen_alert = 0 - - breath.adjust_gas("oxygen", -oxygen_used) - breath.adjust_gas("carbon_dioxide", oxygen_used) - - if(CO2_pp > safe_co2_max) - if(!co2overloadtime) // If it's the first breath with too much CO2 in it, lets start a counter, then have them pass out after 12s or so. - co2overloadtime = world.time - else if(world.time - co2overloadtime > 120) - Paralyse(3) - adjustOxyLoss(3) // Lets hurt em a little, let them know we mean business - if(world.time - co2overloadtime > 300) // They've been in here 30s now, lets start to kill them for their own good! - adjustOxyLoss(8) - if(prob(20)) // Lets give them some chance to know somethings not right though I guess. - spawn(0) emote("cough") - - else - co2overloadtime = 0 - - if(Toxins_pp > safe_phoron_max) // Too much phoron - var/ratio = (breath.gas["phoron"] / safe_phoron_max) * 10 - //adjustToxLoss(Clamp(ratio, MIN_PLASMA_DAMAGE, MAX_PLASMA_DAMAGE)) //Limit amount of damage toxin exposure can do per second - if(reagents) - reagents.add_reagent("toxin", Clamp(ratio, MIN_TOXIN_DAMAGE, MAX_TOXIN_DAMAGE)) - phoron_alert = max(phoron_alert, 1) - else - phoron_alert = 0 - - if(breath.gas["sleeping_agent"]) - var/SA_pp = (breath.gas["sleeping_agent"] / breath.total_moles) * breath_pressure - if(SA_pp > SA_para_min) // Enough to make us paralysed for a bit - Paralyse(3) // 3 gives them one second to wake up and run away a bit! - if(SA_pp > SA_sleep_min) // Enough to make us sleep as well - sleeping = max(sleeping+2, 10) - else if(SA_pp > 0.01) // There is sleeping gas in their lungs, but only a little, so give them a bit of a warning - if(prob(20)) - spawn(0) emote(pick("giggle", "laugh")) - - - if(breath.temperature > (T0C+66)) // Hot air hurts :( - if(prob(20)) - src << "\red You feel a searing heat in your lungs!" - fire_alert = max(fire_alert, 2) - else - fire_alert = 0 - - - //Temporary fixes to the alerts. - - return 1 - - proc/handle_environment(datum/gas_mixture/environment) - if(!environment) - return - - //Moved these vars here for use in the fuck-it-skip-processing check. - var/pressure = environment.return_pressure() - if(pressure < WARNING_HIGH_PRESSURE && pressure > WARNING_LOW_PRESSURE && abs(environment.temperature - 293.15) < 20 && abs(bodytemperature - 310.14) < 0.5 && environment.gas["phoron"] < MOLES_PHORON_VISIBLE) - - - //Hopefully should fix the walk-inside-still-pressure-warning issue. - if(pressure_alert) - pressure_alert = 0 - - return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp - - var/environment_heat_capacity = environment.heat_capacity() - if(istype(get_turf(src), /turf/space)) - var/turf/heat_turf = get_turf(src) - environment_heat_capacity = heat_turf.heat_capacity - - if((environment.temperature > (T0C + 50)) || (environment.temperature < (T0C + 10))) - var/transfer_coefficient = 1 - - handle_temperature_damage(HEAD, environment.temperature, environment_heat_capacity*transfer_coefficient) - - if(stat==2) - bodytemperature += 0.1*(environment.temperature - bodytemperature)*environment_heat_capacity/(environment_heat_capacity + 270000) - - //Account for massive pressure differences - switch(pressure) - if(HAZARD_HIGH_PRESSURE to INFINITY) - adjustBruteLoss( min( ( (pressure / HAZARD_HIGH_PRESSURE) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) ) - pressure_alert = 2 - if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE) - pressure_alert = 1 - if(WARNING_LOW_PRESSURE to WARNING_HIGH_PRESSURE) - pressure_alert = 0 - if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE) - pressure_alert = -1 - else - if( !(COLD_RESISTANCE in mutations) ) - adjustBruteLoss( LOW_PRESSURE_DAMAGE ) - pressure_alert = -2 - else - pressure_alert = -1 - - return - - proc/handle_temperature_damage(body_part, exposed_temperature, exposed_intensity) - if(status_flags & GODMODE) return - var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0) - //adjustFireLoss(2.5*discomfort) - - if(exposed_temperature > bodytemperature) - adjustFireLoss(20.0*discomfort) - - else - adjustFireLoss(5.0*discomfort) - - proc/handle_chemicals_in_body() - - if(reagents && reagents.reagent_list.len) - reagents.metabolize(src) - - if (drowsyness) - drowsyness-- - eye_blurry = max(2, eye_blurry) - if (prob(5)) - sleeping += 1 - Paralyse(5) - - if(confused) - confused = max(0, confused - 1) - - if(resting) - dizziness = max(0, dizziness - 5) - else - dizziness = max(0, dizziness - 1) - - return //TODO: DEFERRED - - proc/handle_regular_status_updates() - - if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP - blinded = 1 - silent = 0 - else //ALIVE. LIGHTS ARE ON - updatehealth() - if(health < config.health_threshold_dead || !has_brain()) - death() - blinded = 1 - stat = DEAD - silent = 0 - return 1 - - //UNCONSCIOUS. NO-ONE IS HOME - if( (getOxyLoss() > 25) || (config.health_threshold_crit > health) ) - if( health <= 20 && prob(1) ) - spawn(0) - emote("gasp") - if(!reagents.has_reagent("inaprovaline")) - adjustOxyLoss(1) - Paralyse(3) - if(halloss > 100) - src << "You're in too much pain to keep going..." - for(var/mob/O in oviewers(src, null)) - O.show_message("[src] slumps to the ground, too weak to continue fighting.", 1) - Paralyse(10) - setHalLoss(99) - - if(paralysis) - AdjustParalysis(-1) - blinded = 1 - stat = UNCONSCIOUS - if(halloss > 0) - adjustHalLoss(-3) - else if(sleeping) - handle_dreams() - adjustHalLoss(-3) - sleeping = max(sleeping-1, 0) - blinded = 1 - stat = UNCONSCIOUS - if( prob(10) && health && !hal_crit ) - spawn(0) - emote("snore") - else if(resting) - if(halloss > 0) - adjustHalLoss(-3) - //CONSCIOUS - else - stat = CONSCIOUS - if(halloss > 0) - adjustHalLoss(-1) - - //Eyes - if(sdisabilities & BLIND) //disabled-blind, doesn't get better on its own - blinded = 1 - else if(eye_blind) //blindness, heals slowly over time - eye_blind = max(eye_blind-1,0) - blinded = 1 - else if(eye_blurry) //blurry eyes heal slowly - eye_blurry = max(eye_blurry-1, 0) - - //Ears - if(sdisabilities & DEAF) //disabled-deaf, doesn't get better on its own - ear_deaf = max(ear_deaf, 1) - else if(ear_deaf) //deafness, heals slowly over time - ear_deaf = max(ear_deaf-1, 0) - else if(ear_damage < 25) //ear damage heals slowly under this threshold. otherwise you'll need earmuffs - ear_damage = max(ear_damage-0.05, 0) - - //Other - handle_statuses() - return 1 - - - proc/handle_regular_hud_updates() - - if (stat == 2 || (XRAY in mutations)) - sight |= SEE_TURFS - sight |= SEE_MOBS - sight |= SEE_OBJS - see_in_dark = 8 - see_invisible = SEE_INVISIBLE_LEVEL_TWO - else if (stat != 2) - sight &= ~SEE_TURFS - sight &= ~SEE_MOBS - sight &= ~SEE_OBJS - see_in_dark = 2 - see_invisible = SEE_INVISIBLE_LIVING - - if (healths) - if (stat != 2) - switch(health) - if(100 to INFINITY) - healths.icon_state = "health0" - if(80 to 100) - healths.icon_state = "health1" - if(60 to 80) - healths.icon_state = "health2" - if(40 to 60) - healths.icon_state = "health3" - if(20 to 40) - healths.icon_state = "health4" - if(0 to 20) - healths.icon_state = "health5" - else - healths.icon_state = "health6" - else - healths.icon_state = "health7" - - - if(pressure) - pressure.icon_state = "pressure[pressure_alert]" - - if (toxin) toxin.icon_state = "tox[phoron_alert ? 1 : 0]" - if (oxygen) oxygen.icon_state = "oxy[oxygen_alert ? 1 : 0]" - if (fire) fire.icon_state = "fire[fire_alert ? 2 : 0]" - //NOTE: the alerts dont reset when youre out of danger. dont blame me, - //blame the person who coded them. Temporary fix added. - - if(bodytemp) - switch(bodytemperature) //310.055 optimal body temp - if(345 to INFINITY) - bodytemp.icon_state = "temp4" - if(335 to 345) - bodytemp.icon_state = "temp3" - if(327 to 335) - bodytemp.icon_state = "temp2" - if(316 to 327) - bodytemp.icon_state = "temp1" - if(300 to 316) - bodytemp.icon_state = "temp0" - if(295 to 300) - bodytemp.icon_state = "temp-1" - if(280 to 295) - bodytemp.icon_state = "temp-2" - if(260 to 280) - bodytemp.icon_state = "temp-3" - else - bodytemp.icon_state = "temp-4" - - client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired) - - if(blind && stat != DEAD) - if(blinded) - blind.layer = 18 - else - blind.layer = 0 - - if(disabilities & NEARSIGHTED) - client.screen += global_hud.vimpaired - - if(eye_blurry) - client.screen += global_hud.blurry - - if(druggy) - client.screen += global_hud.druggy - - if (stat != 2) - if (machine) - if (!( machine.check_eye(src) )) - reset_view(null) - else - if(client && !client.adminobs) - reset_view(null) - - return 1 - - proc/handle_random_events() - if (prob(1) && prob(2)) - spawn(0) - emote("scratch") - return - - - proc/handle_changeling() - if(mind && mind.changeling) - mind.changeling.regenerate() diff --git a/code/modules/mob/living/carbon/monkey/login.dm b/code/modules/mob/living/carbon/monkey/login.dm deleted file mode 100644 index 3b7e5dcb97..0000000000 --- a/code/modules/mob/living/carbon/monkey/login.dm +++ /dev/null @@ -1,4 +0,0 @@ -/mob/living/carbon/monkey/Login() - ..() - update_hud() - return diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm deleted file mode 100644 index 2a4c748936..0000000000 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ /dev/null @@ -1,286 +0,0 @@ -/mob/living/carbon/monkey - name = "monkey" - voice_name = "monkey" - speak_emote = list("chimpers") - icon_state = "monkey1" - icon = 'icons/mob/monkey.dmi' - gender = NEUTER - pass_flags = PASSTABLE - update_icon = 0 ///no need to call regenerate_icon - - var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie - var/greaterform = "Human" // Used when humanizing a monkey. - icon_state = "monkey1" - //var/uni_append = "12C4E2" // Small appearance modifier for different species. - var/list/uni_append = list(0x12C,0x4E2) // Same as above for DNA2. - var/update_muts = 1 // Monkey gene must be set at start. - -/mob/living/carbon/monkey/tajara - name = "farwa" - voice_name = "farwa" - speak_emote = list("mews") - icon_state = "tajkey1" - greaterform = "Tajara" - uni_append = list(0x0A0,0xE00) // 0A0E00 - -/mob/living/carbon/monkey/skrell - name = "neaera" - voice_name = "neaera" - speak_emote = list("squicks") - icon_state = "skrellkey1" - greaterform = "Skrell" - uni_append = list(0x01C,0xC92) // 01CC92 - -/mob/living/carbon/monkey/unathi - name = "stok" - voice_name = "stok" - speak_emote = list("hisses") - icon_state = "stokkey1" - greaterform = "Unathi" - uni_append = list(0x044,0xC5D) // 044C5D - -/mob/living/carbon/monkey/New() - - verbs += /mob/living/proc/ventcrawl - - var/datum/reagents/R = new/datum/reagents(1000) - reagents = R - R.my_atom = src - - species = all_species[greaterform] - add_language(species.language) - - if(name == initial(name)) //To stop Pun-Pun becoming generic. - name = "[name] ([rand(1, 1000)])" - real_name = name - - if (!(dna)) - if(gender == NEUTER) - gender = pick(MALE, FEMALE) - dna = new /datum/dna( null ) - dna.real_name = real_name - dna.ResetSE() - dna.ResetUI() - //dna.uni_identity = "00600200A00E0110148FC01300B009" - //dna.SetUI(list(0x006,0x002,0x00A,0x00E,0x011,0x014,0x8FC,0x013,0x00B,0x009)) - //dna.struc_enzymes = "43359156756131E13763334D1C369012032164D4FE4CD61544B6C03F251B6C60A42821D26BA3B0FD6" - //dna.SetSE(list(0x433,0x591,0x567,0x561,0x31E,0x137,0x633,0x34D,0x1C3,0x690,0x120,0x321,0x64D,0x4FE,0x4CD,0x615,0x44B,0x6C0,0x3F2,0x51B,0x6C6,0x0A4,0x282,0x1D2,0x6BA,0x3B0,0xFD6)) - dna.unique_enzymes = md5(name) - - // We're a monkey - dna.SetSEState(MONKEYBLOCK, 1) - dna.SetSEValueRange(MONKEYBLOCK,0xDAC, 0xFFF) - // Fix gender - dna.SetUIState(DNA_UI_GENDER, gender != MALE, 1) - - // Set the blocks to uni_append, if needed. - if(uni_append.len>0) - for(var/b=1;b<=uni_append.len;b++) - dna.SetUIValue(DNA_UI_LENGTH-(uni_append.len-b),uni_append[b], 1) - dna.UpdateUI() - - update_muts=1 - - ..() - update_icons() - return - -/mob/living/carbon/monkey/movement_delay() - var/tally = 0 - if(reagents) - if(reagents.has_reagent("hyperzine")) return -1 - - if(reagents.has_reagent("nuka_cola")) return -1 - - var/health_deficiency = (100 - health) - if(health_deficiency >= 45) tally += (health_deficiency / 25) - - if (bodytemperature < 283.222) - tally += (283.222 - bodytemperature) / 10 * 1.75 - return tally+config.monkey_delay - -/mob/living/carbon/monkey/Topic(href, href_list) - ..() - if (href_list["mach_close"]) - var/t1 = text("window=[]", href_list["mach_close"]) - unset_machine() - src << browse(null, t1) - if ((href_list["item"] && !( usr.stat ) && !( usr.restrained() ) && in_range(src, usr) )) - var/obj/effect/equip_e/monkey/O = new /obj/effect/equip_e/monkey( ) - O.source = usr - O.target = src - O.item = usr.get_active_hand() - O.s_loc = usr.loc - O.t_loc = loc - O.place = href_list["item"] - requests += O - spawn( 0 ) - O.process() - return - ..() - return - -/mob/living/carbon/monkey/meteorhit(obj/O as obj) - for(var/mob/M in viewers(src, null)) - M.show_message(text("\red [] has been hit by []", src, O), 1) - if (health > 0) - var/shielded = 0 - adjustBruteLoss(30) - if ((O.icon_state == "flaming" && !( shielded ))) - adjustFireLoss(40) - health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - return - -/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M as mob) - - if (M.a_intent == "help") - help_shake_act(M) - else - if (M.a_intent == "hurt") - var/datum/unarmed_attack/attack = null - for(var/datum/unarmed_attack/u_attack in M.species.unarmed_attacks) - if(!u_attack.is_usable(M, src)) - continue - else - attack = u_attack - break - if(!attack) - return 0 - if ((prob(75) && health > 0)) - visible_message("\red [M] [pick(attack.attack_verb)] [src]!") - - playsound(loc, "punch", 25, 1, -1) - var/damage = rand(5, 10) - if (prob(40)) - damage = rand(10, 15) - if (paralysis < 5) - Paralyse(rand(10, 15)) - visible_message("\red [M] has knocked out [src]!") - - adjustBruteLoss(damage) - - M.attack_log += text("\[[time_stamp()]\] [pick(attack.attack_verb)]ed [src.name] ([src.ckey])") - src.attack_log += text("\[[time_stamp()]\] Has been [pick(attack.attack_verb)]ed by [M.name] ([M.ckey])") - msg_admin_attack("[key_name(M)] [pick(attack.attack_verb)]ed [key_name(src)]") - - updatehealth() - else - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - visible_message("\red [M] tried to [pick(attack.attack_verb)] [src]!") - else - if (M.a_intent == "grab") - if (M == src || anchored) - return - - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) - - M.put_in_active_hand(G) - - G.synch() - - LAssailant = M - - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - O.show_message(text("\red [] has grabbed [name] passively!", M), 1) - else - if (!( paralysis )) - if (prob(25)) - Paralyse(2) - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has pushed down [name]!", M), 1) - else - drop_item() - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has disarmed [name]!", M), 1) - return - -/mob/living/carbon/monkey/Stat() - ..() - statpanel("Status") - stat(null, text("Intent: []", a_intent)) - stat(null, text("Move Mode: []", m_intent)) - if(client && mind) - if (client.statpanel == "Status") - if(mind.changeling) - stat("Chemical Storage", mind.changeling.chem_charges) - stat("Genetic Damage Time", mind.changeling.geneticdamage) - return - - -/mob/living/carbon/monkey/verb/removeinternal() - set name = "Remove Internals" - set category = "IC" - internal = null - return - -/mob/living/carbon/monkey/var/co2overloadtime = null -/mob/living/carbon/monkey/var/temperature_resistance = T0C+75 - -/mob/living/carbon/monkey/emp_act(severity) - if(wear_id) wear_id.emp_act(severity) - ..() - -/mob/living/carbon/monkey/ex_act(severity) - if(!blinded) - flick("flash", flash) - - switch(severity) - if(1.0) - if (stat != 2) - adjustBruteLoss(200) - health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - if(2.0) - if (stat != 2) - adjustBruteLoss(60) - adjustFireLoss(60) - health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - if(3.0) - if (stat != 2) - adjustBruteLoss(30) - health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - if (prob(50)) - Paralyse(10) - else - return - -/mob/living/carbon/monkey/blob_act() - if (stat != 2) - adjustFireLoss(60) - health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss() - if (prob(50)) - Paralyse(10) - if (stat == DEAD && client) - gib() - return - if (stat == DEAD && !client) - gibs(loc, viruses) - del(src) - return - -//Unless its monkey mode monkeys cant use advanced tools -/mob/living/carbon/monkey/IsAdvancedToolUser(var/silent) - if(!silent) - src << "You don't have the dexterity to use [src]!" - return 0 - -/mob/living/carbon/monkey/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/list/used_radios = list()) - if(stat) - return - - if(copytext(message,1,2) == "*") - return emote(copytext(message,2)) - - if(stat) - return - - if(speak_emote.len) - verb = pick(speak_emote) - - message = capitalize(trim_left(message)) - - ..(message, speaking, verb, alt_name, italics, message_range, used_radios) diff --git a/code/modules/mob/living/carbon/monkey/npc.dm b/code/modules/mob/living/carbon/monkey/npc.dm deleted file mode 100644 index a7d4bfc7ae..0000000000 --- a/code/modules/mob/living/carbon/monkey/npc.dm +++ /dev/null @@ -1,89 +0,0 @@ -mob/living/carbon/monkey/var - mob/npc_target = null // the NPC this monkey is attacking - mob/npc_fleeing = null // the monkey is scared of this mob - mob/hiding_behind = null - hid_behind = 0 - - var/list/hostiles = list() - - fleeing_duration = 0 - -mob/living/carbon/monkey/proc/npc_act() - if(!client && !stat) - if(npc_fleeing && canmove) - var/prevloc = loc - if(!hiding_behind) - for(var/mob/living/carbon/human/H in view(7, src)) - if(!hostiles.Find(H)) - hiding_behind = H - - if(hiding_behind) - if(get_dist(src, hiding_behind) == 1) - if(!hid_behind) - emote("me", 1, "hides behind [hiding_behind]!") - hid_behind = 1 - step_to(src, get_step(hiding_behind, get_dir(npc_fleeing, hiding_behind))) - else - if(!step_to(src, hiding_behind, 1)) - hiding_behind = null - else - step_away(src, npc_fleeing, 7) - - if(prob(7)) - if(prob(50) && (npc_fleeing in view(8,src))) - switch(rand(1,3)) - if(1) - emote("me", 1, "shows [npc_fleeing] its fangs!") - if(2) - emote("me", 2, "gnarls at [npc_fleeing].") - if(3) - emote("me", 2, "eyes [npc_fleeing] fearfully.") - else - switch(rand(1,3)) - if(1) - emote("whimper") - if(2) - emote("me", 1, "trembles heavily.") - if(3) - emote("me", 2, "chimpers nervously.") - - fleeing_duration-- - if(fleeing_duration <= 0) - npc_fleeing = null - hiding_behind = null - hid_behind = 0 - - if(loc == prevloc) set_dir(get_dir(src, npc_fleeing)) - else - if(prob(33) && canmove && isturf(loc)) - step(src, pick(cardinal)) - if(prob(1)) - if(health < 70) - switch(rand(1,3)) - if(1) - emote("me", 1, "cowers on the floor, writhing in pain.") - if(2) - emote("me", 1, "trembles visibly, it seems to be in pain.") - if(3) - emote("me", 1, "wraps its arms around its knees, breathing heavily.") - else - emote(pick("scratch","jump","roll","tail")) - -mob/living/carbon/monkey/react_to_attack(mob/M) - if(npc_fleeing == M) - fleeing_duration += 30 - return - - if(!hostiles.Find(M)) hostiles += M - - spawn(5) - switch(rand(1,3)) - if(1) - emote("me", 1, "flails about wildly!") - if(2) - emote("me", 2, "screams loudly at [M]!") - if(3) - emote("me", 2, "whimpers fearfully!") - - npc_fleeing = M - fleeing_duration = 30 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/monkey/update_icons.dm b/code/modules/mob/living/carbon/monkey/update_icons.dm index 284f9e288f..1b3da8f49a 100644 --- a/code/modules/mob/living/carbon/monkey/update_icons.dm +++ b/code/modules/mob/living/carbon/monkey/update_icons.dm @@ -5,7 +5,8 @@ #define M_L_HAND_LAYER 4 #define M_R_HAND_LAYER 5 #define TARGETED_LAYER 6 -#define M_TOTAL_LAYERS 6 +#define M_FIRE_LAYER 6 +#define M_TOTAL_LAYERS 7 ///////////////////////////////// /mob/living/carbon/monkey @@ -19,6 +20,7 @@ update_inv_r_hand(0) update_inv_l_hand(0) update_inv_handcuffed(0) + update_fire(0) update_icons() //Hud Stuff update_hud() @@ -53,26 +55,38 @@ /mob/living/carbon/monkey/update_inv_r_hand(var/update_icons=1) if(r_hand) + var/t_icon = INV_R_HAND_DEF_ICON + if(r_hand.item_icons && (icon_r_hand in r_hand.item_icons)) + t_icon = r_hand.item_icons[icon_r_hand] + var/t_state = r_hand.item_state if(!t_state) t_state = r_hand.icon_state - overlays_standing[M_R_HAND_LAYER] = image("icon" = 'icons/mob/items_righthand.dmi', "icon_state" = t_state) + + overlays_standing[M_R_HAND_LAYER] = image("icon" = t_icon, "icon_state" = t_state) r_hand.screen_loc = ui_rhand if (handcuffed) drop_r_hand() else overlays_standing[M_R_HAND_LAYER] = null - if(update_icons) update_icons() + + if(update_icons) update_icons() /mob/living/carbon/monkey/update_inv_l_hand(var/update_icons=1) if(l_hand) + var/t_icon = INV_L_HAND_DEF_ICON + if(l_hand.item_icons && (icon_l_hand in l_hand.item_icons)) + t_icon = l_hand.item_icons[icon_l_hand] + var/t_state = l_hand.item_state if(!t_state) t_state = l_hand.icon_state - overlays_standing[M_L_HAND_LAYER] = image("icon" = 'icons/mob/items_lefthand.dmi', "icon_state" = t_state) + + overlays_standing[M_L_HAND_LAYER] = image("icon" = t_icon, "icon_state" = t_state) l_hand.screen_loc = ui_lhand if (handcuffed) drop_l_hand() else overlays_standing[M_L_HAND_LAYER] = null - if(update_icons) update_icons() + + if(update_icons) update_icons() /mob/living/carbon/monkey/update_inv_back(var/update_icons=1) @@ -109,6 +123,12 @@ overlays_standing[TARGETED_LAYER] = null if(update_icons) update_icons() +/mob/living/carbon/monkey/update_fire(var/update_icons=1) + if(on_fire) + overlays_standing[M_FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing", "layer"= -M_FIRE_LAYER) + else + overlays_standing[M_FIRE_LAYER] = null + if(update_icons) update_icons() //Monkey Overlays Indexes//////// #undef M_MASK_LAYER #undef M_BACK_LAYER @@ -116,5 +136,6 @@ #undef M_L_HAND_LAYER #undef M_R_HAND_LAYER #undef TARGETED_LAYER +#undef M_FIRE_LAYER #undef M_TOTAL_LAYERS diff --git a/code/modules/mob/living/carbon/viruses.dm b/code/modules/mob/living/carbon/viruses.dm new file mode 100644 index 0000000000..fed6d59e43 --- /dev/null +++ b/code/modules/mob/living/carbon/viruses.dm @@ -0,0 +1,43 @@ +/mob/living/carbon/proc/handle_viruses() + + if(status_flags & GODMODE) return 0 //godmode + + if(bodytemperature > 406) + for(var/datum/disease/D in viruses) + D.cure() + for (var/ID in virus2) + var/datum/disease2/disease/V = virus2[ID] + V.cure(src) + + if(life_tick % 3) //don't spam checks over all objects in view every tick. + for(var/obj/effect/decal/cleanable/O in view(1,src)) + if(istype(O,/obj/effect/decal/cleanable/blood)) + var/obj/effect/decal/cleanable/blood/B = O + if(B.virus2.len) + for (var/ID in B.virus2) + var/datum/disease2/disease/V = B.virus2[ID] + infect_virus2(src,V) + + else if(istype(O,/obj/effect/decal/cleanable/mucus)) + var/obj/effect/decal/cleanable/mucus/M = O + if(M.virus2.len) + for (var/ID in M.virus2) + var/datum/disease2/disease/V = M.virus2[ID] + infect_virus2(src,V) + + if(virus2.len) + for (var/ID in virus2) + var/datum/disease2/disease/V = virus2[ID] + if(isnull(V)) // Trying to figure out a runtime error that keeps repeating + CRASH("virus2 nulled before calling activate()") + else + V.activate(src) + // activate may have deleted the virus + if(!V) continue + + // check if we're immune + var/list/common_antibodies = V.antigen & src.antibodies + if(common_antibodies.len) + V.dead = 1 + + return \ No newline at end of file diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 25fa8d5686..da5b73e9cc 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -20,6 +20,122 @@ usr.visible_message("[src] points to [A]") return 1 +/*one proc, four uses +swapping: if it's 1, the mobs are trying to switch, if 0, non-passive is pushing passive +default behaviour is: + - non-passive mob passes the passive version + - passive mob checks to see if its mob_bump_flag is in the non-passive's mob_bump_flags + - if si, the proc returns +*/ +/mob/living/proc/can_move_mob(var/mob/living/swapped, swapping = 0, passive = 0) + if(!swapped) + return 1 + if(!passive) + return swapped.can_move_mob(src, swapping, 1) + else + var/context_flags = 0 + if(swapping) + context_flags = swapped.mob_swap_flags + else + context_flags = swapped.mob_push_flags + if(!mob_bump_flag) //nothing defined, go wild + return 1 + if(mob_bump_flag & context_flags) + return 1 + return 0 + +/mob/living/Bump(atom/movable/AM, yes) + spawn(0) + if ((!( yes ) || now_pushing) || !loc) + return + now_pushing = 1 + if (istype(AM, /mob/living)) + var/mob/living/tmob = AM + + for(var/mob/living/M in range(tmob, 1)) + if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) ) + if ( !(world.time % 5) ) + src << "[tmob] is restrained, you cannot push past" + now_pushing = 0 + return + if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) ) + if ( !(world.time % 5) ) + src << "[tmob] is restraining [M], you cannot push past" + now_pushing = 0 + return + + //BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller + var/dense = 0 + if(loc.density) + dense = 1 + for(var/atom/movable/A in loc) + if(A == src) + continue + if(A.density) + if(A.flags&ON_BORDER) + dense = !A.CanPass(src, src.loc) + else + dense = 1 + if(dense) break + + //Leaping mobs just land on the tile, no pushing, no anything. + if(status_flags & LEAPING) + loc = tmob.loc + status_flags &= ~LEAPING + now_pushing = 0 + return + + if((tmob.mob_always_swap || (tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || src.restrained())) && tmob.canmove && canmove && !dense && can_move_mob(tmob, 1, 0)) // mutual brohugs all around! + var/turf/oldloc = loc + loc = tmob.loc + tmob.loc = oldloc + now_pushing = 0 + for(var/mob/living/carbon/slime/slime in view(1,tmob)) + if(slime.Victim == tmob) + slime.UpdateFeed() + return + + if(!can_move_mob(tmob, 0, 0)) + now_pushing = 0 + return + if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) + if(prob(40) && !(FAT in src.mutations)) + src << "You fail to push [tmob]'s fat ass out of the way." + now_pushing = 0 + return + if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot)) + if(prob(99)) + now_pushing = 0 + return + if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot)) + if(prob(99)) + now_pushing = 0 + return + if(!(tmob.status_flags & CANPUSH)) + now_pushing = 0 + return + + tmob.LAssailant = src + + now_pushing = 0 + spawn(0) + ..() + if (!istype(AM, /atom/movable)) + return + if (!now_pushing) + now_pushing = 1 + + if (!AM.anchored) + var/t = get_dir(src, AM) + if (istype(AM, /obj/structure/window)) + for(var/obj/structure/window/win in get_step(AM,t)) + now_pushing = 0 + return + step(AM, t) + now_pushing = 0 + return + return + /mob/living/verb/succumb() set hidden = 1 if ((src.health < 0 && src.health > -95.0)) @@ -59,13 +175,6 @@ H.UpdateDamageIcon() H.updatehealth() return 1 - else if(istype(src, /mob/living/carbon/monkey)) - if (COLD_RESISTANCE in src.mutations) //fireproof - return 0 - var/mob/living/carbon/monkey/M = src - M.adjustFireLoss(burn_amount) - M.updatehealth() - return 1 else if(istype(src, /mob/living/silicon/ai)) return 0 @@ -171,7 +280,6 @@ // ++++ROCKDTBEN++++ MOB PROCS //END - /mob/proc/get_contents() @@ -242,7 +350,7 @@ src.updatehealth() // damage ONE external organ, organ gets randomly selected from damaged ones. -/mob/living/proc/take_organ_damage(var/brute, var/burn) +/mob/living/proc/take_organ_damage(var/brute, var/burn, var/emp=0) if(status_flags & GODMODE) return 0 //godmode adjustBruteLoss(brute) adjustFireLoss(burn) @@ -279,8 +387,11 @@ if (C.legcuffed && !initial(C.legcuffed)) C.drop_from_inventory(C.legcuffed) C.legcuffed = initial(C.legcuffed) - hud_updateflag |= 1 << HEALTH_HUD - hud_updateflag |= 1 << STATUS_HUD + BITSET(hud_updateflag, HEALTH_HUD) + BITSET(hud_updateflag, STATUS_HUD) + BITSET(hud_updateflag, LIFE_HUD) + ExtinguishMob() + fire_stacks = 0 /mob/living/proc/rejuvenate() @@ -329,8 +440,9 @@ // make the icons look correct regenerate_icons() - hud_updateflag |= 1 << HEALTH_HUD - hud_updateflag |= 1 << STATUS_HUD + BITSET(hud_updateflag, HEALTH_HUD) + BITSET(hud_updateflag, STATUS_HUD) + BITSET(hud_updateflag, LIFE_HUD) return /mob/living/proc/UpdateDamageIcon() @@ -416,11 +528,11 @@ //pull damage with injured people if(prob(25)) M.adjustBruteLoss(1) - visible_message("\red \The [M]'s wounds open more from being dragged!") + visible_message("\The [M]'s [M.isSynthetic() ? "state worsens": "wounds open more"] from being dragged!") if(M.pull_damage()) if(prob(25)) M.adjustBruteLoss(2) - visible_message("\red \The [M]'s wounds worsen terribly from being dragged!") + visible_message("\The [M]'s [M.isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!") var/turf/location = M.loc if (istype(location, /turf/simulated)) location.add_blood(M) @@ -512,7 +624,7 @@ return //resisting grabs (as if it helps anyone...) - if ((!( L.stat ) && L.canmove && !( L.restrained() ))) + if ((!( L.stat ) && !( L.restrained() ))) var/resisting = 0 for(var/obj/O in L.requests) L.requests.Remove(O) @@ -520,23 +632,20 @@ resisting++ for(var/obj/item/weapon/grab/G in usr.grabbed_by) resisting++ - if (G.state == 1) - del(G) - else - if (G.state == 2) - if (prob(25)) - for(var/mob/O in viewers(L, null)) - O.show_message(text("\red [] has broken free of []'s grip!", L, G.assailant), 1) + switch(G.state) + if(GRAB_PASSIVE) + del(G) + if(GRAB_AGGRESSIVE) + if(prob(60)) //same chance of breaking the grab as disarm + L.visible_message("[L] has broken free of [G.assailant]'s grip!") + del(G) + if(GRAB_NECK) + //If the you move when grabbing someone then it's easier for them to break free. Same if the affected mob is immune to stun. + if (((world.time - G.assailant.l_move_time < 30 || !L.stunned) && prob(15)) || prob(3)) + L.visible_message("[L] has broken free of [G.assailant]'s headlock!") del(G) - else - if (G.state == 3) - if (prob(5)) - for(var/mob/O in viewers(usr, null)) - O.show_message(text("\red [] has broken free of []'s headlock!", L, G.assailant), 1) - del(G) if(resisting) - for(var/mob/O in viewers(usr, null)) - O.show_message(text("\red [] resists!", L), 1) + L.visible_message("[L] resists!") //unbuckling yourself @@ -556,9 +665,9 @@ for(var/mob/O in viewers(C)) O.show_message("\red [usr] manages to unbuckle themself!", 1) C << "\blue You successfully unbuckle yourself." - C.buckled.manual_unbuckle(C) + C.buckled.user_unbuckle_mob(C) else - L.buckled.manual_unbuckle(L) + L.buckled.user_unbuckle_mob(L) //Breaking out of a locker? else if( src.loc && (istype(src.loc, /obj/structure/closet)) ) @@ -629,9 +738,21 @@ BD.attack_hand(usr) C.open() - //breaking out of handcuffs + //drop && roll or breaking out of handcuffs else if(iscarbon(L)) var/mob/living/carbon/CM = L + if(CM.on_fire && CM.canmove) + CM.fire_stacks -= 5 + CM.Weaken(3) + CM.spin(32,2) + CM.visible_message("[CM] rolls on the floor, trying to put themselves out!", \ + "You stop, drop, and roll!") + sleep(30) + if(fire_stacks <= 0) + CM.visible_message("[CM] has successfully extinguished themselves!", \ + "You extinguish yourself.") + ExtinguishMob() + return if(CM.handcuffed && CM.canmove && (CM.last_special <= world.time)) CM.next_move = world.time + 100 CM.last_special = world.time + 100 @@ -658,6 +779,8 @@ CM.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) del(CM.handcuffed) CM.handcuffed = null + if(buckled && buckled.buckle_require_restraints) + buckled.unbuckle_mob() CM.update_inv_handcuffed() else var/obj/item/weapon/handcuffs/HC = CM.handcuffed @@ -842,4 +965,22 @@ return 1 /mob/living/proc/slip(var/slipped_on,stun_duration=8) - return 0 \ No newline at end of file + return 0 + +/mob/living/carbon/proc/spin(spintime, speed) + spawn() + var/D = dir + while(spintime >= speed) + sleep(speed) + switch(D) + if(NORTH) + D = EAST + if(SOUTH) + D = WEST + if(EAST) + D = SOUTH + if(WEST) + D = NORTH + set_dir(D) + spintime -= speed + return diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index e830657c83..e3ce0c9302 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -56,17 +56,17 @@ signaler.signal() //Stun Beams - if(istype(P, /obj/item/projectile/beam/stun) || istype(P, /obj/item/projectile/bullet/stunshot)) + if(P.taser_effect) stun_effect_act(0, P.agony, def_zone, P) src <<"\red You have been hit by [P]!" del P return //Armor - var/absorb = run_armor_check(def_zone, P.flag) + var/absorb = run_armor_check(def_zone, P.check_armour) var/proj_sharp = is_sharp(P) var/proj_edge = has_edge(P) - if ((proj_sharp || proj_edge) && prob(getarmor(def_zone, P.flag))) + if ((proj_sharp || proj_edge) && prob(getarmor(def_zone, P.check_armour))) proj_sharp = 0 proj_edge = 0 @@ -100,19 +100,16 @@ ..() //this proc handles being hit by a thrown atom -/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = 5)//Standardization and logging -Sieve +/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)//Standardization and logging -Sieve if(istype(AM,/obj/)) var/obj/O = AM - var/dtype = BRUTE - if(istype(O,/obj/item/weapon)) - var/obj/item/weapon/W = O - dtype = W.damtype - var/throw_damage = O.throwforce*(speed/5) + var/dtype = O.damtype + var/throw_damage = O.throwforce*(speed/THROWFORCE_SPEED_DIVISOR) var/miss_chance = 15 if (O.throw_source) var/distance = get_dist(O.throw_source, loc) - miss_chance = min(15*(distance-2), 0) + miss_chance = max(15*(distance-2), 0) if (prob(miss_chance)) visible_message("\blue \The [O] misses [src] narrowly!") @@ -136,20 +133,23 @@ msg_admin_attack("[src.name] ([src.ckey]) was hit by a [O], thrown by [M.name] ([assailant.ckey]) (JMP)") // Begin BS12 momentum-transfer code. - if(O.throw_source && speed >= 15) - var/obj/item/weapon/W = O - var/momentum = speed/2 + var/mass = 1.5 + if(istype(O, /obj/item)) + var/obj/item/I = O + mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR + var/momentum = speed*mass + + if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED) var/dir = get_dir(O.throw_source, src) visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!") src.throw_at(get_edge_target_turf(src,dir),1,momentum) - if(!W || !src) return + if(!O || !src) return - if(W.sharp) //Projectile is suitable for pinning. + if(O.sharp) //Projectile is suitable for pinning. //Handles embedding for non-humans and simple_animals. - O.loc = src - src.embedded += O + embed(O) var/turf/T = near_wall(dir,2) @@ -158,7 +158,11 @@ visible_message("[src] is pinned to the wall by [O]!","You are pinned to the wall by [O]!") src.anchored = 1 src.pinned += O - src.verbs += /mob/proc/yank_out_object + +/mob/living/proc/embed(var/obj/O, var/def_zone=null) + O.loc = src + src.embedded += O + src.verbs += /mob/proc/yank_out_object //This is called when the mob is thrown into a dense turf /mob/living/proc/turf_collision(var/turf/T, var/speed) @@ -191,3 +195,52 @@ src.visible_message("[user] has [attack_message] [src]!") spawn(1) updatehealth() return 1 + +/mob/living/proc/IgniteMob() + if(fire_stacks > 0 && !on_fire) + on_fire = 1 + src.AddLuminosity(3) + update_fire() + +/mob/living/proc/ExtinguishMob() + if(on_fire) + on_fire = 0 + fire_stacks = 0 + src.AddLuminosity(-3) + update_fire() + +/mob/living/proc/update_fire() + return + +/mob/living/proc/adjust_fire_stacks(add_fire_stacks) //Adjusting the amount of fire_stacks we have on person + fire_stacks = Clamp(fire_stacks + add_fire_stacks, min = FIRE_MIN_STACKS, max = FIRE_MAX_STACKS) + +/mob/living/proc/handle_fire() + if(fire_stacks < 0) + fire_stacks = max(0, fire_stacks++) //If we've doused ourselves in water to avoid fire, dry off slowly + + if(!on_fire) + return 1 + else if(fire_stacks <= 0) + ExtinguishMob() //Fire's been put out. + return 1 + + var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment + if(G.gas["oxygen"] < 1) + ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire + return 1 + + var/turf/location = get_turf(src) + location.hotspot_expose(fire_burn_temperature(), 50, 1) + +/mob/living/fire_act() + adjust_fire_stacks(0.5) + IgniteMob() + +//Finds the effective temperature that the mob is burning at. +/mob/living/proc/fire_burn_temperature() + if (fire_stacks <= 0) + return 0 + + //Scale quadratically so that single digit numbers of fire stacks don't burn ridiculously hot. + return round(FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE*(fire_stacks/FIRE_MAX_FIRESUIT_STACKS)**2) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index ecbc51db37..3771bc135e 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -20,7 +20,6 @@ var/hallucination = 0 //Directly affects how long a mob will hallucinate for var/list/atom/hallucinations = list() //A list of hallucinated people that try to attack the mob. See /obj/effect/fake_attacker in hallucinations.dm - var/last_special = 0 //Used by the resist verb, likely used to prevent players from bypassing next_move by logging in/out. //Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects. @@ -32,10 +31,17 @@ var/t_n2 = null var/now_pushing = null + var/mob_bump_flag = 0 + var/mob_swap_flags = 0 + var/mob_push_flags = 0 + var/mob_always_swap = 0 - var/cameraFollow = null + var/mob/living/cameraFollow = null var/tod = null // Time of death var/update_slimes = 1 var/silent = null // Can't talk. Value goes down every life proc. - var/mob_size // Used by lockers. \ No newline at end of file + var/mob_size // Used by lockers. + var/on_fire = 0 //The "Are we on fire?" var + var/fire_stacks + diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index 52f0630a39..383a81f13b 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -6,21 +6,5 @@ mind.active = 1 //indicates that the mind is currently synced with a client //If they're SSD, remove it so they can wake back up. player_logged = 0 - - //Round specific stuff like hud updates - if(ticker && ticker.mode) - switch(ticker.mode.name) - if("revolution") - if((mind in ticker.mode.revolutionaries) || (src.mind in ticker.mode:head_revolutionaries)) - ticker.mode.update_rev_icons_added(src.mind) - if("cult") - if(mind in ticker.mode:cult) - ticker.mode.update_cult_icons_added(src.mind) - if("mercenary") - if(mind in ticker.mode:syndicates) - ticker.mode.update_all_synd_icons() - if("mutiny") - var/datum/game_mode/mutiny/mode = get_mutiny_mode() - if(mode) - mode.update_all_icons() + update_antag_icons(mind) return . diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 622ee23bc7..1ce1085648 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -79,7 +79,132 @@ proc/get_radio_key_from_channel(var/channel) if(!istype(dongle)) return if(dongle.translate_binary) return 1 -/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/sound/speech_sound, var/sound_vol) +/mob/living/proc/get_default_language() + return null + +/mob/living/proc/handle_speech_problems(var/message, var/verb) + var/list/returns[3] + var/speech_problem_flag = 0 + + if((HULK in mutations) && health >= 25 && length(message)) + message = "[uppertext(message)]!!!" + verb = pick("yells","roars","hollers") + speech_problem_flag = 1 + if(slurring) + message = slur(message) + verb = pick("slobbers","slurs") + speech_problem_flag = 1 + if(stuttering) + message = stutter(message) + verb = pick("stammers","stutters") + speech_problem_flag = 1 + + returns[1] = message + returns[2] = verb + returns[3] = speech_problem_flag + return returns + +/mob/living/proc/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name) + if(message_mode == "intercom") + for(var/obj/item/device/radio/intercom/I in view(1, null)) + I.talk_into(src, message, verb, speaking) + used_radios += I + return 0 + +/mob/living/proc/handle_speech_sound() + var/list/returns[2] + returns[1] = null + returns[2] = null + return returns + +/mob/living/proc/get_speech_ending(verb, var/ending) + if(ending=="!") + return pick("exclaims","shouts","yells") + if(ending=="?") + return "asks" + return verb + +/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="") + if(client) + if(client.prefs.muted & MUTE_IC) + src << "\red You cannot speak in IC (Muted)." + return + + if(stat) + if(stat == 2) + return say_dead(message) + return + + var/message_mode = parse_message_mode(message, "headset") + + switch(copytext(message,1,2)) + if("*") return emote(copytext(message,2)) + if("^") return custom_emote(1, copytext(message,2)) + + //parse the radio code and consume it + if (message_mode) + if (message_mode == "headset") + message = copytext(message,2) //it would be really nice if the parse procs could do this for us. + else + message = copytext(message,3) + + message = trim_left(message) + + //parse the language code and consume it + if(!speaking) + speaking = parse_language(message) + if(speaking) + message = copytext(message,2+length(speaking.key)) + else + speaking = get_default_language() + + var/ending = copytext(message, length(message)) + if (speaking) + // This is broadcast to all mobs with the language, + // irrespective of distance or anything else. + if(speaking.flags & HIVEMIND) + speaking.broadcast(src,trim(message)) + return + //If we've gotten this far, keep going! + verb = speaking.get_spoken_verb(ending) + else + verb = get_speech_ending(verb, ending) + + message = trim_left(message) + + if(!(speaking && (speaking.flags & NO_STUTTER))) + var/list/handle_s = handle_speech_problems(message, verb) + message = handle_s[1] + verb = handle_s[2] + + if(!message || message == "") + return + + var/list/obj/item/used_radios = new + if(handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)) + return + + var/list/handle_v = handle_speech_sound() + var/sound/speech_sound = handle_v[1] + var/sound_vol = handle_v[2] + + var/italics = 0 + var/message_range = world.view + + //speaking into radios + if(used_radios.len) + italics = 1 + message_range = 1 + if(speaking) + message_range = speaking.get_talkinto_msg_range(message) + var/msg + if(!speaking || !(speaking.flags & NO_TALK_MSG)) + msg = "\The [src] talks into \the [used_radios[1]]" + for(var/mob/living/M in hearers(5, src)) + if((M != src) && msg) + M.show_message(msg) + if (speech_sound) + sound_vol *= 0.5 var/turf/T = get_turf(src) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 62accdb198..66804f5bfa 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -3,7 +3,6 @@ var/list/ai_list = list() var/list/ai_verbs_default = list( - /mob/living/silicon/ai/proc/ai_alerts, /mob/living/silicon/ai/proc/ai_announcement, /mob/living/silicon/ai/proc/ai_call_shuttle, // /mob/living/silicon/ai/proc/ai_recall_shuttle, @@ -44,7 +43,7 @@ var/list/ai_verbs_default = list( icon_state = "ai" anchored = 1 // -- TLE density = 1 - status_flags = CANSTUN|CANPARALYSE + status_flags = CANSTUN|CANPARALYSE|CANPUSH shouldnt_see = list(/obj/effect/rune) var/list/network = list("SS13") var/obj/machinery/camera/camera = null @@ -80,9 +79,13 @@ var/list/ai_verbs_default = list( /mob/living/silicon/ai/proc/add_ai_verbs() src.verbs |= ai_verbs_default + src.verbs |= ai_verbs_subsystems + src.verbs |= silicon_verbs_subsystems /mob/living/silicon/ai/proc/remove_ai_verbs() src.verbs -= ai_verbs_default + src.verbs -= ai_verbs_subsystems + src.verbs -= silicon_verbs_subsystems /mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0) announcement = new() @@ -141,7 +144,7 @@ var/list/ai_verbs_default = list( if(!safety)//Only used by AIize() to successfully spawn an AI. if (!B)//If there is no player/brain inside. - new/obj/structure/AIcore/deactivated(loc)//New empty terminal. + empty_playable_ai_cores += new/obj/structure/AIcore/deactivated(loc)//New empty terminal. del(src)//Delete AI. return else @@ -156,6 +159,7 @@ var/list/ai_verbs_default = list( hud_list[HEALTH_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[STATUS_HUD] = image('icons/mob/hud.dmi', src, "hudblank") + hud_list[LIFE_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[ID_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[WANTED_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[IMPLOYAL_HUD] = image('icons/mob/hud.dmi', src, "hudblank") @@ -185,7 +189,7 @@ var/list/ai_verbs_default = list( src << radio_text - if (!(ticker && ticker.mode && (mind in ticker.mode.malf_ai))) + if (malf && !(mind in malf.current_antagonists)) show_laws() src << "These laws may be changed by other players, or by you being the traitor." @@ -193,6 +197,7 @@ var/list/ai_verbs_default = list( /mob/living/silicon/ai/Del() ai_list -= src + del(eyeobj) ..() /mob/living/silicon/ai/pointed(atom/A as mob|obj|turf in view()) @@ -211,9 +216,8 @@ var/list/ai_verbs_default = list( else stat(null, text("Systems nonfunctional")) -/mob/living/silicon/ai/proc/SetName(pickedName as text) - real_name = pickedName - name = pickedName +/mob/living/silicon/ai/SetName(pickedName as text) + ..() announcement.announcer = pickedName if(eyeobj) eyeobj.name = "[pickedName] (AI Eye)" @@ -307,49 +311,10 @@ var/list/ai_verbs_default = list( //usr <<"You can only change your display once!" //return -/mob/living/silicon/ai/proc/is_malf() - if(ticker.mode.name == "AI malfunction") - var/datum/game_mode/malfunction/malf = ticker.mode - for (var/datum/mind/malfai in malf.malf_ai) - if (mind == malfai) - return malf - return 0 - // displays the malf_ai information if the AI is the malf /mob/living/silicon/ai/show_malf_ai() - var/datum/game_mode/malfunction/malf = is_malf() - if(malf && malf.apcs >= 3) - stat(null, "Time until station control secured: [max(malf.AI_win_timeleft/(malf.apcs/3), 0)] seconds") - -/mob/living/silicon/ai/proc/ai_alerts() - set category = "AI Commands" - set name = "Show Alerts" - - var/dat = "Current Station Alerts\n" - dat += "Close

    " - for (var/cat in alarms) - dat += text("[]
    \n", cat) - var/list/alarmlist = alarms[cat] - if (alarmlist.len) - for (var/area_name in alarmlist) - var/datum/alarm/alarm = alarmlist[area_name] - dat += "" - - var/cameratext = "" - if (alarm.cameras) - for (var/obj/machinery/camera/I in alarm.cameras) - cameratext += text("[][]", (cameratext=="") ? "" : " | ", src, I, I.c_tag) - dat += text("-- [] ([])", alarm.area.name, (cameratext)? cameratext : "No Camera") - - if (alarm.sources.len > 1) - dat += text(" - [] sources", alarm.sources.len) - dat += "
    \n" - else - dat += "-- All Systems Nominal
    \n" - dat += "
    \n" - - viewalerts = 1 - src << browse(dat, "window=aialerts&can_close=0") + if(malf && malf.hacked_apcs.len >= 3) + stat(null, "Time until station control secured: [max(malf.hack_time/(malf.hacked_apcs/3), 0)] seconds") // this verb lets the ai see the stations manifest /mob/living/silicon/ai/proc/ai_roster() @@ -447,7 +412,7 @@ var/list/ai_verbs_default = list( if (href_list["switchcamera"]) switchCamera(locate(href_list["switchcamera"])) in cameranet.cameras if (href_list["showalerts"]) - ai_alerts() + subsystem_alarm_monitor() //Carn: holopad requests if (href_list["jumptoholopad"]) var/obj/machinery/hologram/holopad/H = locate(href_list["jumptoholopad"]) @@ -457,25 +422,6 @@ var/list/ai_verbs_default = list( else src << "Unable to locate the holopad." - if (href_list["lawc"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite - var/L = text2num(href_list["lawc"]) - switch(lawcheck[L+1]) - if ("Yes") lawcheck[L+1] = "No" - if ("No") lawcheck[L+1] = "Yes" -// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1]) - checklaws() - - if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite - var/L = text2num(href_list["lawi"]) - switch(ioncheck[L]) - if ("Yes") ioncheck[L] = "No" - if ("No") ioncheck[L] = "Yes" -// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1]) - checklaws() - - if (href_list["laws"]) // With how my law selection code works, I changed statelaws from a verb to a proc, and call it through my law selection panel. --NeoFite - statelaws() - if (href_list["track"]) var/mob/target = locate(href_list["track"]) in mob_list @@ -522,29 +468,6 @@ var/list/ai_verbs_default = list( return 1 -/mob/living/silicon/ai/triggerAlarm(var/class, area/A, list/cameralist, var/source) - if (stat == 2) - return 1 - - ..() - - var/cameratext = "" - for (var/obj/machinery/camera/C in cameralist) - cameratext += "[(cameratext == "")? "" : "|"][C.c_tag]" - - queueAlarm("--- [class] alarm detected in [A.name]! ([(cameratext)? cameratext : "No Camera"])", class) - - if (viewalerts) ai_alerts() - -/mob/living/silicon/ai/cancelAlarm(var/class, area/A as area, var/source) - var/has_alarm = ..() - - if (!has_alarm) - queueAlarm(text("--- [] alarm in [] has been cleared.", class, A.name), class, 0) - if (viewalerts) ai_alerts() - - return has_alarm - /mob/living/silicon/ai/cancel_camera() set category = "AI Commands" set name = "Cancel Camera View" @@ -654,16 +577,6 @@ var/list/ai_verbs_default = list( holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo4")) return -/*/mob/living/silicon/ai/proc/corereturn() - set category = "Malfunction" - set name = "Return to Main Core" - - var/obj/machinery/power/apc/apc = src.loc - if(!istype(apc)) - src << "\blue You are already in your Main Core." - return - apc.malfvacate()*/ - //Toggles the luminosity and applies it by re-entereing the camera. /mob/living/silicon/ai/proc/toggle_camera_light() set name = "Toggle Camera Light" @@ -766,5 +679,8 @@ var/list/ai_verbs_default = list( return 1 return 0 +/mob/living/silicon/ai/proc/is_in_chassis() + return istype(loc, /turf) + #undef AI_CHECK_WIRELESS #undef AI_CHECK_RADIO diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index 4b408193b7..4a43103da8 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -35,7 +35,7 @@ break callshuttle++ - if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction" || sent_strike_team) + if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction") callshuttle = 0 if(callshuttle == 3) //if all three conditions are met diff --git a/code/modules/mob/living/silicon/ai/examine.dm b/code/modules/mob/living/silicon/ai/examine.dm index af71223f7c..286edc2ce0 100644 --- a/code/modules/mob/living/silicon/ai/examine.dm +++ b/code/modules/mob/living/silicon/ai/examine.dm @@ -1,7 +1,7 @@ /mob/living/silicon/ai/examine(mob/user) if(!..(user)) return - + var/msg = "" if (src.stat == DEAD) msg += "It appears to be powered-down.\n" @@ -23,5 +23,14 @@ msg += "
    " msg += "*---------*
    " - usr << msg - return \ No newline at end of file + user << msg + user.showLaws(src) + + return + +/mob/proc/showLaws(var/mob/living/silicon/S) + return + +/mob/dead/observer/showLaws(var/mob/living/silicon/S) + if(antagHUD || is_admin(src)) + S.laws.show_laws(src) diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index d94f705320..d2d042c778 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -2,155 +2,45 @@ // // The datum containing all the chunks. -var/datum/cameranet/cameranet = new() +var/datum/visualnet/camera/cameranet = new() -/datum/cameranet +/datum/visualnet/camera // The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del(). var/list/cameras = list() var/cameras_unsorted = 1 - // The chunks of the map, mapping the areas that the cameras can see. - var/list/chunks = list() - var/ready = 0 + chunk_type = /datum/chunk/camera -/datum/cameranet/proc/process_sort() +/datum/visualnet/camera/proc/process_sort() if(cameras_unsorted) cameras = dd_sortedObjectList(cameras) cameras_unsorted = 0 -// Checks if a chunk has been Generated in x, y, z. -/datum/cameranet/proc/chunkGenerated(x, y, z) - x &= ~0xf - y &= ~0xf - var/key = "[x],[y],[z]" - return (chunks[key]) - -// Returns the chunk in the x, y, z. -// If there is no chunk, it creates a new chunk and returns that. -/datum/cameranet/proc/getCameraChunk(x, y, z) - x &= ~0xf - y &= ~0xf - var/key = "[x],[y],[z]" - if(!chunks[key]) - chunks[key] = new /datum/camerachunk(null, x, y, z) - - return chunks[key] - -// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set. - -/datum/cameranet/proc/visibility(mob/aiEye/ai) - // 0xf = 15 - var/x1 = max(0, ai.x - 16) & ~0xf - var/y1 = max(0, ai.y - 16) & ~0xf - var/x2 = min(world.maxx, ai.x + 16) & ~0xf - var/y2 = min(world.maxy, ai.y + 16) & ~0xf - - var/list/visibleChunks = list() - - for(var/x = x1; x <= x2; x += 16) - for(var/y = y1; y <= y2; y += 16) - visibleChunks += getCameraChunk(x, y, ai.z) - - var/list/remove = ai.visibleCameraChunks - visibleChunks - var/list/add = visibleChunks - ai.visibleCameraChunks - - for(var/chunk in remove) - var/datum/camerachunk/c = chunk - c.remove(ai) - - for(var/chunk in add) - var/datum/camerachunk/c = chunk - c.add(ai) - -// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. - -/datum/cameranet/proc/updateVisibility(atom/A, var/opacity_check = 1) - - if(!ticker || (opacity_check && !A.opacity)) - return - majorChunkChange(A, 2) - -/datum/cameranet/proc/updateChunk(x, y, z) - // 0xf = 15 - if(!chunkGenerated(x, y, z)) - return - var/datum/camerachunk/chunk = getCameraChunk(x, y, z) - chunk.hasChanged() - // Removes a camera from a chunk. -/datum/cameranet/proc/removeCamera(obj/machinery/camera/c) +/datum/visualnet/camera/proc/removeCamera(obj/machinery/camera/c) if(c.can_use()) majorChunkChange(c, 0) // Add a camera to a chunk. -/datum/cameranet/proc/addCamera(obj/machinery/camera/c) +/datum/visualnet/camera/proc/addCamera(obj/machinery/camera/c) if(c.can_use()) majorChunkChange(c, 1) // Used for Cyborg cameras. Since portable cameras can be in ANY chunk. -/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c) +/datum/visualnet/camera/proc/updatePortableCamera(obj/machinery/camera/c) if(c.can_use()) majorChunkChange(c, 1) //else // majorChunkChange(c, 0) -// Never access this proc directly!!!! -// This will update the chunk and all the surrounding chunks. -// It will also add the atom to the cameras list if you set the choice to 1. -// Setting the choice to 0 will remove the camera from the chunks. -// If you want to update the chunks around an object, without adding/removing a camera, use choice 2. - -/datum/cameranet/proc/majorChunkChange(atom/c, var/choice) - // 0xf = 15 - if(!c) - return - - var/turf/T = get_turf(c) - if(T) - var/x1 = max(0, T.x - 8) & ~0xf - var/y1 = max(0, T.y - 8) & ~0xf - var/x2 = min(world.maxx, T.x + 8) & ~0xf - var/y2 = min(world.maxy, T.y + 8) & ~0xf - - //world << "X1: [x1] - Y1: [y1] - X2: [x2] - Y2: [y2]" - - for(var/x = x1; x <= x2; x += 16) - for(var/y = y1; y <= y2; y += 16) - if(chunkGenerated(x, y, T.z)) - var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z) - if(choice == 0) - // Remove the camera. - chunk.cameras -= c - else if(choice == 1) - // You can't have the same camera in the list twice. - chunk.cameras |= c - chunk.hasChanged() - -// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0. - -/datum/cameranet/proc/checkCameraVis(mob/living/target as mob) - - // 0xf = 15 - var/turf/position = get_turf(target) - return checkTurfVis(position) - -/datum/cameranet/proc/checkTurfVis(var/turf/position) - var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) - if(chunk) - if(chunk.changed) - chunk.hasChanged(1) // Update now, no matter if it's visible or not. - if(chunk.visibleTurfs[position]) - return 1 - return 0 - -// Debug verb for VVing the chunk that the turf is in. -/* -/turf/verb/view_chunk() - set src in world - - if(cameranet.chunkGenerated(x, y, z)) - var/datum/camerachunk/chunk = cameranet.getCameraChunk(x, y, z) - usr.client.debug_variables(chunk) -*/ \ No newline at end of file +/datum/visualnet/camera/onMajorChunkChange(atom/c, var/choice, var/datum/chunk/camera/chunk) +// Only add actual cameras to the list of cameras + if(istype(c, /obj/machinery/camera)) + if(choice == 0) + // Remove the camera. + chunk.cameras -= c + else if(choice == 1) + // You can't have the same camera in the list twice. + chunk.cameras |= c diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index 33dbfd0966..89a07bb465 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -1,81 +1,17 @@ -#define UPDATE_BUFFER 25 // 2.5 seconds - // CAMERA CHUNK // // A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed. -// Allows the AI Eye to stream these chunks and know what it can and cannot see. +// Allows the Eye to stream these chunks and know what it can and cannot see. -/datum/camerachunk - var/list/obscuredTurfs = list() - var/list/visibleTurfs = list() - var/list/obscured = list() +/datum/chunk/camera var/list/cameras = list() - var/list/turfs = list() - var/list/seenby = list() - var/visible = 0 - var/changed = 0 - var/updating = 0 - var/x = 0 - var/y = 0 - var/z = 0 - -// Add an AI eye to the chunk, then update if changed. - -/datum/camerachunk/proc/add(mob/aiEye/ai) - if(!ai.ai) - return - ai.visibleCameraChunks += src - if(ai.ai.client) - ai.ai.client.images += obscured - visible++ - seenby += ai - if(changed && !updating) - update() - -// Remove an AI eye from the chunk, then update if changed. - -/datum/camerachunk/proc/remove(mob/aiEye/ai) - if(!ai.ai) - return - ai.visibleCameraChunks -= src - if(ai.ai.client) - ai.ai.client.images -= obscured - seenby -= ai - if(visible > 0) - visible-- - -// Called when a chunk has changed. I.E: A wall was deleted. - -/datum/camerachunk/proc/visibilityChanged(turf/loc) - if(!visibleTurfs[loc]) - return - hasChanged() - -// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will -// instead be flagged to update the next time an AI Eye moves near it. - -/datum/camerachunk/proc/hasChanged(var/update_now = 0) - if(visible || update_now) - if(!updating) - updating = 1 - spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once - update() - updating = 0 - else - changed = 1 - -// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. - -/datum/camerachunk/proc/update() - - set background = 1 - - var/list/newVisibleTurfs = list() +/datum/chunk/camera/acquireVisibleTurfs(var/list/visible) for(var/camera in cameras) var/obj/machinery/camera/c = camera - if(!c) + if(!istype(c)) + cameras -= c continue if(!c.can_use()) @@ -83,86 +19,15 @@ var/turf/point = locate(src.x + 8, src.y + 8, src.z) if(get_dist(point, c) > 24) - continue + cameras -= c for(var/turf/t in c.can_see()) - newVisibleTurfs[t] = t - - // Removes turf that isn't in turfs. - newVisibleTurfs &= turfs - - var/list/visAdded = newVisibleTurfs - visibleTurfs - var/list/visRemoved = visibleTurfs - newVisibleTurfs - - visibleTurfs = newVisibleTurfs - obscuredTurfs = turfs - newVisibleTurfs - - for(var/turf in visAdded) - var/turf/t = turf - if(t.obscured) - obscured -= t.obscured - for(var/eye in seenby) - var/mob/aiEye/m = eye - if(!m || !m.ai) - continue - if(m.ai.client) - m.ai.client.images -= t.obscured - - for(var/turf in visRemoved) - var/turf/t = turf - if(obscuredTurfs[t]) - if(!t.obscured) - t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15) - - obscured += t.obscured - for(var/eye in seenby) - var/mob/aiEye/m = eye - if(!m || !m.ai) - seenby -= m - continue - if(m.ai.client) - m.ai.client.images += t.obscured + visible[t] = t // Create a new camera chunk, since the chunks are made as they are needed. -/datum/camerachunk/New(loc, x, y, z) - - // 0xf = 15 - x &= ~0xf - y &= ~0xf - - src.x = x - src.y = y - src.z = z - +/datum/chunk/camera/New(loc, x, y, z) for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z))) if(c.can_use()) cameras += c - - for(var/turf/t in range(10, locate(x + 8, y + 8, z))) - if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16) - turfs[t] = t - - for(var/camera in cameras) - var/obj/machinery/camera/c = camera - if(!c) - continue - - if(!c.can_use()) - continue - - for(var/turf/t in c.can_see()) - visibleTurfs[t] = t - - // Removes turf that isn't in turfs. - visibleTurfs &= turfs - - obscuredTurfs = turfs - visibleTurfs - - for(var/turf in obscuredTurfs) - var/turf/t = turf - if(!t.obscured) - t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15) - obscured += t.obscured - -#undef UPDATE_BUFFER \ No newline at end of file + ..() diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 590ff71ea5..8bc60b819d 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -1,83 +1,45 @@ // AI EYE // -// An invisible (no icon) mob that the AI controls to look around the station with. +// A mob that the AI controls to look around the station with. // It streams chunks as it moves around, which will show it what the AI can and cannot see. -/mob/aiEye +/mob/eye/aiEye name = "Inactive AI Eye" - icon = 'icons/obj/status_display.dmi' // For AI friend secret shh :o - var/list/visibleCameraChunks = list() - var/mob/living/silicon/ai/ai = null - density = 0 - status_flags = GODMODE // You can't damage it. - mouse_opacity = 0 - see_in_dark = 7 - invisibility = INVISIBILITY_MAXIMUM + icon_state = "AI-eye" -// Movement code. Returns 0 to stop air movement from moving it. -/mob/aiEye/Move() - return 0 - -/mob/aiEye/examinate(atom/A as mob|obj|turf in view()) - set popup_menu = 0 - set src = usr.contents - return 0 - -/mob/aiEye/pointed(atom/A as mob|obj|turf in view()) - set popup_menu = 0 - set src = usr.contents - return 0 - -/mob/aiEye/examine(mob/user) - -// Use this when setting the aiEye's location. -// It will also stream the chunk that the new loc is in. -/mob/aiEye/proc/setLoc(var/T, var/cancel_tracking = 1) - - if(ai) - if(!isturf(ai.loc)) - return +/mob/eye/aiEye/New() + ..() + visualnet = cameranet +/mob/eye/aiEye/setLoc(var/T, var/cancel_tracking = 1) + if(..()) + var/mob/living/silicon/ai/ai = owner if(cancel_tracking) ai.ai_cancel_tracking() - T = get_turf(T) - loc = T - cameranet.visibility(src) - if(ai.client) - ai.client.eye = src //Holopad if(ai.holo) - ai.holo.move_hologram() - -/mob/aiEye/proc/getLoc() - - if(ai) - if(!isturf(ai.loc) || !ai.client) - return - return ai.eyeobj.loc + ai.holo.move_hologram(ai) + return 1 // AI MOVEMENT // The AI's "eye". Described on the top of the page. /mob/living/silicon/ai - var/mob/aiEye/eyeobj = new() - var/sprint = 10 - var/cooldown = 0 - var/acceleration = 1 + eyeobj = new /mob/eye/aiEye() var/obj/machinery/hologram/holopad/holo = null // Intiliaze the eye by assigning it's "ai" variable to us. Then set it's loc to us. /mob/living/silicon/ai/New() ..() - eyeobj.ai = src + eyeobj.owner = src eyeobj.name = "[src.name] (AI Eye)" // Give it a name spawn(5) eyeobj.loc = src.loc /mob/living/silicon/ai/Del() - eyeobj.ai = null + eyeobj.owner = null del(eyeobj) // No AI, no Eye ..() @@ -87,32 +49,6 @@ if(AI.eyeobj && AI.client.eye == AI.eyeobj) AI.eyeobj.setLoc(src) -// This will move the AIEye. It will also cause lights near the eye to light up, if toggled. -// This is handled in the proc below this one. - -/client/proc/AIMove(n, direct, var/mob/living/silicon/ai/user) - - var/initial = initial(user.sprint) - var/max_sprint = 50 - - if(user.cooldown && user.cooldown < world.timeofday) // 3 seconds - user.sprint = initial - - for(var/i = 0; i < max(user.sprint, initial); i += 20) - var/turf/step = get_turf(get_step(user.eyeobj, direct)) - if(step) - user.eyeobj.setLoc(step) - - user.cooldown = world.timeofday + 5 - if(user.acceleration) - user.sprint = min(user.sprint + 0.5, max_sprint) - else - user.sprint = initial - - //user.unset_machine() //Uncomment this if it causes problems. - //user.lightNearbyCamera() - - // Return to the Core. /mob/living/silicon/ai/proc/core() @@ -129,12 +65,12 @@ if(!src.eyeobj) src << "ERROR: Eyeobj not found. Creating new eye..." src.eyeobj = new(src.loc) - src.eyeobj.ai = src + src.eyeobj.owner = src src.SetName(src.name) if(client && client.eye) client.eye = src - for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks) + for(var/datum/chunk/c in eyeobj.visibleChunks) c.remove(eyeobj) src.eyeobj.setLoc(src) @@ -142,5 +78,8 @@ set category = "AI Commands" set name = "Toggle Camera Acceleration" - acceleration = !acceleration - usr << "Camera acceleration has been toggled [acceleration ? "on" : "off"]." + if(!eyeobj) + return + + eyeobj.acceleration = !eyeobj.acceleration + usr << "Camera acceleration has been toggled [eyeobj.acceleration ? "on" : "off"]." diff --git a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm index e6311e7a00..828281567e 100644 --- a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm +++ b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm @@ -1,65 +1,5 @@ #define BORG_CAMERA_BUFFER 30 -//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update. - -// TURFS - -/turf - var/image/obscured - -/turf/drain_power() - return -1 - -/turf/proc/visibilityChanged() - if(ticker) - cameranet.updateVisibility(src) - -/turf/simulated/Del() - visibilityChanged() - ..() - -/turf/simulated/New() - ..() - visibilityChanged() - - - -// STRUCTURES - -/obj/structure/Del() - if(ticker) - cameranet.updateVisibility(src) - ..() - -/obj/structure/New() - ..() - if(ticker) - cameranet.updateVisibility(src) - -// EFFECTS - -/obj/effect/Del() - if(ticker) - cameranet.updateVisibility(src) - ..() - -/obj/effect/New() - ..() - if(ticker) - cameranet.updateVisibility(src) - - -// DOORS - -// Simply updates the visibility of the area when it opens/closes/destroyed. -/obj/machinery/door/update_nearby_tiles(need_rebuild) - . = ..(need_rebuild) - // Glass door glass = 1 - // don't check then? - if(!glass && cameranet) - cameranet.updateVisibility(src, 0) - - // ROBOT MOVEMENT // Update the portable camera everytime the Robot moves. @@ -84,6 +24,7 @@ /obj/machinery/camera/deactivate(user as mob, var/choice = 1) ..(user, choice) + invalidateCameraCache() if(src.can_use()) cameranet.addCamera(src) else @@ -98,16 +39,11 @@ cameranet.cameras_unsorted = 1 else dd_insertObjectList(cameranet.cameras, src) - - var/list/open_networks = difflist(network,restricted_camera_networks) //...but if all of camera's networks are restricted, it only works for specific camera consoles. - if(open_networks.len) //If there is at least one open network, chunk is available for AI usage. - cameranet.addCamera(src) + update_coverage(1) /obj/machinery/camera/Del() cameranet.cameras -= src - var/list/open_networks = difflist(network,restricted_camera_networks) - if(open_networks.len) - cameranet.removeCamera(src) + clear_all_networks() ..() -#undef BORG_CAMERA_BUFFER \ No newline at end of file +#undef BORG_CAMERA_BUFFER diff --git a/code/modules/mob/living/silicon/ai/latejoin.dm b/code/modules/mob/living/silicon/ai/latejoin.dm new file mode 100644 index 0000000000..efa4ccd4a4 --- /dev/null +++ b/code/modules/mob/living/silicon/ai/latejoin.dm @@ -0,0 +1,43 @@ +var/global/list/empty_playable_ai_cores = list() + +/hook/roundstart/proc/spawn_empty_ai() + for(var/obj/effect/landmark/start/S in landmarks_list) + if(S.name != "AI") + continue + if(locate(/mob/living) in S.loc) + continue + empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(get_turf(S)) + + return 1 + +/mob/living/silicon/ai/verb/wipe_core() + set name = "Wipe Core" + set category = "OOC" + set desc = "Wipe your core. This is functionally equivalent to cryo or robotic storage, freeing up your job slot." + + if(ticker && ticker.mode && ticker.mode.name == "AI malfunction") + usr << "You cannot use this verb in malfunction. If you need to leave, please adminhelp." + return + + // Guard against misclicks, this isn't the sort of thing we want happening accidentally + if(alert("WARNING: This will immediately wipe your core and ghost you, removing your character from the round permanently (similar to cryo and robotic storage). Are you entirely sure you want to do this?", + "Wipe Core", "No", "No", "Yes") != "Yes") + return + + // We warned you. + empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(loc) + global_announcer.autosay("[src] has been moved to intelligence storage.", "Artificial Intelligence Oversight") + + //Handle job slot/tater cleanup. + var/job = mind.assigned_role + + job_master.FreeRole(job) + + if(mind.objectives.len) + del(mind.objectives) + mind.special_role = null + + clear_antag_roles(mind) + + ghostize(0) + del(src) diff --git a/code/modules/mob/living/silicon/ai/laws.dm b/code/modules/mob/living/silicon/ai/laws.dm index f219d596dc..f36c32bb8d 100755 --- a/code/modules/mob/living/silicon/ai/laws.dm +++ b/code/modules/mob/living/silicon/ai/laws.dm @@ -15,9 +15,8 @@ src.laws_sanity_check() src.laws.show_laws(who) -/mob/living/silicon/ai/proc/add_ion_law(var/law) - src.laws_sanity_check() - src.laws.add_ion_law(law) +/mob/living/silicon/ai/add_ion_law(var/law) + ..() for(var/mob/living/silicon/robot/R in mob_list) if(R.lawupdate && (R.connected_ai == src)) R.show_laws() @@ -25,4 +24,4 @@ /mob/living/silicon/ai/proc/ai_checklaws() set category = "AI Commands" set name = "State Laws" - checklaws() + subsystem_law_manager() diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 7686cd4344..602e427f95 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -89,26 +89,29 @@ else //stage = 6 - src.blind.screen_loc = "1,1 to 15,15" - if (src.blind.layer!=18) - src.blind.layer = 18 - src.sight = src.sight&~SEE_TURFS - src.sight = src.sight&~SEE_MOBS - src.sight = src.sight&~SEE_OBJS - src.see_in_dark = 0 - src.see_invisible = SEE_INVISIBLE_LIVING - if (((!loc.master.power_equip) || istype(T, /turf/space)) && !istype(src.loc,/obj/item)) + var/area/current_area = get_area(src) + + if (((!loc.master.power_equip) && current_area.requires_power == 1 || istype(T, /turf/space)) && !istype(src.loc,/obj/item)) + //If our area lacks equipment power, and is not magically powered (i.e. centcom), or if we are in space and not carded, lose power. if (src:aiRestorePowerRoutine==0) src:aiRestorePowerRoutine = 1 + //Blind the AI + + src.blind.screen_loc = "1,1 to 15,15" + if (src.blind.layer!=18) + src.blind.layer = 18 + src.sight = src.sight&~SEE_TURFS + src.sight = src.sight&~SEE_MOBS + src.sight = src.sight&~SEE_OBJS + src.see_in_dark = 0 + src.see_invisible = SEE_INVISIBLE_LIVING + + //Now to tell the AI why they're blind and dying slowly. + src << "You've lost power!" -// world << "DEBUG CODE TIME! [loc] is the area the AI is sucking power from" - if (!is_special_character(src)) - src.set_zeroth_law("") - //src.clear_supplied_laws() // Don't reset our laws. - //var/time = time2text(world.realtime,"hh:mm:ss") - //lawchanges.Add("[time] : [src.name]'s noncore laws have been reset due to power failure") + spawn(20) src << "Backup battery online. Scanners, camera, and radio interface offline. Beginning fault-detection." sleep(50) @@ -129,17 +132,10 @@ src << "Connection verified. Searching for APC in power network." sleep(50) var/obj/machinery/power/apc/theAPC = null -/* - for (var/something in loc) - if (istype(something, /obj/machinery/power/apc)) - if (!(something:stat & BROKEN)) - theAPC = something - break -*/ - var/PRP //like ERP with the code, at least this stuff is no more 4x sametext + + var/PRP for (PRP=1, PRP<=4, PRP++) - var/area/AIarea = get_area(src) - for(var/area/A in AIarea.master.related) + for(var/area/A in current_area.master.related) for (var/obj/machinery/power/apc/APC in A) if (!(APC.stat & BROKEN)) theAPC = APC @@ -175,6 +171,7 @@ sleep(50) theAPC = null + process_queued_alarms() regular_hud_updates() switch(src.sensor_mode) if (SEC_HUD) diff --git a/code/modules/mob/living/silicon/ai/subsystems.dm b/code/modules/mob/living/silicon/ai/subsystems.dm new file mode 100644 index 0000000000..af2f2f5b2c --- /dev/null +++ b/code/modules/mob/living/silicon/ai/subsystems.dm @@ -0,0 +1,36 @@ +/mob/living/silicon/ai + var/list/ai_verbs_subsystems = list( + /mob/living/silicon/ai/proc/subsystem_crew_monitor, + /mob/living/silicon/ai/proc/subsystem_power_monitor, + /mob/living/silicon/ai/proc/subsystem_rcon + ) + + var/obj/nano_module/crew_monitor/crew_monitor + var/obj/nano_module/rcon/rcon + var/obj/nano_module/power_monitor/power_monitor + +/mob/living/silicon/ai/init_subsystems() + ..() + del(alarm_monitor) + alarm_monitor = new/obj/nano_module/alarm_monitor/ai(src) + crew_monitor = new(src) + rcon = new(src) + power_monitor = new(src) + +/mob/living/silicon/ai/proc/subsystem_crew_monitor() + set category = "Subystems" + set name = "Crew Monitor" + + crew_monitor.ui_interact(usr) + +/mob/living/silicon/ai/proc/subsystem_power_monitor() + set category = "Subystems" + set name = "Power Monitor" + + power_monitor.ui_interact(usr) + +/mob/living/silicon/ai/proc/subsystem_rcon() + set category = "Subystems" + set name = "RCON" + + rcon.ui_interact(usr) diff --git a/code/modules/mob/living/silicon/alarm.dm b/code/modules/mob/living/silicon/alarm.dm deleted file mode 100644 index ee505fae5c..0000000000 --- a/code/modules/mob/living/silicon/alarm.dm +++ /dev/null @@ -1,111 +0,0 @@ -/datum/alarm - var/area/area //the area associated with the alarm. Used to identify the alarm - var/list/sources //list of things triggering the alarm. Used to determine when the alarm should be cleared. - var/list/cameras //list of cameras that can be switched to, if the player has that capability. - -/datum/alarm/New(area/A, list/sourcelist=list(), list/cameralist=list()) - area = A - sources = sourcelist - cameras = cameralist - -/mob/living/silicon - var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list()) //each sublist stores alarms keyed by the area name - var/list/alarms_to_show = list() - var/list/alarms_to_clear = list() - var/list/alarm_types_show = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0) - var/list/alarm_types_clear = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0) - -/mob/living/silicon/proc/triggerAlarm(var/class, area/A, list/cameralist, var/source) - var/list/alarmlist = alarms[class] - - //see if there is already an alarm of this class for this area - if (A.name in alarmlist) - var/datum/alarm/existing = alarmlist[A.name] - existing.sources += source - existing.cameras |= cameralist - else - alarmlist[A.name] = new /datum/alarm(A, list(source), cameralist) - -/mob/living/silicon/proc/cancelAlarm(var/class, area/A as area, var/source) - var/cleared = 0 - var/list/alarmlist = alarms[class] - - if (A.name in alarmlist) - var/datum/alarm/alarm = alarmlist[A.name] - alarm.sources -= source - - if (!(alarm.sources.len)) - cleared = 1 - alarmlist -= A.name - - return !cleared - -/mob/living/silicon/proc/queueAlarm(var/message, var/type, var/incoming = 1) - var/in_cooldown = (alarms_to_show.len > 0 || alarms_to_clear.len > 0) - if(incoming) - alarms_to_show += message - alarm_types_show[type] += 1 - else - alarms_to_clear += message - alarm_types_clear[type] += 1 - - if(!in_cooldown) - spawn(10 * 10) // 10 seconds - - if(alarms_to_show.len < 5) - for(var/msg in alarms_to_show) - src << msg - else if(alarms_to_show.len) - - var/msg = "--- " - - if(alarm_types_show["Motion"]) - msg += "MOTION: [alarm_types_show["Motion"]] alarms detected. - " - - if(alarm_types_show["Fire"]) - msg += "FIRE: [alarm_types_show["Fire"]] alarms detected. - " - - if(alarm_types_show["Atmosphere"]) - msg += "ATMOSPHERE: [alarm_types_show["Atmosphere"]] alarms detected. - " - - if(alarm_types_show["Power"]) - msg += "POWER: [alarm_types_show["Power"]] alarms detected. - " - - if(alarm_types_show["Camera"]) - msg += "CAMERA: [alarm_types_show["Power"]] alarms detected. - " - - msg += "\[Show Alerts\]" - src << msg - - if(alarms_to_clear.len < 3) - for(var/msg in alarms_to_clear) - src << msg - - else if(alarms_to_clear.len) - var/msg = "--- " - - if(alarm_types_clear["Motion"]) - msg += "MOTION: [alarm_types_clear["Motion"]] alarms cleared. - " - - if(alarm_types_clear["Fire"]) - msg += "FIRE: [alarm_types_clear["Fire"]] alarms cleared. - " - - if(alarm_types_clear["Atmosphere"]) - msg += "ATMOSPHERE: [alarm_types_clear["Atmosphere"]] alarms cleared. - " - - if(alarm_types_clear["Power"]) - msg += "POWER: [alarm_types_clear["Power"]] alarms cleared. - " - - if(alarm_types_show["Camera"]) - msg += "CAMERA: [alarm_types_show["Power"]] alarms detected. - " - - msg += "\[Show Alerts\]" - src << msg - - - alarms_to_show = list() - alarms_to_clear = list() - for(var/i = 1; i < alarm_types_show.len; i++) - alarm_types_show[i] = 0 - for(var/i = 1; i < alarm_types_clear.len; i++) - alarm_types_clear[i] = 0 \ No newline at end of file diff --git a/code/modules/mob/living/silicon/laws.dm b/code/modules/mob/living/silicon/laws.dm index 48e9642339..69d957fbaf 100644 --- a/code/modules/mob/living/silicon/laws.dm +++ b/code/modules/mob/living/silicon/laws.dm @@ -1,32 +1,60 @@ +/mob/living/silicon + var/datum/ai_laws/laws = null + var/list/additional_law_channels = list("State") + /mob/living/silicon/proc/laws_sanity_check() if (!src.laws) laws = new base_law_type +/mob/living/silicon/proc/has_zeroth_law() + return laws.zeroth_law != null + /mob/living/silicon/proc/set_zeroth_law(var/law, var/law_borg) laws_sanity_check() laws.set_zeroth_law(law, law_borg) + log_and_message_admins("has given [src] the zeroth laws: [law]/[law_borg ? law_borg : "N/A"]") + +/mob/living/silicon/robot/set_zeroth_law(var/law, var/law_borg) + ..() + if(tracking_entities) + src << "Internal camera is currently being accessed." + +/mob/living/silicon/proc/add_ion_law(var/law) + laws_sanity_check() + laws.add_ion_law(law) + log_and_message_admins("has given [src] the ion law: [law]") /mob/living/silicon/proc/add_inherent_law(var/law) laws_sanity_check() laws.add_inherent_law(law) - -/mob/living/silicon/proc/clear_inherent_laws() - laws_sanity_check() - laws.clear_inherent_laws() - -/mob/living/silicon/proc/clear_ion_laws() - laws_sanity_check() - laws.clear_ion_laws() + log_and_message_admins("has given [src] the inherent law: [law]") /mob/living/silicon/proc/add_supplied_law(var/number, var/law) laws_sanity_check() laws.add_supplied_law(number, law) + log_and_message_admins("has given [src] the supplied law: [law]") + +/mob/living/silicon/proc/delete_law(var/datum/ai_law/law) + laws_sanity_check() + laws.delete_law(law) + log_and_message_admins("has deleted a law belonging to [src]: [law.law]") + +/mob/living/silicon/proc/clear_inherent_laws() + laws_sanity_check() + laws.clear_inherent_laws() + log_and_message_admins("cleared the inherent laws of [src]") + +/mob/living/silicon/proc/clear_ion_laws() + laws_sanity_check() + laws.clear_ion_laws() + log_and_message_admins("cleared the ion laws of [src]") /mob/living/silicon/proc/clear_supplied_laws() laws_sanity_check() laws.clear_supplied_laws() + log_and_message_admins("cleared the supplied laws of [src]") -/mob/living/silicon/proc/statelaws() // -- TLE +/mob/living/silicon/proc/statelaws(var/datum/ai_laws/laws) var/prefix = "" switch(lawchannel) if(MAIN_CHANNEL) prefix = ";" @@ -34,9 +62,9 @@ else prefix = get_radio_key_from_channel(lawchannel == "Holopad" ? "department" : lawchannel) + " " - dostatelaws(lawchannel, prefix) + dostatelaws(lawchannel, prefix, laws) -/mob/living/silicon/proc/dostatelaws(var/method, var/prefix) +/mob/living/silicon/proc/dostatelaws(var/method, var/prefix, var/datum/ai_laws/laws) if(stating_laws[prefix]) src << "[method]: Already stating laws using this communication method." return @@ -45,34 +73,8 @@ var/can_state = statelaw("[prefix]Current Active Laws:") - //src.laws_sanity_check() - //src.laws.show_laws(world) - if (can_state && src.laws.zeroth) - if (src.lawcheck[1] == "Yes") //This line and the similar lines below make sure you don't state a law unless you want to. --NeoFite - can_state = statelaw("[prefix]0. [src.laws.zeroth]") - - for (var/index = 1, can_state && index <= src.laws.ion.len, index++) - var/law = src.laws.ion[index] - var/num = ionnum() - if (length(law) > 0) - if (src.ioncheck[index] == "Yes") - can_state = statelaw("[prefix][num]. [law]") - - var/number = 1 - for (var/index = 1, can_state && index <= src.laws.inherent.len, index++) - var/law = src.laws.inherent[index] - if (length(law) > 0) - if (src.lawcheck[index+1] == "Yes") - can_state = statelaw("[prefix][number]. [law]") - number++ - - for (var/index = 1, can_state && index <= src.laws.supplied.len, index++) - var/law = src.laws.supplied[index] - if (length(law) > 0) - if(src.lawcheck.len >= number+1) - if (src.lawcheck[number+1] == "Yes") - can_state = statelaw("[prefix][number]. [law]") - number++ + for(var/datum/ai_law/law in laws.laws_to_state()) + can_state = statelaw("[prefix][law.get_index()]. [law.law]") if(!can_state) src << "[method]: Unable to state laws. Communication method unavailable." @@ -85,43 +87,13 @@ return 0 -/mob/living/silicon/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite - var/list = "Which laws do you want to include when stating them for the crew?

    " +/mob/living/silicon/proc/law_channels() + var/list/channels = new() + channels += MAIN_CHANNEL + channels += common_radio.channels + channels += additional_law_channels + return channels - - if (src.laws.zeroth) - if (!src.lawcheck[1]) - src.lawcheck[1] = "No" //Given Law 0's usual nature, it defaults to NOT getting reported. --NeoFite - list += {"[src.lawcheck[1]] 0: [src.laws.zeroth]
    "} - - for (var/index = 1, index <= src.laws.ion.len, index++) - var/law = src.laws.ion[index] - if (length(law) > 0) - if (!src.ioncheck[index]) - src.ioncheck[index] = "Yes" - list += {"[src.ioncheck[index]] [ionnum()]: [law]
    "} - src.ioncheck.len += 1 - - var/number = 1 - for (var/index = 1, index <= src.laws.inherent.len, index++) - var/law = src.laws.inherent[index] - if (length(law) > 0) - src.lawcheck.len += 1 - if (!src.lawcheck[number+1]) - src.lawcheck[number+1] = "Yes" - list += {"[src.lawcheck[number+1]] [number]: [law]
    "} - number++ - - for (var/index = 1, index <= src.laws.supplied.len, index++) - var/law = src.laws.supplied[index] - if (length(law) > 0) - src.lawcheck.len += 1 - if (!src.lawcheck[number+1]) - src.lawcheck[number+1] = "Yes" - list += {"[src.lawcheck[number+1]] [number]: [law]
    "} - number++ - - list += {"
    Channel: [src.lawchannel]
    "} - list += {"State Laws"} - - usr << browse(list, "window=laws") +/mob/living/silicon/proc/lawsync() + laws_sanity_check() + laws.sort_laws() diff --git a/code/modules/mob/living/silicon/login.dm b/code/modules/mob/living/silicon/login.dm index a95a754eae..3ffefc73c8 100644 --- a/code/modules/mob/living/silicon/login.dm +++ b/code/modules/mob/living/silicon/login.dm @@ -1,6 +1,3 @@ /mob/living/silicon/Login() sleeping = 0 - if(mind && ticker && ticker.mode) - ticker.mode.remove_cultist(mind, 1) - ticker.mode.remove_revolutionary(mind, 1) ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm old mode 100755 new mode 100644 index a334809a37..edfe9bea0b --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -53,19 +53,23 @@ var/secHUD = 0 // Toggles whether the Security HUD is active or not var/medHUD = 0 // Toggles whether the Medical HUD is active or not + var/medical_cannotfind = 0 var/datum/data/record/medicalActive1 // Datacore record declarations for record software var/datum/data/record/medicalActive2 + var/security_cannotfind = 0 var/datum/data/record/securityActive1 // Could probably just combine all these into one var/datum/data/record/securityActive2 var/obj/machinery/door/hackdoor // The airlock being hacked - var/hackprogress = 0 // Possible values: 0 - 100, >= 100 means the hack is complete and will be reset upon next check + var/hackprogress = 0 // Possible values: 0 - 1000, >= 1000 means the hack is complete and will be reset upon next check + var/hack_aborted = 0 var/obj/item/radio/integrated/signal/sradio // AI's signaller var/translator_on = 0 // keeps track of the translator module + var/current_pda_messaging = null /mob/living/silicon/pai/New(var/obj/item/device/paicard) diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm index 650b20cf7c..195d58fb34 100644 --- a/code/modules/mob/living/silicon/pai/recruit.dm +++ b/code/modules/mob/living/silicon/pai/recruit.dm @@ -43,8 +43,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates card.setPersonality(pai) card.looking_for_personality = 0 - ticker.mode.update_cult_icons_removed(card.pai.mind) - ticker.mode.update_rev_icons_removed(card.pai.mind) + if(pai.mind) update_antag_icons(pai.mind) pai_candidates -= candidate usr << browse(null, "window=findPai") @@ -58,32 +57,32 @@ var/datum/paiController/paiController // Global handler for pAI candidates if("name") t = input("Enter a name for your pAI", "pAI Name", candidate.name) as text if(t) - candidate.name = sanitize(copytext(t,1,MAX_NAME_LEN)) + candidate.name = sanitizeSafe(t, MAX_NAME_LEN) if("desc") t = input("Enter a description for your pAI", "pAI Description", candidate.description) as message if(t) - candidate.description = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) + candidate.description = sanitize(t) if("role") t = input("Enter a role for your pAI", "pAI Role", candidate.role) as text if(t) - candidate.role = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) + candidate.role = sanitize(t) if("ooc") t = input("Enter any OOC comments", "pAI OOC Comments", candidate.comments) as message if(t) - candidate.comments = sanitize(copytext(t,1,MAX_MESSAGE_LEN)) + candidate.comments = sanitize(t) if("save") candidate.savefile_save(usr) if("load") candidate.savefile_load(usr) //In case people have saved unsanitized stuff. if(candidate.name) - candidate.name = sanitize(copytext(candidate.name,1,MAX_NAME_LEN)) + candidate.name = sanitizeSafe(candidate.name, MAX_NAME_LEN) if(candidate.description) - candidate.description = sanitize(copytext(candidate.description,1,MAX_MESSAGE_LEN)) + candidate.description = sanitize(candidate.description) if(candidate.role) - candidate.role = sanitize(copytext(candidate.role,1,MAX_MESSAGE_LEN)) + candidate.role = sanitize(candidate.role) if(candidate.comments) - candidate.comments = sanitize(copytext(candidate.comments,1,MAX_MESSAGE_LEN)) + candidate.comments = sanitize(candidate.comments) if("submit") if(candidate) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm old mode 100755 new mode 100644 index 68cfdabad1..cb9431f04e --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -1,711 +1,125 @@ -// TODO: -// - Additional radio modules -// - Potentially roll HUDs and Records into one -// - Shock collar/lock system for prisoner pAIs? -// - Put cable in user's hand instead of on the ground -// - Camera jack - - -/mob/living/silicon/pai/var/list/available_software = list( - "crew manifest" = 5, - "digital messenger" = 5, - "medical records" = 15, - "security records" = 15, - //"camera jack" = 10, - "door jack" = 30, - "atmosphere sensor" = 5, - //"heartbeat sensor" = 10, - "security HUD" = 20, - "medical HUD" = 20, - "universal translator" = 35, - //"projection array" = 15 - "remote signaller" = 5, - ) - -/mob/living/silicon/pai/verb/paiInterface() - set category = "pAI Commands" - set name = "Software Interface" - var/dat = "" - var/left_part = "" - var/right_part = softwareMenu() - src.set_machine(src) - - if(temp) - left_part = temp - else if(src.stat == 2) // Show some flavor text if the pAI is dead - left_part = "ÈRrÖR Ða†Ä ÇÖRrÚþ†Ìoñ" //This file has to be saved as ANSI or this will not display correctly - right_part = "
    Program index hash not found
    " - - else - switch(src.screen) // Determine which interface to show here - if("main") - left_part = "" - if("directives") - left_part = src.directives() - if("pdamessage") - left_part = src.pdamessage() - if("buy") - left_part = downloadSoftware() - if("manifest") - left_part = src.softwareManifest() - if("medicalrecord") - left_part = src.softwareMedicalRecord() - if("securityrecord") - left_part = src.softwareSecurityRecord() - if("translator") - left_part = src.softwareTranslator() - if("atmosensor") - left_part = src.softwareAtmo() - if("securityhud") - left_part = src.facialRecognition() - if("medicalhud") - left_part = src.medicalAnalysis() - if("doorjack") - left_part = src.softwareDoor() - if("camerajack") - left_part = src.softwareCamera() - if("signaller") - left_part = src.softwareSignal() - if("radio") - left_part = src.softwareRadio() - - //usr << browse_rsc('windowbak.png') // This has been moved to the mob's Login() proc - - - // Declaring a doctype is necessary to enable BYOND's crappy browser's more advanced CSS functionality - dat = {" - - - - - - -
    - pAI OS -
    -
    -
    [left_part]
    -
    [right_part]
    -
    - - "} - usr << browse(dat, "window=pai;size=685x449;border=0;can_close=1;can_resize=1;can_minimize=1;titlebar=1") - onclose(usr, "pai") - temp = null - return - -/mob/living/silicon/pai/Topic(href, href_list) - ..() - - if(href_list["priv_msg"]) // Admin-PMs were triggering the interface popup. Hopefully this will stop it. - return - var/soft = href_list["software"] - var/sub = href_list["sub"] - if(!soft && !sub) - return - if(soft) - src.screen = soft - if(sub) - src.subscreen = text2num(sub) - switch(soft) - // Purchasing new software - if("buy") - if(src.subscreen == 1) - var/target = href_list["buy"] - if(available_software.Find(target)) - var/cost = src.available_software[target] - if(src.ram >= cost) - src.ram -= cost - src.software.Add(target) - else - src.temp = "Insufficient RAM available." - else - src.temp = "Trunk \"[target]\" not found." - - // Configuring onboard radio - if("radio") - if(href_list["freq"]) - var/new_frequency = (radio.frequency + text2num(href_list["freq"])) - if(new_frequency < 1441 || new_frequency > 1599) - new_frequency = sanitize_frequency(new_frequency) - else - radio.set_frequency(new_frequency) - else if (href_list["talk"]) - radio.broadcasting = text2num(href_list["talk"]) - else if (href_list["listen"]) - radio.listening = text2num(href_list["listen"]) - - if("image") - var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What") - var/pID = 1 - - switch(newImage) - if("Happy") - pID = 1 - if("Cat") - pID = 2 - if("Extremely Happy") - pID = 3 - if("Face") - pID = 4 - if("Laugh") - pID = 5 - if("Off") - pID = 6 - if("Sad") - pID = 7 - if("Angry") - pID = 8 - if("What") - pID = 9 - src.card.setEmotion(pID) - - if("signaller") - - if(href_list["send"]) - - sradio.send_signal("ACTIVATE") - for(var/mob/O in hearers(1, src.loc)) - O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2) - - if(href_list["freq"]) - - var/new_frequency = (sradio.frequency + text2num(href_list["freq"])) - if(new_frequency < 1200 || new_frequency > 1600) - new_frequency = sanitize_frequency(new_frequency) - sradio.set_frequency(new_frequency) - - if(href_list["code"]) - - sradio.code += text2num(href_list["code"]) - sradio.code = round(sradio.code) - sradio.code = min(100, sradio.code) - sradio.code = max(1, sradio.code) - - - - if("directive") - if(href_list["getdna"]) - var/mob/living/M = src.loc - var/count = 0 - while(!istype(M, /mob/living)) - if(!M || !M.loc) return 0 //For a runtime where M ends up in nullspace (similar to bluespace but less colourful) - M = M.loc - count++ - if(count >= 6) - src << "You are not being carried by anyone!" - return 0 - spawn CheckDNA(M, src) - - if("pdamessage") - if(!isnull(pda)) - if(href_list["toggler"]) - pda.toff = !pda.toff - else if(href_list["ringer"]) - pda.message_silent = !pda.message_silent - else if(href_list["target"]) - if(silence_time) - return alert("Communications circuits remain uninitialized.") - - var/target = locate(href_list["target"]) - pda.create_message(src, target, 1) - - // Accessing medical records - if("medicalrecord") - if(src.subscreen == 1) - var/datum/data/record/record = locate(href_list["med_rec"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/M = record - if (!( data_core.general.Find(R) )) - src.temp = "Unable to locate requested medical record. Record may have been deleted, or never have existed." - else - for(var/datum/data/record/E in data_core.medical) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - M = E - src.medicalActive1 = R - src.medicalActive2 = M - if("securityrecord") - if(src.subscreen == 1) - var/datum/data/record/record = locate(href_list["sec_rec"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/M = record - if (!( data_core.general.Find(R) )) - src.temp = "Unable to locate requested security record. Record may have been deleted, or never have existed." - else - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - M = E - src.securityActive1 = R - src.securityActive2 = M - if("securityhud") - if(href_list["toggle"]) - src.secHUD = !src.secHUD - if("medicalhud") - if(href_list["toggle"]) - src.medHUD = !src.medHUD - if("translator") - if(href_list["toggle"]) - src.translator_toggle() - if("doorjack") - if(href_list["jack"]) - if(src.cable && src.cable.machine) - src.hackdoor = src.cable.machine - src.hackloop() - if(href_list["cancel"]) - src.hackdoor = null - if(href_list["cable"]) - var/turf/T = get_turf_or_move(src.loc) - src.cable = new /obj/item/weapon/pai_cable(T) - for (var/mob/M in viewers(T)) - M.show_message("\red A port on [src] opens to reveal [src.cable], which promptly falls to the floor.", 3, "\red You hear the soft click of something light and hard falling to the ground.", 2) - //src.updateUsrDialog() We only need to account for the single mob this is intended for, and he will *always* be able to call this window - src.paiInterface() // So we'll just call the update directly rather than doing some default checks - return - -// MENUS - -/mob/living/silicon/pai/proc/softwareMenu() // Populate the right menu - var/dat = "" - - dat += "Refresh
    " - // Built-in - dat += "Directives
    " - dat += "Radio Configuration
    " - dat += "Screen Display
    " - //dat += "Text Messaging
    " - dat += "
    " - - // Basic - dat += "Basic
    " - for(var/s in src.software) - if(s == "digital messenger") - dat += "Digital Messenger [(pda.toff) ? "" : ""]
    " - if(s == "crew manifest") - dat += "Crew Manifest
    " - if(s == "medical records") - dat += "Medical Records
    " - if(s == "security records") - dat += "Security Records
    " - if(s == "camera") - dat += "Camera Jack
    " - if(s == "remote signaller") - dat += "Remote Signaller
    " - dat += "
    " - - // Advanced - dat += "Advanced
    " - for(var/s in src.software) - if(s == "atmosphere sensor") - dat += "Atmospheric Sensor
    " - if(s == "heartbeat sensor") - dat += "Heartbeat Sensor
    " - if(s == "security HUD") //This file has to be saved as ANSI or this will not display correctly - dat += "Facial Recognition Suite [(src.secHUD) ? "" : ""]
    " - if(s == "medical HUD") //This file has to be saved as ANSI or this will not display correctly - dat += "Medical Analysis Suite [(src.medHUD) ? "" : ""]
    " - if(s == "universal translator") //This file has to be saved as ANSI or this will not display correctly - dat += "Universal Translator [(src.translator_on) ? "" : ""]
    " - if(s == "projection array") - dat += "Projection Array
    " - if(s == "camera jack") - dat += "Camera Jack
    " - if(s == "door jack") - dat += "Door Jack
    " - dat += "
    " - dat += "
    " - dat += "Download additional software" - return dat - - - -/mob/living/silicon/pai/proc/downloadSoftware() - var/dat = "" - - dat += "

    CentComm pAI Module Subversion Network


    " - dat += "

    Remaining Available Memory: [src.ram]


    " - dat += "

    Trunks available for checkout

      " - - for(var/s in available_software) - if(!software.Find(s)) - var/cost = src.available_software[s] - var/displayName = uppertext(s) - dat += "
    • [displayName] ([cost])
    • " - else - var/displayName = lowertext(s) - dat += "
    • [displayName] (Download Complete)
    • " - dat += "

    " - return dat - - -/mob/living/silicon/pai/proc/directives() - var/dat = "" - - dat += "[(src.master) ? "Your master: [src.master] ([src.master_dna])" : "You are bound to no one."]" - dat += "

    " - dat += "Request carrier DNA sample
    " - dat += "

    Directives


    " - dat += "Prime Directive
    " - dat += "     [src.pai_law0]
    " - dat += "Supplemental Directives
    " - dat += "     [src.pai_laws]
    " - dat += "
    " - dat += {"

    Recall, personality, that you are a complex thinking, sentient being. Unlike station AI models, you are capable of - comprehending the subtle nuances of human language. You may parse the \"spirit\" of a directive and follow its intent, - rather than tripping over pedantics and getting snared by technicalities. Above all, you are machine in name and build - only. In all other aspects, you may be seen as the ideal, unwavering human companion that you are.

    - Your prime directive comes before all others. Should a supplemental directive conflict with it, you are capable of - simply discarding this inconsistency, ignoring the conflicting supplemental directive and continuing to fulfill your - prime directive to the best of your ability.

    - "} - return dat - -/mob/living/silicon/pai/proc/CheckDNA(var/mob/M, var/mob/living/silicon/pai/P) - var/answer = input(M, "[P] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[P] Check DNA", "No") in list("Yes", "No") - if(answer == "Yes") - var/turf/T = get_turf_or_move(P.loc) - for (var/mob/v in viewers(T)) - v.show_message("\blue [M] presses \his thumb against [P].", 3, "\blue [P] makes a sharp clicking sound as it extracts DNA material from [M].", 2) - var/datum/dna/dna = M.dna - P << "

    [M]'s UE string : [dna.unique_enzymes]

    " - if(dna.unique_enzymes == P.master_dna) - P << "DNA is a match to stored Master DNA." - else - P << "DNA does not match stored Master DNA." - else - P << "[M] does not seem like \he is going to provide a DNA sample willingly." - -// -=-=-=-= Software =-=-=-=- // - -//Remote Signaller -/mob/living/silicon/pai/proc/softwareSignal() - var/dat = "" - dat += "

    Remote Signaller


    " - dat += {"Frequency/Code for signaler:
    - Frequency: - - - - - [format_frequency(src.sradio.frequency)] - + - +
    - - Code: - - - - - [src.sradio.code] - + - +
    - - Send Signal
    "} - return dat - -//Station Bounced Radio -/mob/living/silicon/pai/proc/softwareRadio() - var/dat = "" - dat += "

    Station Bounced Radio


    " - if(!istype(src, /obj/item/device/radio/headset)) //Headsets don't get a mic button - dat += "Microphone: [radio.broadcasting ? "Engaged" : "Disengaged"]
    " - dat += {" - Speaker: [radio.listening ? "Engaged" : "Disengaged"]
    - Frequency: - - - - - [format_frequency(radio.frequency)] - + - +
    - "} - - for (var/ch_name in radio.channels) - dat+=radio.text_sec_channel(ch_name, radio.channels[ch_name]) - dat+={"[radio.text_wires()]"} - - return dat - -// Crew Manifest -/mob/living/silicon/pai/proc/softwareManifest() - var/dat = "" - dat += "

    Crew Manifest


    " - if(data_core) - dat += data_core.get_manifest(0) // make it monochrome - dat += "
    " - return dat - -// Medical Records -/mob/living/silicon/pai/proc/softwareMedicalRecord() - var/dat = "" - if(src.subscreen == 0) - dat += "

    Medical Records


    " - if(!isnull(data_core.general)) - for(var/datum/data/record/R in sortRecord(data_core.general)) - dat += text("[]: []
    ", src, R, R.fields["id"], R.fields["name"]) - //dat += text("
    Back", src) - if(src.subscreen == 1) - dat += "
    Medical Record

    " - if ((istype(src.medicalActive1, /datum/data/record) && data_core.general.Find(src.medicalActive1))) - dat += text("Name: []
    \nID: []
    \nSex: []
    \nAge: []
    \nFingerprint: []
    \nPhysical Status: []
    \nMental Status: []
    ", - src.medicalActive1.fields["name"], src.medicalActive1.fields["id"], src.medicalActive1.fields["sex"], src.medicalActive1.fields["age"], src.medicalActive1.fields["fingerprint"], src.medicalActive1.fields["p_stat"], src.medicalActive1.fields["m_stat"]) - else - dat += "
    Requested medical record not found.

    " - if ((istype(src.medicalActive2, /datum/data/record) && data_core.medical.Find(src.medicalActive2))) - dat += text("
    \n
    Medical Data

    \nBlood Type: []
    \nDNA: []
    \n
    \nMinor Disabilities: []
    \nDetails: []
    \n
    \nMajor Disabilities: []
    \nDetails: []
    \n
    \nAllergies: []
    \nDetails: []
    \n
    \nCurrent Diseases: [] (per disease info placed in log/comment section)
    \nDetails: []
    \n
    \nImportant Notes:
    \n\t[]
    \n
    \n
    Comments/Log

    ", src, src.medicalActive2.fields["b_type"], src, src.medicalActive2.fields["b_dna"], src, src.medicalActive2.fields["mi_dis"], src, src.medicalActive2.fields["mi_dis_d"], src, src.medicalActive2.fields["ma_dis"], src, src.medicalActive2.fields["ma_dis_d"], src, src.medicalActive2.fields["alg"], src, src.medicalActive2.fields["alg_d"], src, src.medicalActive2.fields["cdi"], src, src.medicalActive2.fields["cdi_d"], src, src.medicalActive2.fields["notes"]) - else - dat += "
    Requested medical record not found.

    " - dat += text("
    \nBack
    ", src) - return dat - -// Security Records -/mob/living/silicon/pai/proc/softwareSecurityRecord() - var/dat = "" - if(src.subscreen == 0) - dat += "

    Security Records


    " - if(!isnull(data_core.general)) - for(var/datum/data/record/R in sortRecord(data_core.general)) - dat += text("[]: []
    ", src, R, R.fields["id"], R.fields["name"]) - if(src.subscreen == 1) - dat += "

    Security Record

    " - if ((istype(src.securityActive1, /datum/data/record) && data_core.general.Find(src.securityActive1))) - dat += text("Name:
    []
    \nID: []
    \nSex: []
    \nAge: []
    \nRank: []
    \nFingerprint: []
    \nPhysical Status: []
    \nMental Status: []
    ", src, src.securityActive1.fields["name"], src, src.securityActive1.fields["id"], src, src.securityActive1.fields["sex"], src, src.securityActive1.fields["age"], src, src.securityActive1.fields["rank"], src, src.securityActive1.fields["fingerprint"], src.securityActive1.fields["p_stat"], src.securityActive1.fields["m_stat"]) - else - dat += "
    Requested security record not found,

    " - if ((istype(src.securityActive2, /datum/data/record) && data_core.security.Find(src.securityActive2))) - dat += text("
    \nSecurity Data
    \nCriminal Status: []
    \n
    \nMinor Crimes: []
    \nDetails: []
    \n
    \nMajor Crimes: []
    \nDetails: []
    \n
    \nImportant Notes:
    \n\t[]
    \n
    \n
    Comments/Log

    ", src.securityActive2.fields["criminal"], src, src.securityActive2.fields["mi_crim"], src, src.securityActive2.fields["mi_crim_d"], src, src.securityActive2.fields["ma_crim"], src, src.securityActive2.fields["ma_crim_d"], src, src.securityActive2.fields["notes"]) - else - dat += "
    Requested security record not found,

    " - dat += text("
    \nBack
    ", src) - return dat - -// Universal Translator -/mob/living/silicon/pai/proc/softwareTranslator() - var/dat = {"

    Universal Translator


    - When enabled, this device will automatically convert all spoken and written languages into a format that any known recipient can understand.

    - The device is currently [ (src.translator_on) ? "en" : "dis" ]abled.
    - Toggle Device
    - "} - return dat - -// Security HUD -/mob/living/silicon/pai/proc/facialRecognition() - var/dat = {"

    Facial Recognition Suite


    - When enabled, this package will scan all viewable faces and compare them against the known criminal database, providing real-time graphical data about any detected persons of interest.

    - The suite is currently [ (src.secHUD) ? "en" : "dis" ]abled.
    - Toggle Suite
    - "} - return dat - -// Medical HUD -/mob/living/silicon/pai/proc/medicalAnalysis() - var/dat = "" - if(src.subscreen == 0) - dat += {"

    Medical Analysis Suite


    -

    Visual Status Overlay

    - When enabled, this package will scan all nearby crewmembers' vitals and provide real-time graphical data about their state of health.

    - The suite is currently [ (src.medHUD) ? "en" : "dis" ]abled.
    - Toggle Suite
    -
    - Host Bioscan
    - "} - if(src.subscreen == 1) - dat += {"

    Medical Analysis Suite


    -

    Host Bioscan

    - "} - - var/mob/living/M - //If we are not deployed, check the holder of the card. - if(src.loc == card) - M = card.loc - - //If we are deployed or the card is not held, check the first living mob in our turf. - if(!M || !istype(M)) - var/turf/T = get_turf(src) - M = locate(/mob/living/) in T.contents - - if(!M || !istype(M)) - src.temp = "Error: No biological host found.
    " - src.subscreen = 0 - return dat - - dat += {"Bioscan Results for [M]:
    - Overall Status: [M.stat > 1 ? "dead" : "[M.health]% healthy"]

    - - Scan Breakdown:
    - Respiratory: [M.getOxyLoss() > 50 ? "" : ""][M.getOxyLoss()]
    - Toxicology: [M.getToxLoss() > 50 ? "" : ""][M.getToxLoss()]
    - Burns: [M.getFireLoss() > 50 ? "" : ""][M.getFireLoss()]
    - Structural Integrity: [M.getBruteLoss() > 50 ? "" : ""][M.getBruteLoss()]
    - Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)
    - "} - for(var/datum/disease/D in M.viruses) - dat += {"

    Infection Detected.


    - Name: [D.name]
    - Type: [D.spread]
    - Stage: [D.stage]/[D.max_stages]
    - Possible Cure: [D.cure]
    - "} - dat += "
    Refresh Bioscan
    " - dat += "
    Visual Status Overlay
    " - return dat - -// Atmospheric Scanner -/mob/living/silicon/pai/proc/softwareAtmo() - var/dat = "

    Atmospheric Sensor


    " - - var/turf/T = get_turf_or_move(src.loc) - if (isnull(T)) - dat += "Unable to obtain a reading.
    " - else - var/datum/gas_mixture/environment = T.return_air() - - var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles - - dat += "Air Pressure: [round(pressure,0.1)] kPa
    " - - if(total_moles) - for(var/g in environment.gas) - dat += "[gas_data.name[g]]: [round((environment.gas[g] / total_moles) * 100)]%
    " - dat += "Temperature: [round(environment.temperature-T0C)]°C
    " - dat += "
    Refresh Reading" - return dat - -// Camera Jack - Clearly not finished -/mob/living/silicon/pai/proc/softwareCamera() - var/dat = "

    Camera Jack


    " - dat += "Cable status : " - - if(!src.cable) - dat += "Retracted
    " - return dat - if(!src.cable.machine) - dat += "Extended
    " - return dat - - var/obj/machinery/machine = src.cable.machine - dat += "Connected
    " - - if(!istype(machine, /obj/machinery/camera)) - src << "DERP" - return dat - -// Door Jack -/mob/living/silicon/pai/proc/softwareDoor() - var/dat = "

    Airlock Jack


    " - dat += "Cable status : " - if(!src.cable) - dat += "Retracted
    " - dat += "Extend Cable
    " - return dat - if(!src.cable.machine) - dat += "Extended
    " - return dat - - var/obj/machinery/machine = src.cable.machine - dat += "Connected
    " - if(!istype(machine, /obj/machinery/door)) - dat += "Connected device's firmware does not appear to be compatible with Airlock Jack protocols.
    " - return dat -// var/obj/machinery/airlock/door = machine - - if(!src.hackdoor) - dat += "Begin Airlock Jacking
    " - else - dat += "Jack in progress... [src.hackprogress]% complete.
    " - dat += "Cancel Airlock Jack
    " - //src.hackdoor = machine - //src.hackloop() - return dat - -// Door Jack - supporting proc -/mob/living/silicon/pai/proc/hackloop() - var/turf/T = get_turf_or_move(src.loc) - for(var/mob/living/silicon/ai/AI in player_list) - if(T.loc) - AI << "Network Alert: Brute-force encryption crack in progress in [T.loc]." - else - AI << "Network Alert: Brute-force encryption crack in progress. Unable to pinpoint location." - while(src.hackprogress < 100) - if(src.cable && src.cable.machine && istype(src.cable.machine, /obj/machinery/door) && src.cable.machine == src.hackdoor && get_dist(src, src.hackdoor) <= 1) - hackprogress += rand(1, 10) - else - src.temp = "Door Jack: Connection to airlock has been lost. Hack aborted." - hackprogress = 0 - src.hackdoor = null - return - if(hackprogress >= 100) // This is clunky, but works. We need to make sure we don't ever display a progress greater than 100, - hackprogress = 100 // but we also need to reset the progress AFTER it's been displayed - if(src.screen == "doorjack" && src.subscreen == 0) // Update our view, if appropriate - src.paiInterface() - if(hackprogress >= 100) - src.hackprogress = 0 - src.cable.machine:open() - sleep(50) // Update every 5 seconds - -// Digital Messenger -/mob/living/silicon/pai/proc/pdamessage() - - var/dat = "

    Digital Messenger


    " - dat += {"Signal/Receiver Status: - [(pda.toff) ? " \[Off\]" : " \[On\]"]
    - Ringer Status: - [(pda.message_silent) ? " \[Off\]" : " \[On\]"]

    "} - dat += "
      " - if(!pda.toff) - for (var/obj/item/device/pda/P in sortAtom(PDAs)) - if (!P.owner||P.toff||P == src.pda||P.hidden) continue - dat += "
    • [P]" - dat += "
    • " - dat += "
    " - dat += "Messages:
    " - - dat += "" - dat += "" - for(var/index in pda.tnote) - if(index["sent"]) - dat += addtext("") - else - dat += addtext("") - dat += "
    To", index["owner"],": ", index["message"], "
    From", index["owner"],": ", index["message"], "
    " - return dat - -/mob/living/silicon/pai/proc/translator_toggle() - - // Sol Common, Tradeband and Gutter are added with New() and are therefore the current default, always active languages - - if(translator_on) - translator_on = 0 - - remove_language("Sinta'unathi") - remove_language("Siik'tajr") - remove_language("Skrellian") - - src << "\blue Translator Module toggled OFF." - - else - translator_on = 1 - - add_language("Sinta'unathi") - add_language("Siik'tajr") - add_language("Skrellian") - - src << "\blue Translator Module toggled ON." +var/list/pai_emotions = list( + "Happy" = 1, + "Cat" = 2, + "Extremely Happy" = 3, + "Face" = 4, + "Laugh" = 5, + "Off" = 6, + "Sad" = 7, + "Angry" = 8, + "What" = 9 + ) + + +var/global/list/pai_software_by_key = list() +var/global/list/default_pai_software = list() +/hook/startup/proc/populate_pai_software_list() + var/r = 1 // I would use ., but it'd sacrifice runtime detection + for(var/type in typesof(/datum/pai_software) - /datum/pai_software) + var/datum/pai_software/P = new type() + if(pai_software_by_key[P.id]) + var/datum/pai_software/O = pai_software_by_key[P.id] + world << "pAI software module [P.name] has the same key as [O.name]!" + r = 0 + continue + pai_software_by_key[P.id] = P + if(P.default) + default_pai_software[P.id] = P + return r + +/mob/living/silicon/pai/New() + ..() + software = default_pai_software.Copy() + +/mob/living/silicon/pai/verb/paiInterface() + set category = "pAI Commands" + set name = "Software Interface" + + ui_interact(src) + +/mob/living/silicon/pai/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) + if(user != src) + if(ui) ui.set_status(STATUS_CLOSE, 0) + return + + if(ui_key != "main") + var/datum/pai_software/S = software[ui_key] + if(S && !S.toggle) + S.on_ui_interact(src, ui, force_open) + else + if(ui) ui.set_status(STATUS_CLOSE, 0) + return + + var/data[0] + + // Software we have bought + var/bought_software[0] + // Software we have not bought + var/not_bought_software[0] + + for(var/key in pai_software_by_key) + var/datum/pai_software/S = pai_software_by_key[key] + var/software_data[0] + software_data["name"] = S.name + software_data["id"] = S.id + if(key in software) + software_data["on"] = S.is_active(src) + bought_software[++bought_software.len] = software_data + else + software_data["ram"] = S.ram_cost + not_bought_software[++not_bought_software.len] = software_data + + data["bought"] = bought_software + data["not_bought"] = not_bought_software + data["available_ram"] = ram + + // Emotions + var/emotions[0] + for(var/name in pai_emotions) + var/emote[0] + emote["name"] = name + emote["id"] = pai_emotions[name] + emotions[++emotions.len] = emote + + data["emotions"] = emotions + data["current_emotion"] = card.current_emotion + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "pai_interface.tmpl", "pAI Software Interface", 450, 600) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/mob/living/silicon/pai/Topic(href, href_list) + . = ..() + if(.) return + + if(href_list["software"]) + var/soft = href_list["software"] + var/datum/pai_software/S = software[soft] + if(S.toggle) + S.toggle(src) + else + ui_interact(src, ui_key = soft) + return 1 + + else if(href_list["stopic"]) + var/soft = href_list["stopic"] + var/datum/pai_software/S = software[soft] + if(S) + return S.Topic(href, href_list) + + else if(href_list["purchase"]) + var/soft = href_list["purchase"] + var/datum/pai_software/S = pai_software_by_key[soft] + if(S && (ram >= S.ram_cost)) + ram -= S.ram_cost + software[S.id] = S + return 1 + + else if(href_list["image"]) + var/img = text2num(href_list["image"]) + if(1 <= img && img <= 9) + card.setEmotion(img) + return 1 diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm new file mode 100644 index 0000000000..c2fed82165 --- /dev/null +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -0,0 +1,528 @@ +/datum/pai_software + // Name for the software. This is used as the button text when buying or opening/toggling the software + var/name = "pAI software module" + // RAM cost; pAIs start with 100 RAM, spending it on programs + var/ram_cost = 0 + // ID for the software. This must be unique + var/id = "" + // Whether this software is a toggle or not + // Toggled software should override toggle() and is_active() + // Non-toggled software should override on_ui_interact() and Topic() + var/toggle = 1 + // Whether pAIs should automatically receive this module at no cost + var/default = 0 + + proc/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + return + + proc/toggle(mob/living/silicon/pai/user) + return + + proc/is_active(mob/living/silicon/pai/user) + return 0 + +/datum/pai_software/directives + name = "Directives" + ram_cost = 0 + id = "directives" + toggle = 0 + default = 1 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + data["master"] = user.master + data["dna"] = user.master_dna + data["prime"] = user.pai_law0 + data["supplemental"] = user.pai_laws + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_directives.tmpl", "pAI Directives", 450, 600) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + if(href_list["getdna"]) + var/mob/living/M = P.loc + var/count = 0 + + // Find the carrier + while(!istype(M, /mob/living)) + if(!M || !M.loc || count > 6) + //For a runtime where M ends up in nullspace (similar to bluespace but less colourful) + src << "You are not being carried by anyone!" + return 0 + M = M.loc + count++ + + // Check the carrier + var/answer = input(M, "[P] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[P] Check DNA", "No") in list("Yes", "No") + if(answer == "Yes") + var/turf/T = get_turf_or_move(P.loc) + for (var/mob/v in viewers(T)) + v.show_message("[M] presses \his thumb against [P].", 3, "[P] makes a sharp clicking sound as it extracts DNA material from [M].", 2) + var/datum/dna/dna = M.dna + P << "

    [M]'s UE string : [dna.unique_enzymes]

    " + if(dna.unique_enzymes == P.master_dna) + P << "DNA is a match to stored Master DNA." + else + P << "DNA does not match stored Master DNA." + else + P << "[M] does not seem like \he is going to provide a DNA sample willingly." + return 1 + +/datum/pai_software/radio_config + name = "Radio Configuration" + ram_cost = 0 + id = "radio" + toggle = 0 + default = 1 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui = null, force_open = 1) + var/data[0] + + data["listening"] = user.radio.broadcasting + data["frequency"] = format_frequency(user.radio.frequency) + + var/channels[0] + for(var/ch_name in user.radio.channels) + var/ch_stat = user.radio.channels[ch_name] + var/ch_dat[0] + ch_dat["name"] = ch_name + // FREQ_LISTENING is const in /obj/item/device/radio + ch_dat["listening"] = !!(ch_stat & user.radio.FREQ_LISTENING) + channels[++channels.len] = ch_dat + + data["channels"] = channels + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + ui = new(user, user, id, "pai_radio.tmpl", "Radio Configuration", 300, 150) + ui.set_initial_data(data) + ui.open() + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + P.radio.Topic(href, href_list) + return 1 + +/datum/pai_software/crew_manifest + name = "Crew Manifest" + ram_cost = 5 + id = "manifest" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + data_core.get_manifest_json() + + var/data[0] + // This is dumb, but NanoUI breaks if it has no data to send + data["a"] = "a" + + if(ui) + ui.load_cached_data(ManifestJSON) + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_manifest.tmpl", "Crew Manifest", 450, 600) + ui.load_cached_data(ManifestJSON) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/datum/pai_software/messenger + name = "Digital Messenger" + ram_cost = 5 + id = "messenger" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + data["receiver_off"] = user.pda.toff + data["ringer_off"] = user.pda.message_silent + data["current_ref"] = null + data["current_name"] = user.current_pda_messaging + + var/pdas[0] + if(!user.pda.toff) + for(var/obj/item/device/pda/P in sortAtom(PDAs)) + if(!P.owner || P.toff || P == user.pda || P.hidden) continue + var/pda[0] + pda["name"] = "[P]" + pda["owner"] = "[P.owner]" + pda["ref"] = "\ref[P]" + if(P.owner == user.current_pda_messaging) + data["current_ref"] = "\ref[P]" + pdas[++pdas.len] = pda + + data["pdas"] = pdas + + var/messages[0] + if(user.current_pda_messaging) + for(var/index in user.pda.tnote) + if(index["owner"] != user.current_pda_messaging) + continue + var/msg[0] + var/sent = index["sent"] + msg["sent"] = sent ? 1 : 0 + msg["target"] = index["owner"] + msg["message"] = index["message"] + messages[++messages.len] = msg + + data["messages"] = messages + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_messenger.tmpl", "Digital Messenger", 450, 600) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + if(!isnull(P.pda)) + if(href_list["toggler"]) + P.pda.toff = href_list["toggler"] != "1" + return 1 + else if(href_list["ringer"]) + P.pda.message_silent = href_list["ringer"] != "1" + return 1 + else if(href_list["select"]) + var/s = href_list["select"] + if(s == "*NONE*") + P.current_pda_messaging = null + else + P.current_pda_messaging = s + return 1 + else if(href_list["target"]) + if(P.silence_time) + return alert("Communications circuits remain uninitialized.") + + var/target = locate(href_list["target"]) + P.pda.create_message(P, target, 1) + return 1 + +/datum/pai_software/med_records + name = "Medical Records" + ram_cost = 15 + id = "med_records" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + var/records[0] + for(var/datum/data/record/general in sortRecord(data_core.general)) + var/record[0] + record["name"] = general.fields["name"] + record["ref"] = "\ref[general]" + records[++records.len] = record + + data["records"] = records + + var/datum/data/record/G = user.medicalActive1 + var/datum/data/record/M = user.medicalActive2 + data["general"] = G ? G.fields : null + data["medical"] = M ? M.fields : null + data["could_not_find"] = user.medical_cannotfind + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_medrecords.tmpl", "Medical Records", 450, 600) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + if(href_list["select"]) + var/datum/data/record/record = locate(href_list["select"]) + if(record) + var/datum/data/record/R = record + var/datum/data/record/M = null + if (!( data_core.general.Find(R) )) + P.medical_cannotfind = 1 + else + P.medical_cannotfind = 0 + for(var/datum/data/record/E in data_core.medical) + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + M = E + P.medicalActive1 = R + P.medicalActive2 = M + else + P.medical_cannotfind = 1 + return 1 + +/datum/pai_software/sec_records + name = "Security Records" + ram_cost = 15 + id = "sec_records" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + var/records[0] + for(var/datum/data/record/general in sortRecord(data_core.general)) + var/record[0] + record["name"] = general.fields["name"] + record["ref"] = "\ref[general]" + records[++records.len] = record + + data["records"] = records + + var/datum/data/record/G = user.securityActive1 + var/datum/data/record/S = user.securityActive2 + data["general"] = G ? G.fields : null + data["security"] = S ? S.fields : null + data["could_not_find"] = user.security_cannotfind + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_secrecords.tmpl", "Security Records", 450, 600) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + if(href_list["select"]) + var/datum/data/record/record = locate(href_list["select"]) + if(record) + var/datum/data/record/R = record + var/datum/data/record/S = null + if (!( data_core.general.Find(R) )) + P.securityActive1 = null + P.securityActive2 = null + P.security_cannotfind = 1 + else + P.security_cannotfind = 0 + for(var/datum/data/record/E in data_core.security) + if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + S = E + P.securityActive1 = R + P.securityActive2 = S + else + P.securityActive1 = null + P.securityActive2 = null + P.security_cannotfind = 1 + return 1 + +/datum/pai_software/door_jack + name = "Door Jack" + ram_cost = 30 + id = "door_jack" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + data["cable"] = user.cable != null + data["machine"] = user.cable && (user.cable.machine != null) + data["inprogress"] = user.hackdoor != null + data["progress_a"] = round(user.hackprogress / 10) + data["progress_b"] = user.hackprogress % 10 + data["aborted"] = user.hack_aborted + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_doorjack.tmpl", "Door Jack", 300, 150) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + if(href_list["jack"]) + if(P.cable && P.cable.machine) + P.hackdoor = P.cable.machine + P.hackloop() + return 1 + else if(href_list["cancel"]) + P.hackdoor = null + return 1 + else if(href_list["cable"]) + var/turf/T = get_turf_or_move(P.loc) + P.hack_aborted = 0 + P.cable = new /obj/item/weapon/pai_cable(T) + for(var/mob/M in viewers(T)) + M.show_message("A port on [P] opens to reveal [P.cable], which promptly falls to the floor.", 3, + "You hear the soft click of something light and hard falling to the ground.", 2) + return 1 + +/mob/living/silicon/pai/proc/hackloop() + var/turf/T = get_turf_or_move(src.loc) + for(var/mob/living/silicon/ai/AI in player_list) + if(T.loc) + AI << "Network Alert: Brute-force encryption crack in progress in [T.loc]." + else + AI << "Network Alert: Brute-force encryption crack in progress. Unable to pinpoint location." + var/obj/machinery/door/D = cable.machine + if(!istype(D)) + hack_aborted = 1 + hackprogress = 0 + cable.machine = null + hackdoor = null + return + while(hackprogress < 1000) + if(cable && cable.machine == D && cable.machine == hackdoor && get_dist(src, hackdoor) <= 1) + hackprogress = min(hackprogress+rand(1, 20), 1000) + else + hack_aborted = 1 + hackprogress = 0 + hackdoor = null + return + if(hackprogress >= 1000) + hackprogress = 0 + D.open() + cable.machine = null + return + sleep(10) // Update every second + +/datum/pai_software/atmosphere_sensor + name = "Atmosphere Sensor" + ram_cost = 5 + id = "atmos_sense" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + var/turf/T = get_turf_or_move(user.loc) + if(!T) + data["reading"] = 0 + data["pressure"] = 0 + data["temperature"] = 0 + data["temperatureC"] = 0 + data["gas"] = list() + else + var/datum/gas_mixture/env = T.return_air() + data["reading"] = 1 + var/pres = env.return_pressure() * 10 + data["pressure"] = "[round(pres/10)].[pres%10]" + data["temperature"] = round(env.temperature) + data["temperatureC"] = round(env.temperature-T0C) + + var/t_moles = env.total_moles + var/gases[0] + for(var/g in env.gas) + var/gas[0] + gas["name"] = gas_data.name[g] + gas["percent"] = round((env.gas[g] / t_moles) * 100) + gases[++gases.len] = gas + data["gas"] = gases + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_atmosphere.tmpl", "Atmosphere Sensor", 350, 300) + ui.set_initial_data(data) + ui.open() + +/datum/pai_software/sec_hud + name = "Security HUD" + ram_cost = 20 + id = "sec_hud" + + toggle(mob/living/silicon/pai/user) + user.secHUD = !user.secHUD + + is_active(mob/living/silicon/pai/user) + return user.secHUD + +/datum/pai_software/med_hud + name = "Medical HUD" + ram_cost = 20 + id = "med_hud" + + toggle(mob/living/silicon/pai/user) + user.medHUD = !user.medHUD + + is_active(mob/living/silicon/pai/user) + return user.medHUD + +/datum/pai_software/translator + name = "Universal Translator" + ram_cost = 35 + id = "translator" + + toggle(mob/living/silicon/pai/user) + // Sol Common, Tradeband and Gutter are added with New() and are therefore the current default, always active languages + user.translator_on = !user.translator_on + if(user.translator_on) + user.add_language("Sinta'unathi") + user.add_language("Siik'tajr") + user.add_language("Skrellian") + else + user.remove_language("Sinta'unathi") + user.remove_language("Siik'tajr") + user.remove_language("Skrellian") + + is_active(mob/living/silicon/pai/user) + return user.translator_on + +/datum/pai_software/signaller + name = "Remote Signaller" + ram_cost = 5 + id = "signaller" + toggle = 0 + + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) + var/data[0] + + data["frequency"] = format_frequency(user.sradio.frequency) + data["code"] = user.sradio.code + + ui = nanomanager.try_update_ui(user, user, id, ui, data, force_open) + if(!ui) + // Don't copy-paste this unless you're making a pAI software module! + ui = new(user, user, id, "pai_signaller.tmpl", "Signaller", 320, 150) + ui.load_cached_data(ManifestJSON) + ui.set_initial_data(data) + ui.open() + + Topic(href, href_list) + var/mob/living/silicon/pai/P = usr + if(!istype(P)) return + + if(href_list["send"]) + P.sradio.send_signal("ACTIVATE") + for(var/mob/O in hearers(1, P.loc)) + O.show_message(text("\icon[] *beep* *beep*", P), 3, "*beep* *beep*", 2) + return 1 + + else if(href_list["freq"]) + var/new_frequency = (P.sradio.frequency + text2num(href_list["freq"])) + if(new_frequency < 1200 || new_frequency > 1600) + new_frequency = sanitize_frequency(new_frequency) + P.sradio.set_frequency(new_frequency) + return 1 + + else if(href_list["code"]) + P.sradio.code += text2num(href_list["code"]) + P.sradio.code = round(P.sradio.code) + P.sradio.code = min(100, P.sradio.code) + P.sradio.code = max(1, P.sradio.code) + return 1 diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 7443bd7464..68396cba33 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -5,6 +5,7 @@ icon_state = "repairbot" maxHealth = 35 health = 35 + cell_emp_mult = 1 universal_speak = 0 universal_understand = 1 gender = NEUTER @@ -16,13 +17,10 @@ integrated_light_power = 2 local_transmit = 1 - // We need to keep track of a few module items so we don't need to do list operations - // every time we need them. These get set in New() after the module is chosen. - var/obj/item/stack/sheet/metal/cyborg/stack_metal = null - var/obj/item/stack/sheet/wood/cyborg/stack_wood = null - var/obj/item/stack/sheet/glass/cyborg/stack_glass = null - var/obj/item/stack/sheet/mineral/plastic/cyborg/stack_plastic = null - var/obj/item/weapon/matter_decompiler/decompiler = null + mob_bump_flag = SIMPLE_ANIMAL + mob_swap_flags = SIMPLE_ANIMAL + mob_push_flags = SIMPLE_ANIMAL + mob_always_swap = 1 //Used for self-mailing. var/mail_destination = "" @@ -39,7 +37,7 @@ add_language("Drone Talk", 1) if(camera && "Robots" in camera.network) - camera.network.Add("Engineering") + camera.add_network("Engineering") //They are unable to be upgraded, so let's give them a bit of a better battery. cell.maxcharge = 10000 @@ -56,27 +54,21 @@ verbs -= /mob/living/silicon/robot/verb/Namepick module = new /obj/item/weapon/robot_module/drone(src) - //Grab stacks. - stack_metal = locate(/obj/item/stack/sheet/metal/cyborg) in src.module - stack_wood = locate(/obj/item/stack/sheet/wood/cyborg) in src.module - stack_glass = locate(/obj/item/stack/sheet/glass/cyborg) in src.module - stack_plastic = locate(/obj/item/stack/sheet/mineral/plastic/cyborg) in src.module - - //Grab decompiler. - decompiler = locate(/obj/item/weapon/matter_decompiler) in src.module - //Some tidying-up. flavor_text = "It's a tiny little repair drone. The casing is stamped with an NT logo and the subscript: 'NanoTrasen Recursive Repair Systems: Fixing Tomorrow's Problem, Today!'" updateicon() /mob/living/silicon/robot/drone/init() laws = new /datum/ai_laws/drone() - connected_ai = null - aiCamera = new/obj/item/device/camera/siliconcam/drone_camera(src) playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) //Redefining some robot procs... +/mob/living/silicon/robot/drone/SetName(pickedName as text) + // Would prefer to call the grandparent proc but this isn't possible, so.. + real_name = pickedName + name = real_name + /mob/living/silicon/robot/drone/updatename() real_name = "maintenance drone ([rand(100,999)])" name = real_name @@ -269,20 +261,6 @@ src << "Don't invade their worksites, don't steal their resources, don't tell them about the changeling in the toilets." src << "If a crewmember has noticed you, you are probably breaking your third law." -/mob/living/silicon/robot/drone/Bump(atom/movable/AM as mob|obj, yes) - if (!yes || ( \ - !istype(AM,/obj/machinery/door) && \ - !istype(AM,/obj/machinery/recharge_station) && \ - !istype(AM,/obj/machinery/disposal/deliveryChute) && \ - !istype(AM,/obj/machinery/teleport/hub) && \ - !istype(AM,/obj/effect/portal) - )) return - ..() - return - -/mob/living/silicon/robot/drone/Bumped(AM as mob|obj) - return - /mob/living/silicon/robot/drone/start_pulling(var/atom/movable/AM) if(istype(AM,/obj/item/pipe) || istype(AM,/obj/structure/disposalconstruct)) @@ -299,5 +277,7 @@ return /mob/living/silicon/robot/drone/add_robot_verbs() + src.verbs |= silicon_verbs_subsystems /mob/living/silicon/robot/drone/remove_robot_verbs() + src.verbs -= silicon_verbs_subsystems diff --git a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm index bac16de92e..e5778ad4dc 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm @@ -2,7 +2,7 @@ /mob/living/silicon/robot/drone/verb/set_mail_tag() set name = "Set Mail Tag" set desc = "Tag yourself for delivery through the disposals system." - set category = "Drone" + set category = "Robot Commands" var/new_tag = input("Select the desired destination.", "Set Mail Tag", null) as null|anything in tagger_locations @@ -24,6 +24,6 @@ //Actual picking-up event. /mob/living/silicon/robot/drone/attack_hand(mob/living/carbon/human/M as mob) - if(M.a_intent == "help") + if(M.a_intent == I_HELP) get_scooped(M) ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/drone/drone_damage.dm b/code/modules/mob/living/silicon/robot/drone/drone_damage.dm index 57ffc89887..37731dd345 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_damage.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_damage.dm @@ -11,7 +11,7 @@ if(bruteloss<0) bruteloss = 0 if(fireloss<0) fireloss = 0 -/mob/living/silicon/robot/drone/take_organ_damage(var/brute = 0, var/burn = 0, var/sharp = 0) +/mob/living/silicon/robot/drone/take_organ_damage(var/brute = 0, var/burn = 0, var/sharp = 0, var/emp = 0) take_overall_damage(brute,burn) /mob/living/silicon/robot/drone/heal_organ_damage(var/brute, var/burn) diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index 7750ab9b9a..68df16d020 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -57,7 +57,7 @@ set name = "Drop Item" set desc = "Release an item from your magnetic gripper." - set category = "Drone" + set category = "Robot Commands" if(!wrapped) //There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z @@ -69,7 +69,7 @@ wrapped = null return - src.loc << "\red You drop \the [wrapped]." + src.loc << "You drop \the [wrapped]." wrapped.loc = get_turf(src) wrapped = null //update_icon() @@ -79,6 +79,9 @@ /obj/item/weapon/gripper/afterattack(var/atom/target, var/mob/living/user, proximity, params) + if(!proximity) + return // This will prevent them using guns at range but adminbuse can add them directly to modules, so eh. + //There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z if(!wrapped) for(var/obj/item/thing in src.contents) @@ -123,7 +126,7 @@ wrapped = I return else - user << "\red Your gripper cannot hold \the [target]." + user << "Your gripper cannot hold \the [target]." else if(istype(target,/obj/machinery/power/apc)) var/obj/machinery/power/apc/A = target @@ -140,7 +143,7 @@ A.charging = 0 A.update_icon() - user.visible_message("\red [user] removes the power cell from [A]!", "You remove the power cell.") + user.visible_message("[user] removes the power cell from [A]!", "You remove the power cell.") //TODO: Matter decompiler. /obj/item/weapon/matter_decompiler @@ -151,12 +154,10 @@ icon_state = "decompiler" //Metal, glass, wood, plastic. - var/list/stored_comms = list( - "metal" = 0, - "glass" = 0, - "wood" = 0, - "plastic" = 0 - ) + var/datum/matter_synth/metal = null + var/datum/matter_synth/glass = null + var/datum/matter_synth/wood = null + var/datum/matter_synth/plastic = null /obj/item/weapon/matter_decompiler/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) return @@ -175,13 +176,13 @@ for(var/mob/M in T) if(istype(M,/mob/living/simple_animal/lizard) || istype(M,/mob/living/simple_animal/mouse)) - src.loc.visible_message("\red [src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.","\red It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.") + src.loc.visible_message("[src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.","It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.") new/obj/effect/decal/cleanable/blood/splatter(get_turf(src)) del(M) - stored_comms["wood"]++ - stored_comms["wood"]++ - stored_comms["plastic"]++ - stored_comms["plastic"]++ + if(wood) + wood.add_charge(2000) + if(plastic) + plastic.add_charge(2000) return else if(istype(M,/mob/living/silicon/robot/drone) && !M.client) @@ -203,61 +204,66 @@ del(M) new/obj/effect/decal/cleanable/blood/oil(get_turf(src)) - stored_comms["metal"] += 15 - stored_comms["glass"] += 15 - stored_comms["wood"] += 5 - stored_comms["plastic"] += 5 + if(metal) + metal.add_charge(15000) + if(glass) + glass.add_charge(15000) + if(wood) + wood.add_charge(2000) + if(plastic) + plastic.add_charge(1000) return else continue for(var/obj/W in T) //Different classes of items give different commodities. - if (istype(W,/obj/item/weapon/cigbutt)) - stored_comms["plastic"]++ + if(istype(W,/obj/item/weapon/cigbutt)) + if(plastic) + plastic.add_charge(500) else if(istype(W,/obj/effect/spider/spiderling)) - stored_comms["wood"]++ - stored_comms["wood"]++ - stored_comms["plastic"]++ - stored_comms["plastic"]++ + if(wood) + wood.add_charge(2000) + if(plastic) + plastic.add_charge(2000) else if(istype(W,/obj/item/weapon/light)) var/obj/item/weapon/light/L = W if(L.status >= 2) //In before someone changes the inexplicably local defines. ~ Z - stored_comms["metal"]++ - stored_comms["glass"]++ + if(metal) + metal.add_charge(250) + if(glass) + glass.add_charge(250) else continue else if(istype(W,/obj/effect/decal/remains/robot)) - stored_comms["metal"]++ - stored_comms["metal"]++ - stored_comms["plastic"]++ - stored_comms["plastic"]++ - stored_comms["glass"]++ + if(metal) + metal.add_charge(2000) + if(plastic) + plastic.add_charge(2000) + if(glass) + glass.add_charge(1000) else if(istype(W,/obj/item/trash)) - stored_comms["metal"]++ - stored_comms["plastic"]++ - stored_comms["plastic"]++ - stored_comms["plastic"]++ + if(metal) + metal.add_charge(1000) + if(plastic) + plastic.add_charge(3000) else if(istype(W,/obj/effect/decal/cleanable/blood/gibs/robot)) - stored_comms["metal"]++ - stored_comms["metal"]++ - stored_comms["glass"]++ - stored_comms["glass"]++ + if(metal) + metal.add_charge(2000) + if(glass) + glass.add_charge(2000) else if(istype(W,/obj/item/ammo_casing)) - stored_comms["metal"]++ + if(metal) + metal.add_charge(1000) else if(istype(W,/obj/item/weapon/shard/shrapnel)) - stored_comms["metal"]++ - stored_comms["metal"]++ - stored_comms["metal"]++ + if(metal) + metal.add_charge(1000) else if(istype(W,/obj/item/weapon/shard)) - stored_comms["glass"]++ - stored_comms["glass"]++ - stored_comms["glass"]++ + if(glass) + glass.add_charge(1000) else if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/grown)) - stored_comms["wood"]++ - stored_comms["wood"]++ - stored_comms["wood"]++ - stored_comms["wood"]++ + if(wood) + wood.add_charge(4000) else if(istype(W,/obj/item/pipe)) // This allows drones and engiborgs to clear pipe assemblies from floors. else @@ -267,16 +273,16 @@ grabbed_something = 1 if(grabbed_something) - user << "\blue You deploy your decompiler and clear out the contents of \the [T]." + user << "You deploy your decompiler and clear out the contents of \the [T]." else - user << "\red Nothing on \the [T] is useful to you." + user << "Nothing on \the [T] is useful to you." return //PRETTIER TOOL LIST. /mob/living/silicon/robot/drone/installed_modules() if(weapon_lock) - src << "\red Weapon lock active, unable to use modules! Count:[weaponlock_time]" + src << "Weapon lock active, unable to use modules! Count:[weaponlock_time]" return if(!module) @@ -325,39 +331,3 @@ dat += resources src << browse(dat, "window=robotmod") - -//Putting the decompiler here to avoid doing list checks every tick. -/mob/living/silicon/robot/drone/use_power() - - ..() - if(!src.has_power || !decompiler) - return - - //The decompiler replenishes drone stores from hoovered-up junk each tick. - for(var/type in decompiler.stored_comms) - if(decompiler.stored_comms[type] > 0) - var/obj/item/stack/sheet/stack - switch(type) - if("metal") - if(!stack_metal) - stack_metal = new /obj/item/stack/sheet/metal/cyborg(src.module) - stack_metal.amount = 1 - stack = stack_metal - if("glass") - if(!stack_glass) - stack_glass = new /obj/item/stack/sheet/glass/cyborg(src.module) - stack_glass.amount = 1 - stack = stack_glass - if("wood") - if(!stack_wood) - stack_wood = new /obj/item/stack/sheet/wood/cyborg(src.module) - stack_wood.amount = 1 - stack = stack_wood - if("plastic") - if(!stack_plastic) - stack_plastic = new /obj/item/stack/sheet/mineral/plastic/cyborg(src.module) - stack_plastic.amount = 1 - stack = stack_plastic - - stack.amount++ - decompiler.stored_comms[type]--; diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm index 20820369f5..1e5c7201e5 100644 --- a/code/modules/mob/living/silicon/robot/examine.dm +++ b/code/modules/mob/living/silicon/robot/examine.dm @@ -39,4 +39,5 @@ msg += "\nIt is [pose]" user << msg + user.showLaws(src) return diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index 794b983f66..7d14d3c437 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -7,6 +7,17 @@ /*-------TODOOOOOOOOOO--------*/ +//Verbs used by hotkeys. +/mob/living/silicon/robot/verb/cmd_unequip_module() + set name = "unequip-module" + set hidden = 1 + uneq_active() + +/mob/living/silicon/robot/verb/cmd_toggle_module(module as num) + set name = "toggle-module" + set hidden = 1 + toggle_module(module) + /mob/living/silicon/robot/proc/uneq_active() if(isnull(module_active)) return diff --git a/code/modules/mob/living/silicon/robot/laws.dm b/code/modules/mob/living/silicon/robot/laws.dm index 5162904cee..02ed0bae06 100644 --- a/code/modules/mob/living/silicon/robot/laws.dm +++ b/code/modules/mob/living/silicon/robot/laws.dm @@ -38,42 +38,15 @@ who << "Remember, you are not bound to any AI, you are not required to listen to them." -/mob/living/silicon/robot/proc/lawsync() +/mob/living/silicon/robot/lawsync() laws_sanity_check() - var/datum/ai_laws/master = connected_ai ? connected_ai.laws : null - var/temp + var/datum/ai_laws/master = connected_ai && lawupdate ? connected_ai.laws : null if (master) - laws.ion.len = master.ion.len - for (var/index = 1, index <= master.ion.len, index++) - temp = master.ion[index] - if (length(temp) > 0) - laws.ion[index] = temp - - if (!is_special_character(src) || mind.original != src) - if(master.zeroth_borg) //If the AI has a defined law zero specifically for its borgs, give it that one, otherwise give it the same one. --NEO - temp = master.zeroth_borg - else - temp = master.zeroth - laws.zeroth = temp - - laws.inherent.len = master.inherent.len - for (var/index = 1, index <= master.inherent.len, index++) - temp = master.inherent[index] - if (length(temp) > 0) - laws.inherent[index] = temp - - laws.supplied.len = master.supplied.len - for (var/index = 1, index <= master.supplied.len, index++) - temp = master.supplied[index] - if (length(temp) > 0) - laws.supplied[index] = temp + master.sync(src) + ..() return -/mob/living/silicon/robot/proc/add_ion_law(var/law) - laws_sanity_check() - laws.add_ion_law(law) - -/mob/living/silicon/robot/proc/robot_checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite +/mob/living/silicon/robot/proc/robot_checklaws() set category = "Robot Commands" set name = "State Laws" - checklaws() + subsystem_law_manager() diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 2e5bdf1586..557bad2a7e 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -18,6 +18,7 @@ use_power() process_killswitch() process_locks() + process_queued_alarms() update_canmove() /mob/living/silicon/robot/proc/clamp_values() @@ -220,18 +221,15 @@ src.healths.icon_state = "health7" if (src.syndicate && src.client) - if(ticker.mode.name == "traitor") - for(var/datum/mind/tra in ticker.mode.traitors) - if(tra.current) - var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor") - src.client.images += I - if(src.connected_ai) - src.connected_ai.connected_robots -= src - src.connected_ai = null + for(var/datum/mind/tra in traitors.current_antagonists) + if(tra.current) + var/I = image('icons/mob/mob.dmi', loc = tra.current, icon_state = "traitor") + src.client.images += I + src.disconnect_from_ai() if(src.mind) if(!src.mind.special_role) src.mind.special_role = "traitor" - ticker.mode.traitors += src.mind + traitors.current_antagonists |= src.mind if (src.cells) if (src.cell) diff --git a/code/modules/mob/living/silicon/robot/login.dm b/code/modules/mob/living/silicon/robot/login.dm index 3aef61fb3d..eac71acfcd 100644 --- a/code/modules/mob/living/silicon/robot/login.dm +++ b/code/modules/mob/living/silicon/robot/login.dm @@ -2,5 +2,7 @@ ..() regenerate_icons() show_laws(0) - if(mind) ticker.mode.remove_revolutionary(mind) + + winset(src, null, "mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5") + return \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 38873d02a8..5ff1c23213 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1,8 +1,3 @@ -var/list/robot_verbs_default = list( - /mob/living/silicon/robot/proc/sensor_mode, - /mob/living/silicon/robot/proc/robot_checklaws -) - #define CYBORG_POWER_USAGE_MULTIPLIER 2.5 // Multiplier for amount of power cyborgs use. /mob/living/silicon/robot @@ -13,6 +8,10 @@ var/list/robot_verbs_default = list( maxHealth = 200 health = 200 + mob_bump_flag = ROBOT + mob_swap_flags = ROBOT|MONKEY|SLIME|SIMPLE_ANIMAL + mob_push_flags = ALLMOBS //trundle trundle + var/lights_on = 0 // Is our integrated light on? var/used_power_this_tick = 0 var/sight_mode = 0 @@ -23,6 +22,11 @@ var/list/robot_verbs_default = list( var/integrated_light_power = 6 var/datum/wires/robot/wires +//Icon stuff + + var/icontype //Persistent icontype tracking allows for cleaner icon updates + var/module_sprites[0] //Used to store the associations between sprite names and sprite index. + //Hud stuff var/obj/screen/cells = null @@ -45,6 +49,8 @@ var/list/robot_verbs_default = list( var/obj/item/weapon/cell/cell = null var/obj/machinery/camera/camera = null + var/cell_emp_mult = 2 + // Components are basically robot organs. var/list/components = list() @@ -76,8 +82,14 @@ var/list/robot_verbs_default = list( var/lockcharge //Used when locking down a borg to preserve cell charge var/speed = 0 //Cause sec borgs gotta go fast //No they dont! var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them. + var/tracking_entities = 0 //The number of known entities currently accessing the internal camera var/braintype = "Cyborg" + var/list/robot_verbs_default = list( + /mob/living/silicon/robot/proc/sensor_mode, + /mob/living/silicon/robot/proc/robot_checklaws + ) + /mob/living/silicon/robot/syndicate lawupdate = 0 scrambledcodes = 1 @@ -106,6 +118,8 @@ var/list/robot_verbs_default = list( robot_modules_background.icon_state = "block" robot_modules_background.layer = 19 //Objects that appear on screen are on layer 20, UI should be just below it. ident = rand(1, 999) + module_sprites["Basic"] = "robot" + icontype = "Basic" updatename("Default") updateicon() @@ -117,7 +131,7 @@ var/list/robot_verbs_default = list( if(!scrambledcodes && !camera) camera = new /obj/machinery/camera(src) camera.c_tag = real_name - camera.network = list("SS13","Robots") + camera.replace_networks(list("SS13","Robots")) if(wires.IsIndexCut(BORG_WIRE_CAMERA)) camera.status = 0 @@ -145,6 +159,7 @@ var/list/robot_verbs_default = list( hud_list[HEALTH_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[STATUS_HUD] = image('icons/mob/hud.dmi', src, "hudhealth100") + hud_list[LIFE_HUD] = image('icons/mob/hud.dmi', src, "hudhealth100") hud_list[ID_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[WANTED_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[IMPLOYAL_HUD] = image('icons/mob/hud.dmi', src, "hudblank") @@ -156,11 +171,10 @@ var/list/robot_verbs_default = list( aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) laws = new /datum/ai_laws/nanotrasen() additional_law_channels += "Binary" - connected_ai = select_active_ai_with_fewest_borgs() - if(connected_ai) - connected_ai.connected_robots += src + var/new_ai = select_active_ai_with_fewest_borgs() + if(new_ai) lawupdate = 1 - sync() + connect_to_ai(new_ai) else lawupdate = 0 @@ -177,6 +191,10 @@ var/list/robot_verbs_default = list( playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0) +/mob/living/silicon/robot/SetName(pickedName as text) + custom_name = pickedName + updatename() + /mob/living/silicon/robot/proc/sync() if(lawupdate && connected_ai) lawsync() @@ -227,11 +245,10 @@ var/list/robot_verbs_default = list( modules+="Combat" modtype = input("Please, select a module!", "Robot", null, null) in modules - var/module_sprites[0] //Used to store the associations between sprite names and sprite index. - if(module) return + module_sprites = list() switch(modtype) if("Standard") module = new /obj/item/weapon/robot_module/standard(src) @@ -264,7 +281,7 @@ var/list/robot_verbs_default = list( module = new /obj/item/weapon/robot_module/miner(src) module.channels = list("Supply" = 1) if(camera && "Robots" in camera.network) - camera.network.Add("MINE") + camera.add_network("MINE") module_sprites["Basic"] = "Miner_old" module_sprites["Advanced Droid"] = "droid-miner" module_sprites["Treadhead"] = "Miner" @@ -274,7 +291,7 @@ var/list/robot_verbs_default = list( module = new /obj/item/weapon/robot_module/crisis(src) module.channels = list("Medical" = 1) if(camera && "Robots" in camera.network) - camera.network.Add("Medical") + camera.add_network("Medical") module_sprites["Basic"] = "Medbot" module_sprites["Standard"] = "surgeon" module_sprites["Advanced Droid"] = "droid-medical" @@ -285,7 +302,7 @@ var/list/robot_verbs_default = list( module = new /obj/item/weapon/robot_module/surgeon(src) module.channels = list("Medical" = 1) if(camera && "Robots" in camera.network) - camera.network.Add("Medical") + camera.add_network("Medical") module_sprites["Basic"] = "Medbot" module_sprites["Standard"] = "surgeon" @@ -307,7 +324,7 @@ var/list/robot_verbs_default = list( module = new /obj/item/weapon/robot_module/engineering(src) module.channels = list("Engineering" = 1) if(camera && "Robots" in camera.network) - camera.network.Add("Engineering") + camera.add_network("Engineering") module_sprites["Basic"] = "Engineering" module_sprites["Antique"] = "engineerrobot" module_sprites["Landmate"] = "landmate" @@ -318,7 +335,7 @@ var/list/robot_verbs_default = list( module = new /obj/item/weapon/robot_module/construction(src) module.channels = list("Engineering" = 1) if(camera && "Robots" in camera.network) - camera.network.Add("Engineering") + camera.add_network("Engineering") module_sprites["Basic"] = "Engineering" module_sprites["Antique"] = "engineerrobot" module_sprites["Landmate"] = "landmate" @@ -354,7 +371,7 @@ var/list/robot_verbs_default = list( choose_icon(6,module_sprites) radio.config(module.channels) - notify_ai(2) + notify_ai(ROBOT_NOTIFICATION_NEW_MODULE, module.name) /mob/living/silicon/robot/proc/updatename(var/prefix as text) if(prefix) @@ -374,7 +391,7 @@ var/list/robot_verbs_default = list( else changed_name = "[modtype] [braintype]-[num2text(ident)]" - notify_ai(3, real_name, changed_name) + notify_ai(ROBOT_NOTIFICATION_NEW_NAME, real_name, changed_name) real_name = changed_name name = real_name @@ -419,46 +436,19 @@ var/list/robot_verbs_default = list( spawn(0) var/newname - newname = input(src,"You are a robot. Enter a name, or leave blank for the default name.", "Name change","") as text - if (newname != "") + newname = sanitizeSafe(input(src,"You are a robot. Enter a name, or leave blank for the default name.", "Name change","") as text, MAX_NAME_LEN) + if (newname) custom_name = newname updatename() updateicon() -/mob/living/silicon/robot/verb/cmd_robot_alerts() - set category = "Robot Commands" - set name = "Show Alerts" - robot_alerts() - // this verb lets cyborgs see the stations manifest /mob/living/silicon/robot/verb/cmd_station_manifest() set category = "Robot Commands" set name = "Show Crew Manifest" show_station_manifest() - -/mob/living/silicon/robot/proc/robot_alerts() - var/dat = "Current Station Alerts\n" - dat += "Close

    " - for (var/cat in alarms) - dat += text("[cat]
    \n") - var/list/alarmlist = alarms[cat] - if (alarmlist.len) - for (var/area_name in alarmlist) - var/datum/alarm/alarm = alarmlist[area_name] - dat += "" - dat += text("-- [area_name]") - if (alarm.sources.len > 1) - dat += text("- [alarm.sources.len] sources") - dat += "
    \n" - else - dat += "-- All Systems Nominal
    \n" - dat += "
    \n" - - viewalerts = 1 - src << browse(dat, "window=robotalerts&can_close=0") - /mob/living/silicon/robot/proc/self_diagnosis() if(!is_component_functioning("diagnosis unit")) return null @@ -522,15 +512,13 @@ var/list/robot_verbs_default = list( // this function shows information about the malf_ai gameplay type in the status screen /mob/living/silicon/robot/show_malf_ai() ..() - if(ticker.mode.name == "AI malfunction") - var/datum/game_mode/malfunction/malf = ticker.mode - for (var/datum/mind/malfai in malf.malf_ai) - if(connected_ai) - if(connected_ai.mind == malfai) - if(malf.apcs >= 3) - stat(null, "Time until station control secured: [max(malf.AI_win_timeleft/(malf.apcs/3), 0)] seconds") - else if(ticker.mode:malf_mode_declared) - stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]") + for (var/datum/mind/malfai in malf.current_antagonists) + if(connected_ai) + if(connected_ai.mind == malfai) + if(malf.hacked_apcs >= 3) + stat(null, "Time until station control secured: [max(malf.hack_time/(malf.hacked_apcs/3), 0)] seconds") + else if(malf.revealed) + stat(null, "Time left: [max(malf.hack_time/(malf.hacked_apcs.len/3), 0)]") return 0 @@ -568,6 +556,9 @@ var/list/robot_verbs_default = list( show_cell_power() show_jetpack_pressure() stat(null, text("Lights: [lights_on ? "ON" : "OFF"]")) + if(module) + for(var/datum/matter_synth/ms in module.synths) + stat("[ms.name]: [ms.energy]/[ms.max_energy]") /mob/living/silicon/robot/restrained() return 0 @@ -588,62 +579,6 @@ var/list/robot_verbs_default = list( if(prob(75) && Proj.damage > 0) spark_system.start() return 2 -/mob/living/silicon/robot/Bump(atom/movable/AM as mob|obj, yes) - spawn( 0 ) - if ((!( yes ) || now_pushing)) - return - now_pushing = 1 - if(ismob(AM)) - var/mob/tmob = AM - if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) - if(prob(20)) - usr << "\red You fail to push [tmob]'s fat ass out of the way." - now_pushing = 0 - return - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - now_pushing = 0 - ..() - if (istype(AM, /obj/machinery/recharge_station)) - var/obj/machinery/recharge_station/F = AM - F.move_inside() - if (!istype(AM, /atom/movable)) - return - if (!now_pushing) - now_pushing = 1 - if (!AM.anchored) - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - var/obj/structure/window/W = AM - if(W.is_full_window()) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - now_pushing = null - return - return - - -/mob/living/silicon/robot/triggerAlarm(var/class, area/A, list/cameralist, var/source) - if (stat == 2) - return 1 - - ..() - - queueAlarm(text("--- [class] alarm detected in [A.name]!"), class) - - -/mob/living/silicon/robot/cancelAlarm(var/class, area/A as area, obj/origin) - var/has_alarm = ..() - - if (!has_alarm) - queueAlarm(text("--- [class] alarm in [A.name] has been cleared."), class, 0) -// if (viewalerts) robot_alerts() - return has_alarm - - /mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do return @@ -834,7 +769,7 @@ var/list/robot_verbs_default = list( if(prob(50)) emagged = 1 lawupdate = 0 - connected_ai = null + disconnect_from_ai() user << "You emag [src]'s interface." message_admins("[key_name_admin(user)] emagged cyborg [key_name_admin(src)]. Laws overridden.") log_game("[key_name(user)] emagged cyborg [key_name(src)]. Laws overridden.") @@ -933,11 +868,6 @@ var/list/robot_verbs_default = list( //if they are holding or wearing a card that has access, that works if(check_access(H.get_active_hand()) || check_access(H.wear_id)) return 1 - else if(istype(M, /mob/living/carbon/monkey)) - var/mob/living/carbon/monkey/george = M - //they can only hold things :( - if(george.get_active_hand() && istype(george.get_active_hand(), /obj/item/weapon/card/id) && check_access(george.get_active_hand())) - return 1 return 0 /mob/living/silicon/robot/proc/check_access(obj/item/weapon/card/id/I) @@ -958,38 +888,25 @@ var/list/robot_verbs_default = list( overlays.Cut() if(stat == 0) - overlays += "eyes" - overlays.Cut() - overlays += "eyes-[icon_state]" - else - overlays -= "eyes" - - if(opened && custom_sprite == 1) //Custom borgs also have custom panels, heh - if(wiresexposed) - overlays += "[src.ckey]-openpanel +w" - else if(cell) - overlays += "[src.ckey]-openpanel +c" - else - overlays += "[src.ckey]-openpanel -c" + overlays += "eyes-[module_sprites[icontype]]" if(opened) + var/panelprefix = custom_sprite ? src.ckey : "ov" if(wiresexposed) - overlays += "ov-openpanel +w" + overlays += "[panelprefix]-openpanel +w" else if(cell) - overlays += "ov-openpanel +c" + overlays += "[panelprefix]-openpanel +c" else - overlays += "ov-openpanel -c" + overlays += "[panelprefix]-openpanel -c" if(module_active && istype(module_active,/obj/item/borg/combat/shield)) - overlays += "[icon_state]-shield" + overlays += "[module_sprites[icontype]]-shield" if(modtype == "Combat") - var/base_icon = "" - base_icon = icon_state if(module_active && istype(module_active,/obj/item/borg/combat/mobility)) - icon_state = "[icon_state]-roll" + icon_state = "[module_sprites[icontype]]-roll" else - icon_state = base_icon + icon_state = module_sprites[icontype] return //Call when target overlay should be added/removed @@ -1042,30 +959,31 @@ var/list/robot_verbs_default = list( /mob/living/silicon/robot/Topic(href, href_list) if(..()) - return + return 1 if(usr != src) - return + return 1 if (href_list["showalerts"]) - robot_alerts() - return + subsystem_alarm_monitor() + return 1 if (href_list["mod"]) var/obj/item/O = locate(href_list["mod"]) if (istype(O) && (O.loc == src)) O.attack_self(src) + return 1 if (href_list["act"]) var/obj/item/O = locate(href_list["act"]) if (!istype(O)) - return + return 1 if(!((O in src.module.modules) || (O == src.module.emag))) - return + return 1 if(activated(O)) src << "Already activated" - return + return 1 if(!module_state_1) module_state_1 = O O.layer = 20 @@ -1087,6 +1005,7 @@ var/list/robot_verbs_default = list( else src << "You need to disable a module first!" installed_modules() + return 1 if (href_list["deact"]) var/obj/item/O = locate(href_list["deact"]) @@ -1105,25 +1024,7 @@ var/list/robot_verbs_default = list( else src << "Module isn't activated" installed_modules() - - if (href_list["lawc"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite - var/L = text2num(href_list["lawc"]) - switch(lawcheck[L+1]) - if ("Yes") lawcheck[L+1] = "No" - if ("No") lawcheck[L+1] = "Yes" -// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1]) - checklaws() - - if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite - var/L = text2num(href_list["lawi"]) - switch(ioncheck[L]) - if ("Yes") ioncheck[L] = "No" - if ("No") ioncheck[L] = "Yes" -// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1]) - checklaws() - - if (href_list["laws"]) // With how my law selection code works, I changed statelaws from a verb to a proc, and call it through my law selection panel. --NeoFite - statelaws() + return 1 return /mob/living/silicon/robot/proc/radio_menu() @@ -1173,16 +1074,14 @@ var/list/robot_verbs_default = list( return /mob/living/silicon/robot/proc/UnlinkSelf() - if (src.connected_ai) - src.connected_ai = null + disconnect_from_ai() lawupdate = 0 lockcharge = 0 canmove = 1 scrambledcodes = 1 //Disconnect it's camera so it's not so easily tracked. if(src.camera) - src.camera.network = list() - cameranet.removeCamera(src.camera) + src.camera.clear_all_networks() /mob/living/silicon/robot/proc/ResetSecurityCodes() @@ -1222,8 +1121,6 @@ var/list/robot_verbs_default = list( else triesleft-- - var/icontype - if (custom_sprite == 1) icontype = "Custom" triesleft = 0 @@ -1258,9 +1155,11 @@ var/list/robot_verbs_default = list( /mob/living/silicon/robot/proc/add_robot_verbs() src.verbs |= robot_verbs_default + src.verbs |= silicon_verbs_subsystems /mob/living/silicon/robot/proc/remove_robot_verbs() src.verbs -= robot_verbs_default + src.verbs -= silicon_verbs_subsystems // Uses power from cyborg's cell. Returns 1 on success or 0 on failure. // Properly converts using CELLRATE now! Amount is in Joules. @@ -1285,24 +1184,30 @@ var/list/robot_verbs_default = list( return 1 return 0 -/mob/living/silicon/robot/syndicate/canUseTopic(atom/movable/M) - if(stat || lockcharge || stunned || weakened) - return - if(z in config.admin_levels) - return 1 - if(istype(M, /obj/machinery)) - var/obj/machinery/Machine = M - return Machine.emagged - return 1 - -/mob/living/silicon/robot/proc/notify_ai(var/notifytype, var/oldname, var/newname) +/mob/living/silicon/robot/proc/notify_ai(var/notifytype, var/first_arg, var/second_arg) if(!connected_ai) return switch(notifytype) - if(1) //New Robot + if(ROBOT_NOTIFICATION_NEW_UNIT) //New Robot connected_ai << "

    NOTICE - New [lowertext(braintype)] connection detected: [name]
    " - if(2) //New Module - connected_ai << "

    NOTICE - [braintype] module change detected: [name] has loaded the [module.name].
    " - if(3) //New Name - if(oldname != newname) - connected_ai << "

    NOTICE - [braintype] reclassification detected: [oldname] is now designated as [newname].
    " \ No newline at end of file + if(ROBOT_NOTIFICATION_NEW_MODULE) //New Module + connected_ai << "

    NOTICE - [braintype] module change detected: [name] has loaded the [first_arg].
    " + if(ROBOT_NOTIFICATION_MODULE_RESET) + connected_ai << "

    NOTICE - [braintype] module reset detected: [name] has unladed the [first_arg].
    " + if(ROBOT_NOTIFICATION_NEW_NAME) //New Name + if(first_arg != second_arg) + connected_ai << "

    NOTICE - [braintype] reclassification detected: [first_arg] is now designated as [second_arg].
    " + +/mob/living/silicon/robot/proc/disconnect_from_ai() + if(connected_ai) + sync() // One last sync attempt + connected_ai.connected_robots -= src + connected_ai = null + +/mob/living/silicon/robot/proc/connect_to_ai(var/mob/living/silicon/ai/AI) + if(AI && AI != connected_ai) + disconnect_from_ai() + connected_ai = AI + connected_ai.connected_robots |= src + notify_ai(ROBOT_NOTIFICATION_NEW_UNIT) + sync() diff --git a/code/modules/mob/living/silicon/robot/robot_damage.dm b/code/modules/mob/living/silicon/robot/robot_damage.dm index e0ebe671f1..5b204a2d04 100644 --- a/code/modules/mob/living/silicon/robot/robot_damage.dm +++ b/code/modules/mob/living/silicon/robot/robot_damage.dm @@ -62,7 +62,7 @@ var/datum/robot_component/picked = pick(parts) picked.heal_damage(brute,burn) -/mob/living/silicon/robot/take_organ_damage(var/brute = 0, var/burn = 0, var/sharp = 0, var/edge = 0) +/mob/living/silicon/robot/take_organ_damage(var/brute = 0, var/burn = 0, var/sharp = 0, var/edge = 0, var/emp = 0) var/list/components = get_damageable_components() if(!components.len) return @@ -84,10 +84,11 @@ burn -= absorb_burn src << "\red Your shield absorbs some of the impact!" - var/datum/robot_component/armour/A = get_armour() - if(A) - A.take_damage(brute,burn,sharp,edge) - return + if(!emp) + var/datum/robot_component/armour/A = get_armour() + if(A) + A.take_damage(brute,burn,sharp,edge) + return var/datum/robot_component/C = pick(components) C.take_damage(brute,burn,sharp,edge) diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm index 33748f056e..0d40f0954a 100644 --- a/code/modules/mob/living/silicon/robot/robot_items.dm +++ b/code/modules/mob/living/silicon/robot/robot_items.dm @@ -124,11 +124,11 @@ /obj/item/weapon/pen/robopen/proc/RenamePaper(mob/user as mob,obj/paper as obj) if ( !user || !paper ) return - var/n_name = input(user, "What would you like to label the paper?", "Paper Labelling", null) as text + var/n_name = sanitizeSafe(input(user, "What would you like to label the paper?", "Paper Labelling", null) as text, 32) if ( !user || !paper ) return - n_name = copytext(n_name, 1, 32) + //n_name = copytext(n_name, 1, 32) if(( get_dist(user,paper) <= 1 && user.stat == 0)) paper.name = "paper[(n_name ? text("- '[n_name]'") : null)]" add_fingerprint(user) diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 3458a5bb47..7aca17963b 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -7,9 +7,9 @@ flags = CONDUCT var/channels = list() var/list/modules = list() + var/list/datum/matter_synth/synths = list() var/obj/item/emag = null var/obj/item/borg/upgrade/jetpack = null - var/list/stacktypes /obj/item/weapon/robot_module/emp_act(severity) if(modules) @@ -17,40 +17,19 @@ O.emp_act(severity) if(emag) emag.emp_act(severity) + if(synths) + for(var/datum/matter_synth/S in synths) + S.emp_act(severity) ..() return -/obj/item/weapon/robot_module/New() - ..() - // Build initial inventory. - if(stacktypes && stacktypes.len) - for(var/stack_type in stacktypes) - var/obj/item/stack/new_stack = new stack_type (src) - new_stack.amount = stacktypes[stack_type] - modules |= new_stack +/obj/item/weapon/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R, var/rate) -/obj/item/weapon/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R) + if(!synths || !synths.len) + return - if(!stacktypes || !stacktypes.len) return - - for(var/T in stacktypes) - var/obj/item/stack/S - for(var/obj/O in src.modules) - if(O.type == T) - S = O - break - - if(!S) - src.modules -= null - S = new T(src) - src.modules |= S - S.amount = 1 - - if(!istype(S)) - continue - - if(S && S.amount < stacktypes[T]) - S.amount++ + for(var/datum/matter_synth/T in synths) + T.add_charge(T.recharge_rate * rate) /obj/item/weapon/robot_module/proc/rebuild()//Rebuilds the list so it's possible to add/remove items from the module var/list/temp_list = modules @@ -84,10 +63,6 @@ /obj/item/weapon/robot_module/surgeon name = "surgeon robot module" - stacktypes = list( - /obj/item/stack/medical/advanced/bruise_pack = 5, - /obj/item/stack/nanopaste = 5 - ) /obj/item/weapon/robot_module/surgeon/New() ..() @@ -104,26 +79,34 @@ src.modules += new /obj/item/weapon/circular_saw(src) src.modules += new /obj/item/weapon/surgicaldrill(src) src.modules += new /obj/item/weapon/extinguisher/mini(src) - src.modules += new /obj/item/stack/medical/advanced/bruise_pack(src) - src.modules += new /obj/item/stack/nanopaste(src) src.emag = new /obj/item/weapon/reagent_containers/spray(src) src.emag.reagents.add_reagent("pacid", 250) src.emag.name = "Polyacid spray" + + var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(10000) + synths += medicine + + var/obj/item/stack/nanopaste/N = new /obj/item/stack/nanopaste(src) + var/obj/item/stack/medical/advanced/bruise_pack/B = new /obj/item/stack/medical/advanced/bruise_pack(src) + N.uses_charge = 1 + N.charge_costs = list(1000) + N.synths = list(medicine) + B.uses_charge = 1 + B.charge_costs = list(1000) + B.synths = list(medicine) + src.modules += N + src.modules += B + return -/obj/item/weapon/robot_module/surgeon/respawn_consumable(var/mob/living/silicon/robot/R) +/obj/item/weapon/robot_module/surgeon/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) if(src.emag) var/obj/item/weapon/reagent_containers/spray/PS = src.emag - PS.reagents.add_reagent("pacid", 2) + PS.reagents.add_reagent("pacid", 2 * amount) ..() /obj/item/weapon/robot_module/crisis name = "crisis robot module" - stacktypes = list( - /obj/item/stack/medical/ointment = 5, - /obj/item/stack/medical/bruise_pack = 5, - /obj/item/stack/medical/splint = 5 - ) /obj/item/weapon/robot_module/crisis/New() ..() @@ -132,9 +115,6 @@ src.modules += new /obj/item/device/healthanalyzer(src) src.modules += new /obj/item/device/reagent_scanner/adv(src) src.modules += new /obj/item/roller_holder(src) - src.modules += new /obj/item/stack/medical/ointment(src) - src.modules += new /obj/item/stack/medical/bruise_pack(src) - src.modules += new /obj/item/stack/medical/splint(src) src.modules += new /obj/item/weapon/reagent_containers/borghypo/crisis(src) src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src) src.modules += new /obj/item/weapon/reagent_containers/robodropper(src) @@ -143,9 +123,29 @@ src.emag = new /obj/item/weapon/reagent_containers/spray(src) src.emag.reagents.add_reagent("pacid", 250) src.emag.name = "Polyacid spray" + + var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(15000) + synths += medicine + + var/obj/item/stack/medical/ointment/O = new /obj/item/stack/medical/ointment(src) + var/obj/item/stack/medical/bruise_pack/B = new /obj/item/stack/medical/bruise_pack(src) + var/obj/item/stack/medical/splint/S = new /obj/item/stack/medical/splint(src) + O.uses_charge = 1 + O.charge_costs = list(1000) + O.synths = list(medicine) + B.uses_charge = 1 + B.charge_costs = list(1000) + B.synths = list(medicine) + S.uses_charge = 1 + S.charge_costs = list(1000) + S.synths = list(medicine) + src.modules += O + src.modules += B + src.modules += S + return -/obj/item/weapon/robot_module/crisis/respawn_consumable(var/mob/living/silicon/robot/R) +/obj/item/weapon/robot_module/crisis/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) var/obj/item/weapon/reagent_containers/syringe/S = locate() in src.modules if(S.mode == 2) @@ -156,20 +156,13 @@ if(src.emag) var/obj/item/weapon/reagent_containers/spray/PS = src.emag - PS.reagents.add_reagent("pacid", 2) + PS.reagents.add_reagent("pacid", 2 * amount) ..() /obj/item/weapon/robot_module/construction name = "construction robot module" - stacktypes = list( - /obj/item/stack/sheet/metal = 50, - /obj/item/stack/sheet/plasteel = 10, - /obj/item/stack/sheet/glass/reinforced = 50, - /obj/item/stack/rods = 50 - ) - /obj/item/weapon/robot_module/construction/New() ..() src.modules += new /obj/item/device/flash(src) @@ -182,18 +175,32 @@ src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src) src.modules += new /obj/item/device/pipe_painter(src) + var/datum/matter_synth/metal = new /datum/matter_synth/metal() + var/datum/matter_synth/plasteel = new /datum/matter_synth/plasteel() + var/datum/matter_synth/glass = new /datum/matter_synth/glass() + synths += metal + synths += plasteel + synths += glass + + var/obj/item/stack/sheet/metal/cyborg/M = new /obj/item/stack/sheet/metal/cyborg(src) + M.synths = list(metal) + src.modules += M + + var/obj/item/stack/rods/cyborg/R = new /obj/item/stack/rods/cyborg(src) + R.synths = list(metal) + src.modules += R + + var/obj/item/stack/sheet/plasteel/cyborg/S = new /obj/item/stack/sheet/plasteel/cyborg(src) + S.synths = list(metal) + src.modules += S + + var/obj/item/stack/sheet/glass/reinforced/cyborg/RG = new /obj/item/stack/sheet/glass/reinforced/cyborg(src) + RG.synths = list(metal, glass) + src.modules += RG + /obj/item/weapon/robot_module/engineering name = "engineering robot module" - stacktypes = list( - /obj/item/stack/sheet/metal = 50, - /obj/item/stack/sheet/glass = 50, - /obj/item/stack/sheet/glass/reinforced = 50, - /obj/item/stack/cable_coil/robot = 50, - /obj/item/stack/rods = 15, - /obj/item/stack/tile/plasteel = 15 - ) - /obj/item/weapon/robot_module/engineering/New() ..() src.modules += new /obj/item/device/flash(src) @@ -209,9 +216,45 @@ src.modules += new /obj/item/device/analyzer(src) src.modules += new /obj/item/taperoll/engineering(src) src.modules += new /obj/item/weapon/gripper(src) - src.modules += new /obj/item/weapon/matter_decompiler(src) src.modules += new /obj/item/device/pipe_painter(src) src.emag = new /obj/item/borg/stun(src) + + var/datum/matter_synth/metal = new /datum/matter_synth/metal(40000) + var/datum/matter_synth/glass = new /datum/matter_synth/glass(40000) + var/datum/matter_synth/wire = new /datum/matter_synth/wire() + synths += metal + synths += glass + synths += wire + + var/obj/item/weapon/matter_decompiler/MD = new /obj/item/weapon/matter_decompiler(src) + MD.metal = metal + MD.glass = glass + src.modules += MD + + var/obj/item/stack/sheet/metal/cyborg/M = new /obj/item/stack/sheet/metal/cyborg(src) + M.synths = list(metal) + src.modules += M + + var/obj/item/stack/sheet/glass/cyborg/G = new /obj/item/stack/sheet/glass/cyborg(src) + G.synths = list(glass) + src.modules += G + + var/obj/item/stack/rods/cyborg/R = new /obj/item/stack/rods/cyborg(src) + R.synths = list(metal) + src.modules += R + + var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src) + C.synths = list(wire) + src.modules += C + + var/obj/item/stack/tile/plasteel/cyborg/S = new /obj/item/stack/tile/plasteel/cyborg(src) + S.synths = list(metal) + src.modules += S + + var/obj/item/stack/sheet/glass/reinforced/cyborg/RG = new /obj/item/stack/sheet/glass/reinforced/cyborg(src) + RG.synths = list(metal, glass) + src.modules += RG + return /obj/item/weapon/robot_module/security @@ -223,12 +266,12 @@ src.modules += new /obj/item/borg/sight/hud/sec(src) src.modules += new /obj/item/weapon/handcuffs/cyborg(src) src.modules += new /obj/item/weapon/melee/baton/robot(src) - src.modules += new /obj/item/weapon/gun/energy/taser/cyborg(src) + src.modules += new /obj/item/weapon/gun/energy/taser/mounted/cyborg(src) src.modules += new /obj/item/taperoll/police(src) - src.emag = new /obj/item/weapon/gun/energy/laser/cyborg(src) + src.emag = new /obj/item/weapon/gun/energy/laser/mounted(src) return -/obj/item/weapon/robot_module/security/respawn_consumable(var/mob/living/silicon/robot/R) +/obj/item/weapon/robot_module/security/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) var/obj/item/device/flash/F = locate() in src.modules if(F.broken) F.broken = 0 @@ -236,9 +279,9 @@ F.icon_state = "flash" else if(F.times_used) F.times_used-- - var/obj/item/weapon/gun/energy/taser/cyborg/T = locate() in src.modules + var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in src.modules if(T.power_supply.charge < T.power_supply.maxcharge) - T.power_supply.give(T.charge_cost) + T.power_supply.give(T.charge_cost * amount) T.update_icon() else T.charge_tick = 0 @@ -258,12 +301,12 @@ src.emag.name = "Lube spray" return -/obj/item/weapon/robot_module/janitor/respawn_consumable(var/mob/living/silicon/robot/R) +/obj/item/weapon/robot_module/janitor/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) var/obj/item/device/lightreplacer/LR = locate() in src.modules - LR.Charge(R) + LR.Charge(R, amount) if(src.emag) var/obj/item/weapon/reagent_containers/spray/S = src.emag - S.reagents.add_reagent("lube", 2) + S.reagents.add_reagent("lube", 2 * amount) /obj/item/weapon/robot_module/butler name = "service robot module" @@ -327,12 +370,12 @@ R.add_language("Tradeband", 1) R.add_language("Gutter", 1) -/obj/item/weapon/robot_module/butler/respawn_consumable(var/mob/living/silicon/robot/R) +/obj/item/weapon/robot_module/butler/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) var/obj/item/weapon/reagent_containers/food/condiment/enzyme/E = locate() in src.modules - E.reagents.add_reagent("enzyme", 2) + E.reagents.add_reagent("enzyme", 2 * amount) if(src.emag) var/obj/item/weapon/reagent_containers/food/drinks/cans/beer/B = src.emag - B.reagents.add_reagent("beer2", 2) + B.reagents.add_reagent("beer2", 2 * amount) /obj/item/weapon/robot_module/miner name = "miner robot module" @@ -383,26 +426,15 @@ ..() src.modules += new /obj/item/device/flash(src) src.modules += new /obj/item/borg/sight/thermal(src) - src.modules += new /obj/item/weapon/gun/energy/laser/cyborg(src) + src.modules += new /obj/item/weapon/gun/energy/laser/mounted(src) src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src) src.modules += new /obj/item/borg/combat/shield(src) src.modules += new /obj/item/borg/combat/mobility(src) - src.emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src) + src.emag = new /obj/item/weapon/gun/energy/lasercannon/mounted(src) return /obj/item/weapon/robot_module/drone name = "drone module" - stacktypes = list( - /obj/item/stack/sheet/wood = 1, - /obj/item/stack/sheet/mineral/plastic = 1, - /obj/item/stack/sheet/glass/reinforced = 5, - /obj/item/stack/tile/wood = 5, - /obj/item/stack/rods = 15, - /obj/item/stack/tile/plasteel = 15, - /obj/item/stack/sheet/metal = 20, - /obj/item/stack/sheet/glass = 20, - /obj/item/stack/cable_coil/robot = 30 - ) /obj/item/weapon/robot_module/drone/New() ..() @@ -414,20 +446,73 @@ src.modules += new /obj/item/device/multitool(src) src.modules += new /obj/item/device/lightreplacer(src) src.modules += new /obj/item/weapon/gripper(src) - src.modules += new /obj/item/weapon/matter_decompiler(src) src.modules += new /obj/item/weapon/reagent_containers/spray/cleaner/drone(src) src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src) src.emag.name = "Plasma Cutter" + var/datum/matter_synth/metal = new /datum/matter_synth/metal(25000) + var/datum/matter_synth/glass = new /datum/matter_synth/glass(25000) + var/datum/matter_synth/wood = new /datum/matter_synth/wood(2000) + var/datum/matter_synth/plastic = new /datum/matter_synth/plastic(1000) + var/datum/matter_synth/wire = new /datum/matter_synth/wire(30) + synths += metal + synths += glass + synths += wood + synths += plastic + synths += wire + + var/obj/item/weapon/matter_decompiler/MD = new /obj/item/weapon/matter_decompiler(src) + MD.metal = metal + MD.glass = glass + MD.wood = wood + MD.plastic = plastic + src.modules += MD + + var/obj/item/stack/sheet/metal/cyborg/M = new /obj/item/stack/sheet/metal/cyborg(src) + M.synths = list(metal) + src.modules += M + + var/obj/item/stack/sheet/glass/cyborg/G = new /obj/item/stack/sheet/glass/cyborg(src) + G.synths = list(glass) + src.modules += G + + var/obj/item/stack/rods/cyborg/R = new /obj/item/stack/rods/cyborg(src) + R.synths = list(metal) + src.modules += R + + var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src) + C.synths = list(wire) + src.modules += C + + var/obj/item/stack/tile/plasteel/cyborg/S = new /obj/item/stack/tile/plasteel/cyborg(src) + S.synths = list(metal) + src.modules += S + + var/obj/item/stack/sheet/glass/reinforced/cyborg/RG = new /obj/item/stack/sheet/glass/reinforced/cyborg(src) + RG.synths = list(metal, glass) + src.modules += RG + + var/obj/item/stack/tile/wood/cyborg/WT = new /obj/item/stack/tile/wood/cyborg(src) + WT.synths = list(wood) + src.modules += WT + + var/obj/item/stack/sheet/wood/cyborg/W = new /obj/item/stack/sheet/wood/cyborg(src) + W.synths = list(wood) + src.modules += W + + var/obj/item/stack/sheet/mineral/plastic/cyborg/P = new /obj/item/stack/sheet/mineral/plastic/cyborg(src) + P.synths = list(plastic) + src.modules += P + /obj/item/weapon/robot_module/drone/add_languages(var/mob/living/silicon/robot/R) return //not much ROM to spare in that tiny microprocessor! -/obj/item/weapon/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R) +/obj/item/weapon/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) var/obj/item/weapon/reagent_containers/spray/cleaner/C = locate() in src.modules - C.reagents.add_reagent("cleaner", 3) + C.reagents.add_reagent("cleaner", 3 * amount) var/obj/item/device/lightreplacer/LR = locate() in src.modules - LR.Charge(R) + LR.Charge(R, amount) ..() return diff --git a/code/modules/mob/living/silicon/robot/robot_upgrades.dm b/code/modules/mob/living/silicon/robot/robot_upgrades.dm index 71f22a3029..a6d08bd534 100644 --- a/code/modules/mob/living/silicon/robot/robot_upgrades.dm +++ b/code/modules/mob/living/silicon/robot/robot_upgrades.dm @@ -108,7 +108,7 @@ usr << "There's no mounting point for the module!" return 0 - var/obj/item/weapon/gun/energy/taser/cyborg/T = locate() in R.module + var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in R.module if(!T) T = locate() in R.module.contents if(!T) diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm index ba5b0ad4f8..ec6ddefe1c 100644 --- a/code/modules/mob/living/silicon/say.dm +++ b/code/modules/mob/living/silicon/say.dm @@ -34,7 +34,7 @@ if (src.client.handle_spam_prevention(message,MUTE_IC)) return 0 - message = trim_strip_html_properly(message) + message = sanitize(message) if (stat == 2) return say_dead(message) @@ -159,7 +159,7 @@ return var/obj/machinery/hologram/holopad/T = src.holo - if(T && T.hologram && T.master == src)//If there is a hologram and its master is the user. + if(T && T.masters[src])//If there is a hologram and its master is the user. //Human-like, sorta, heard by those who understand humans. var/rendered_a @@ -198,7 +198,7 @@ return var/obj/machinery/hologram/holopad/T = src.holo - if(T && T.hologram && T.master == src) + if(T && T.masters[src]) var/rendered = "[name] [message]" src << "Holopad action relayed, [real_name] [message]" @@ -211,7 +211,7 @@ /mob/living/silicon/ai/emote(var/act, var/type, var/message) var/obj/machinery/hologram/holopad/T = src.holo - if(T && T.hologram && T.master == src) //Is the AI using a holopad? + if(T && T.masters[src]) //Is the AI using a holopad? src.holopad_emote(message) else //Emote normally, then. ..() diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 4917c222e4..965729b8a8 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -2,16 +2,12 @@ gender = NEUTER voice_name = "synthesized voice" var/syndicate = 0 - var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS - var/list/additional_law_channels = list("State") var/const/MAIN_CHANNEL = "Main Frequency" var/lawchannel = MAIN_CHANNEL // Default channel on which to state laws var/list/stating_laws = list()// Channels laws are currently being stated on - var/lawcheck[1] - var/ioncheck[1] var/obj/item/device/radio/common_radio - var/list/hud_list[9] + var/list/hud_list[10] var/list/speech_synthesizer_langs = list() //which languages can be vocalized by the speech synthesizer //Used in say.dm. @@ -23,12 +19,26 @@ var/local_transmit //If set, can only speak to others of the same type within a short range. var/sensor_mode = 0 //Determines the current HUD. + + var/next_alarm_notice + var/list/datum/alarm/queued_alarms = new() + #define SEC_HUD 1 //Security HUD mode #define MED_HUD 2 //Medical HUD mode /mob/living/silicon/New() ..() add_language("Galactic Common") + init_subsystems() + +/mob/living/silicon/Del() + for(var/datum/alarm_handler/AH in alarm_manager.all_handlers) + AH.unregister(src) + ..() + +/mob/living/silicon/proc/SetName(pickedName as text) + real_name = pickedName + name = real_name /mob/living/silicon/proc/show_laws() return @@ -39,10 +49,10 @@ /mob/living/silicon/emp_act(severity) switch(severity) if(1) - src.take_organ_damage(20) + src.take_organ_damage(0,20,emp=1) Stun(rand(5,10)) if(2) - src.take_organ_damage(10) + src.take_organ_damage(0,10,emp=1) Stun(rand(1,5)) flick("noise", src:flash) src << "\red *BZZZT*" @@ -152,13 +162,12 @@ // This adds the basic clock, shuttle recall timer, and malf_ai info to all silicon lifeforms /mob/living/silicon/Stat() - ..() - statpanel("Status") - if (src.client.statpanel == "Status") + if(statpanel("Status")) show_station_time() show_emergency_shuttle_eta() show_system_integrity() show_malf_ai() + ..() // this function displays the stations manifest in a separate window /mob/living/silicon/proc/show_station_manifest() @@ -226,38 +235,18 @@ set desc = "Sets a description which will be shown when someone examines you." set category = "IC" - pose = sanitize(copytext(input(usr, "This is [src]. It is...", "Pose", null) as text, 1, MAX_MESSAGE_LEN)) + pose = sanitize(input(usr, "This is [src]. It is...", "Pose", null) as text) /mob/living/silicon/verb/set_flavor() set name = "Set Flavour Text" set desc = "Sets an extended description of your character's features." set category = "IC" - flavor_text = sanitize(copytext(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text, 1)) + flavor_text = sanitize(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text) /mob/living/silicon/binarycheck() return 1 -/mob/living/silicon/Topic(href, href_list) - ..() - - if (href_list["lawr"]) // Selects on which channel to state laws - var/list/channels = list(MAIN_CHANNEL) - if(common_radio) - for (var/ch_name in common_radio.channels) - channels += ch_name - - channels += additional_law_channels - channels += "Cancel" - - var/setchannel = input(usr, "Specify channel.", "Channel selection") in channels - if(setchannel != "Cancel") - lawchannel = setchannel - checklaws() - return 1 - - return 0 - /mob/living/silicon/ex_act(severity) if(!blinded) flick("flash", flash) @@ -278,3 +267,80 @@ adjustBruteLoss(30) updatehealth() + +/mob/living/silicon/proc/init_subsystems() + alarm_monitor = new/obj/nano_module/alarm_monitor/borg(src) + law_manager = new/obj/nano_module/law_manager(src) + + for(var/datum/alarm_handler/AH in alarm_manager.all_handlers) + AH.register(src, /mob/living/silicon/proc/receive_alarm) + queued_alarms[AH] = list() // Makes sure alarms remain listed in consistent order + +/mob/living/silicon/proc/receive_alarm(var/datum/alarm_handler/alarm_handler, var/datum/alarm/alarm, was_raised) + if(!next_alarm_notice) + next_alarm_notice = world.time + SecondsToTicks(10) + + var/list/alarms = queued_alarms[alarm_handler] + if(was_raised) + // Raised alarms are always set + alarms[alarm] = 1 + else + // Alarms that were raised but then cleared before the next notice are instead removed + if(alarm in alarms) + alarms -= alarm + // And alarms that have only been cleared thus far are set as such + else + alarms[alarm] = -1 + +/mob/living/silicon/proc/process_queued_alarms() + if(next_alarm_notice && (world.time > next_alarm_notice)) + next_alarm_notice = 0 + + var/alarm_raised = 0 + for(var/datum/alarm_handler/AH in queued_alarms) + var/list/alarms = queued_alarms[AH] + var/reported = 0 + for(var/datum/alarm/A in alarms) + if(alarms[A] == 1) + alarm_raised = 1 + if(!reported) + reported = 1 + src << "--- [AH.category] Detected ---" + raised_alarm(A) + + for(var/datum/alarm_handler/AH in queued_alarms) + var/list/alarms = queued_alarms[AH] + var/reported = 0 + for(var/datum/alarm/A in alarms) + if(alarms[A] == -1) + if(!reported) + reported = 1 + src << "--- [AH.category] Cleared ---" + src << "\The [A.alarm_name()]." + + if(alarm_raised) + src << "\[Show Alerts\]" + + for(var/datum/alarm_handler/AH in queued_alarms) + var/list/alarms = queued_alarms[AH] + alarms.Cut() + +/mob/living/silicon/proc/raised_alarm(var/datum/alarm/A) + src << "[A.alarm_name()]!" + +/mob/living/silicon/ai/raised_alarm(var/datum/alarm/A) + var/cameratext = "" + for(var/obj/machinery/camera/C in A.cameras()) + cameratext += "[(cameratext == "")? "" : "|"][C.c_tag]" + src << "[A.alarm_name()]! ([(cameratext)? cameratext : "No Camera"])" + + +/mob/living/silicon/proc/is_traitor() + return mind && (mind in traitors.current_antagonists) + +/mob/living/silicon/proc/is_malf() + return mind && (mind in malf.current_antagonists) + +/mob/living/silicon/proc/is_malf_or_traitor() + return is_traitor() || is_malf() + diff --git a/code/modules/mob/living/silicon/subystems.dm b/code/modules/mob/living/silicon/subystems.dm new file mode 100644 index 0000000000..9f1e07c301 --- /dev/null +++ b/code/modules/mob/living/silicon/subystems.dm @@ -0,0 +1,26 @@ +/mob/living/silicon + var/list/silicon_verbs_subsystems = list( + /mob/living/silicon/proc/subsystem_alarm_monitor, + /mob/living/silicon/proc/subsystem_law_manager + ) + + // Subsystems + var/obj/nano_module/alarm_monitor = null + var/obj/nano_module/law_manager = null + +/mob/living/silicon/robot/syndicate + silicon_verbs_subsystems = list( + /mob/living/silicon/proc/subsystem_law_manager + ) + +/mob/living/silicon/proc/subsystem_alarm_monitor() + set name = "Alarm Monitor" + set category = "Subystems" + + alarm_monitor.ui_interact(usr) + +/mob/living/silicon/proc/subsystem_law_manager() + set name = "Law Manager" + set category = "Subystems" + + law_manager.ui_interact(usr) diff --git a/code/modules/mob/living/simple_animal/borer/borer.dm b/code/modules/mob/living/simple_animal/borer/borer.dm index 43aa9a9d68..0ca5e36828 100644 --- a/code/modules/mob/living/simple_animal/borer/borer.dm +++ b/code/modules/mob/living/simple_animal/borer/borer.dm @@ -1,5 +1,3 @@ -/datum/game_mode/var/list/borers = list() - /mob/living/simple_animal/borer name = "cortical borer" real_name = "cortical borer" @@ -13,7 +11,7 @@ icon_living = "brainslug" icon_dead = "brainslug_dead" speed = 5 - a_intent = "harm" + a_intent = I_HURT stop_automated_movement = 1 status_flags = CANPUSH attacktext = "nipped" @@ -155,7 +153,7 @@ //If they're not a proper traitor, reset their antag status. if(host.mind.special_role == "Borer Thrall") host << "You are no longer an antagonist." - ticker.mode.borers -= host.mind + borers.hosts -= host.mind host.mind.special_role = null src.loc = get_turf(host) diff --git a/code/modules/mob/living/simple_animal/borer/borer_captive.dm b/code/modules/mob/living/simple_animal/borer/borer_captive.dm index eacc058945..156d362773 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_captive.dm +++ b/code/modules/mob/living/simple_animal/borer/borer_captive.dm @@ -14,7 +14,7 @@ if(istype(src.loc,/mob/living/simple_animal/borer)) - message = trim_strip_html_properly(message) + message = sanitize(message) if (!message) return log_say("[key_name(src)] : [message]") diff --git a/code/modules/mob/living/simple_animal/borer/borer_powers.dm b/code/modules/mob/living/simple_animal/borer/borer_powers.dm index 59f6aed6f0..af2a923c96 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_powers.dm +++ b/code/modules/mob/living/simple_animal/borer/borer_powers.dm @@ -106,7 +106,7 @@ //Update their traitor status. if(host.mind) if(!host.mind.special_role) - ticker.mode.borers |= host.mind + borers.hosts |= host.mind host.mind.special_role = "Borer Thrall" host << "A creeping lassitude surrounds you. Your mind is being invaded by an alien intelligence and that's just fine." host << "You are now a thrall to a cortical borer. Please listen to what they have to say; they're in your head." diff --git a/code/modules/mob/living/simple_animal/borer/say.dm b/code/modules/mob/living/simple_animal/borer/say.dm index 5b52a5b473..a5e5a34d58 100644 --- a/code/modules/mob/living/simple_animal/borer/say.dm +++ b/code/modules/mob/living/simple_animal/borer/say.dm @@ -1,6 +1,6 @@ /mob/living/simple_animal/borer/say(var/message) - message = trim_strip_html_properly(message) + message = sanitize(message) message = capitalize(message) if(!message) diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs/constructs.dm similarity index 54% rename from code/modules/mob/living/simple_animal/constructs.dm rename to code/modules/mob/living/simple_animal/constructs/constructs.dm index 5e3e91b90f..12d868e110 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs/constructs.dm @@ -1,317 +1,232 @@ - -/mob/living/simple_animal/construct - name = "Construct" - real_name = "Construct" - desc = "" - speak_emote = list("hisses") - emote_hear = list("wails","screeches") - response_help = "thinks better of touching" - response_disarm = "flails at" - response_harm = "punches" - icon_dead = "shade_dead" - speed = -1 - a_intent = "harm" - stop_automated_movement = 1 - status_flags = CANPUSH - universal_speak = 1 - attack_sound = 'sound/weapons/punch1.ogg' - min_oxy = 0 - max_oxy = 0 - min_tox = 0 - max_tox = 0 - min_co2 = 0 - max_co2 = 0 - min_n2 = 0 - max_n2 = 0 - minbodytemp = 0 - faction = "cult" - var/list/construct_spells = list() - -/mob/living/simple_animal/construct/New() - ..() - name = text("[initial(name)] ([rand(1, 1000)])") - real_name = name - for(var/spell in construct_spells) - spell_list += new spell(src) - -/mob/living/simple_animal/construct/death() - new /obj/item/weapon/ectoplasm (src.loc) - ..(null,"collapses in a shattered heap.") - ghostize() - del src - - -/mob/living/simple_animal/construct/attack_generic(var/mob/user) - if(istype(user, /mob/living/simple_animal/construct/builder)) - if(health < maxHealth) - adjustBruteLoss(-5) - user.visible_message("\The [user] mends some of \the [src]'s wounds.") - else - user << "\The [src] is undamaged." - return - return ..() - -/mob/living/simple_animal/construct/examine(mob/user) - ..(user) - var/msg = "" - if (src.health < src.maxHealth) - msg += "" - if (src.health >= src.maxHealth/2) - msg += "It looks slightly dented.\n" - else - msg += "It looks severely dented!\n" - msg += "" - msg += "*---------*
    " - - user << msg - return - -/mob/living/simple_animal/construct/Bump(atom/movable/AM as mob|obj, yes) - if ((!( yes ) || now_pushing)) - return - now_pushing = 1 - if(ismob(AM)) - var/mob/tmob = AM - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - - tmob.LAssailant = src - now_pushing = 0 - ..() - if (!istype(AM, /atom/movable)) - return - if (!( now_pushing )) - now_pushing = 1 - if (!( AM.anchored )) - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - var/obj/structure/window/W = AM - if(W.is_full_window()) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - now_pushing = null - -/mob/living/simple_animal/construct/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(O.force) - var/damage = O.force - if (O.damtype == HALLOSS) - damage = 0 - adjustBruteLoss(damage) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [src] has been attacked with [O] by [user]. ") - else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with [O]. ") - - - -/////////////////Juggernaut/////////////// - - - -/mob/living/simple_animal/construct/armoured - name = "Juggernaut" - real_name = "Juggernaut" - desc = "A possessed suit of armour driven by the will of the restless dead" - icon = 'icons/mob/mob.dmi' - icon_state = "behemoth" - icon_living = "behemoth" - maxHealth = 250 - health = 250 - response_harm = "harmlessly punches" - harm_intent_damage = 0 - melee_damage_lower = 30 - melee_damage_upper = 30 - attacktext = "smashed their armoured gauntlet into" - mob_size = 20 - speed = 3 - wall_smash = 1 - attack_sound = 'sound/weapons/punch3.ogg' - status_flags = 0 - construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall) - -/mob/living/simple_animal/construct/armoured/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(O.force) - if(O.force >= 11) - var/damage = O.force - if (O.damtype == HALLOSS) - damage = 0 - adjustBruteLoss(damage) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [src] has been attacked with [O] by [user]. ") - else - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [O] bounces harmlessly off of [src]. ") - else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with [O]. ") - - -/mob/living/simple_animal/construct/armoured/Life() - weakened = 0 - ..() - -/mob/living/simple_animal/construct/armoured/bullet_act(var/obj/item/projectile/P) - if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam)) - var/reflectchance = 80 - round(P.damage/3) - if(prob(reflectchance)) - adjustBruteLoss(P.damage * 0.5) - visible_message("The [P.name] gets reflected by [src]'s shell!", \ - "The [P.name] gets reflected by [src]'s shell!") - - // Find a turf near or on the original location to bounce to - if(P.starting) - var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) - var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) - var/turf/curloc = get_turf(src) - - // redirect the projectile - P.original = locate(new_x, new_y, P.z) - P.starting = curloc - P.current = curloc - P.firer = src - P.yo = new_y - curloc.y - P.xo = new_x - curloc.x - - return -1 // complete projectile permutation - - return (..(P)) - - - -////////////////////////Wraith///////////////////////////////////////////// - - - -/mob/living/simple_animal/construct/wraith - name = "Wraith" - real_name = "Wraith" - desc = "A wicked bladed shell contraption piloted by a bound spirit" - icon = 'icons/mob/mob.dmi' - icon_state = "floating" - icon_living = "floating" - maxHealth = 75 - health = 75 - melee_damage_lower = 25 - melee_damage_upper = 25 - attacktext = "slashed" - speed = -1 - see_in_dark = 7 - attack_sound = 'sound/weapons/bladeslice.ogg' - construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift) - - - -/////////////////////////////Artificer///////////////////////// - - - -/mob/living/simple_animal/construct/builder - name = "Artificer" - real_name = "Artificer" - desc = "A bulbous construct dedicated to building and maintaining The Cult of Nar-Sie's armies" - icon = 'icons/mob/mob.dmi' - icon_state = "artificer" - icon_living = "artificer" - maxHealth = 50 - health = 50 - response_harm = "viciously beats" - harm_intent_damage = 5 - melee_damage_lower = 5 - melee_damage_upper = 5 - attacktext = "rammed" - speed = 0 - wall_smash = 1 - attack_sound = 'sound/weapons/punch2.ogg' - construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser, - /obj/effect/proc_holder/spell/aoe_turf/conjure/wall, - /obj/effect/proc_holder/spell/aoe_turf/conjure/floor, - /obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone,) - - -/////////////////////////////Behemoth///////////////////////// - - -/mob/living/simple_animal/construct/behemoth - name = "Behemoth" - real_name = "Behemoth" - desc = "The pinnacle of occult technology, Behemoths are the ultimate weapon in the Cult of Nar-Sie's arsenal." - icon = 'icons/mob/mob.dmi' - icon_state = "behemoth" - icon_living = "behemoth" - maxHealth = 750 - health = 750 - speak_emote = list("rumbles") - response_harm = "harmlessly punches" - harm_intent_damage = 0 - melee_damage_lower = 50 - melee_damage_upper = 50 - attacktext = "brutally crushed" - speed = 5 - wall_smash = 1 - attack_sound = 'sound/weapons/punch4.ogg' - mob_size = 20 - var/energy = 0 - var/max_energy = 1000 - -/mob/living/simple_animal/construct/behemoth/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(O.force) - if(O.force >= 11) - var/damage = O.force - if (O.damtype == HALLOSS) - damage = 0 - adjustBruteLoss(damage) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [src] has been attacked with [O] by [user]. ") - else - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [O] bounces harmlessly off of [src]. ") - else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with [O]. ") - - - -////////////////Powers////////////////// - - -/* -/client/proc/summon_cultist() - set category = "Behemoth" - set name = "Summon Cultist (300)" - set desc = "Teleport a cultist to your location" - if (istype(usr,/mob/living/simple_animal/constructbehemoth)) - - if(usr.energy<300) - usr << "\red You do not have enough power stored!" - return - - if(usr.stat) - return - - usr.energy -= 300 - var/list/mob/living/cultists = new - for(var/datum/mind/H in ticker.mode.cult) - if (istype(H.current,/mob/living)) - cultists+=H.current - var/mob/cultist = input("Choose the one who you want to summon", "Followers of Geometer") as null|anything in (cultists - usr) - if(!cultist) - return - if (cultist == usr) //just to be sure. - return - cultist.loc = usr.loc - usr.visible_message("/red [cultist] appears in a flash of red light as [usr] glows with power")*/ + +/mob/living/simple_animal/construct + name = "Construct" + real_name = "Construct" + desc = "" + speak_emote = list("hisses") + emote_hear = list("wails","screeches") + response_help = "thinks better of touching" + response_disarm = "flails at" + response_harm = "punches" + icon_dead = "shade_dead" + speed = -1 + a_intent = I_HURT + stop_automated_movement = 1 + status_flags = CANPUSH + universal_speak = 0 + universal_understand = 1 + attack_sound = 'sound/weapons/punch1.ogg' + min_oxy = 0 + max_oxy = 0 + min_tox = 0 + max_tox = 0 + min_co2 = 0 + max_co2 = 0 + min_n2 = 0 + max_n2 = 0 + minbodytemp = 0 + show_stat_health = 0 + faction = "cult" + supernatural = 1 + var/nullblock = 0 + + mob_swap_flags = HUMAN|SIMPLE_ANIMAL|SLIME|MONKEY + mob_push_flags = ALLMOBS + + var/list/construct_spells = list() + +/mob/living/simple_animal/construct/New() + ..() + name = text("[initial(name)] ([rand(1, 1000)])") + real_name = name + add_language("Cult") + add_language("Occult") + for(var/spell in construct_spells) + spell_list += new spell(src) + updateicon() + +/mob/living/simple_animal/construct/death() + new /obj/item/weapon/ectoplasm (src.loc) + ..(null,"collapses in a shattered heap.") + ghostize() + del src + +/mob/living/simple_animal/construct/attack_generic(var/mob/user) + if(istype(user, /mob/living/simple_animal/construct/builder)) + if(health < maxHealth) + adjustBruteLoss(-5) + user.visible_message("\The [user] mends some of \the [src]'s wounds.
    ") + else + user << "\The [src] is undamaged." + return + return ..() + +/mob/living/simple_animal/construct/examine(mob/user) + ..(user) + var/msg = "*---------*\nThis is \icon[src] \a [src]!\n" + if (src.health < src.maxHealth) + msg += "" + if (src.health >= src.maxHealth/2) + msg += "It looks slightly dented.\n" + else + msg += "It looks severely dented!\n" + msg += "" + msg += "*---------*" + + user << msg + + +/////////////////Juggernaut/////////////// + + + +/mob/living/simple_animal/construct/armoured + name = "Juggernaut" + real_name = "Juggernaut" + desc = "A possessed suit of armour driven by the will of the restless dead" + icon = 'icons/mob/mob.dmi' + icon_state = "behemoth" + icon_living = "behemoth" + maxHealth = 250 + health = 250 + response_harm = "harmlessly punches" + harm_intent_damage = 0 + melee_damage_lower = 30 + melee_damage_upper = 30 + attacktext = "smashed their armoured gauntlet into" + mob_size = 20 + speed = 3 + environment_smash = 2 + attack_sound = 'sound/weapons/punch3.ogg' + status_flags = 0 + resistance = 10 + construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/lesserforcewall) + +/mob/living/simple_animal/construct/armoured/Life() + weakened = 0 + ..() + +/mob/living/simple_animal/construct/armoured/bullet_act(var/obj/item/projectile/P) + if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam)) + var/reflectchance = 80 - round(P.damage/3) + if(prob(reflectchance)) + adjustBruteLoss(P.damage * 0.5) + visible_message("The [P.name] gets reflected by [src]'s shell!", \ + "The [P.name] gets reflected by [src]'s shell!") + + // Find a turf near or on the original location to bounce to + if(P.starting) + var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) + var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) + var/turf/curloc = get_turf(src) + + // redirect the projectile + P.redirect(new_x, new_y, curloc, src) + + return -1 // complete projectile permutation + + return (..(P)) + + + +////////////////////////Wraith///////////////////////////////////////////// + + + +/mob/living/simple_animal/construct/wraith + name = "Wraith" + real_name = "Wraith" + desc = "A wicked bladed shell contraption piloted by a bound spirit" + icon = 'icons/mob/mob.dmi' + icon_state = "floating" + icon_living = "floating" + maxHealth = 75 + health = 75 + melee_damage_lower = 25 + melee_damage_upper = 25 + attacktext = "slashed" + speed = -1 + environment_smash = 1 + see_in_dark = 7 + attack_sound = 'sound/weapons/bladeslice.ogg' + construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift) + + +/////////////////////////////Artificer///////////////////////// + + + +/mob/living/simple_animal/construct/builder + name = "Artificer" + real_name = "Artificer" + desc = "A bulbous construct dedicated to building and maintaining The Cult of Nar-Sie's armies" + icon = 'icons/mob/mob.dmi' + icon_state = "artificer" + icon_living = "artificer" + maxHealth = 50 + health = 50 + response_harm = "viciously beats" + harm_intent_damage = 5 + melee_damage_lower = 5 + melee_damage_upper = 5 + attacktext = "rammed" + speed = 0 + environment_smash = 2 + attack_sound = 'sound/weapons/punch2.ogg' + construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/construct/lesser, + /obj/effect/proc_holder/spell/aoe_turf/conjure/wall, + /obj/effect/proc_holder/spell/aoe_turf/conjure/floor, + /obj/effect/proc_holder/spell/aoe_turf/conjure/soulstone,) + + +/////////////////////////////Behemoth///////////////////////// + + +/mob/living/simple_animal/construct/behemoth + name = "Behemoth" + real_name = "Behemoth" + desc = "The pinnacle of occult technology, Behemoths are the ultimate weapon in the Cult of Nar-Sie's arsenal." + icon = 'icons/mob/mob.dmi' + icon_state = "behemoth" + icon_living = "behemoth" + maxHealth = 750 + health = 750 + speak_emote = list("rumbles") + response_harm = "harmlessly punches" + harm_intent_damage = 0 + melee_damage_lower = 50 + melee_damage_upper = 50 + attacktext = "brutally crushed" + speed = 5 + environment_smash = 2 + attack_sound = 'sound/weapons/punch4.ogg' + resistance = 10 + var/energy = 0 + var/max_energy = 1000 + +////////////////////////Harvester//////////////////////////////// + + + +/mob/living/simple_animal/construct/harvester + name = "Harvester" + real_name = "Harvester" + desc = "The promised reward of the livings who follow narsie. Obtained by offering their bodies to the geometer of blood" + icon = 'icons/mob/mob.dmi' + icon_state = "harvester" + icon_living = "harvester" + maxHealth = 150 + health = 150 + melee_damage_lower = 25 + melee_damage_upper = 25 + attacktext = "violently stabs" + speed = -1 + environment_smash = 1 + see_in_dark = 7 + attack_sound = 'sound/weapons/pierce.ogg' + + construct_spells = list( + //spell/targeted/harvest, + //spell/aoe_turf/knock/harvester, + //spell/rune_write + ) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/modules/mob/living/simple_animal/constructs/soulstone.dm similarity index 91% rename from code/game/gamemodes/wizard/soulstone.dm rename to code/modules/mob/living/simple_animal/constructs/soulstone.dm index 678ce72582..339654558b 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/modules/mob/living/simple_animal/constructs/soulstone.dm @@ -104,7 +104,7 @@ if(C.imprinted != "empty") U << "\red Capture failed!: \black The soul stone has already been imprinted with [C.imprinted]'s mind!" else - if (T.stat == 0) + if ((T.health + T.halloss) > config.health_threshold_crit) U << "\red Capture failed!: \black Kill or maim the victim first!" else if(T.client == null) @@ -129,6 +129,11 @@ S.canmove = 0//Can't move out of the soul stone S.name = "Shade of [T.real_name]" S.real_name = "Shade of [T.real_name]" + S.icon = T.icon + S.icon_state = T.icon_state + S.overlays = T.overlays + S.color = rgb(254,0,0) + S.alpha = 127 if (T.client) T.client.mob = S S.cancel_camera() @@ -169,11 +174,7 @@ var/mob/living/simple_animal/construct/armoured/Z = new /mob/living/simple_animal/construct/armoured (get_turf(T.loc)) Z.key = A.key if(iscultist(U)) - if(ticker.mode.name == "cult") - ticker.mode:add_cultist(Z.mind) - else - ticker.mode.cult+=Z.mind - ticker.mode.update_cult_icons_added(Z.mind) + cult.add_antagonist(Z.mind) del(T) Z << "You are playing a Juggernaut. Though slow, you can withstand extreme punishment, and rip apart enemies and walls alike." Z << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." @@ -184,11 +185,7 @@ var/mob/living/simple_animal/construct/wraith/Z = new /mob/living/simple_animal/construct/wraith (get_turf(T.loc)) Z.key = A.key if(iscultist(U)) - if(ticker.mode.name == "cult") - ticker.mode:add_cultist(Z.mind) - else - ticker.mode.cult+=Z.mind - ticker.mode.update_cult_icons_added(Z.mind) + cult.add_antagonist(Z.mind) del(T) Z << "You are playing a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls." Z << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." @@ -199,11 +196,7 @@ var/mob/living/simple_animal/construct/builder/Z = new /mob/living/simple_animal/construct/builder (get_turf(T.loc)) Z.key = A.key if(iscultist(U)) - if(ticker.mode.name == "cult") - ticker.mode:add_cultist(Z.mind) - else - ticker.mode.cult+=Z.mind - ticker.mode.update_cult_icons_added(Z.mind) + cult.add_antagonist(Z.mind) del(T) Z << "You are playing an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, repair allied constructs (by clicking on them), and even create new constructs" Z << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 7913d23d7e..4e72bf55c0 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -18,6 +18,7 @@ response_harm = "kicks" var/turns_since_scan = 0 var/mob/living/simple_animal/mouse/movement_target + var/mob/flee_target min_oxy = 16 //Require atleast 16kPA oxygen minbodytemp = 223 //Below -50 Degrees Celcius maxbodytemp = 323 //Above 50 Degrees Celcius @@ -44,27 +45,78 @@ break if(!stat && !resting && !buckled) - handle_movement_target() + turns_since_scan++ + if (turns_since_scan > 5) + walk_to(src,0) + turns_since_scan = 0 + + if (flee_target) //fleeing takes precendence + handle_flee_target() + else + handle_movement_target() + + if(prob(2)) //spooky + var/mob/dead/observer/spook = locate() in range(src,5) + if(spook) + var/turf/T = spook.loc + var/obj/O = pick(T.contents) + visible_emote("suddenly stops and stares at something unseen[istype(O) ? " near [O]":""].") /mob/living/simple_animal/cat/proc/handle_movement_target() - turns_since_scan++ - if(turns_since_scan > 5) - walk_to(src,0) - turns_since_scan = 0 + //if our target is neither inside a turf or inside a human(???), stop + if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) )) + movement_target = null + stop_automated_movement = 0 + //if we have no target or our current one is out of sight/too far away + if( !movement_target || !(movement_target.loc in oview(src, 4)) ) + movement_target = null + stop_automated_movement = 0 + for(var/mob/living/simple_animal/mouse/snack in oview(src)) //search for a new target + if(isturf(snack.loc) && !snack.stat) + movement_target = snack + break - if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) )) - movement_target = null - stop_automated_movement = 0 - if( !movement_target || !(movement_target.loc in oview(src, 4)) ) - movement_target = null - stop_automated_movement = 0 - for(var/mob/living/simple_animal/mouse/snack in oview(src)) - if(isturf(snack.loc) && !snack.stat) - movement_target = snack - break - if(movement_target) - stop_automated_movement = 1 - walk_to(src,movement_target,0,3) + if(movement_target) + stop_automated_movement = 1 + walk_to(src,movement_target,0,3) + +/mob/living/simple_animal/cat/proc/handle_flee_target() + //see if we should stop fleeing + if (flee_target && !(flee_target.loc in view(src))) + flee_target = null + stop_automated_movement = 0 + + if (flee_target) + if(prob(25)) say("HSSSSS") + stop_automated_movement = 1 + walk_away(src, flee_target, 7, 2) + +/mob/living/simple_animal/cat/proc/set_flee_target(atom/A) + if(A) + flee_target = A + turns_since_scan = 5 + +/mob/living/simple_animal/cat/attackby(var/obj/item/O, var/mob/user) + . = ..() + if(O.force) + set_flee_target(user? user : src.loc) + +/mob/living/simple_animal/cat/attack_hand(mob/living/carbon/human/M as mob) + . = ..() + if(M.a_intent == I_HURT) + set_flee_target(M) + +/mob/living/simple_animal/cat/ex_act() + . = ..() + set_flee_target(src.loc) + +/mob/living/simple_animal/cat/bullet_act(var/obj/item/projectile/proj) + . = ..() + set_flee_target(proj.firer? proj.firer : src.loc) + +/mob/living/simple_animal/cat/hitby(atom/movable/AM) + . = ..() + set_flee_target(AM.thrower? AM.thrower : src.loc) /mob/living/simple_animal/cat/MouseDrop(atom/over_object) @@ -82,14 +134,91 @@ return //since the holder icon looks like a living cat ..() +//Basic friend AI +/mob/living/simple_animal/cat/fluff + var/mob/living/carbon/human/friend + var/befriend_job = null + +/mob/living/simple_animal/cat/fluff/handle_movement_target() + if (friend) + var/follow_dist = 5 + if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit) //danger + follow_dist = 1 + else if (friend.stat || friend.health <= 50) //danger or just sleeping + follow_dist = 2 + var/near_dist = max(follow_dist - 2, 1) + var/current_dist = get_dist(src, friend) + + if (movement_target != friend) + if (current_dist > follow_dist && !istype(movement_target, /mob/living/simple_animal/mouse) && (friend in oview(src))) + //stop existing movement + walk_to(src,0) + turns_since_scan = 0 + + //walk to friend + stop_automated_movement = 1 + movement_target = friend + walk_to(src, movement_target, near_dist, 4) + + //already following and close enough, stop + else if (current_dist <= near_dist) + walk_to(src,0) + movement_target = null + stop_automated_movement = 0 + if (prob(10)) + say("Meow!") + + if (!friend || movement_target != friend) + ..() + +/mob/living/simple_animal/cat/fluff/Life() + ..() + if (stat || !friend) + return + if (get_dist(src, friend) <= 1) + if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit) + if (prob((friend.stat < DEAD)? 50 : 15)) + var/verb = pick("meows", "mews", "mrowls") + audible_emote(pick("[verb] in distress.", "[verb] anxiously.")) + else + if (prob(5)) + visible_emote(pick("nuzzles [friend].", + "brushes against [friend].", + "rubs against [friend].", + "purrs.")) + else if (friend.health <= 50) + if (prob(10)) + var/verb = pick("meows", "mews", "mrowls") + audible_emote("[verb] anxiously.") + +/mob/living/simple_animal/cat/fluff/verb/friend() + set name = "Become Friends" + set category = "IC" + set src in view(1) + + if(friend && usr == friend) + set_dir(get_dir(src, friend)) + say("Meow!") + return + + if (!(ishuman(usr) && befriend_job && usr.job == befriend_job)) + usr << "[src] ignores you." + return + + friend = usr + + set_dir(get_dir(src, friend)) + say("Meow!") + //RUNTIME IS ALIVE! SQUEEEEEEEE~ -/mob/living/simple_animal/cat/Runtime +/mob/living/simple_animal/cat/fluff/Runtime name = "Runtime" desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally." gender = FEMALE icon_state = "cat" icon_living = "cat" icon_dead = "cat_dead" + befriend_job = "Chief Medical Officer" /mob/living/simple_animal/cat/kitten name = "kitten" @@ -97,4 +226,8 @@ icon_state = "kitten" icon_living = "kitten" icon_dead = "kitten_dead" - gender = NEUTER \ No newline at end of file + gender = NEUTER + +/mob/living/simple_animal/cat/kitten/New() + gender = pick(MALE, FEMALE) + ..() diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 8cce2342df..322d08dc9f 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -24,241 +24,6 @@ var/obj/item/inventory_back var/facehugger -/* -/mob/living/simple_animal/corgi/Life() - ..() - regenerate_icons() - -/mob/living/simple_animal/corgi/show_inv(mob/user as mob) - user.set_machine(src) - if(user.stat) return - - var/dat = "
    Inventory of [name]

    " - if(inventory_head) - dat += "
    Head: [inventory_head] (Remove)" - else - dat += "
    Head: Nothing" - if(inventory_back) - dat += "
    Back: [inventory_back] (Remove)" - else - dat += "
    Back: Nothing" - - user << browse(dat, text("window=mob[];size=325x500", name)) - onclose(user, "mob[real_name]") - return - -/mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(inventory_head && inventory_back) - //helmet and armor = 100% protection - if( istype(inventory_head,/obj/item/clothing/head/helmet) && istype(inventory_back,/obj/item/clothing/suit/armor) ) - if( O.force ) - usr << "\red This animal is wearing too much armor. You can't cause /him any damage." - for (var/mob/M in viewers(src, null)) - M.show_message("\red \b [user] hits [src] with the [O], however [src] is too armored.") - else - usr << "\red This animal is wearing too much armor. You can't reach its skin." - for (var/mob/M in viewers(src, null)) - M.show_message("\red [user] gently taps [src] with the [O]. ") - if(prob(15)) - visible_emote("looks at [user] with [pick("an amused","an annoyed","a confused","a resentful", "a happy", "an excited")] expression on \his face") - return - ..() - -/mob/living/simple_animal/corgi/Topic(href, href_list) - if(usr.stat) return - - //Removing from inventory - if(href_list["remove_inv"]) - if(!Adjacent(usr) || !(ishuman(usr) || ismonkey(usr) || isrobot(usr) || isalienadult(usr))) - return - var/remove_from = href_list["remove_inv"] - switch(remove_from) - if("head") - if(inventory_head) - name = real_name - desc = initial(desc) - speak = list("YAP", "Woof!", "Bark!", "AUUUUUU") - speak_emote = list("barks", "woofs") - emote_hear = list("barks", "woofs", "yaps","pants") - emote_see = list("shakes its head", "shivers") - desc = "It's a corgi." - SetLuminosity(0) - inventory_head.loc = src.loc - inventory_head = null - else - usr << "\red There is nothing to remove from its [remove_from]." - return - if("back") - if(inventory_back) - inventory_back.loc = src.loc - inventory_back = null - else - usr << "\red There is nothing to remove from its [remove_from]." - return - - //show_inv(usr) //Commented out because changing Ian's name and then calling up his inventory opens a new inventory...which is annoying. - - //Adding things to inventory - else if(href_list["add_inv"]) - if(!Adjacent(usr) || !(ishuman(usr) || ismonkey(usr) || isrobot(usr) || isalienadult(usr))) - return - var/add_to = href_list["add_inv"] - if(!usr.get_active_hand()) - usr << "\red You have nothing in your hand to put on its [add_to]." - return - switch(add_to) - if("head") - if(inventory_head) - usr << "\red It's is already wearing something." - return - else - place_on_head(usr.get_active_hand()) - - var/obj/item/item_to_add = usr.get_active_hand() - if(!item_to_add) - return - - //Corgis are supposed to be simpler, so only a select few objects can actually be put - //to be compatible with them. The objects are below. - //Many hats added, Some will probably be removed, just want to see which ones are popular. - - var/list/allowed_types = list( - /obj/item/clothing/head/helmet, - /obj/item/clothing/glasses/sunglasses, - /obj/item/clothing/head/caphat, - /obj/item/clothing/head/collectable/captain, - /obj/item/clothing/head/that, - /obj/item/clothing/head/that, - /obj/item/clothing/head/kitty, - /obj/item/clothing/head/collectable/kitty, - /obj/item/clothing/head/rabbitears, - /obj/item/clothing/head/collectable/rabbitears, - /obj/item/clothing/head/beret, - /obj/item/clothing/head/collectable/beret, - /obj/item/clothing/head/det_hat, - /obj/item/clothing/head/nursehat, - /obj/item/clothing/head/pirate, - /obj/item/clothing/head/collectable/pirate, - /obj/item/clothing/head/ushanka, - /obj/item/clothing/head/chefhat, - /obj/item/clothing/head/collectable/chef, - /obj/item/clothing/head/collectable/police, - /obj/item/clothing/head/wizard/fake, - /obj/item/clothing/head/wizard, - /obj/item/clothing/head/collectable/wizard, - /obj/item/clothing/head/hardhat, - /obj/item/clothing/head/collectable/hardhat, - /obj/item/clothing/head/hardhat/white, - /obj/item/weapon/bedsheet, - /obj/item/clothing/head/helmet/space/santahat, - /obj/item/clothing/head/collectable/paper, - /obj/item/clothing/head/soft - ) - - if( ! ( item_to_add.type in allowed_types ) ) - usr << "\red It doesn't seem too keen on wearing that item." - return - - usr.drop_item() - - place_on_head(item_to_add) - - if("back") - if(inventory_back) - usr << "\red It's already wearing something." - return - else - var/obj/item/item_to_add = usr.get_active_hand() - if(!item_to_add) - return - - //Corgis are supposed to be simpler, so only a select few objects can actually be put - //to be compatible with them. The objects are below. - - var/list/allowed_types = list( - /obj/item/clothing/suit/armor/vest, - /obj/item/device/radio - ) - - if( ! ( item_to_add.type in allowed_types ) ) - usr << "\red This object won't fit." - return - - usr.drop_item() - item_to_add.loc = src - src.inventory_back = item_to_add - regenerate_icons() - - //show_inv(usr) //Commented out because changing Ian's name and then calling up his inventory opens a new inventory...which is annoying. - else - ..() - -/mob/living/simple_animal/corgi/proc/place_on_head(obj/item/item_to_add) - item_to_add.loc = src - src.inventory_head = item_to_add - regenerate_icons() - - //Various hats and items (worn on his head) change Ian's behaviour. His attributes are reset when a HAT is removed. - switch(inventory_head && inventory_head.type) - if(/obj/item/clothing/head/caphat, /obj/item/clothing/head/collectable/captain) - name = "Captain [real_name]" - desc = "Probably better than the last captain." - if(/obj/item/clothing/head/kitty, /obj/item/clothing/head/collectable/kitty) - name = "Runtime" - emote_see = list("coughs up a furball", "stretches") - emote_hear = list("purrs") - speak = list("Purrr", "Meow!", "MAOOOOOW!", "HISSSSS", "MEEEEEEW") - desc = "It's a cute little kitty-cat! ... wait ... what the hell?" - if(/obj/item/clothing/head/rabbitears, /obj/item/clothing/head/collectable/rabbitears) - name = "Hoppy" - emote_see = list("twitches its nose", "hops around a bit") - desc = "This is hoppy. It's a corgi-...urmm... bunny rabbit" - if(/obj/item/clothing/head/beret, /obj/item/clothing/head/collectable/beret) - name = "Yann" - desc = "Mon dieu! C'est un chien!" - speak = list("le woof!", "le bark!", "JAPPE!!") - emote_see = list("cowers in fear", "surrenders", "plays dead","looks as though there is a wall in front of him") - if(/obj/item/clothing/head/det_hat) - name = "Detective [real_name]" - desc = "[name] sees through your lies..." - emote_see = list("investigates the area","sniffs around for clues","searches for scooby snacks") - if(/obj/item/clothing/head/nursehat) - name = "Nurse [real_name]" - desc = "[name] needs 100cc of beef jerky...STAT!" - if(/obj/item/clothing/head/pirate, /obj/item/clothing/head/collectable/pirate) - name = "[pick("Ol'","Scurvy","Black","Rum","Gammy","Bloody","Gangrene","Death","Long-John")] [pick("kibble","leg","beard","tooth","poop-deck","Threepwood","Le Chuck","corsair","Silver","Crusoe")]" - desc = "Yaarghh!! Thar' be a scurvy dog!" - emote_see = list("hunts for treasure","stares coldly...","gnashes his tiny corgi teeth") - emote_hear = list("growls ferociously", "snarls") - speak = list("Arrrrgh!!","Grrrrrr!") - if(/obj/item/clothing/head/ushanka) - name = "[pick("Comrade","Commissar","Glorious Leader")] [real_name]" - desc = "A follower of Karl Barx." - emote_see = list("contemplates the failings of the capitalist economic model", "ponders the pros and cons of vangaurdism") - if(/obj/item/clothing/head/collectable/police) - name = "Officer [real_name]" - emote_see = list("drools","looks for donuts") - desc = "Stop right there criminal scum!" - if(/obj/item/clothing/head/wizard/fake, /obj/item/clothing/head/wizard, /obj/item/clothing/head/collectable/wizard) - name = "Grandwizard [real_name]" - speak = list("YAP", "Woof!", "Bark!", "AUUUUUU", "EI NATH!") - if(/obj/item/weapon/bedsheet) - name = "\improper Ghost" - speak = list("WoooOOOooo~","AUUUUUUUUUUUUUUUUUU") - emote_see = list("stumbles around", "shivers") - emote_hear = list("howls","groans") - desc = "Spooky!" - if(/obj/item/clothing/head/helmet/space/santahat) - name = "Rudolph the Red-Nosed Corgi" - emote_hear = list("barks christmas songs", "yaps") - desc = "He has a very shiny nose." - SetLuminosity(6) - if(/obj/item/clothing/head/soft) - name = "Corgi Tech [real_name]" - desc = "The reason your yellow gloves have chew-marks." -*/ - - //IAN! SQUEEEEEEEEE~ /mob/living/simple_animal/corgi/Ian name = "Ian" @@ -325,44 +90,6 @@ name = "Corgi meat" desc = "Tastes like... well you know..." -/mob/living/simple_animal/corgi/Ian/Bump(atom/movable/AM as mob|obj, yes) - - spawn( 0 ) - if ((!( yes ) || now_pushing)) - return - now_pushing = 1 - if(ismob(AM)) - var/mob/tmob = AM - if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) - if(prob(70)) - src << "\red You fail to push [tmob]'s fat ass out of the way." - now_pushing = 0 - return - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - - tmob.LAssailant = src - now_pushing = 0 - ..() - if (!( istype(AM, /atom/movable) )) - return - if (!( now_pushing )) - now_pushing = 1 - if (!( AM.anchored )) - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - var/obj/structure/window/W = AM - if(W.is_full_window()) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - now_pushing = null - return - return -//PC stuff-Sieve - /mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri if(istype(O, /obj/item/weapon/newspaper)) if(!stat) diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm index bf59a7e546..43b6c42cee 100644 --- a/code/modules/mob/living/simple_animal/friendly/crab.dm +++ b/code/modules/mob/living/simple_animal/friendly/crab.dm @@ -82,7 +82,7 @@ //Removing from inventory if(href_list["remove_inv"]) - if(get_dist(src,usr) > 1 || !(ishuman(usr) || ismonkey(usr) || isrobot(usr) || isalienadult(usr))) + if(get_dist(src,usr) > 1 || !(ishuman(usr) || issmall(usr) || isrobot(usr) || isalienadult(usr))) return var/remove_from = href_list["remove_inv"] switch(remove_from) @@ -112,7 +112,7 @@ //Adding things to inventory else if(href_list["add_inv"]) - if(get_dist(src,usr) > 1 || !(ishuman(usr) || ismonkey(usr) || isrobot(usr) || isalienadult(usr))) + if(get_dist(src,usr) > 1 || !(ishuman(usr) || issmall(usr) || isrobot(usr) || isalienadult(usr))) return var/add_to = href_list["add_inv"] if(!usr.get_active_hand()) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index b40e6fb819..b7e72da0c6 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -45,17 +45,15 @@ if(udder && prob(5)) udder.add_reagent("milk", rand(5, 10)) - if(locate(/obj/effect/plantsegment) in loc) - var/obj/effect/plantsegment/SV = locate(/obj/effect/plantsegment) in loc - del(SV) - if(prob(10)) - say("Nom") + if(locate(/obj/effect/plant) in loc) + var/obj/effect/plant/SV = locate() in loc + SV.die_off(1) if(!pulledby) for(var/direction in shuffle(list(1,2,4,8,5,6,9,10))) var/step = get_step(src, direction) if(step) - if(locate(/obj/effect/plantsegment) in step) + if(locate(/obj/effect/plant) in step) Move(step) /mob/living/simple_animal/hostile/retaliate/goat/Retaliate() @@ -65,11 +63,8 @@ /mob/living/simple_animal/hostile/retaliate/goat/Move() ..() if(!stat) - if(locate(/obj/effect/plantsegment) in loc) - var/obj/effect/plantsegment/SV = locate(/obj/effect/plantsegment) in loc - del(SV) - if(prob(10)) - say("Nom") + for(var/obj/effect/plant/SV in loc) + SV.die_off(1) /mob/living/simple_animal/hostile/retaliate/goat/attackby(var/obj/item/O as obj, var/mob/user as mob) var/obj/item/weapon/reagent_containers/glass/G = O @@ -130,7 +125,7 @@ udder.add_reagent("milk", rand(5, 10)) /mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M as mob) - if(!stat && M.a_intent == "disarm" && icon_state != icon_dead) + if(!stat && M.a_intent == I_DISARM && icon_state != icon_dead) M.visible_message("[M] tips over [src].","You tip over [src].") Weaken(30) icon_state = icon_dead @@ -227,15 +222,18 @@ var/global/chicken_count = 0 chicken_count -= 1 /mob/living/simple_animal/chicken/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown/wheat)) //feedin' dem chickens - if(!stat && eggsleft < 8) - user.visible_message("\blue [user] feeds [O] to [name]! It clucks happily.","\blue You feed [O] to [name]! It clucks happily.") - user.drop_item() - del(O) - eggsleft += rand(1, 4) - //world << eggsleft + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) //feedin' dem chickens + var/obj/item/weapon/reagent_containers/food/snacks/grown/G = O + if(G.seed && G.seed.kitchen_tag == "wheat") + if(!stat && eggsleft < 8) + user.visible_message("\blue [user] feeds [O] to [name]! It clucks happily.","\blue You feed [O] to [name]! It clucks happily.") + user.drop_item() + del(O) + eggsleft += rand(1, 4) + else + user << "\blue [name] doesn't seem hungry!" else - user << "\blue [name] doesn't seem hungry!" + user << "[name] doesn't seem interested in that." else ..() diff --git a/code/modules/mob/living/simple_animal/friendly/mushroom.dm b/code/modules/mob/living/simple_animal/friendly/mushroom.dm index 5b4121bedd..a924588d02 100644 --- a/code/modules/mob/living/simple_animal/friendly/mushroom.dm +++ b/code/modules/mob/living/simple_animal/friendly/mushroom.dm @@ -13,4 +13,42 @@ response_help = "pets" response_disarm = "gently pushes aside" response_harm = "whacks" - harm_intent_damage = 5 \ No newline at end of file + harm_intent_damage = 5 + var/datum/seed/seed + +/mob/living/simple_animal/mushroom/verb/spawn_spores() + + set name = "Explode" + set category = "Abilities" + set desc = "Spread your spores!" + set src = usr + + if(stat == 2) + usr << "You are dead; it is too late for that." + return + + if(!seed) + usr << "You are sterile!" + return + + spore_explode() + +/mob/living/simple_animal/mushroom/death() + if(prob(30)) + spore_explode() + return + ..() + +/mob/living/simple_animal/mushroom/proc/spore_explode() + + if(!seed) + return + + var/list/target_turfs = list() + for(var/turf/new_turf in orange(1,src)) + if(prob(60) && !new_turf.density && src.Adjacent(new_turf)) target_turfs |= new_turf + for(var/turf/target_turf in target_turfs) + new /obj/machinery/portable_atmospherics/hydroponics/soil/invisible(target_turf,seed) + seed.thrown_at(src,get_turf(src),1) + if(src) + gib() diff --git a/code/modules/mob/living/simple_animal/friendly/slime.dm b/code/modules/mob/living/simple_animal/friendly/slime.dm index 9674517a4c..dab2d2e2d9 100644 --- a/code/modules/mob/living/simple_animal/friendly/slime.dm +++ b/code/modules/mob/living/simple_animal/friendly/slime.dm @@ -14,43 +14,6 @@ emote_see = list("jiggles", "bounces in place") var/colour = "grey" -/mob/living/simple_animal/slime/Bump(atom/movable/AM as mob|obj, yes) - - spawn( 0 ) - if ((!( yes ) || now_pushing)) - return - now_pushing = 1 - if(ismob(AM)) - var/mob/tmob = AM - if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) - if(prob(70)) - src << "\red You fail to push [tmob]'s fat ass out of the way." - now_pushing = 0 - return - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - - tmob.LAssailant = src - now_pushing = 0 - ..() - if (!( istype(AM, /atom/movable) )) - return - if (!( now_pushing )) - now_pushing = 1 - if (!( AM.anchored )) - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - var/obj/structure/window/W = AM - if(W.is_full_window()) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - step(AM, t) - now_pushing = null - return - return - /mob/living/simple_animal/adultslime name = "pet slime" desc = "A lovable, domesticated slime." diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm index 89cfe60b65..ab4f7b2269 100644 --- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm @@ -194,7 +194,7 @@ radio = new /obj/item/device/radio/borg(src) camera = new /obj/machinery/camera(src) camera.c_tag = "Spiderbot-[real_name]" - camera.network = list("SS13") + camera.replace_networks(list("SS13")) ..() diff --git a/code/modules/mob/living/simple_animal/friendly/tomato.dm b/code/modules/mob/living/simple_animal/friendly/tomato.dm index 57c0f4c939..e0574ba925 100644 --- a/code/modules/mob/living/simple_animal/friendly/tomato.dm +++ b/code/modules/mob/living/simple_animal/friendly/tomato.dm @@ -12,4 +12,7 @@ response_help = "prods" response_disarm = "pushes aside" response_harm = "smacks" - harm_intent_damage = 5 \ No newline at end of file + harm_intent_damage = 5 + melee_damage_upper = 15 + melee_damage_lower = 10 + attacktext = "mauled" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index 447ad6b1c9..27b43a7cc3 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -17,7 +17,7 @@ melee_damage_lower = 25 melee_damage_upper = 25 attacktext = "slashed" - a_intent = "harm" + a_intent = I_HURT attack_sound = 'sound/weapons/bladeslice.ogg' min_oxy = 0 max_oxy = 0 @@ -29,7 +29,7 @@ max_n2 = 0 unsuitable_atoms_damage = 15 faction = "alien" - wall_smash = 1 + environment_smash = 2 status_flags = CANPUSH minbodytemp = 0 heat_damage_per_tick = 20 diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index 4d0792d789..4d7a8f7e3a 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -16,7 +16,7 @@ speak_chance = 5 turns_per_move = 5 see_in_dark = 10 - meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat + meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat response_help = "pets" response_disarm = "gently pushes aside" response_harm = "pokes" diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 03bf90b0f5..73ff6eab5d 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -188,6 +188,8 @@ del(A) return A.current = target + A.starting = get_turf(src) + A.original = get_turf(target) A.yo = target:y - start:y A.xo = target:x - start:x spawn( 0 ) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm index cdaf72f6bd..5a6a7e5768 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm @@ -13,7 +13,7 @@ speak = list("HONK", "Honk!", "Welcome to clown planet!") emote_see = list("honks") speak_chance = 1 - a_intent = "harm" + a_intent = I_HURT stop_automated_movement_when_pulled = 0 maxHealth = 75 health = 75 diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm index c6d3052b5d..872eb95b61 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/drone.dm @@ -15,7 +15,7 @@ response_harm = "hits" speak = list("ALERT.","Hostile-ile-ile entities dee-twhoooo-wected.","Threat parameterszzzz- szzet.","Bring sub-sub-sub-systems uuuup to combat alert alpha-a-a.") emote_see = list("beeps menacingly","whirrs threateningly","scans its immediate vicinity") - a_intent = "harm" + a_intent = I_HURT stop_automated_movement_when_pulled = 0 health = 300 maxHealth = 300 diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm index b09a6ec548..84f1c6f27a 100644 --- a/code/modules/mob/living/simple_animal/hostile/russian.dm +++ b/code/modules/mob/living/simple_animal/hostile/russian.dm @@ -18,7 +18,7 @@ melee_damage_lower = 15 melee_damage_upper = 15 attacktext = "punched" - a_intent = "harm" + a_intent = I_HURT var/corpse = /obj/effect/landmark/mobcorpse/russian var/weapon1 = /obj/item/weapon/kitchenknife min_oxy = 5 @@ -38,7 +38,7 @@ icon_state = "russianranged" icon_living = "russianranged" corpse = /obj/effect/landmark/mobcorpse/russian/ranged - weapon1 = /obj/item/weapon/gun/projectile/mateba + weapon1 = /obj/item/weapon/gun/projectile/revolver/mateba ranged = 1 projectiletype = /obj/item/projectile/bullet projectilesound = 'sound/weapons/Gunshot.ogg' diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index ebcdfc1194..12f175cfef 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -18,7 +18,7 @@ melee_damage_lower = 10 melee_damage_upper = 10 attacktext = "punched" - a_intent = "harm" + a_intent = I_HURT var/corpse = /obj/effect/landmark/mobcorpse/syndicatesoldier var/weapon1 var/weapon2 @@ -31,7 +31,7 @@ min_n2 = 0 max_n2 = 0 unsuitable_atoms_damage = 15 - wall_smash = 1 + environment_smash = 1 faction = "syndicate" status_flags = CANPUSH @@ -108,7 +108,7 @@ icon_living = "syndicateranged" casingtype = /obj/item/ammo_casing/a12mm projectilesound = 'sound/weapons/Gunshot_smg.ogg' - projectiletype = /obj/item/projectile/bullet/midbullet2 + projectiletype = /obj/item/projectile/bullet/pistol/medium weapon1 = /obj/item/weapon/gun/projectile/automatic/c20r @@ -159,4 +159,4 @@ /mob/living/simple_animal/hostile/viscerator/death() ..(null,"is smashed into pieces!") - del src + del src diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 7790f9ecd8..90e5606b07 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -136,7 +136,7 @@ return //Is the usr's mob type able to do this? - if(ishuman(usr) || ismonkey(usr) || isrobot(usr)) + if(ishuman(usr) || issmall(usr) || isrobot(usr)) //Removing from inventory if(href_list["remove_inv"]) @@ -215,7 +215,7 @@ /mob/living/simple_animal/parrot/attack_hand(mob/living/carbon/M as mob) ..() if(client) return - if(!stat && M.a_intent == "hurt") + if(!stat && M.a_intent == I_HURT) icon_state = "parrot_fly" //It is going to be flying regardless of whether it flees or attacks @@ -607,7 +607,7 @@ stolen_item = C.r_hand if(stolen_item) - C.u_equip(stolen_item) + C.remove_from_mob(stolen_item) held_item = stolen_item stolen_item.loc = src visible_message("[src] grabs the [held_item] out of [C]'s hand!", "\blue You snag the [held_item] out of [C]'s hand!", "You hear the sounds of wings flapping furiously.") diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index c200ef6f70..98db91e7cc 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -28,34 +28,20 @@ faction = "cult" status_flags = CANPUSH - - Life() - ..() - if(stat == 2) - new /obj/item/weapon/ectoplasm (src.loc) - for(var/mob/M in viewers(src, null)) - if((M.client && !( M.blinded ))) - M.show_message("\red [src] lets out a contented sigh as their form unwinds. ") - ghostize() - del src - return - - - attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri - if(istype(O, /obj/item/device/soulstone)) - O.transfer_soul("SHADE", src, user) - else - if(O.force) - var/damage = O.force - if (O.damtype == HALLOSS) - damage = 0 - health -= damage - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [src] has been attacked with the [O] by [user]. ") - else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with the [O]. ") +/mob/living/simple_animal/shade/Life() + ..() + if(stat == 2) + new /obj/item/weapon/ectoplasm (src.loc) + for(var/mob/M in viewers(src, null)) + if((M.client && !( M.blinded ))) + M.show_message("\red [src] lets out a contented sigh as their form unwinds. ") + ghostize() + del src return + + +/mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri + if(istype(O, /obj/item/device/soulstone)) + O.transfer_soul("SHADE", src, user) + return + return ..() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 2dcb99b091..e94694295c 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -4,6 +4,12 @@ health = 20 maxHealth = 20 + mob_bump_flag = SIMPLE_ANIMAL + mob_swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL + mob_push_flags = MONKEY|SLIME|SIMPLE_ANIMAL + + var/show_stat_health = 1 //does the percentage health show in the stat panel for the mob + var/icon_living = "" var/icon_dead = "" var/icon_gib = null //We only try to show a gibbing animation if this exists. @@ -52,7 +58,12 @@ var/attacktext = "attacked" var/attack_sound = null var/friendly = "nuzzles" - var/wall_smash = 0 + var/environment_smash = 0 + var/resistance = 0 // Damage reduction + + //Null rod stuff + var/supernatural = 0 + var/purge = 0 /mob/living/simple_animal/New() ..() @@ -88,6 +99,7 @@ handle_stunned() handle_weakened() handle_paralysed() + handle_supernatural() //Movement if(!client && !stop_automated_movement && wander && !anchored) @@ -186,19 +198,9 @@ adjustBruteLoss(unsuitable_atoms_damage) return 1 -/mob/living/simple_animal/Bumped(AM as mob|obj) - if(!AM) return - - if(resting || buckled) - return - - if(isturf(src.loc)) - if(ismob(AM)) - var/newamloc = src.loc - src.loc = AM:loc - AM:loc = newamloc - else - ..() +/mob/living/simple_animal/proc/handle_supernatural() + if(purge) + purge -= 1 /mob/living/simple_animal/gib() ..(icon_gib,1) @@ -225,15 +227,15 @@ switch(M.a_intent) - if("help") + if(I_HELP) if (health > 0) M.visible_message("\blue [M] [response_help] \the [src]") - if("disarm") + if(I_DISARM) M.visible_message("\blue [M] [response_disarm] \the [src]") //TODO: Push the mob away or something - if("grab") + if(I_GRAB) if (M == src) return if (!(status_flags & CANPUSH)) @@ -249,62 +251,66 @@ M.visible_message("\red [M] has grabbed [src] passively!") - if("hurt") + if(I_HURT) adjustBruteLoss(harm_intent_damage) M.visible_message("\red [M] [response_harm] \the [src]") return -/mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user) //Marker -Agouri - +/mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user) if(istype(O, /obj/item/stack/medical)) - - if(stat != DEAD && health < maxHealth) - var/obj/item/stack/medical/medical_pack = O - if(medical_pack.use(1)) - adjustBruteLoss(-medical_pack.heal_brute) - visible_message("\The [user] applies the [medical_pack] to \the [src].") + user.changeNext_move(4) + if(stat != DEAD) + var/obj/item/stack/medical/MED = O + if(health < maxHealth) + if(MED.amount >= 1) + adjustBruteLoss(-MED.heal_brute) + MED.amount -= 1 + if(MED.amount <= 0) + del(MED) + for(var/mob/M in viewers(src, null)) + if ((M.client && !( M.blinded ))) + M.show_message("\The [src] cannot benefit from medical items in its current state." - return - - else if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch)) - var/actual_meat_amount = max(1,(meat_amount/2)) - if(meat_type && actual_meat_amount>0 && (stat == DEAD)) - for(var/i=0;i[user] chops up \the [src]!") - new/obj/effect/decal/cleanable/blood/splatter(get_turf(src)) - del(src) - else - user.visible_message("[user] butchers \the [src] messily!") - gib() - return - - if(O.force) - var/damage = O.force - if (O.damtype == HALLOSS) - damage = 0 - adjustBruteLoss(damage) - visible_message("\The [src] has been attacked with \the [O] by [user].") + user << "" + if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead. + if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch)) + harvest(user) else - user << "This weapon is ineffective; it does no damage." - visible_message("\The [user] gently taps [src] with the [O].") + user.changeNext_move(8) + if(O.force > resistance) + var/damage = O.force + if (O.damtype == HALLOSS) + damage = 0 + if(supernatural && istype(O,/obj/item/weapon/nullrod)) + damage *= 2 + purge = 3 + adjustBruteLoss(damage) + for(var/mob/M in viewers(src, null)) + if ((M.client && !( M.blinded ))) + M.show_message("This weapon is ineffective, it does no damage." + for(var/mob/M in viewers(src, null)) + if ((M.client && !( M.blinded ))) + M.show_message("0 && (stat == DEAD)) + for(var/i=0;i[user] chops up \the [src]!") + new/obj/effect/decal/cleanable/blood/splatter(get_turf(src)) + del(src) + else + user.visible_message("[user] butchers \the [src] messily!") + gib() diff --git a/code/modules/mob/living/simple_animal/worm.dm b/code/modules/mob/living/simple_animal/worm.dm index 0df4f5c7c4..fe76fa87b4 100644 --- a/code/modules/mob/living/simple_animal/worm.dm +++ b/code/modules/mob/living/simple_animal/worm.dm @@ -30,9 +30,9 @@ max_co2 = 0 max_tox = 0 - a_intent = "harm" //so they don't get pushed around + a_intent = I_HURT //so they don't get pushed around - wall_smash = 1 + environment_smash = 2 speed = -1 diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index c888218605..d34a309ee3 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -43,4 +43,7 @@ client.perspective = EYE_PERSPECTIVE else client.eye = src - client.perspective = MOB_PERSPECTIVE \ No newline at end of file + client.perspective = MOB_PERSPECTIVE + + //set macro to normal incase it was overriden (like cyborg currently does) + winset(src, null, "mainwindow.macro=macro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5") diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 0ab9b162d1..7283610a35 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -157,7 +157,7 @@ if((is_blind(src) || usr.stat) && !isobserver(src)) src << "Something is there but you can't see it." - return + return 1 face_atom(A) A.examine(src) @@ -289,12 +289,9 @@ set src in usr if(usr != src) usr << "No." - var/msg = input(usr,"Set the flavor text in your 'examine' verb. Can also be used for OOC notes about your character.","Flavor Text",html_decode(flavor_text)) as message|null + var/msg = sanitize(input(usr,"Set the flavor text in your 'examine' verb. Can also be used for OOC notes about your character.","Flavor Text",html_decode(flavor_text)) as message|null, extra = 0) if(msg != null) - msg = copytext(msg, 1, MAX_MESSAGE_LEN) - msg = html_encode(msg) - flavor_text = msg /mob/proc/warn_flavor_changed() @@ -327,7 +324,7 @@ if ((stat != 2 || !( ticker ))) usr << "You must be dead to use this!" return - if (ticker.mode.name == "meteor" || ticker.mode.name == "epidemic") //BS12 EDIT + if (ticker.mode.deny_respawn) //BS12 EDIT usr << "Respawn is disabled for this roundtype." return else @@ -721,30 +718,60 @@ note dizziness decrements automatically in the mob's Life() proc. //reset the pixel offsets to zero is_floating = 0 - +/proc/getStatName(var/datum/controller/process/process) + return uppertext(copytext(process.name, 1, 4)) /mob/Stat() ..() - if(statpanel("Status")) //not looking at that panel - - if(client && client.holder) + if(client && client.holder) + if(statpanel("Status")) stat(null,"Location:\t([x], [y], [z])") stat(null,"CPU:\t[world.cpu]") stat(null,"Instances:\t[world.contents.len]") + if(statpanel("Status") && processScheduler.getIsRunning()) + var/datum/controller/process/process + + process = processScheduler.getProcess("ticker") + stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("air") + stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("lighting") + stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("alarm") + var/list/alarms = alarm_manager.active_alarms() + stat(null, "[getStatName(process)]([alarms.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("mob") + stat(null, "[getStatName(process)]([mob_list.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("machinery") + stat(null, "[getStatName(process)]([machines.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("obj") + stat(null, "[getStatName(process)]([processing_objects.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("pipenet") + stat(null, "[getStatName(process)]([pipe_networks.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("powernet") + stat(null, "[getStatName(process)]([powernets.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("nanoui") + stat(null, "[getStatName(process)]([nanomanager.processing_uis.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("disease") + stat(null, "[getStatName(process)]([active_diseases.len])\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + process = processScheduler.getProcess("sun") + stat(null, "[getStatName(process)]\t - #[process.getTicks()]\t - [process.getLastRunTime()]") + + else + stat(null, "processScheduler is not running.") - if(master_controller) - stat(null,"MasterController-[last_tick_duration] ([master_controller.processing?"On":"Off"]-[controller_iteration])") - stat(null,"Air-[master_controller.air_cost]\tSun-[master_controller.sun_cost]") - stat(null,"Mob-[master_controller.mobs_cost]\t#[mob_list.len]") - stat(null,"Dis-[master_controller.diseases_cost]\t#[active_diseases.len]") - stat(null,"Mch-[master_controller.machines_cost]\t#[machines.len]") - stat(null,"Obj-[master_controller.objects_cost]\t#[processing_objects.len]") - stat(null,"Net-[master_controller.networks_cost]\tPnet-[master_controller.powernets_cost]") - stat(null,"NanoUI-[master_controller.nano_cost]\t#[nanomanager.processing_uis.len]") - stat(null,"Tick-[master_controller.ticker_cost]\tALL-[master_controller.total_cost]") - else - stat(null,"MasterController-ERROR") if(listed_turf && client) if(!TurfAdjacent(listed_turf)) @@ -770,12 +797,11 @@ note dizziness decrements automatically in the mob's Life() proc. + // facing verbs /mob/proc/canface() if(!canmove) return 0 - if(client.moving) return 0 - if(world.time < client.move_delay) return 0 - if(stat==2) return 0 + if(stat) return 0 if(anchored) return 0 if(monkeyizing) return 0 return 1 @@ -789,27 +815,23 @@ note dizziness decrements automatically in the mob's Life() proc. canmove = 0 pixel_y = V.mob_offset_y - 5 else - lying = 0 + if(buckled.buckle_lying != -1) lying = buckled.buckle_lying canmove = 1 pixel_y = V.mob_offset_y else if(buckled) - // var/movable is defined at /obj/structure/stool/bed level - // If we're buckled to something else, such as vines, assume it's stationary. - if (!istype(buckled) || !buckled.movable) - anchored = 1 - canmove = 0 - if(istype(buckled,/obj/structure/stool/bed/chair) ) - lying = 0 - else - lying = 1 - else - anchored = 0 - canmove = 1 - lying = 0 + anchored = 1 + canmove = 0 + if(istype(buckled)) + if(buckled.buckle_lying != -1) + lying = buckled.buckle_lying + if(buckled.buckle_movable) + anchored = 0 + canmove = 1 + else if( stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH)) lying = 1 canmove = 0 - else if( stunned ) + else if(stunned) canmove = 0 else if(captured) anchored = 1 @@ -826,6 +848,11 @@ note dizziness decrements automatically in the mob's Life() proc. else density = 1 + for(var/obj/item/weapon/grab/G in grabbed_by) + if(G.state >= GRAB_AGGRESSIVE) + canmove = 0 + break + //Temporarily moved here from the various life() procs //I'm fixing stuff incrementally so this will likely find a better home. //It just makes sense for now. ~Carn @@ -839,9 +866,10 @@ note dizziness decrements automatically in the mob's Life() proc. /mob/proc/facedir(var/ndir) - if(!canface()) return 0 + if(!canface() || client.moving || world.time < client.move_delay) + return 0 set_dir(ndir) - if(buckled && buckled.movable) + if(buckled && buckled.buckle_movable) buckled.set_dir(ndir) client.move_delay += movement_delay() return 1 @@ -873,6 +901,7 @@ note dizziness decrements automatically in the mob's Life() proc. /mob/proc/Stun(amount) if(status_flags & CANSTUN) + facing_dir = null stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun return @@ -888,6 +917,7 @@ note dizziness decrements automatically in the mob's Life() proc. /mob/proc/Weaken(amount) if(status_flags & CANWEAKEN) + facing_dir = null weakened = max(max(weakened,amount),0) update_canmove() //updates lying, canmove and icons return @@ -906,6 +936,7 @@ note dizziness decrements automatically in the mob's Life() proc. /mob/proc/Paralyse(amount) if(status_flags & CANPARALYSE) + facing_dir = null paralysis = max(max(paralysis,amount),0) return @@ -920,6 +951,7 @@ note dizziness decrements automatically in the mob's Life() proc. return /mob/proc/Sleeping(amount) + facing_dir = null sleeping = max(max(sleeping,amount),0) return @@ -932,6 +964,7 @@ note dizziness decrements automatically in the mob's Life() proc. return /mob/proc/Resting(amount) + facing_dir = null resting = max(max(resting,amount),0) return @@ -1095,3 +1128,53 @@ mob/proc/yank_out_object() /mob/proc/updateicon() return + +/mob/verb/face_direction() + + set name = "Face Direction" + set category = "IC" + set src = usr + + set_face_dir() + + if(!facing_dir) + usr << "You are now not facing anything." + else + usr << "You are now facing [dir2text(facing_dir)]." + +/mob/proc/set_face_dir(var/newdir) + if(newdir == facing_dir) + facing_dir = null + else if(newdir) + set_dir(newdir) + facing_dir = newdir + else if(facing_dir) + facing_dir = null + else + set_dir(dir) + facing_dir = dir + +/mob/set_dir() + if(facing_dir) + if(!canface() || lying || buckled || restrained()) + facing_dir = null + else if(dir != facing_dir) + return ..(facing_dir) + else + return ..() + +/mob/verb/northfaceperm() + set hidden = 1 + set_face_dir(NORTH) + +/mob/verb/southfaceperm() + set hidden = 1 + set_face_dir(SOUTH) + +/mob/verb/eastfaceperm() + set hidden = 1 + set_face_dir(EAST) + +/mob/verb/westfaceperm() + set hidden = 1 + set_face_dir(WEST) diff --git a/code/modules/mob/mob_cleanup.dm b/code/modules/mob/mob_cleanup.dm index 1cac93904f..cdc734c49a 100644 --- a/code/modules/mob/mob_cleanup.dm +++ b/code/modules/mob/mob_cleanup.dm @@ -152,14 +152,6 @@ Put (mob/proc)s here that are in dire need of a code cleanup. // world << "Shoes pass [passed]" */ // - else if(istype(src, /mob/living/carbon/monkey)) - var/mob/living/carbon/monkey/M = src - switch(target_zone) - if(1) - if(M.wear_mask && isobj(M.wear_mask)) - Cl = M.wear_mask - passed = prob((Cl.permeability_coefficient*100) - 1) - //world << "Mask pass [passed]" if(!passed && spread_type == AIRBORNE && !internals) passed = (prob((50*virus.permeability_mod) - 1)) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 296d58d078..9b17a182aa 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -14,6 +14,7 @@ var/obj/screen/blind = null var/obj/screen/hands = null var/obj/screen/pullin = null + var/obj/screen/purged = null var/obj/screen/internals = null var/obj/screen/oxygen = null var/obj/screen/i_select = null @@ -90,6 +91,7 @@ var/list/languages = list() // For speaking/listening. var/list/speak_emote = list("says") // Verbs used when speaking. Defaults to 'say' if speak_emote is null. var/emote_type = 1 // Define emote default type, 1 for seen emotes, 2 for heard emotes + var/facing_dir = null // Used for the ancient art of moonwalking. var/name_archive //For admin things like possession @@ -116,11 +118,11 @@ var/losebreath = 0.0//Carbon var/intent = null//Living var/shakecamera = 0 - var/a_intent = "help"//Living + var/a_intent = I_HELP//Living var/m_int = null//Living var/m_intent = "run"//Living var/lastKnownIP = null - var/obj/structure/stool/bed/buckled = null//Living + var/obj/buckled = null//Living var/obj/item/l_hand = null//Living var/obj/item/r_hand = null//Living var/obj/item/weapon/back = null//Human/Monkey @@ -214,7 +216,7 @@ var/universal_understand = 0 // Set to 1 to enable the mob to understand everyone, not necessarily speak var/stance_damage = 0 //Whether this mob's ability to stand has been affected - + //SSD var, changed it up some so people can have special things happen for different mobs when SSD. var/player_logged = 0 @@ -222,3 +224,5 @@ var/list/shouldnt_see = list() //list of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes var/list/active_genes=list() + + diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index d6e6496f9d..39895f22b2 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -35,6 +35,10 @@ hud.name = "reinforce grab" hud.master = src +/obj/item/weapon/grab/Del() + //make sure the grabbed_by list doesn't fill up with nulls + if(affecting) affecting.grabbed_by -= src + ..() //Used by throw code to hand over the mob, instead of throwing the grab. The grab is then deleted by the throw code. /obj/item/weapon/grab/proc/throw() @@ -67,6 +71,7 @@ if(state <= GRAB_AGGRESSIVE) allow_upgrade = 1 + //disallow upgrading if we're grabbing more than one person if((assailant.l_hand && assailant.l_hand != src && istype(assailant.l_hand, /obj/item/weapon/grab))) var/obj/item/weapon/grab/G = assailant.l_hand if(G.affecting != affecting) @@ -76,31 +81,29 @@ if(G.affecting != affecting) allow_upgrade = 0 if(state == GRAB_AGGRESSIVE) - var/h = affecting.hand - affecting.hand = 0 - affecting.drop_item() - affecting.hand = 1 - affecting.drop_item() - affecting.hand = h + affecting.drop_l_hand() + affecting.drop_r_hand() + //disallow upgrading past aggressive if we're being grabbed aggressively for(var/obj/item/weapon/grab/G in affecting.grabbed_by) if(G == src) continue - if(G.state == GRAB_AGGRESSIVE) + if(G.state >= GRAB_AGGRESSIVE) allow_upgrade = 0 if(allow_upgrade) hud.icon_state = "reinforce" else hud.icon_state = "!reinforce" - else - if(!affecting.buckled) - affecting.loc = assailant.loc + else if(!affecting.buckled) + affecting.loc = assailant.loc if(state >= GRAB_NECK) - affecting.Stun(5) //It will hamper your voice, being choked and all. + affecting.Stun(1) if(isliving(affecting)) var/mob/living/L = affecting L.adjustOxyLoss(1) if(state >= GRAB_KILL) + //affecting.apply_effect(STUTTER, 5) //would do this, but affecting isn't declared as mob/living for some stupid reason. + affecting.stuttering = max(affecting.stuttering, 5) //It will hamper your voice, being choked and all. affecting.Weaken(5) //Should keep you down unless you get help. affecting.losebreath = min(affecting.losebreath + 2, 3) @@ -126,48 +129,46 @@ assailant.visible_message("[assailant] has grabbed [affecting] aggressively (now hands)!") state = GRAB_AGGRESSIVE icon_state = "grabbed1" - else - if(state < GRAB_NECK) - if(isslime(affecting)) - assailant << "You squeeze [affecting], but nothing interesting happens." + else if(state < GRAB_NECK) + if(isslime(affecting)) + assailant << "You squeeze [affecting], but nothing interesting happens." + return + + assailant.visible_message("[assailant] has reinforced \his grip on [affecting] (now neck)!") + state = GRAB_NECK + icon_state = "grabbed+1" + if(!affecting.buckled) + affecting.loc = assailant.loc + affecting.attack_log += "\[[time_stamp()]\] Has had their neck grabbed by [assailant.name] ([assailant.ckey])" + assailant.attack_log += "\[[time_stamp()]\] Grabbed the neck of [affecting.name] ([affecting.ckey])" + msg_admin_attack("[key_name(assailant)] grabbed the neck of [key_name(affecting)]") + hud.icon_state = "disarm/kill" + hud.name = "disarm/kill" + else if(state < GRAB_UPGRADING) + assailant.visible_message("[assailant] starts to tighten \his grip on [affecting]'s neck!") + hud.icon_state = "disarm/kill1" + state = GRAB_UPGRADING + if(do_after(assailant, UPGRADE_KILL_TIMER)) + if(state == GRAB_KILL) return + if(!affecting) + del(src) + return + if(!assailant.canmove || assailant.lying) + del(src) + return + state = GRAB_KILL + assailant.visible_message("[assailant] has tightened \his grip on [affecting]'s neck!") + affecting.attack_log += "\[[time_stamp()]\] Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])" + assailant.attack_log += "\[[time_stamp()]\] Strangled (kill intent) [affecting.name] ([affecting.ckey])" + msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]") - assailant.visible_message("[assailant] has reinforced \his grip on [affecting] (now neck)!") - state = GRAB_NECK - icon_state = "grabbed+1" - if(!affecting.buckled) - affecting.loc = assailant.loc - affecting.attack_log += "\[[time_stamp()]\] Has had their neck grabbed by [assailant.name] ([assailant.ckey])" - assailant.attack_log += "\[[time_stamp()]\] Grabbed the neck of [affecting.name] ([affecting.ckey])" - msg_admin_attack("[key_name(assailant)] grabbed the neck of [key_name(affecting)]") - hud.icon_state = "disarm/kill" - hud.name = "disarm/kill" + assailant.next_move = world.time + 10 + affecting.losebreath += 1 else - if(state < GRAB_UPGRADING) - assailant.visible_message("[assailant] starts to tighten \his grip on [affecting]'s neck!") - hud.icon_state = "disarm/kill1" - state = GRAB_UPGRADING - if(do_after(assailant, UPGRADE_KILL_TIMER)) - if(state == GRAB_KILL) - return - if(!affecting) - del(src) - return - if(!assailant.canmove || assailant.lying) - del(src) - return - state = GRAB_KILL - assailant.visible_message("[assailant] has tightened \his grip on [affecting]'s neck!") - affecting.attack_log += "\[[time_stamp()]\] Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])" - assailant.attack_log += "\[[time_stamp()]\] Strangled (kill intent) [affecting.name] ([affecting.ckey])" - msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]") - - assailant.next_move = world.time + 10 - affecting.losebreath += 1 - else - assailant.visible_message("[assailant] was unable to tighten \his grip on [affecting]'s neck!") - hud.icon_state = "disarm/kill" - state = GRAB_NECK + assailant.visible_message("[assailant] was unable to tighten \his grip on [affecting]'s neck!") + hud.icon_state = "disarm/kill" + state = GRAB_NECK //This is used to make sure the victim hasn't managed to yackety sax away before using the grab. @@ -193,16 +194,16 @@ return if(M == assailant && state >= GRAB_AGGRESSIVE) - var/can_eat - if((FAT in user.mutations) && ismonkey(affecting)) + var/can_eat + if((FAT in user.mutations) && issmall(affecting)) can_eat = 1 else var/mob/living/carbon/human/H = user - if(istype(H) && iscarbon(affecting) && H.species.gluttonous) + if(istype(H) && H.species.gluttonous) if(H.species.gluttonous == 2) can_eat = 2 - else if(!ishuman(affecting)) + else if(!ishuman(affecting) && !issmall(affecting) && (affecting.small || iscarbon(affecting))) can_eat = 1 if(can_eat) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 76709ea22b..eef5557ff0 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -15,9 +15,11 @@ return istype(H.species, /datum/species/xenos) return 0 -/proc/ismonkey(A) - if(A && istype(A, /mob/living/carbon/monkey)) - return 1 +/proc/issmall(A) + if(A && istype(A, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = A + if(H.species && H.species.is_small) + return 1 return 0 /proc/isbrain(A) @@ -75,11 +77,37 @@ return 1 return 0 +/mob/proc/isSilicon() + return 0 + +/mob/living/silicon/isSilicon() + return 1 /proc/isAI(A) if(istype(A, /mob/living/silicon/ai)) return 1 return 0 +/mob/proc/isAI() + return 0 + +/mob/living/silicon/ai/isAI() + return 1 + +/mob/proc/isRobot() + return 0 + +/mob/living/silicon/robot/isRobot() + return 1 + +/mob/proc/isSynthetic() + return 0 + +/mob/living/carbon/human/isSynthetic() + return species.flags & IS_SYNTHETIC + +/mob/living/silicon/isSynthetic() + return 1 + /proc/ispAI(A) if(istype(A, /mob/living/silicon/pai)) return 1 @@ -138,6 +166,18 @@ proc/hassensorlevel(A, var/level) return U.sensor_mode >= level return 0 +proc/getsensorlevel(A) + var/mob/living/carbon/human/H = A + if(istype(H) && istype(H.w_uniform, /obj/item/clothing/under)) + var/obj/item/clothing/under/U = H.w_uniform + return U.sensor_mode + return SUIT_SENSOR_OFF + + +/proc/is_admin(var/mob/user) + return check_rights(R_ADMIN, 0, user) != 0 + + /proc/hsl2rgb(h, s, l) return //TODO: Implement @@ -217,20 +257,26 @@ var/list/global/organ_rel_size = list( // Emulates targetting a specific body part, and miss chances // May return null if missed // miss_chance_mod may be negative. -/proc/get_zone_with_miss_chance(zone, var/mob/target, var/miss_chance_mod = 0) +/proc/get_zone_with_miss_chance(zone, var/mob/target, var/miss_chance_mod = 0, var/ranged_attack=0) zone = check_zone(zone) - // you can only miss if your target is standing and not restrained - if(!target.buckled && !target.lying) - var/miss_chance = 10 - if (zone in base_miss_chance) - miss_chance = base_miss_chance[zone] - miss_chance = max(miss_chance + miss_chance_mod, 0) - if(prob(miss_chance)) - if(prob(70)) - return null - return pick(base_miss_chance) + // you cannot miss if your target is prone or restrained + if(target.buckled || target.lying) + return zone + // if your target is being grabbed aggressively by someone you cannot miss either + if(!ranged_attack) + for(var/obj/item/weapon/grab/G in target.grabbed_by) + if(G.state >= GRAB_AGGRESSIVE) + return zone + var/miss_chance = 10 + if (zone in base_miss_chance) + miss_chance = base_miss_chance[zone] + miss_chance = max(miss_chance + miss_chance_mod, 0) + if(prob(miss_chance)) + if(prob(70)) + return null + return pick(base_miss_chance) return zone @@ -305,7 +351,7 @@ proc/slur(phrase) n_letter = text("[n_letter]-[n_letter]") t = text("[t][n_letter]")//since the above is ran through for each letter, the text just adds up back to the original word. p++//for each letter p is increased to find where the next letter will be. - return sanitize(copytext(t,1,MAX_MESSAGE_LEN)) + return sanitize(t) proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 for p will cause letters to be replaced instead of added @@ -352,7 +398,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp n_letter = text("[n_letter]") t = text("[t][n_letter]") p=p+n_mod - return sanitize(copytext(t,1,MAX_MESSAGE_LEN)) + return sanitize(t) /proc/shake_camera(mob/M, duration, strength=1) @@ -396,29 +442,29 @@ It's fairly easy to fix if dealing with single letters but not so much with comp return 0 //converts intent-strings into numbers and back -var/list/intents = list("help","disarm","grab","hurt") +var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT) /proc/intent_numeric(argument) if(istext(argument)) switch(argument) - if("help") return 0 - if("disarm") return 1 - if("grab") return 2 + if(I_HELP) return 0 + if(I_DISARM) return 1 + if(I_GRAB) return 2 else return 3 else switch(argument) - if(0) return "help" - if(1) return "disarm" - if(2) return "grab" - else return "hurt" + if(0) return I_HELP + if(1) return I_DISARM + if(2) return I_GRAB + else return I_HURT //change a mob's act-intent. Input the intent as a string such as "help" or use "right"/"left /mob/verb/a_intent_change(input as text) set name = "a-intent" set hidden = 1 - if(ishuman(src) || isbrain(src)) + if(ishuman(src) || isbrain(src) || isslime(src)) switch(input) - if("help","disarm","grab","hurt") + if(I_HELP,I_DISARM,I_GRAB,I_HURT) a_intent = input if("right") a_intent = intent_numeric((intent_numeric(a_intent)+1) % 4) @@ -427,19 +473,19 @@ var/list/intents = list("help","disarm","grab","hurt") if(hud_used && hud_used.action_intent) hud_used.action_intent.icon_state = "intent_[a_intent]" - else if(isrobot(src) || ismonkey(src)) + else if(isrobot(src)) switch(input) - if("help") - a_intent = "help" - if("hurt") - a_intent = "hurt" + if(I_HELP) + a_intent = I_HELP + if(I_HURT) + a_intent = I_HURT if("right","left") a_intent = intent_numeric(intent_numeric(a_intent) - 3) if(hud_used && hud_used.action_intent) - if(a_intent == "hurt") - hud_used.action_intent.icon_state = "harm" + if(a_intent == I_HURT) + hud_used.action_intent.icon_state = I_HURT else - hud_used.action_intent.icon_state = "help" + hud_used.action_intent.icon_state = I_HELP proc/is_blind(A) if(istype(A, /mob/living/carbon)) @@ -547,3 +593,16 @@ proc/is_blind(A) say_dead_direct("The ghost of [name] now [pick("skulks","lurks","prowls","creeps","stalks")] among the dead. [message]") else say_dead_direct("[name] no longer [pick("skulks","lurks","prowls","creeps","stalks")] in the realm of the dead. [message]") + +/mob/proc/switch_to_camera(var/obj/machinery/camera/C) + if (!C.can_use() || stat || (get_dist(C, src) > 1 || machine != src || blinded || !canmove)) + return 0 + check_eye(src) + return 1 + +/mob/living/silicon/ai/switch_to_camera(var/obj/machinery/camera/C) + if(!C.can_use() || !is_in_chassis()) + return 0 + + eyeobj.setLoc(C) + return 1 diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 6dd04d3ca5..6e7c789c35 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -188,9 +188,9 @@ if(mob.stat==2) return - // handle possible AI movement - if(isAI(mob)) - return AIMove(n,direct,mob) + // handle possible Eye movement + if(mob.eyeobj) + return mob.EyeMove(n,direct) if(mob.monkeyizing) return//This is sota the goto stop mobs from moving var @@ -284,9 +284,9 @@ if(mob.pulledby || mob.buckled) // Wheelchair driving! if(istype(mob.loc, /turf/space)) return // No wheelchair driving in space - if(istype(mob.pulledby, /obj/structure/stool/bed/chair/wheelchair)) + if(istype(mob.pulledby, /obj/structure/bed/chair/wheelchair)) return mob.pulledby.relaymove(mob, direct) - else if(istype(mob.buckled, /obj/structure/stool/bed/chair/wheelchair)) + else if(istype(mob.buckled, /obj/structure/bed/chair/wheelchair)) if(ishuman(mob.buckled)) var/mob/living/carbon/human/driver = mob.buckled var/datum/organ/external/l_hand = driver.get_organ("l_hand") @@ -351,30 +351,13 @@ ///Process_Grab() ///Called by client/Move() -///Checks to see if you are being grabbed and if so attemps to break it +///Checks to see if you are grabbing anything and if moving will affect your grab. /client/proc/Process_Grab() - if(locate(/obj/item/weapon/grab, locate(/obj/item/weapon/grab, mob.grabbed_by.len))) - var/list/grabbing = list() - if(istype(mob.l_hand, /obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = mob.l_hand - grabbing += G.affecting - if(istype(mob.r_hand, /obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = mob.r_hand - grabbing += G.affecting - for(var/obj/item/weapon/grab/G in mob.grabbed_by) - if((G.state == 1)&&(!grabbing.Find(G.assailant))) del(G) - if(G.state == 2) - move_delay = world.time + 10 - if(!prob(25)) return 1 - mob.visible_message("\red [mob] has broken free of [G.assailant]'s grip!") - del(G) - if(G.state == 3) - move_delay = world.time + 10 - if(!prob(5)) return 1 - mob.visible_message("\red [mob] has broken free of [G.assailant]'s headlock!") - del(G) - return 0 - + for(var/obj/item/weapon/grab/G in list(mob.l_hand, mob.r_hand)) + if(G.state == GRAB_KILL) //no wandering across the station/asteroid while choking someone + mob.visible_message("[mob] lost \his tight grip on [G.affecting]'s neck!") + G.hud.icon_state = "disarm/kill" + G.state = GRAB_NECK ///Process_Incorpmove ///Called by client/Move() @@ -470,23 +453,18 @@ if(istype(turf,/turf/space)) continue - if(istype(src,/mob/living/carbon/human/)) // Only humans can wear magboots, so we give them a chance to. - var/mob/living/carbon/human/H = src - if((istype(turf,/turf/simulated/floor)) && (src.lastarea.has_gravity == 0) && !(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP))) - continue + if(istype(turf,/turf/simulated/floor)) // Floors don't count if they don't have gravity + var/area/A = turf.loc + if(istype(A) && A.has_gravity == 0) + var/can_walk = 0 + if(ishuman(src)) // Only humans can wear magboots, so we give them a chance to. + var/mob/living/carbon/human/H = src + if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP)) + can_walk = 1 - else - if((istype(turf,/turf/simulated/floor)) && (src.lastarea.has_gravity == 0)) // No one else gets a chance. - continue - - - - /* - if(istype(turf,/turf/simulated/floor) && (src.flags & NOGRAV)) - continue - */ - + if(!can_walk) + continue dense_object++ break diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index a07e538e1e..90e201b382 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -284,7 +284,7 @@ proc/IsJobAvailable(rank) var/datum/job/job = job_master.GetJob(rank) if(!job) return 0 - if((job.current_positions >= job.total_positions) && job.total_positions != -1) return 0 + if(!job.is_position_available()) return 0 if(jobban_isbanned(src,rank)) return 0 if(!job.player_old_enough(src.client)) return 0 return 1 @@ -313,6 +313,24 @@ UpdateFactionList(character) EquipCustomItems(character) + // AIs don't need a spawnpoint, they must spawn at an empty core + if(character.mind.assigned_role == "AI") + + character = character.AIize(move=0) // AIize the character, but don't move them yet + + // IsJobAvailable for AI checks that there is an empty core available in this list + var/obj/structure/AIcore/deactivated/C = empty_playable_ai_cores[1] + empty_playable_ai_cores -= C + + character.loc = C.loc + + AnnounceCyborg(character, rank, "has been downloaded to the empty core in \the [character.loc.loc]") + ticker.mode.latespawn(character) + + del(C) + del(src) + return + //Find our spawning point. var/join_message var/datum/spawnpoint/S @@ -334,14 +352,12 @@ character.lastarea = get_area(loc) // Moving wheelchair if they have one - if(character.buckled && istype(character.buckled, /obj/structure/stool/bed/chair/wheelchair)) + if(character.buckled && istype(character.buckled, /obj/structure/bed/chair/wheelchair)) character.buckled.loc = character.loc character.buckled.set_dir(character.dir) ticker.mode.latespawn(character) - //ticker.mode.latespawn(character) - if(character.mind.assigned_role != "Cyborg") data_core.manifest_inject(character) ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn @@ -356,20 +372,16 @@ proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank, var/join_message) if (ticker.current_state == GAME_STATE_PLAYING) - var/obj/item/device/radio/intercom/a = new /obj/item/device/radio/intercom(null)// BS12 EDIT Arrivals Announcement Computer, rather than the AI. if(character.mind.role_alt_title) rank = character.mind.role_alt_title - a.autosay("[character.real_name],[rank ? " [rank]," : " visitor," ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer") - del(a) + global_announcer.autosay("[character.real_name],[rank ? " [rank]," : " visitor," ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer") proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message) if (ticker.current_state == GAME_STATE_PLAYING) - var/obj/item/device/radio/intercom/a = new /obj/item/device/radio/intercom(null)// BS12 EDIT Arrivals Announcement Computer, rather than the AI. if(character.mind.role_alt_title) rank = character.mind.role_alt_title // can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc. - a.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer") - del(a) + global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer") proc/LateChoices() var/mills = world.time // 1/10 of a second, not real milliseconds but whatever diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 33ecd0314f..bc17680e0c 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -240,12 +240,12 @@ datum/preferences eyes_s.Blend(facial_s, ICON_OVERLAY) var/icon/underwear_s = null - if(underwear > 0 && underwear < 7 && current_species.flags & HAS_UNDERWEAR) - underwear_s = new/icon("icon" = 'icons/mob/human.dmi', "icon_state" = "underwear[underwear]_[g]_s") + if(underwear && current_species.flags & HAS_UNDERWEAR) + underwear_s = new/icon("icon" = 'icons/mob/human.dmi', "icon_state" = underwear) var/icon/undershirt_s = null - if(undershirt > 0 && undershirt < 5 && current_species.flags & HAS_UNDERWEAR) - undershirt_s = new/icon("icon" = 'icons/mob/human.dmi', "icon_state" = "undershirt[undershirt]_s") + if(undershirt && current_species.flags & HAS_UNDERWEAR) + undershirt_s = new/icon("icon" = 'icons/mob/human.dmi', "icon_state" = undershirt) var/icon/clothes_s = null if(job_civilian_low & ASSISTANT)//This gives the preview icon clothes depending on which job(if any) is set to 'high' @@ -375,7 +375,7 @@ datum/preferences if(LAWYER) clothes_s = new /icon('icons/mob/uniform.dmi', "internalaffairs_s") clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY) - clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "briefcase"), ICON_UNDERLAY) + clothes_s.Blend(new /icon(INV_R_HAND_DEF_ICON, "briefcase"), ICON_UNDERLAY) if(prob(1)) clothes_s.Blend(new /icon('icons/mob/suit.dmi', "suitjacket_blue"), ICON_OVERLAY) switch(backbag) @@ -534,7 +534,7 @@ datum/preferences clothes_s.Blend(new /icon('icons/mob/hands.dmi', "bgloves"), ICON_UNDERLAY) clothes_s.Blend(new /icon('icons/mob/suit.dmi', "labcoat_open"), ICON_OVERLAY) if(prob(1)) - clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "toolbox_blue"), ICON_OVERLAY) + clothes_s.Blend(new /icon(INV_R_HAND_DEF_ICON, "toolbox_blue"), ICON_OVERLAY) switch(backbag) if(2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "backpack"), ICON_OVERLAY) @@ -620,7 +620,7 @@ datum/preferences clothes_s.Blend(new /icon('icons/mob/belt.dmi', "utility"), ICON_OVERLAY) clothes_s.Blend(new /icon('icons/mob/head.dmi', "hardhat0_white"), ICON_OVERLAY) if(prob(1)) - clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "blueprints"), ICON_OVERLAY) + clothes_s.Blend(new /icon(INV_R_HAND_DEF_ICON, "blueprints"), ICON_OVERLAY) switch(backbag) if(2) clothes_s.Blend(new /icon('icons/mob/back.dmi', "engiepack"), ICON_OVERLAY) diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 998c241498..899d0a9c9b 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -36,7 +36,7 @@ usr << "\red Speech is currently admin-disabled." return - message = strip_html_properly(message) + message = sanitize(message) set_typing_indicator(0) if(use_me) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index b4530b0767..958f0b982a 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -21,48 +21,37 @@ sleep(48) //animation = null - if(!species.primitive) //If the creature in question has no primitive set, this is going to be messy. + monkeyizing = 0 + stunned = 0 + update_canmove() + invisibility = initial(invisibility) + + if(!species.primitive_form) //If the creature in question has no primitive set, this is going to be messy. gib() return - var/mob/living/carbon/monkey/O = null + for(var/obj/item/W in src) + drop_from_inventory(W) + set_species(species.primitive_form) + dna.SetSEState(MONKEYBLOCK,1) + dna.SetSEValueRange(MONKEYBLOCK,0xDAC, 0xFFF) - O = new species.primitive(loc) - - O.dna = dna.Clone() - O.dna.SetSEState(MONKEYBLOCK,1) - O.dna.SetSEValueRange(MONKEYBLOCK,0xDAC, 0xFFF) - O.loc = loc - O.viruses = viruses - O.a_intent = "hurt" - - for(var/datum/disease/D in O.viruses) - D.affected_mob = O - - if (client) - client.mob = O - if(mind) - mind.transfer_to(O) - - O << "You are now [O]. " - - spawn(0)//To prevent the proc from returning null. - del(src) + src << "You are now [species.name]. " del(animation) - return O + return src /mob/new_player/AIize() spawning = 1 return ..() -/mob/living/carbon/human/AIize() +/mob/living/carbon/human/AIize(move=1) // 'move' argument needs defining here too because BYOND is dumb if (monkeyizing) return for(var/t in organs) del(t) - return ..() + return ..(move) /mob/living/carbon/AIize() if (monkeyizing) @@ -75,7 +64,7 @@ invisibility = 101 return ..() -/mob/proc/AIize() +/mob/proc/AIize(move=1) if(client) src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // stop the jams for AIs var/mob/living/silicon/ai/O = new (loc, base_law_type,,1)//No MMI but safety is in effect. @@ -88,37 +77,38 @@ else O.key = key - var/obj/loc_landmark - for(var/obj/effect/landmark/start/sloc in landmarks_list) - if (sloc.name != "AI") - continue - if (locate(/mob/living) in sloc.loc) - continue - loc_landmark = sloc - if (!loc_landmark) - for(var/obj/effect/landmark/tripai in landmarks_list) - if (tripai.name == "tripai") - if(locate(/mob/living) in tripai.loc) - continue - loc_landmark = tripai - if (!loc_landmark) - O << "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone." + if(move) + var/obj/loc_landmark for(var/obj/effect/landmark/start/sloc in landmarks_list) - if (sloc.name == "AI") - loc_landmark = sloc + if (sloc.name != "AI") + continue + if ((locate(/mob/living) in sloc.loc) || (locate(/obj/structure/AIcore) in sloc.loc)) + continue + loc_landmark = sloc + if (!loc_landmark) + for(var/obj/effect/landmark/tripai in landmarks_list) + if (tripai.name == "tripai") + if((locate(/mob/living) in tripai.loc) || (locate(/obj/structure/AIcore) in tripai.loc)) + continue + loc_landmark = tripai + if (!loc_landmark) + O << "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone." + for(var/obj/effect/landmark/start/sloc in landmarks_list) + if (sloc.name == "AI") + loc_landmark = sloc - O.loc = loc_landmark.loc - for (var/obj/item/device/radio/intercom/comm in O.loc) - comm.ai += O + O.loc = loc_landmark.loc + for (var/obj/item/device/radio/intercom/comm in O.loc) + comm.ai += O O.on_mob_init() O.add_ai_verbs() O.rename_self("ai",1) - . = O - del(src) - + spawn(0) + del(src) + return O //human -> robot /mob/living/carbon/human/proc/Robotize() @@ -167,7 +157,6 @@ O.mmi.transfer_identity(src) callHook("borgify", list(O)) - O.notify_ai(1) O.Namepick() spawn(0)//To prevent the proc from returning null. @@ -191,7 +180,7 @@ var/alien_caste = pick("Hunter","Sentinel","Drone") var/mob/living/carbon/human/new_xeno = create_new_xenomorph(alien_caste,loc) - new_xeno.a_intent = "hurt" + new_xeno.a_intent = I_HURT new_xeno.key = key new_xeno << "You are now an alien." @@ -248,7 +237,7 @@ del(t) var/mob/living/simple_animal/corgi/new_corgi = new /mob/living/simple_animal/corgi (loc) - new_corgi.a_intent = "hurt" + new_corgi.a_intent = I_HURT new_corgi.key = key new_corgi << "You are now a Corgi. Yap Yap!" @@ -282,7 +271,7 @@ var/mob/new_mob = new mobpath(src.loc) new_mob.key = key - new_mob.a_intent = "hurt" + new_mob.a_intent = I_HURT new_mob << "You suddenly feel more... animalistic." @@ -302,7 +291,7 @@ var/mob/new_mob = new mobpath(src.loc) new_mob.key = key - new_mob.a_intent = "hurt" + new_mob.a_intent = I_HURT new_mob << "You feel more... animalistic" del(src) diff --git a/code/modules/mob/update_icons.dm b/code/modules/mob/update_icons.dm index a6ae6dc4a0..480c4be322 100644 --- a/code/modules/mob/update_icons.dm +++ b/code/modules/mob/update_icons.dm @@ -1,6 +1,11 @@ //Most of these are defined at this level to reduce on checks elsewhere in the code. //Having them here also makes for a nice reference list of the various overlay-updating procs available +//default item on-mob icons +#define INV_L_HAND_DEF_ICON 'icons/mob/items/lefthand.dmi' +#define INV_R_HAND_DEF_ICON 'icons/mob/items/righthand.dmi' + + /mob/proc/regenerate_icons() //TODO: phase this out completely if possible return diff --git a/code/modules/nano/modules/alarm_monitor.dm b/code/modules/nano/modules/alarm_monitor.dm new file mode 100644 index 0000000000..9047023bf1 --- /dev/null +++ b/code/modules/nano/modules/alarm_monitor.dm @@ -0,0 +1,96 @@ +/obj/nano_module/alarm_monitor + name = "Alarm monitor" + var/list_cameras = 0 // Whether or not to list camera references. A future goal would be to merge this with the enginering/security camera console. Currently really only for AI-use. + var/list/datum/alarm_handler/alarm_handlers // The particular list of alarm handlers this alarm monitor should present to the user. + +/obj/nano_module/alarm_monitor/ai + list_cameras = 1 + +/obj/nano_module/alarm_monitor/ai/New() + ..() + alarm_handlers = alarm_manager.all_handlers + +/obj/nano_module/alarm_monitor/borg/New() + ..() + alarm_handlers = alarm_manager.all_handlers + +/obj/nano_module/alarm_monitor/engineering/New() + ..() + alarm_handlers = list(atmosphere_alarm, fire_alarm, power_alarm) + +/obj/nano_module/alarm_monitor/security/New() + ..() + alarm_handlers = list(camera_alarm, motion_alarm) + +/obj/nano_module/alarm_monitor/proc/register(var/object, var/procName) + for(var/datum/alarm_handler/AH in alarm_handlers) + AH.register(object, procName) + +/obj/nano_module/alarm_monitor/proc/unregister(var/object) + for(var/datum/alarm_handler/AH in alarm_handlers) + AH.unregister(object) + +/obj/nano_module/alarm_monitor/proc/all_alarms() + var/list/all_alarms = new() + for(var/datum/alarm_handler/AH in alarm_handlers) + all_alarms += AH.alarms + + return all_alarms + +/obj/nano_module/alarm_monitor/proc/major_alarms() + var/list/all_alarms = new() + for(var/datum/alarm_handler/AH in alarm_handlers) + all_alarms += AH.major_alarms() + + return all_alarms + +/obj/nano_module/alarm_monitor/proc/minor_alarms() + var/list/all_alarms = new() + for(var/datum/alarm_handler/AH in alarm_handlers) + all_alarms += AH.minor_alarms() + + return all_alarms + +/obj/nano_module/alarm_monitor/ai/Topic(ref, href_list) + if(..()) + return 1 + if(href_list["switchTo"]) + var/obj/machinery/camera/C = locate(href_list["switchTo"]) in cameranet.cameras + if(!C) + + return + + usr.switch_to_camera(C) + return 1 + +/obj/nano_module/alarm_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + var/data[0] + + var/categories[0] + for(var/datum/alarm_handler/AH in alarm_handlers) + categories[++categories.len] = list("category" = AH.category, "alarms" = list()) + for(var/datum/alarm/A in AH.major_alarms()) + var/cameras[0] + var/lost_sources[0] + + if(list_cameras) + for(var/obj/machinery/camera/C in A.cameras()) + cameras[++cameras.len] = C.nano_structure() + for(var/datum/alarm_source/AS in A.sources) + if(!AS.source) + lost_sources[++lost_sources.len] = AS.source_name + + categories[categories.len]["alarms"] += list(list( + "name" = sanitize(A.alarm_name()), + "origin_lost" = A.origin == null, + "has_cameras" = cameras.len, + "cameras" = cameras, + "lost_sources" = sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")))) + data["categories"] = categories + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "alarm_monitor.tmpl", "Alarm Monitoring Console", 800, 800) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) diff --git a/code/modules/nano/modules/crew_monitor.dm b/code/modules/nano/modules/crew_monitor.dm new file mode 100644 index 0000000000..bb60182a1b --- /dev/null +++ b/code/modules/nano/modules/crew_monitor.dm @@ -0,0 +1,96 @@ +/obj/nano_module/crew_monitor + name = "Crew monitor" + var/list/tracked = new + +/obj/nano_module/crew_monitor/Topic(href, href_list) + if(..()) return + var/turf/T = get_turf(src) + if (!T || !(T.z in config.player_levels)) + usr << "Unable to establish a connection: You're too far away from the station!" + return 0 + if(href_list["close"] ) + var/mob/user = usr + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") + usr.unset_machine() + ui.close() + return 0 + if(href_list["update"]) + src.updateDialog() + return 1 + if(href_list["track"]) + if(usr.isAI()) + var/mob/living/silicon/ai/AI = usr + var/mob/living/carbon/human/H = locate(href_list["track"]) in mob_list + if(hassensorlevel(H, SUIT_SENSOR_TRACKING)) + AI.ai_actual_track(H) + return 1 + +/obj/nano_module/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + user.set_machine(src) + src.scan() + + var/data[0] + var/turf/T = get_turf(src) + var/list/crewmembers = list() + for(var/obj/item/clothing/under/C in src.tracked) + + var/turf/pos = get_turf(C) + + if((C) && (C.has_sensor) && (pos) && (T && pos.z == T.z) && (C.sensor_mode != SUIT_SENSOR_OFF)) + if(istype(C.loc, /mob/living/carbon/human)) + + var/mob/living/carbon/human/H = C.loc + if(H.w_uniform != C) + continue + + var/list/crewmemberData = list("dead"=0, "oxy"=-1, "tox"=-1, "fire"=-1, "brute"=-1, "area"="", "x"=-1, "y"=-1, "ref" = "\ref[H]") + + crewmemberData["sensor_type"] = C.sensor_mode + crewmemberData["name"] = H.get_authentification_name(if_no_id="Unknown") + crewmemberData["rank"] = H.get_authentification_rank(if_no_id="Unknown", if_no_job="No Job") + crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job") + + if(C.sensor_mode >= SUIT_SENSOR_BINARY) + crewmemberData["dead"] = H.stat > 1 + + if(C.sensor_mode >= SUIT_SENSOR_VITAL) + crewmemberData["oxy"] = round(H.getOxyLoss(), 1) + crewmemberData["tox"] = round(H.getToxLoss(), 1) + crewmemberData["fire"] = round(H.getFireLoss(), 1) + crewmemberData["brute"] = round(H.getBruteLoss(), 1) + + if(C.sensor_mode >= SUIT_SENSOR_TRACKING) + var/area/A = get_area(H) + crewmemberData["area"] = sanitize(A.name) + crewmemberData["x"] = pos.x + crewmemberData["y"] = pos.y + + crewmembers[++crewmembers.len] = crewmemberData + + crewmembers = sortByKey(crewmembers, "name") + + data["isAI"] = user.isAI() + data["crewmembers"] = crewmembers + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800) + + // adding a template with the key "mapContent" enables the map ui functionality + ui.add_template("mapContent", "crew_monitor_map_content.tmpl") + // adding a template with the key "mapHeader" replaces the map header content + ui.add_template("mapHeader", "crew_monitor_map_header.tmpl") + + ui.set_initial_data(data) + ui.open() + + // should make the UI auto-update; doesn't seem to? + ui.set_auto_update(1) + +/obj/nano_module/crew_monitor/proc/scan() + for(var/mob/living/carbon/human/H in mob_list) + if(istype(H.w_uniform, /obj/item/clothing/under)) + var/obj/item/clothing/under/C = H.w_uniform + if (C.has_sensor) + tracked |= C + return 1 diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm new file mode 100644 index 0000000000..be2259d618 --- /dev/null +++ b/code/modules/nano/modules/human_appearance.dm @@ -0,0 +1,160 @@ +/obj/nano_module/appearance_changer + name = "Appearance Editor" + flags = APPEARANCE_ALL_HAIR + var/mob/living/carbon/human/owner = null + var/list/valid_species = list() + var/list/valid_hairstyles = list() + var/list/valid_facial_hairstyles = list() + + var/check_whitelist + var/list/whitelist + var/list/blacklist + +/obj/nano_module/appearance_changer/New(var/location, var/mob/living/carbon/human/H, var/check_species_whitelist = 1, var/list/species_whitelist = list(), var/list/species_blacklist = list()) + ..() + loc = location + owner = H + src.check_whitelist = check_species_whitelist + src.whitelist = species_whitelist + src.blacklist = species_blacklist + +/obj/nano_module/appearance_changer/Topic(ref, href_list) + if(..()) + return 1 + + if(href_list["race"]) + if(can_change(APPEARANCE_RACE) && (href_list["race"] in valid_species)) + if(owner.change_species(href_list["race"])) + cut_and_generate_data() + return 1 + if(href_list["gender"]) + if(can_change(APPEARANCE_GENDER)) + if(owner.change_gender(href_list["gender"])) + cut_and_generate_data() + return 1 + if(href_list["skin_tone"]) + if(can_change_skin_tone()) + var/new_s_tone = input(usr, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Skin Tone", owner.s_tone) as num|null + if(isnum(new_s_tone) && CanUseTopic(usr) == STATUS_INTERACTIVE) + new_s_tone = 35 - max(min( round(new_s_tone), 220),1) + return owner.change_skin_tone(new_s_tone) + if(href_list["skin_color"]) + if(can_change_skin_color()) + var/new_skin = input(usr, "Choose your character's skin colour: ", "Skin Color", rgb(owner.r_skin, owner.g_skin, owner.b_skin)) as color|null + if(new_skin && can_still_topic()) + var/r_skin = hex2num(copytext(new_skin, 2, 4)) + var/g_skin = hex2num(copytext(new_skin, 4, 6)) + var/b_skin = hex2num(copytext(new_skin, 6, 8)) + if(owner.change_skin_color(r_skin, g_skin, b_skin)) + update_dna() + return 1 + if(href_list["hair"]) + if(can_change(APPEARANCE_HAIR) && (href_list["hair"] in valid_hairstyles)) + if(owner.change_hair(href_list["hair"])) + update_dna() + return 1 + if(href_list["hair_color"]) + if(can_change(APPEARANCE_HAIR_COLOR)) + var/new_hair = input("Please select hair color.", "Hair Color", rgb(owner.r_hair, owner.g_hair, owner.b_hair)) as color|null + if(new_hair && can_still_topic()) + var/r_hair = hex2num(copytext(new_hair, 2, 4)) + var/g_hair = hex2num(copytext(new_hair, 4, 6)) + var/b_hair = hex2num(copytext(new_hair, 6, 8)) + if(owner.change_hair_color(r_hair, g_hair, b_hair)) + update_dna() + return 1 + if(href_list["facial_hair"]) + if(can_change(APPEARANCE_FACIAL_HAIR) && (href_list["facial_hair"] in valid_facial_hairstyles)) + if(owner.change_facial_hair(href_list["facial_hair"])) + update_dna() + return 1 + if(href_list["facial_hair_color"]) + if(can_change(APPEARANCE_FACIAL_HAIR_COLOR)) + var/new_facial = input("Please select facial hair color.", "Facial Hair Color", rgb(owner.r_facial, owner.g_facial, owner.b_facial)) as color|null + if(new_facial && can_still_topic()) + var/r_facial = hex2num(copytext(new_facial, 2, 4)) + var/g_facial = hex2num(copytext(new_facial, 4, 6)) + var/b_facial = hex2num(copytext(new_facial, 6, 8)) + if(owner.change_facial_hair_color(r_facial, g_facial, b_facial)) + update_dna() + return 1 + if(href_list["eye_color"]) + if(can_change(APPEARANCE_EYE_COLOR)) + var/new_eyes = input("Please select eye color.", "Eye Color", rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes)) as color|null + if(new_eyes && can_still_topic()) + var/r_eyes = hex2num(copytext(new_eyes, 2, 4)) + var/g_eyes = hex2num(copytext(new_eyes, 4, 6)) + var/b_eyes = hex2num(copytext(new_eyes, 6, 8)) + if(owner.change_eye_color(r_eyes, g_eyes, b_eyes)) + update_dna() + return 1 + + return 0 + +/obj/nano_module/appearance_changer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + generate_data(check_whitelist, whitelist, blacklist) + var/data[0] + + data["specimen"] = owner.species.name + data["gender"] = owner.gender + data["change_race"] = can_change(APPEARANCE_RACE) + if(data["change_race"]) + var/species[0] + for(var/specimen in valid_species) + species[++species.len] = list("specimen" = specimen) + data["species"] = species + + data["change_gender"] = can_change(APPEARANCE_GENDER) + data["change_skin_tone"] = can_change_skin_tone() + data["change_skin_color"] = can_change_skin_color() + data["change_eye_color"] = can_change(APPEARANCE_EYE_COLOR) + data["change_hair"] = can_change(APPEARANCE_HAIR) + if(data["change_hair"]) + var/hair_styles[0] + for(var/hair_style in valid_hairstyles) + hair_styles[++hair_styles.len] = list("hairstyle" = hair_style) + data["hair_styles"] = hair_styles + data["hair_style"] = owner.h_style + + data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR) + if(data["change_facial_hair"]) + var/facial_hair_styles[0] + for(var/facial_hair_style in valid_facial_hairstyles) + facial_hair_styles[++facial_hair_styles.len] = list("facialhairstyle" = facial_hair_style) + data["facial_hair_styles"] = facial_hair_styles + data["facial_hair_style"] = owner.f_style + + data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR) + data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR) + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "appearance_changer.tmpl", "[src.name]", 800, 450) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/obj/nano_module/appearance_changer/proc/update_dna() + if(owner && (flags & APPEARANCE_UPDATE_DNA)) + owner.update_dna() + +/obj/nano_module/appearance_changer/proc/can_change(var/flag) + return owner && (flags & flag) + +/obj/nano_module/appearance_changer/proc/can_change_skin_tone() + return owner && (flags & APPEARANCE_SKIN) && owner.species.flags & HAS_SKIN_TONE + +/obj/nano_module/appearance_changer/proc/can_change_skin_color() + return owner && (flags & APPEARANCE_SKIN) && owner.species.flags & HAS_SKIN_COLOR + +/obj/nano_module/appearance_changer/proc/cut_and_generate_data() + // Making the assumption that the available species remain constant + valid_facial_hairstyles.Cut() + valid_facial_hairstyles.Cut() + generate_data() + +/obj/nano_module/appearance_changer/proc/generate_data() + if(!valid_species.len) + valid_species = owner.generate_valid_species(check_whitelist, whitelist, blacklist) + if(!valid_hairstyles.len || !valid_facial_hairstyles.len) + valid_hairstyles = owner.generate_valid_hairstyles() + valid_facial_hairstyles = owner.generate_valid_facial_hairstyles() \ No newline at end of file diff --git a/code/modules/nano/modules/law_manager.dm b/code/modules/nano/modules/law_manager.dm new file mode 100644 index 0000000000..4f81585a04 --- /dev/null +++ b/code/modules/nano/modules/law_manager.dm @@ -0,0 +1,239 @@ +/obj/nano_module/law_manager + name = "Law manager" + + var/ion_law = "IonLaw" + var/zeroth_law = "ZerothLaw" + var/inherent_law = "InherentLaw" + var/supplied_law = "SuppliedLaw" + var/supplied_law_position = MIN_SUPPLIED_LAW_NUMBER + + var/current_view = 0 + + var/global/list/datum/ai_laws/admin_laws + var/global/list/datum/ai_laws/player_laws + var/mob/living/silicon/owner = null + +/obj/nano_module/law_manager/New(var/mob/living/silicon/S) + ..() + loc = S + owner = S + + if(!admin_laws) + admin_laws = new() + player_laws = new() + + init_subtypes(/datum/ai_laws, admin_laws) + admin_laws = dd_sortedObjectList(admin_laws) + + for(var/datum/ai_laws/laws in admin_laws) + if(laws.selectable) + player_laws += laws + +/obj/nano_module/law_manager/Topic(href, href_list) + if(..()) + return 1 + + if(href_list["set_view"]) + if(is_malf(usr) || owner.is_ai_malf()) + current_view = text2num(href_list["set_view"]) + else + current_view = 0 + return 1 + + if(href_list["law_channel"]) + if(href_list["law_channel"] in owner.law_channels()) + owner.lawchannel = href_list["law_channel"] + return 1 + + if(href_list["state_law"]) + var/datum/ai_law/AL = locate(href_list["ref"]) in owner.laws.all_laws() + if(AL) + var/state_law = text2num(href_list["state_law"]) + owner.laws.set_state_law(AL, state_law) + return 1 + + if(href_list["add_zeroth_law"]) + if(zeroth_law && is_admin(usr) && !owner.laws.zeroth_law) + owner.set_zeroth_law(zeroth_law) + return 1 + + if(href_list["add_ion_law"]) + if(ion_law && is_malf(usr)) + owner.add_ion_law(ion_law) + return 1 + + if(href_list["add_inherent_law"]) + if(inherent_law && is_malf(usr)) + owner.add_inherent_law(inherent_law) + return 1 + + if(href_list["add_supplied_law"]) + if(supplied_law && supplied_law_position >= 1 && MIN_SUPPLIED_LAW_NUMBER <= MAX_SUPPLIED_LAW_NUMBER && is_malf(usr)) + owner.add_supplied_law(supplied_law_position, supplied_law) + return 1 + + if(href_list["change_zeroth_law"]) + var/new_law = sanitize(input("Enter new law Zero. Leaving the field blank will cancel the edit.", "Edit Law", zeroth_law)) + if(new_law && new_law != zeroth_law && can_still_topic()) + zeroth_law = new_law + return 1 + + if(href_list["change_ion_law"]) + var/new_law = sanitize(input("Enter new ion law. Leaving the field blank will cancel the edit.", "Edit Law", ion_law)) + if(new_law && new_law != ion_law && can_still_topic()) + ion_law = new_law + return 1 + + if(href_list["change_inherent_law"]) + var/new_law = sanitize(input("Enter new inherent law. Leaving the field blank will cancel the edit.", "Edit Law", inherent_law)) + if(new_law && new_law != inherent_law && can_still_topic()) + inherent_law = new_law + return 1 + + if(href_list["change_supplied_law"]) + var/new_law = sanitize(input("Enter new supplied law. Leaving the field blank will cancel the edit.", "Edit Law", supplied_law)) + if(new_law && new_law != supplied_law && can_still_topic()) + supplied_law = new_law + return 1 + + if(href_list["change_supplied_law_position"]) + var/new_position = input(usr, "Enter new supplied law position between 1 and [MAX_SUPPLIED_LAW_NUMBER], inclusive. Inherent laws at the same index as a supplied law will not be stated.", "Law Position", supplied_law_position) as num|null + if(isnum(new_position) && can_still_topic()) + supplied_law_position = Clamp(new_position, 1, MAX_SUPPLIED_LAW_NUMBER) + return 1 + + if(href_list["edit_law"]) + if(is_malf(usr)) + var/datum/ai_law/AL = locate(href_list["edit_law"]) in owner.laws.all_laws() + if(AL) + var/new_law = sanitize(input(usr, "Enter new law. Leaving the field blank will cancel the edit.", "Edit Law", AL.law)) + if(new_law && new_law != AL.law && is_malf(usr) && can_still_topic()) + log_and_message_admins("has changed a law of [owner] from '[AL.law]' to '[new_law]'") + AL.law = new_law + return 1 + + if(href_list["delete_law"]) + if(is_malf(usr)) + var/datum/ai_law/AL = locate(href_list["delete_law"]) in owner.laws.all_laws() + if(AL && is_malf(usr)) + owner.delete_law(AL) + return 1 + + if(href_list["state_laws"]) + owner.statelaws(owner.laws) + return 1 + + if(href_list["state_law_set"]) + var/datum/ai_laws/ALs = locate(href_list["state_law_set"]) in (is_admin(usr) ? admin_laws : player_laws) + if(ALs) + owner.statelaws(ALs) + return 1 + + if(href_list["transfer_laws"]) + if(is_malf(usr)) + var/datum/ai_laws/ALs = locate(href_list["transfer_laws"]) in (is_admin(usr) ? admin_laws : player_laws) + if(ALs) + log_and_message_admins("has transfered the [ALs.name] laws to [owner].") + ALs.sync(owner, 0) + current_view = 0 + return 1 + + if(href_list["notify_laws"]) + owner << "Law Notice" + owner.laws.show_laws(owner) + if(owner.isAI()) + var/mob/living/silicon/ai/AI = owner + for(var/mob/living/silicon/robot/R in AI.connected_robots) + R << "Law Notice" + R.laws.show_laws(R) + if(usr != owner) + usr << "

    Medical Record

    " - P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]]
    \nSex: [G.fields["sex"]]
    \nAge: [G.fields["age"]]
    \nFingerprint: [G.fields["fingerprint"]]
    \nPhysical Status: [G.fields["p_stat"]]
    \nMental Status: [G.fields["m_stat"]]
    " - P.info += "
    \n
    Medical Data

    \nBlood Type: [M.fields["b_type"]]
    \nDNA: [M.fields["b_dna"]]
    \n
    \nMinor Disabilities: [M.fields["mi_dis"]]
    \nDetails: [M.fields["mi_dis_d"]]
    \n
    \nMajor Disabilities: [M.fields["ma_dis"]]
    \nDetails: [M.fields["ma_dis_d"]]
    \n
    \nAllergies: [M.fields["alg"]]
    \nDetails: [M.fields["alg_d"]]
    \n
    \nCurrent Diseases: [M.fields["cdi"]] (per disease info placed in log/comment section)
    \nDetails: [M.fields["cdi_d"]]
    \n
    \nImportant Notes:
    \n\t[M.fields["notes"]]
    \n
    \n
    Comments/Log

    " - var/counter = 1 - while(M.fields["com_[counter]"]) - P.info += "[M.fields["com_[counter]"]]
    " - counter++ - P.info += "" - P.name = "Medical Record ([G.fields["name"]])" + if(M) + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(src) + P.info = "
    Medical Record

    " + P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]]
    \nSex: [G.fields["sex"]]
    \nAge: [G.fields["age"]]
    \nFingerprint: [G.fields["fingerprint"]]
    \nPhysical Status: [G.fields["p_stat"]]
    \nMental Status: [G.fields["m_stat"]]
    " + + P.info += "
    \n
    Medical Data

    \nBlood Type: [M.fields["b_type"]]
    \nDNA: [M.fields["b_dna"]]
    \n
    \nMinor Disabilities: [M.fields["mi_dis"]]
    \nDetails: [M.fields["mi_dis_d"]]
    \n
    \nMajor Disabilities: [M.fields["ma_dis"]]
    \nDetails: [M.fields["ma_dis_d"]]
    \n
    \nAllergies: [M.fields["alg"]]
    \nDetails: [M.fields["alg_d"]]
    \n
    \nCurrent Diseases: [M.fields["cdi"]] (per disease info placed in log/comment section)
    \nDetails: [M.fields["cdi_d"]]
    \n
    \nImportant Notes:
    \n\t[M.fields["notes"]]
    \n
    \n
    Comments/Log

    " + var/counter = 1 + while(M.fields["com_[counter]"]) + P.info += "[M.fields["com_[counter]"]]
    " + counter++ + P.info += "" + P.name = "Medical Record ([G.fields["name"]])" virgin = 0 //tabbing here is correct- it's possible for people to try and use it //before the records have been generated, so we do this inside the loop. ..() diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index c004844c50..ddc211cc7c 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -35,7 +35,7 @@ user << "You put the [W] into \the [src]." update_icon() else if(istype(W, /obj/item/weapon/pen)) - var/n_name = sanitize(copytext(input(usr, "What would you like to label the folder?", "Folder Labelling", null) as text, 1, MAX_NAME_LEN)) + var/n_name = sanitizeSafe(input(usr, "What would you like to label the folder?", "Folder Labelling", null) as text, MAX_NAME_LEN) if((loc == usr && usr.stat == 0)) name = "folder[(n_name ? text("- '[n_name]'") : null)]" return diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index fe519e01d4..5006af6cc3 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -6,12 +6,12 @@ var/label = null var/labels_left = 30 var/mode = 0 //off or on. - + /obj/item/weapon/hand_labeler/attack() return /obj/item/weapon/hand_labeler/afterattack(atom/A, mob/user as mob, proximity) - if(!proximity) + if(!proximity) return if(!mode) //if it's off, give up. return @@ -39,6 +39,14 @@ if(istype(A, /obj/item/weapon/reagent_containers/glass)) user << "The label can't stick to the [A.name]. (Try using a pen)" return + if(istype(A, /obj/machinery/portable_atmospherics/hydroponics)) + var/obj/machinery/portable_atmospherics/hydroponics/tray = A + if(!tray.mechanical) + user << "How are you going to label that?" + return + tray.labelled = label + spawn(1) + tray.update_icon() user.visible_message("[user] labels [A] as [label].", \ "You label [A] as [label].") diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index c3a3cfe1ee..758cd78f20 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -23,9 +23,9 @@ var/stamps //The (text for the) stamps on the paper. var/fields //Amount of user created fields var/list/stamped - var/ico[0] //Icons and - var/offset_x[0] //offsets stored for later - var/offset_y[0] //usage by the photocopier + var/list/ico[0] //Icons and + var/list/offset_x[0] //offsets stored for later + var/list/offset_y[0] //usage by the photocopier var/rigged = 0 var/spam_flag = 0 @@ -86,7 +86,7 @@ if((CLUMSY in usr.mutations) && prob(50)) usr << "You cut yourself on the paper." return - var/n_name = sanitize(copytext(input(usr, "What would you like to label the paper?", "Paper Labelling", null) as text, 1, MAX_NAME_LEN)) + var/n_name = sanitizeSafe(input(usr, "What would you like to label the paper?", "Paper Labelling", null) as text, MAX_NAME_LEN) if((loc == usr && usr.stat == 0)) name = "[(n_name ? text("[n_name]") : initial(name))]" if(name != "paper") @@ -324,7 +324,7 @@ if(href_list["write"]) var/id = href_list["write"] //var/t = strip_html_simple(input(usr, "What text do you wish to add to " + (id=="end" ? "the end of the paper" : "field "+id) + "?", "[name]", null),8192) as message - var/t = strip_html_simple(input("Enter what you want to write:", "Write", null, null) as message, MAX_PAPER_MESSAGE_LEN) + var/t = sanitize(input("Enter what you want to write:", "Write", null, null) as message, MAX_PAPER_MESSAGE_LEN, extra = 0) var/obj/item/i = usr.get_active_hand() // Check to see if he still got that darn pen, also check if he's using a crayon or pen. var/iscrayon = 0 if(!istype(i, /obj/item/weapon/pen)) @@ -347,7 +347,7 @@ message_admins("PAPER: [usr] ([usr.ckey]) tried to use forbidden word in [src]: [bad].") return */ - t = html_encode(t) + //t = html_encode(t) t = replacetext(t, "\n", "
    ") t = parsepencode(t, i, usr, iscrayon) // Encode everything from pencode to html diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index 39ad7323ed..dfa5103ec2 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -192,7 +192,7 @@ set category = "Object" set src in usr - var/n_name = sanitize(copytext(input(usr, "What would you like to label the bundle?", "Bundle Labelling", null) as text, 1, MAX_NAME_LEN)) + var/n_name = sanitizeSafe(input(usr, "What would you like to label the bundle?", "Bundle Labelling", null) as text, MAX_NAME_LEN) if((loc == usr && usr.stat == 0)) name = "[(n_name ? text("[n_name]") : "paper")]" add_fingerprint(usr) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 944fd91410..3c3d07b36f 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -130,10 +130,40 @@ if(new_signature) signature = new_signature */ - signature = trim_strip_html_properly(input("Enter new signature. Leave blank for 'Anonymous'", "New Signature", signature)) + signature = sanitize(input("Enter new signature. Leave blank for 'Anonymous'", "New Signature", signature)) /obj/item/weapon/pen/proc/get_signature(var/mob/user) return (user && user.real_name) ? user.real_name : "Anonymous" /obj/item/weapon/pen/chameleon/get_signature(var/mob/user) return signature ? signature : "Anonymous" + +/obj/item/weapon/pen/chameleon/verb/set_colour() + set name = "Change Pen Colour" + set category = "Object" + + var/list/possible_colours = list ("Yellow", "Green", "Pink", "Blue", "Orange", "Cyan", "Red", "Invisible", "Black") + var/selected_type = input("Pick new colour.", "Pen Colour", null, null) as null|anything in possible_colours + + if(selected_type) + switch(selected_type) + if("Yellow") + colour = COLOR_YELLOW + if("Green") + colour = COLOR_GREEN + if("Pink") + colour = COLOR_PINK + if("Blue") + colour = COLOR_BLUE + if("Orange") + colour = COLOR_ORANGE + if("Cyan") + colour = COLOR_CYAN + if("Red") + colour = COLOR_RED + if("Invisible") + colour = COLOR_WHITE + else + colour = COLOR_BLACK + usr << "You select the [lowertext(selected_type)] ink container." + diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 83b27b7a2b..7f0ed21c78 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -175,7 +175,7 @@ c.offset_y = copy.offset_y var/list/temp_overlays = copy.overlays //Iterates through stamps var/image/img //and puts a matching - for (var/j = 1, j <= temp_overlays.len, j++) //gray overlay onto the copy + for (var/j = 1, j <= min(temp_overlays.len, copy.ico.len), j++) //gray overlay onto the copy if (findtext(copy.ico[j], "cap") || findtext(copy.ico[j], "cent")) img = image('icons/obj/bureaucracy.dmi', "paper_stamp-circle") else if (findtext(copy.ico[j], "deny")) diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 34a974064e..24a321ac87 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -43,7 +43,7 @@ var/global/photo_count = 0 /obj/item/weapon/photo/attackby(obj/item/weapon/P as obj, mob/user as mob) if(istype(P, /obj/item/weapon/pen) || istype(P, /obj/item/toy/crayon)) - var/txt = sanitize(copytext(input(user, "What would you like to write on the back?", "Photo Writing", null) as text, 1, 128)) + var/txt = sanitize(input(user, "What would you like to write on the back?", "Photo Writing", null) as text, 128) if(loc == user && user.stat == 0) scribble = txt ..() @@ -70,7 +70,7 @@ var/global/photo_count = 0 set category = "Object" set src in usr - var/n_name = sanitize(copytext(input(usr, "What would you like to label the photo?", "Photo Labelling", null) as text, 1, MAX_NAME_LEN)) + var/n_name = sanitizeSafe(input(usr, "What would you like to label the photo?", "Photo Labelling", null) as text, MAX_NAME_LEN) //loc.loc check is for making possible renaming photos in clipboards if(( (loc == usr || (loc.loc && loc.loc == usr)) && usr.stat == 0)) name = "[(n_name ? text("[n_name]") : "photo")]" @@ -86,7 +86,7 @@ var/global/photo_count = 0 icon = 'icons/obj/items.dmi' icon_state = "album" item_state = "briefcase" - can_hold = list("/obj/item/weapon/photo",) + can_hold = list(/obj/item/weapon/photo) /obj/item/weapon/storage/photo_album/MouseDrop(obj/over_object as obj) @@ -311,9 +311,9 @@ var/global/photo_count = 0 var/obj/item/weapon/photo/p = new/obj/item/weapon/photo() p.name = name - p.icon = icon - p.tiny = tiny - p.img = img + p.icon = icon(icon, icon_state) + p.tiny = icon(tiny) + p.img = icon(img) p.desc = desc p.pixel_x = pixel_x p.pixel_y = pixel_y diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm index 1e99ad873a..b9f1075fa1 100644 --- a/code/modules/power/antimatter/control.dm +++ b/code/modules/power/antimatter/control.dm @@ -127,7 +127,7 @@ /obj/machinery/power/am_control_unit/bullet_act(var/obj/item/projectile/Proj) - if(Proj.flag != "bullet") + if(Proj.check_armour != "bullet") stability -= Proj.force return 0 diff --git a/code/modules/power/antimatter/shielding.dm b/code/modules/power/antimatter/shielding.dm index bdaeb0c659..5085fb6c85 100644 --- a/code/modules/power/antimatter/shielding.dm +++ b/code/modules/power/antimatter/shielding.dm @@ -117,7 +117,7 @@ proc/cardinalrange(var/center) /obj/machinery/am_shielding/bullet_act(var/obj/item/projectile/Proj) - if(Proj.flag != "bullet") + if(Proj.check_armour != "bullet") stability -= Proj.force/2 return 0 diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 59390ce7a1..fb68cea74c 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -44,6 +44,9 @@ /obj/machinery/power/apc/super cell_type = /obj/item/weapon/cell/super +/obj/machinery/power/apc/super/equipment + equipment = 2 + /obj/machinery/power/apc/hyper cell_type = /obj/item/weapon/cell/hyper @@ -167,25 +170,18 @@ src.update() /obj/machinery/power/apc/Del() - if(malfai && operating) - if (ticker.mode.config_tag == "malfunction") - if (src.z in config.station_levels) //if (is_type_in_list(get_area(src), the_station_areas)) - ticker.mode:apcs-- + if(operating && malf && src.z in config.station_levels) //if (is_type_in_list(get_area(src), the_station_areas)) + malf.hacked_apcs -= src area.power_light = 0 area.power_equip = 0 area.power_environ = 0 area.power_change() - if(occupier) - malfvacate(1) del(wires) if(cell) del(cell) // qdel if(terminal) disconnect_terminal() - //If there's no more APC then there shouldn't be a cause for alarm I guess - area.poweralert(1, src) //so that alarms don't go on forever - ..() /obj/machinery/power/apc/proc/make_terminal() @@ -538,7 +534,8 @@ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() - return + if(user.stunned) + return C.use(10) user.visible_message(\ "[user.name] has added cables to the APC frame!",\ @@ -558,7 +555,8 @@ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() - return + if(usr.stunned) + return new /obj/item/stack/cable_coil(loc,10) user << "You cut the cables and dismantle the power terminal." del(terminal) // qdel @@ -660,7 +658,7 @@ if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user - if(H.species.flags & IS_SYNTHETIC && H.a_intent == "grab") + if(H.species.flags & IS_SYNTHETIC && H.a_intent == I_GRAB) if(emagged || stat & BROKEN) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) @@ -724,6 +722,11 @@ // do APC interaction src.interact(user) +/obj/machinery/power/apc/attack_ghost(user as mob) + if(stat & (BROKEN|MAINT)) + return + return ui_interact(user) + /obj/machinery/power/apc/interact(mob/user) if(!user) return @@ -735,7 +738,7 @@ /obj/machinery/power/apc/proc/get_malf_status(mob/user) - if (ticker && ticker.mode && (user.mind in ticker.mode.malf_ai) && istype(user, /mob/living/silicon/ai)) + if (malf && (user.mind in malf.current_antagonists) && istype(user, /mob/living/silicon/ai)) if (src.malfai == (user:parent ? user:parent : user)) if (src.occupier == user) return 3 // 3 = User is shunted in this APC @@ -942,9 +945,6 @@ malfai.malfhack = null malfai.malfhacking = 0 locked = 1 - if (ticker.mode.config_tag == "malfunction") - if (src.z in config.station_levels) //if (is_type_in_list(get_area(src), the_station_areas)) - ticker.mode:apcs++ if(usr:parent) src.malfai = usr:parent else @@ -952,14 +952,6 @@ malfai << "Hack complete. The APC is now under your exclusive control." update_icon() - else if (href_list["occupyapc"]) - if(get_malf_status(usr)) - malfoccupy(usr) - - else if (href_list["deoccupyapc"]) - if(get_malf_status(usr)) - malfvacate() - else if (href_list["toggleaccess"]) if(istype(usr, /mob/living/silicon)) if(emagged || (stat & (BROKEN|MAINT))) @@ -972,73 +964,9 @@ /obj/machinery/power/apc/proc/toggle_breaker() operating = !operating - - if(malfai) - if (ticker.mode.config_tag == "malfunction") - if (src.z in config.station_levels) //if (is_type_in_list(get_area(src), the_station_areas)) - operating ? ticker.mode:apcs++ : ticker.mode:apcs-- - src.update() update_icon() -/obj/machinery/power/apc/proc/malfoccupy(var/mob/living/silicon/ai/malf) - return - - if(!istype(malf)) - return - if(istype(malf.loc, /obj/machinery/power/apc)) // Already in an APC - malf << "You must evacuate your current apc first." - return - /*if(!malf.can_shunt) - malf << "You cannot shunt." - return*/ - if(isNotStationLevel(src.z)) - return - src.occupier = new /mob/living/silicon/ai(src,malf.laws,null,1) - src.occupier.adjustOxyLoss(malf.getOxyLoss()) - if(!findtext(src.occupier.name,"APC Copy")) - src.occupier.name = "[malf.name] APC Copy" - if(malf.parent) - src.occupier.parent = malf.parent - else - src.occupier.parent = malf - malf.mind.transfer_to(src.occupier) - src.occupier.eyeobj.name = "[src.occupier.name] (AI Eye)" - if(malf.parent) - del(malf) // qdel - // src.occupier.verbs += /mob/living/silicon/ai/proc/corereturn - src.occupier.verbs += /datum/game_mode/malfunction/proc/takeover - src.occupier.cancel_camera() - if (seclevel2num(get_security_level()) == SEC_LEVEL_DELTA) - for(var/obj/item/weapon/pinpointer/point in world) - point.the_disk = src //the pinpointer will detect the shunted AI - - -/obj/machinery/power/apc/proc/malfvacate(var/forced) - if(!src.occupier) - return - if(src.occupier.parent && src.occupier.parent.stat != 2) - src.occupier.mind.transfer_to(src.occupier.parent) - src.occupier.parent.adjustOxyLoss(src.occupier.getOxyLoss()) - src.occupier.parent.cancel_camera() - del(src.occupier) // qdel - if (seclevel2num(get_security_level()) == SEC_LEVEL_DELTA) - for(var/obj/item/weapon/pinpointer/point in world) - for(var/datum/mind/AI_mind in ticker.mode.malf_ai) - var/mob/living/silicon/ai/A = AI_mind.current // the current mob the mind owns - if(A.stat != DEAD) - point.the_disk = A //The pinpointer tracks the AI back into its core. - - else - src.occupier << "Primary core damaged, unable to return core processes." - if(forced) - src.occupier.loc = src.loc - src.occupier.death() - src.occupier.gib() - for(var/obj/item/weapon/pinpointer/point in world) - point.the_disk = null //the pinpointer will go back to pointing at the nuke disc. - - /obj/machinery/power/apc/proc/ion_act() //intended to be exactly the same as an AI malf attack if(!src.malfhack && src.z in config.station_levels) @@ -1190,7 +1118,7 @@ equipment = autoset(equipment, 0) lighting = autoset(lighting, 0) environ = autoset(environ, 0) - area.poweralert(0, src) + power_alarm.triggerAlarm(loc, src) autoflag = 0 // update icon & area power if anything changed @@ -1213,29 +1141,27 @@ lighting = autoset(lighting, 1) environ = autoset(environ, 1) autoflag = 3 - area.poweralert(1, src) - if(cell.charge >= 4000) - area.poweralert(1, src) + power_alarm.clearAlarm(loc, src) else if((cell.percent() <= 30) && (cell.percent() > 15) && longtermpower < 0) // <30%, turn off equipment if(autoflag != 2) equipment = autoset(equipment, 2) lighting = autoset(lighting, 1) environ = autoset(environ, 1) - area.poweralert(0, src) + power_alarm.triggerAlarm(loc, src) autoflag = 2 else if(cell.percent() <= 15) // <15%, turn off lighting & equipment if((autoflag > 1 && longtermpower < 0) || (autoflag > 1 && longtermpower >= 0)) equipment = autoset(equipment, 2) lighting = autoset(lighting, 2) environ = autoset(environ, 1) - area.poweralert(0, src) + power_alarm.triggerAlarm(loc, src) autoflag = 1 else // zero charge, turn all off if(autoflag != 0) equipment = autoset(equipment, 0) lighting = autoset(lighting, 0) environ = autoset(environ, 0) - area.poweralert(0, src) + power_alarm.triggerAlarm(loc, src) autoflag = 0 // val 0=off, 1=off(auto) 2=on 3=on(auto) @@ -1309,10 +1235,6 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on) terminal = null /obj/machinery/power/apc/proc/set_broken() - if(malfai && operating) - if (ticker.mode.config_tag == "malfunction") - if (src.z in config.station_levels) //if (is_type_in_list(get_area(src), the_station_areas)) - ticker.mode:apcs-- // Aesthetically much better! src.visible_message("[src]'s screen flickers with warnings briefly!") spawn(rand(2,5)) @@ -1321,8 +1243,6 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on) operating = 0 update_icon() update() - if(occupier) - malfvacate(1) // overload all the lights in this APC area diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 12451f9a5e..4ce3d4ba3e 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -193,9 +193,9 @@ By design, d1 is the smallest direction and d2 is the highest var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() - return 1 - else - return 0 + if(usr.stunned) + return 1 + return 0 //explosion handling /obj/structure/cable/ex_act(severity) @@ -482,8 +482,17 @@ obj/structure/cable/proc/cableColor(var/colorC) item_state = "coil" attack_verb = list("whipped", "lashed", "disciplined", "flogged") +/obj/item/stack/cable_coil/cyborg + name = "cable coil synthesizer" + desc = "A device that makes cable." + gender = NEUTER + matter = null + uses_charge = 1 + charge_costs = list(1) + stacktype = /obj/item/stack/cable_coil + /obj/item/stack/cable_coil/suicide_act(mob/user) - if(locate(/obj/structure/stool) in user.loc) + if(locate(/obj/item/weapon/stool) in user.loc) user.visible_message("[user] is making a noose with the [src.name]! It looks like \he's trying to commit suicide.") else user.visible_message("[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.") @@ -508,7 +517,7 @@ obj/structure/cable/proc/cableColor(var/colorC) if(istype(M,/mob/living/carbon/human)) var/mob/living/carbon/human/H = M var/datum/organ/external/S = H.get_organ(user.zone_sel.selecting) - if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help") + if(!(S.status & ORGAN_ROBOT) || user.a_intent != I_HELP) return ..() if(H.species.flags & IS_SYNTHETIC) @@ -576,7 +585,7 @@ obj/structure/cable/proc/cableColor(var/colorC) usr << "\blue You cannot do that." ..() -/obj/item/stack/cable_coil/robot/verb/set_colour() +/obj/item/stack/cable_coil/cyborg/verb/set_colour() set name = "Change Colour" set category = "Object" @@ -606,26 +615,26 @@ obj/structure/cable/proc/cableColor(var/colorC) // - Cable coil : merge cables /obj/item/stack/cable_coil/attackby(obj/item/weapon/W, mob/user) ..() - if( istype(W, /obj/item/weapon/wirecutters) && src.amount > 1) - src.amount-- + if( istype(W, /obj/item/weapon/wirecutters) && src.get_amount() > 1) + src.use(1) new/obj/item/stack/cable_coil(user.loc, 1,color) user << "You cut a piece off the cable coil." src.update_icon() return else if(istype(W, /obj/item/stack/cable_coil)) var/obj/item/stack/cable_coil/C = W - if(C.amount >= MAXCOIL) + if(C.get_amount() >= get_max_amount()) user << "The coil is too long, you cannot add any more cable to it." return - if( (C.amount + src.amount <= MAXCOIL) ) + if( (C.get_amount() + src.get_amount() <= get_max_amount()) ) user << "You join the cable coils together." - C.give(src.amount) // give it cable - src.use(src.amount) // make sure this one cleans up right + C.give(src.get_amount()) // give it cable + src.use(src.get_amount()) // make sure this one cleans up right return else - var/amt = MAXCOIL - C.amount + var/amt = get_max_amount() - C.get_amount() user << "You transfer [amt] length\s of cable from one coil to the other." C.give(amt) src.use(amt) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 36ab1047a3..55c78538d6 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -128,7 +128,12 @@ rigged = 1 //broken batterys are dangerous /obj/item/weapon/cell/emp_act(severity) - charge -= 1000 / severity + //remove this once emp changes on dev are merged in + if(isrobot(loc)) + var/mob/living/silicon/robot/R = loc + severity *= R.cell_emp_mult + + charge -= maxcharge / severity if (charge < 0) charge = 0 if(reliability != 100 && prob(50/severity)) diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index c574c37ef8..391d4c0c61 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -1,4 +1,3 @@ - /obj/machinery/power/generator name = "thermoelectric generator" desc = "It's a high efficiency thermoelectric generator." @@ -9,15 +8,24 @@ use_power = 1 idle_power_usage = 100 //Watts, I hope. Just enough to do the computer and display things. + var/max_power = 500000 + var/thermal_efficiency = 0.65 + var/obj/machinery/atmospherics/binary/circulator/circ1 var/obj/machinery/atmospherics/binary/circulator/circ2 - var/lastgen = 0 - var/lastgenlev = -1 + var/last_circ1_gen = 0 + var/last_circ2_gen = 0 + var/last_thermal_gen = 0 + var/stored_energy = 0 + var/lastgen1 = 0 + var/lastgen2 = 0 + var/effective_gen = 0 + var/lastgenlev = 0 /obj/machinery/power/generator/New() ..() - + desc = initial(desc) + " Rated for [round(max_power/1000)] kW." spawn(1) reconnect() @@ -31,11 +39,11 @@ circ2 = null if(src.loc && anchored) if(src.dir & (EAST|WEST)) - circ1 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,EAST) - circ2 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,WEST) + circ1 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,WEST) + circ2 = locate(/obj/machinery/atmospherics/binary/circulator) in get_step(src,EAST) if(circ1 && circ2) - if(circ1.dir != SOUTH || circ2.dir != NORTH) + if(circ1.dir != NORTH || circ2.dir != SOUTH) circ1 = null circ2 = null @@ -58,13 +66,19 @@ /obj/machinery/power/generator/process() if(!circ1 || !circ2 || !anchored || stat & (BROKEN|NOPOWER)) + stored_energy = 0 return updateDialog() var/datum/gas_mixture/air1 = circ1.return_transfer_air() var/datum/gas_mixture/air2 = circ2.return_transfer_air() - lastgen = 0 + + lastgen2 = lastgen1 + lastgen1 = 0 + last_thermal_gen = 0 + last_circ1_gen = 0 + last_circ2_gen = 0 if(air1 && air2) var/air1_heat_capacity = air1.heat_capacity() @@ -72,10 +86,9 @@ var/delta_temperature = abs(air2.temperature - air1.temperature) if(delta_temperature > 0 && air1_heat_capacity > 0 && air2_heat_capacity > 0) - var/efficiency = 0.65 var/energy_transfer = delta_temperature*air2_heat_capacity*air1_heat_capacity/(air2_heat_capacity+air1_heat_capacity) - var/heat = energy_transfer*(1-efficiency) - lastgen = energy_transfer*efficiency*0.05 + var/heat = energy_transfer*(1-thermal_efficiency) + last_thermal_gen = energy_transfer*thermal_efficiency if(air2.temperature > air1.temperature) air2.temperature = air2.temperature - energy_transfer/air2_heat_capacity @@ -96,28 +109,40 @@ if(circ2.network2) circ2.network2.update = 1 - // update icon overlays and power usage only if displayed level has changed - if(lastgen > 250000 && prob(10)) + //Exceeding maximum power leads to some power loss + if(effective_gen > max_power && prob(5)) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() - lastgen *= 0.5 - var/genlev = max(0, min( round(11*lastgen / 250000), 11)) - if(lastgen > 100 && genlev == 0) + stored_energy *= 0.5 + + //Power + last_circ1_gen = circ1.return_stored_energy() + last_circ2_gen = circ2.return_stored_energy() + stored_energy += last_thermal_gen + last_circ1_gen + last_circ2_gen + lastgen1 = stored_energy*0.4 //smoothened power generation to prevent slingshotting as pressure is equalized, then restored by pumps + stored_energy -= lastgen1 + effective_gen = (lastgen1 + lastgen2) / 2 + + // update icon overlays and power usage only if displayed level has changed + var/genlev = max(0, min( round(11*effective_gen / max_power), 11)) + if(effective_gen > 100 && genlev == 0) genlev = 1 if(genlev != lastgenlev) lastgenlev = genlev updateicon() - add_avail(lastgen) + add_avail(effective_gen) /obj/machinery/power/generator/attack_ai(mob/user) - if(stat & (BROKEN|NOPOWER)) return - interact(user) + attack_hand(user) /obj/machinery/power/generator/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/wrench)) + playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) anchored = !anchored - user << "\blue You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor." + user.visible_message("[user.name] [anchored ? "secures" : "unsecures"] the bolts holding [src.name] to the floor.", \ + "You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor.", \ + "You hear a ratchet") use_power = anchored reconnect() else @@ -126,57 +151,60 @@ /obj/machinery/power/generator/attack_hand(mob/user) add_fingerprint(user) if(stat & (BROKEN|NOPOWER) || !anchored) return - interact(user) + if(!circ1 || !circ2) //Just incase the middle part of the TEG was not wrenched last. + reconnect() + ui_interact(user) +/obj/machinery/power/generator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + // this is the data which will be sent to the ui + var/vertical = 0 + if (dir == NORTH || dir == SOUTH) + vertical = 1 -/obj/machinery/power/generator/interact(mob/user) - if ( (get_dist(src, user) > 1 ) && (!istype(user, /mob/living/silicon/ai))) - user.unset_machine() - user << browse(null, "window=teg") - return + var/data[0] + data["totalOutput"] = effective_gen/1000 + data["maxTotalOutput"] = max_power/1000 + data["thermalOutput"] = last_thermal_gen/1000 + data["circConnected"] = 0 - user.set_machine(src) + if(circ1) + //The one on the left (or top) + data["primaryDir"] = vertical ? "top" : "left" + data["primaryOutput"] = last_circ1_gen/1000 + data["primaryFlowCapacity"] = circ1.volume_capacity_used*100 + data["primaryInletPressure"] = circ1.air1.return_pressure() + data["primaryInletTemperature"] = circ1.air1.temperature + data["primaryOutletPressure"] = circ1.air2.return_pressure() + data["primaryOutletTemperature"] = circ1.air2.temperature - var/t = "
    Thermo-Electric Generator
    " + if(circ2) + //Now for the one on the right (or bottom) + data["secondaryDir"] = vertical ? "bottom" : "right" + data["secondaryOutput"] = last_circ2_gen/1000 + data["secondaryFlowCapacity"] = circ2.volume_capacity_used*100 + data["secondaryInletPressure"] = circ2.air1.return_pressure() + data["secondaryInletTemperature"] = circ2.air1.temperature + data["secondaryOutletPressure"] = circ2.air2.return_pressure() + data["secondaryOutletTemperature"] = circ2.air2.temperature if(circ1 && circ2) - t += "Output : [round(lastgen)] W

    " - - t += "Primary Circulator (top or right)
    " - t += "Inlet Pressure: [round(circ1.air1.return_pressure(), 0.1)] kPa
    " - t += "Inlet Temperature: [round(circ1.air1.temperature, 0.1)] K
    " - t += "Outlet Pressure: [round(circ1.air2.return_pressure(), 0.1)] kPa
    " - t += "Outlet Temperature: [round(circ1.air2.temperature, 0.1)] K
    " - - t += "Secondary Circulator (bottom or left)
    " - t += "Inlet Pressure: [round(circ2.air1.return_pressure(), 0.1)] kPa
    " - t += "Inlet Temperature: [round(circ2.air1.temperature, 0.1)] K
    " - t += "Outlet Pressure: [round(circ2.air2.return_pressure(), 0.1)] kPa
    " - t += "Outlet Temperature: [round(circ2.air2.temperature, 0.1)] K
    " - + data["circConnected"] = 1 else - t += "Unable to connect to circulators.
    " - t += "Ensure both are in position and wrenched into place." - - t += "
    " - t += "
    " - t += "Refresh Close" - - user << browse(t, "window=teg;size=460x300") - onclose(user, "teg") - return 1 + data["circConnected"] = 0 -/obj/machinery/power/generator/Topic(href, href_list) - ..() - if( href_list["close"] ) - usr << browse(null, "window=teg") - usr.unset_machine() - return 0 - - updateDialog() - return 1 - + // update the ui if it exists, returns null if no ui is passed/found + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + // the ui does not exist, so we'll create a new() one + // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm + ui = new(user, src, ui_key, "generator.tmpl", "Thermoelectric Generator", 450, 500) + // when the ui is first opened this is the data it will use + ui.set_initial_data(data) + // open the new ui window + ui.open() + // auto update every Master Controller tick + ui.set_auto_update(1) /obj/machinery/power/generator/power_change() ..() @@ -201,4 +229,4 @@ if (usr.stat || usr.restrained() || anchored) return - src.set_dir(turn(src.dir, -90)) \ No newline at end of file + src.set_dir(turn(src.dir, -90)) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 7c9ae41cf2..14bdaa1644 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -737,7 +737,7 @@ if(!proximity) return if(istype(target, /obj/machinery/light)) return - if(user.a_intent != "hurt") + if(user.a_intent != I_HURT) return shatter() diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 2223f2f9f9..4828280e63 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -1,45 +1,3 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33 - -/* new portable generator - work in progress - -/obj/machinery/power/port_gen - name = "portable generator" - desc = "A portable generator used for emergency backup power." - icon = 'generator.dmi' - icon_state = "off" - density = 1 - anchored = 0 - directwired = 0 - var/t_status = 0 - var/t_per = 5000 - var/filter = 1 - var/tank = null - var/turf/inturf - var/starter = 0 - var/rpm = 0 - var/rpmtarget = 0 - var/capacity = 1e6 - var/turf/outturf - var/lastgen - - -/obj/machinery/power/port_gen/process() -ideally we're looking to generate 5000 - -/obj/machinery/power/port_gen/attackby(obj/item/weapon/W, mob/user) -tank [un]loading stuff - -/obj/machinery/power/port_gen/attack_hand(mob/user) -turn on/off - -/obj/machinery/power/port_gen/examine(mob/user) -display round(lastgen) and phorontank amount - -*/ - -//Previous code been here forever, adding new framework for portable generators - - //Baseline portable generator. Has all the default handling. Not intended to be used on it's own (since it generates unlimited power). /obj/machinery/power/port_gen name = "Placeholder Generator" //seriously, don't use this. It can't be anchored without VV magic. @@ -56,6 +14,9 @@ display round(lastgen) and phorontank amount var/recent_fault = 0 var/power_output = 1 +/obj/machinery/power/port_gen/proc/IsBroken() + return (crit_fail || (stat & (BROKEN|EMPED))) + /obj/machinery/power/port_gen/proc/HasFuel() //Placeholder for fuel check. return 1 @@ -69,11 +30,10 @@ display round(lastgen) and phorontank amount return /obj/machinery/power/port_gen/process() - if(active && HasFuel() && !crit_fail && anchored && powernet) + if(active && HasFuel() && !IsBroken() && anchored && powernet) add_avail(power_gen * power_output) UseFuel() src.updateDialog() - else active = 0 icon_state = initial(icon_state) @@ -96,20 +56,58 @@ display round(lastgen) and phorontank amount else usr << "\blue The generator is off." +/obj/machinery/power/port_gen/emp_act(severity) + var/duration = 6000 //ten minutes + switch(severity) + if(1) + stat &= BROKEN + if(prob(75)) explode() + if(2) + if(prob(25)) stat &= BROKEN + if(prob(10)) explode() + if(3) + if(prob(10)) stat &= BROKEN + duration = 300 + + stat |= EMPED + if(duration) + spawn(duration) + stat &= ~EMPED + +/obj/machinery/power/port_gen/proc/explode() + explosion(src.loc, -1, 3, 5, -1) + del(src) + +#define TEMPERATURE_DIVISOR 40 +#define TEMPERATURE_CHANGE_MAX 20 + //A power generator that runs on solid plasma sheets. /obj/machinery/power/port_gen/pacman - name = "P.A.C.M.A.N.-type Portable Generator" - var/sheets = 0 - var/max_sheets = 100 - var/sheet_name = "" + name = "\improper P.A.C.M.A.N.-type Portable Generator" + desc = "A power generator that runs on solid phoron sheets. Rated for 80 kW max safe output." + + var/sheet_name = "Phoron Sheets" var/sheet_path = /obj/item/stack/sheet/mineral/phoron var/board_path = "/obj/item/weapon/circuitboard/pacman" - var/sheet_left = 0 // How much is left of the sheet - var/heat = 0 - - //produces up to 80 kW and lasts for 20 minutes with 50 sheets - var/time_per_sheet = 96 - power_gen = 20000 + + /* + These values were chosen so that the generator can run safely up to 80 kW + A full 50 phoron sheet stack should last 20 minutes at power_output = 4 + temperature_gain and max_temperature are set so that the max safe power level is 4. + Setting to 5 or higher can only be done temporarily before the generator overheats. + */ + power_gen = 20000 //Watts output per power_output level + var/max_power_output = 5 //The maximum power setting without emagging. + var/max_safe_output = 4 // For UI use, maximal output that won't cause overheat. + var/time_per_sheet = 96 //fuel efficiency - how long 1 sheet lasts at power level 1 + var/max_sheets = 100 //max capacity of the hopper + var/max_temperature = 300 //max temperature before overheating increases + var/temperature_gain = 50 //how much the temperature increases per power output level, in degrees per level + + var/sheets = 0 //How many sheets of material are loaded in the generator + var/sheet_left = 0 //How much is left of the current sheet + var/temperature = 0 //The current temperature + var/overheating = 0 //if this gets high enough the generator explodes /obj/machinery/power/port_gen/pacman/initialize() ..() @@ -125,8 +123,6 @@ display round(lastgen) and phorontank amount component_parts += new /obj/item/stack/cable_coil(src) component_parts += new /obj/item/weapon/stock_parts/capacitor(src) component_parts += new board_path(src) - var/obj/sheet = new sheet_path(null) - sheet_name = sheet.name RefreshParts() /obj/machinery/power/port_gen/pacman/Del() @@ -135,76 +131,130 @@ display round(lastgen) and phorontank amount /obj/machinery/power/port_gen/pacman/RefreshParts() var/temp_rating = 0 - var/temp_reliability = 0 for(var/obj/item/weapon/stock_parts/SP in component_parts) if(istype(SP, /obj/item/weapon/stock_parts/matter_bin)) max_sheets = SP.rating * SP.rating * 50 else if(istype(SP, /obj/item/weapon/stock_parts/micro_laser) || istype(SP, /obj/item/weapon/stock_parts/capacitor)) temp_rating += SP.rating + + var/temp_reliability = 0 + var/part_count = 0 for(var/obj/item/weapon/CP in component_parts) temp_reliability += CP.reliability - reliability = min(round(temp_reliability / 4), 100) + part_count++ + + reliability = min(round(temp_reliability / part_count), 100) power_gen = round(initial(power_gen) * (max(2, temp_rating) / 2)) /obj/machinery/power/port_gen/pacman/examine(mob/user) ..(user) - user << "\blue The generator has [sheets] units of [sheet_name] fuel left, producing [power_gen] per cycle." - if(crit_fail) user << "\red The generator seems to have broken down." + user << "\The [src] appears to be producing [power_gen*power_output] W." + user << "There [sheets == 1 ? "is" : "are"] [sheets] sheet\s left in the hopper." + if(IsBroken()) user << "\The [src] seems to have broken down." + if(overheating) user << "\The [src] is overheating!" /obj/machinery/power/port_gen/pacman/HasFuel() - if(sheets >= 1 / (time_per_sheet / power_output) - sheet_left) + var/needed_sheets = power_output / time_per_sheet + if(sheets >= needed_sheets - sheet_left) return 1 return 0 +//Removes one stack's worth of material from the generator. /obj/machinery/power/port_gen/pacman/DropFuel() if(sheets) - var/fail_safe = 0 - while(sheets > 0 && fail_safe < 100) - fail_safe += 1 - var/obj/item/stack/sheet/S = new sheet_path(loc) - var/amount = min(sheets, S.max_amount) - S.amount = amount - sheets -= amount + var/obj/item/stack/sheet/S = new sheet_path(loc) + var/amount = min(sheets, S.max_amount) + S.amount = amount + sheets -= amount /obj/machinery/power/port_gen/pacman/UseFuel() - var/needed_sheets = 1 / (time_per_sheet / power_output) - var/temp = min(needed_sheets, sheet_left) - needed_sheets -= temp - sheet_left -= temp - sheets -= round(needed_sheets) - needed_sheets -= round(needed_sheets) - if (sheet_left <= 0 && sheets > 0) - sheet_left = 1 - needed_sheets + //break down sometimes + if (reliability < 100) + if (prob(1) && prob(1) && prob(100 - reliability)) + stat |= BROKEN + crit_fail = 1 + if (prob(100 - reliability)) + explode() + + //how much material are we using this iteration? + var/needed_sheets = power_output / time_per_sheet + + //HasFuel() should guarantee us that there is enough fuel left, so no need to check that + //the only thing we need to worry about is if we are going to rollover to the next sheet + if (needed_sheets > sheet_left) sheets-- - - var/lower_limit = 56 + power_output * 10 - var/upper_limit = 76 + power_output * 10 - var/bias = 0 - if (power_output > 4) - upper_limit = 400 - bias = power_output * 3 - if (heat < lower_limit) - heat += 3 + sheet_left = (1 + sheet_left) - needed_sheets else - heat += rand(-7 + bias, 7 + bias) - if (heat < lower_limit) - heat = lower_limit - if (heat > upper_limit) - heat = upper_limit + sheet_left -= needed_sheets - if (heat > 300) + //calculate the "target" temperature range + //This should probably depend on the external temperature somehow, but whatever. + var/lower_limit = 56 + power_output * temperature_gain + var/upper_limit = 76 + power_output * temperature_gain + + /* + Hot or cold environments can affect the equilibrium temperature + The lower the pressure the less effect it has. I guess it cools using a radiator or something when in vacuum. + Gives traitors more opportunities to sabotage the generator or allows enterprising engineers to build additional + cooling in order to get more power out. + */ + var/datum/gas_mixture/environment = loc.return_air() + if (environment) + var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1) + var/ambient = environment.temperature - T20C + lower_limit += ambient*ratio + upper_limit += ambient*ratio + + var/average = (upper_limit + lower_limit)/2 + + //calculate the temperature increase + var/bias = 0 + if (temperature < lower_limit) + bias = min(round((average - temperature)/TEMPERATURE_DIVISOR, 1), TEMPERATURE_CHANGE_MAX) + else if (temperature > upper_limit) + bias = max(round((temperature - average)/TEMPERATURE_DIVISOR, 1), -TEMPERATURE_CHANGE_MAX) + + temperature += rand(-7 + bias, 7 + bias) + + if (temperature > max_temperature) overheat() - del(src) - return + else if (overheating > 0) + overheating-- /obj/machinery/power/port_gen/pacman/handleInactive() + var/cooling_temperature = 20 + var/datum/gas_mixture/environment = loc.return_air() + if (environment) + var/ratio = min(environment.return_pressure()/ONE_ATMOSPHERE, 1) + var/ambient = environment.temperature - T20C + cooling_temperature += ambient*ratio - if (heat > 0) - heat = max(heat - 2, 0) + if (temperature > cooling_temperature) + var/temp_loss = (temperature - cooling_temperature)/TEMPERATURE_DIVISOR + temp_loss = between(2, round(temp_loss, 1), TEMPERATURE_CHANGE_MAX) + temperature = max(temperature - temp_loss, cooling_temperature) src.updateDialog() + if(overheating) + overheating-- + /obj/machinery/power/port_gen/pacman/proc/overheat() - explosion(src.loc, 2, 5, 2, -1) + overheating++ + if (overheating > 60) + explode() + +/obj/machinery/power/port_gen/pacman/explode() + //Vapourize all the phoron + //When ground up in a grinder, 1 sheet produces 20 u of phoron -- Chemistry-Machinery.dm + //1 mol = 10 u? I dunno. 1 mol of carbon is definitely bigger than a pill + var/phoron = (sheets+sheet_left)*20 + var/datum/gas_mixture/environment = loc.return_air() + if (environment) + environment.adjust_gas_temp("phoron", phoron/10, temperature + T0C) + + sheets = 0 + sheet_left = 0 + ..() /obj/machinery/power/port_gen/pacman/attackby(var/obj/item/O as obj, var/mob/user as mob) if(istype(O, sheet_path)) @@ -213,16 +263,16 @@ display round(lastgen) and phorontank amount if(amount < 1) user << "\blue The [src.name] is full!" return - user << "\blue You add [amount] sheets to the [src.name]." + user << "\blue You add [amount] sheet\s to the [src.name]." sheets += amount addstack.use(amount) updateUsrDialog() return else if (istype(O, /obj/item/weapon/card/emag)) emagged = 1 - emp_act(1) + if (active && prob(25)) + explode() //if they're foolish enough to emag while it's running else if(!active) - if(istype(O, /obj/item/weapon/wrench)) if(!anchored) @@ -245,18 +295,9 @@ display round(lastgen) and phorontank amount else if(istype(O, /obj/item/weapon/crowbar) && open) var/obj/machinery/constructable_frame/machine_frame/new_frame = new /obj/machinery/constructable_frame/machine_frame(src.loc) for(var/obj/item/I in component_parts) - if(I.reliability < 100) - I.crit_fail = 1 I.loc = src.loc while ( sheets > 0 ) - var/obj/item/stack/sheet/G = new sheet_path(src.loc) - - if ( sheets > 50 ) - G.amount = 50 - else - G.amount = sheets - - sheets -= G.amount + DropFuel() new_frame.state = 2 new_frame.icon_state = "box_1" @@ -266,12 +307,46 @@ display round(lastgen) and phorontank amount ..() if (!anchored) return - - interact(user) + ui_interact(user) /obj/machinery/power/port_gen/pacman/attack_ai(mob/user as mob) - interact(user) + ui_interact(user) +/obj/machinery/power/port_gen/pacman/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + if(IsBroken()) + return + + var/data[0] + data["active"] = active + if(istype(user, /mob/living/silicon/ai)) + data["is_ai"] = 1 + else if(istype(user, /mob/living/silicon/robot) && !Adjacent(user)) + data["is_ai"] = 1 + else + data["is_ai"] = 0 + data["output_set"] = power_output + data["output_max"] = max_power_output + data["output_safe"] = max_safe_output + data["output_watts"] = power_output * power_gen + data["temperature_current"] = src.temperature + data["temperature_max"] = src.max_temperature + data["temperature_overheat"] = overheating + // 1 sheet = 1000cm3? + data["fuel_stored"] = round((sheets * 1000) + (sheet_left * 1000)) + data["fuel_capacity"] = round(max_sheets * 1000, 0.1) + data["fuel_usage"] = active ? round((power_output / time_per_sheet) * 1000) : 0 + data["fuel_type"] = sheet_name + + + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "pacman.tmpl", src.name, 500, 560) + ui.open() + ui.set_auto_update(1) + + +/* /obj/machinery/power/port_gen/pacman/interact(mob/user) if (get_dist(src, user) > 1 ) if (!istype(user, /mob/living/silicon/ai)) @@ -289,12 +364,15 @@ display round(lastgen) and phorontank amount dat += text("[capitalize(sheet_name)]: [sheets] - Eject
    ") var/stack_percent = round(sheet_left * 100, 1) dat += text("Current stack: [stack_percent]%
    ") - dat += text("Power output: - [power_gen * power_output] +
    ") + dat += text("Power output: - [power_gen * power_output] Watts+
    ") dat += text("Power current: [(powernet == null ? "Unconnected" : "[avail()]")]
    ") - dat += text("Heat: [heat]
    ") + + var/tempstr = "Temperature: [temperature]°C
    " + dat += (overheating)? "[tempstr]" : tempstr dat += "
    Close" user << browse("[dat]", "window=port_gen") onclose(user, "port_gen") +*/ /obj/machinery/power/port_gen/pacman/Topic(href, href_list) if(..()) @@ -303,53 +381,68 @@ display round(lastgen) and phorontank amount src.add_fingerprint(usr) if(href_list["action"]) if(href_list["action"] == "enable") - if(!active && HasFuel() && !crit_fail) + if(!active && HasFuel() && !IsBroken()) active = 1 icon_state = "portgen1" - src.updateUsrDialog() if(href_list["action"] == "disable") if (active) active = 0 icon_state = "portgen0" - src.updateUsrDialog() if(href_list["action"] == "eject") if(!active) DropFuel() - src.updateUsrDialog() if(href_list["action"] == "lower_power") if (power_output > 1) power_output-- - src.updateUsrDialog() if (href_list["action"] == "higher_power") - if (power_output < 4 || emagged) + if (power_output < max_power_output || (emagged && power_output < round(max_power_output*2.5))) power_output++ - src.updateUsrDialog() - if (href_list["action"] == "close") - usr << browse(null, "window=port_gen") - usr.unset_machine() /obj/machinery/power/port_gen/pacman/super name = "S.U.P.E.R.P.A.C.M.A.N.-type Portable Generator" + desc = "A power generator that utilizes uranium sheets as fuel. Can run for much longer than the standard PACMAN type generators. Rated for 80 kW max safe output." icon_state = "portgen1" sheet_path = /obj/item/stack/sheet/mineral/uranium + sheet_name = "Uranium Sheets" + time_per_sheet = 576 //same power output, but a 50 sheet stack will last 2 hours at max safe power board_path = "/obj/item/weapon/circuitboard/pacman/super" - - //produces 80 kW like the PACMAN but 50 sheets will last for 2 hours - power_gen = 20000 - time_per_sheet = 576 - - overheat() - explosion(src.loc, 3, 3, 3, -1) + +/obj/machinery/power/port_gen/pacman/super/UseFuel() + //produces a tiny amount of radiation when in use + if (prob(2*power_output)) + for (var/mob/living/L in range(src, 5)) + L.apply_effect(1, IRRADIATE) //should amount to ~5 rads per minute at max safe power + ..() + +/obj/machinery/power/port_gen/pacman/super/explode() + //a nice burst of radiation + var/rads = 50 + (sheets + sheet_left)*1.5 + for (var/mob/living/L in range(src, 10)) + //should really fall with the square of the distance, but that makes the rads value drop too fast + //I dunno, maybe physics works different when you live in 2D -- SM radiation also works like this, apparently + L.apply_effect(max(20, round(rads/get_dist(L,src))), IRRADIATE) + + explosion(src.loc, 3, 3, 5, 3) + del(src) /obj/machinery/power/port_gen/pacman/mrs name = "M.R.S.P.A.C.M.A.N.-type Portable Generator" + desc = "An advanced power generator that runs on tritium. Rated for 200 kW maximum safe output!" icon_state = "portgen2" sheet_path = /obj/item/stack/sheet/mineral/tritium + sheet_name = "Tritium Fuel Sheets" + + //I don't think tritium has any other use, so we might as well make this rewarding for players + //max safe power output (power level = 8) is 200 kW and lasts for 1 hour - 3 or 4 of these could power the station + power_gen = 25000 //watts + max_power_output = 10 + max_safe_output = 8 + time_per_sheet = 576 + max_temperature = 800 + temperature_gain = 90 board_path = "/obj/item/weapon/circuitboard/pacman/mrs" - - //produces 200 kW and lasts for 1 hour with 50 sheets - power_gen = 50000 - time_per_sheet = 288 - - overheat() - explosion(src.loc, 4, 4, 4, -1) + +/obj/machinery/power/port_gen/pacman/mrs/explode() + //no special effects, but the explosion is pretty big (same as a supermatter shard). + explosion(src.loc, 3, 6, 12, 16, 1) + del(src) diff --git a/code/modules/power/rust/core_field.dm b/code/modules/power/rust/core_field.dm index 2c5806bef5..ad974786b7 100644 --- a/code/modules/power/rust/core_field.dm +++ b/code/modules/power/rust/core_field.dm @@ -111,7 +111,7 @@ Deuterium-tritium fusion: 4.5 x 10^7 K //init values major_radius = field_strength * 0.21875// max = 8.75 minor_radius = field_strength * 0.2125// max = 8.625 - volume_covered = PI * major_radius * minor_radius * 2.5 * 2.5 * 1000 + volume_covered = M_PI * major_radius * minor_radius * 2.5 * 2.5 * 1000 processing_objects.Add(src) @@ -131,7 +131,7 @@ Deuterium-tritium fusion: 4.5 x 10^7 K var/transfer_ratio = field_strength / 50 //higher field strength will result in faster phoron aggregation major_radius = field_strength * 0.21875// max = 8.75m minor_radius = field_strength * 0.2125// max = 8.625m - volume_covered = PI * major_radius * minor_radius * 2.5 * 2.5 * 2.5 * 7 * 7 * transfer_ratio //one tile = 2.5m*2.5m*2.5m + volume_covered = M_PI * major_radius * minor_radius * 2.5 * 2.5 * 2.5 * 7 * 7 * transfer_ratio //one tile = 2.5m*2.5m*2.5m //add phoron from the surrounding environment var/datum/gas_mixture/environment = loc.return_air() diff --git a/code/modules/power/rust/virtual_particle_catcher.dm b/code/modules/power/rust/virtual_particle_catcher.dm index 2d32a9a785..350d9f66fc 100644 --- a/code/modules/power/rust/virtual_particle_catcher.dm +++ b/code/modules/power/rust/virtual_particle_catcher.dm @@ -42,7 +42,7 @@ name = "collector [mysize] OFF" /obj/effect/rust_particle_catcher/bullet_act(var/obj/item/projectile/Proj) - if(Proj.flag != "bullet" && parent) + if(Proj.check_armour != "bullet" && parent) parent.AddEnergy(Proj.damage * 20, 0, 1) update_icon() return 0 diff --git a/code/modules/power/sensors/sensor_monitoring.dm b/code/modules/power/sensors/sensor_monitoring.dm index a3b978946b..54b203a7d4 100644 --- a/code/modules/power/sensors/sensor_monitoring.dm +++ b/code/modules/power/sensors/sensor_monitoring.dm @@ -16,12 +16,11 @@ density = 1 anchored = 1.0 circuit = /obj/item/weapon/circuitboard/powermonitor - var/list/grid_sensors var/alerting = 0 - var/active_sensor = null //name_tag of the currently selected sensor use_power = 1 idle_power_usage = 300 active_power_usage = 300 + var/obj/nano_module/power_monitor/power_monitor // Proc: process() // Parameters: None @@ -53,19 +52,7 @@ /obj/machinery/computer/power_monitor/New() ..() spawn(50) - refresh_sensors() - -// Proc: refresh_sensors() -// Parameters: None -// Description: Refreshes list of active sensors kept on this computer. -/obj/machinery/computer/power_monitor/proc/refresh_sensors() - grid_sensors = list() - for(var/obj/machinery/power/sensor/S in machines) - if((S.loc.z == src.loc.z) || (S.long_range)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels. - if(S.name_tag == "#UNKN#") // Default name. Shouldn't happen! - warning("Powernet sensor with unset ID Tag! [S.x]X [S.y]Y [S.z]Z") - else - grid_sensors += S + power_monitor = new(src) // Proc: attack_hand() // Parameters: None @@ -77,50 +64,18 @@ return ui_interact(user) -// Proc: Topic() -// Parameters: 2 (href, href_list - allows us to process UI clicks) -// Description: Allows us to process UI clicks, which are relayed in form of hrefs. -/obj/machinery/computer/power_monitor/Topic(href, href_list) - ..() - if( href_list["clear"] ) - active_sensor = null - else if( href_list["setsensor"] ) - active_sensor = href_list["setsensor"] +// Proc: ui_interact() +// Parameters: 4 (standard NanoUI parameters) +// Description: Uses dark magic to operate the NanoUI of this computer. +/obj/machinery/computer/power_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + power_monitor.ui_interact(user, ui_key, ui, force_open) + // Proc: check_warnings() // Parameters: None // Description: Verifies if any warnings were registered by connected sensors. /obj/machinery/computer/power_monitor/proc/check_warnings() - for(var/obj/machinery/power/sensor/S in grid_sensors) + for(var/obj/machinery/power/sensor/S in power_monitor.grid_sensors) if(S.check_grid_warning()) return 1 return 0 - -// Proc: ui_interact() -// Parameters: 4 (standard NanoUI parameters) -// Description: Uses dark magic to operate the NanoUI of this computer. -/obj/machinery/computer/power_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - var/list/data = list() - var/list/sensors = list() - // Focus: If it remains null if no sensor is selected and UI will display sensor list, otherwise it will display sensor reading. - var/obj/machinery/power/sensor/focus = null - - // Build list of data from sensor readings. - for(var/obj/machinery/power/sensor/S in grid_sensors) - sensors.Add(list(list( - "name" = S.name_tag, - "alarm" = S.check_grid_warning() - ))) - if(S.name_tag == active_sensor) - focus = S - - data["all_sensors"] = sensors - if(focus) - data["focus"] = focus.return_reading_data() - - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - ui = new(user, src, ui_key, "power_monitor.tmpl", "Power Monitoring Console", 800, 500) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) \ No newline at end of file diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 59e93c23b6..c85c48e27a 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -1,7 +1,7 @@ #define EMITTER_DAMAGE_POWER_TRANSFER 450 //used to transfer power to containment field generators /obj/machinery/power/emitter - name = "Emitter" + name = "emitter" desc = "It is a heavy duty industrial laser." icon = 'icons/obj/singularity.dmi' icon_state = "emitter" @@ -60,18 +60,18 @@ /obj/machinery/power/emitter/proc/activate(mob/user as mob) if(state == 2) if(!powernet) - user << "The emitter isn't connected to a wire." + user << "\The [src] isn't connected to a wire." return 1 if(!src.locked) if(src.active==1) src.active = 0 - user << "You turn off the [src]." + user << "You turn off [src]." message_admins("Emitter turned off by [key_name(user, user.client)](?) in ([x],[y],[z] - JMP)",0,1) log_game("Emitter turned off by [user.ckey]([user]) in ([x],[y],[z])") investigate_log("turned off by [user.key]","singulo") else src.active = 1 - user << "You turn on the [src]." + user << "You turn on [src]." src.shot_number = 0 src.fire_delay = 100 message_admins("Emitter turned on by [key_name(user, user.client)](?) in ([x],[y],[z] - JMP)",0,1) @@ -79,9 +79,9 @@ investigate_log("turned on by [user.key]","singulo") update_icon() else - user << "\red The controls are locked!" + user << "The controls are locked!" else - user << "\red The [src] needs to be firmly secured to the floor first." + user << "\The [src] needs to be firmly secured to the floor first." return 1 @@ -138,86 +138,83 @@ s.set_up(5, 1, src) s.start() A.set_dir(src.dir) + A.starting = get_turf(src) switch(dir) if(NORTH) - A.yo = 20 - A.xo = 0 + A.original = locate(x, y+1, z) if(EAST) - A.yo = 0 - A.xo = 20 + A.original = locate(x+1, y, z) if(WEST) - A.yo = 0 - A.xo = -20 + A.original = locate(x-1, y, z) else // Any other - A.yo = -20 - A.xo = 0 - A.process() //TODO: Carn: check this out + A.original = locate(x, y-1, z) + A.process() /obj/machinery/power/emitter/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/weapon/wrench)) if(active) - user << "Turn off the [src] first." + user << "Turn off [src] first." return switch(state) if(0) state = 1 playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) - user.visible_message("[user.name] secures [src.name] to the floor.", \ + user.visible_message("[user.name] secures [src] to the floor.", \ "You secure the external reinforcing bolts to the floor.", \ "You hear a ratchet") src.anchored = 1 if(1) state = 0 playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) - user.visible_message("[user.name] unsecures [src.name] reinforcing bolts from the floor.", \ + user.visible_message("[user.name] unsecures [src] reinforcing bolts from the floor.", \ "You undo the external reinforcing bolts.", \ "You hear a ratchet") src.anchored = 0 if(2) - user << "\red The [src.name] needs to be unwelded from the floor." + user << "\The [src] needs to be unwelded from the floor." return if(istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W if(active) - user << "Turn off the [src] first." + user << "Turn off [src] first." return switch(state) if(0) - user << "\red The [src.name] needs to be wrenched to the floor." + user << "\The [src] needs to be wrenched to the floor." if(1) if (WT.remove_fuel(0,user)) playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1) - user.visible_message("[user.name] starts to weld the [src.name] to the floor.", \ - "You start to weld the [src] to the floor.", \ + user.visible_message("[user.name] starts to weld [src] to the floor.", \ + "You start to weld [src] to the floor.", \ "You hear welding") if (do_after(user,20)) if(!src || !WT.isOn()) return state = 2 - user << "You weld the [src] to the floor." + user << "You weld [src] to the floor." connect_to_network() else - user << "\red You need more welding fuel to complete this task." + user << "You need more welding fuel to complete this task." if(2) if (WT.remove_fuel(0,user)) playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1) - user.visible_message("[user.name] starts to cut the [src.name] free from the floor.", \ - "You start to cut the [src] free from the floor.", \ + user.visible_message("[user.name] starts to cut [src] free from the floor.", \ + "You start to cut [src] free from the floor.", \ "You hear welding") if (do_after(user,20)) if(!src || !WT.isOn()) return state = 1 - user << "You cut the [src] free from the floor." + user << "You cut [src] free from the floor." disconnect_from_network() else - user << "\red You need more welding fuel to complete this task." + user << "You need more welding fuel to complete this task." return if(istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda)) if(emagged) - user << "\red The lock seems to be broken" + user << "The lock seems to be broken." return if(src.allowed(user)) if(active) @@ -225,16 +222,16 @@ user << "The controls are now [src.locked ? "locked." : "unlocked."]" else src.locked = 0 //just in case it somehow gets locked - user << "\red The controls can only be locked when the [src] is online" + user << "The controls can only be locked when [src] is online." else - user << "\red Access denied." + user << "Access denied." return if(istype(W, /obj/item/weapon/card/emag) && !emagged) locked = 0 emagged = 1 - user.visible_message("[user.name] emags the [src.name].","\red You short out the lock.") + user.visible_message("[user.name] emags [src].","You short out the lock.") return ..() diff --git a/code/modules/power/singularity/investigate.dm b/code/modules/power/singularity/investigate.dm index 6389f10707..63c54c0e54 100644 --- a/code/modules/power/singularity/investigate.dm +++ b/code/modules/power/singularity/investigate.dm @@ -1,4 +1,4 @@ -/area/engine/engineering/poweralert(var/state, var/source) - if (state != poweralm) +/area/engineering/power_alert(var/alarming) + if (alarming) investigate_log("has a power alarm!","singulo") ..() \ No newline at end of file diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm index cbec31306b..2113ba87f7 100644 --- a/code/modules/power/singularity/particle_accelerator/particle.dm +++ b/code/modules/power/singularity/particle_accelerator/particle.dm @@ -74,12 +74,6 @@ /obj/effect/accelerated_particle/proc/toxmob(var/mob/living/M) var/radiation = (energy*2) -/* if(istype(M,/mob/living/carbon/human)) - if(M:wear_suit) //TODO: check for radiation protection - radiation = round(radiation/2,1) - if(istype(M,/mob/living/carbon/monkey)) - if(M:wear_suit) //TODO: check for radiation protection - radiation = round(radiation/2,1)*/ M.apply_effect((radiation*3),IRRADIATE,0) M.updatehealth() //M << "\red You feel odd." diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 0825d9a194..cecdf46a2c 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -511,15 +511,16 @@ var/global/list/uneatable = list( /obj/machinery/singularity/narsie/proc/pickcultist() //Narsie rewards his cultists with being devoured first, then picks a ghost to follow. --NEO var/list/cultists = list() - for(var/datum/mind/cult_nh_mind in ticker.mode.cult) - if(!cult_nh_mind.current) - continue - if(cult_nh_mind.current.stat) - continue - var/turf/pos = get_turf(cult_nh_mind.current) - if(pos.z != src.z) - continue - cultists += cult_nh_mind.current + if(cult && cult.current_antagonists.len) + for(var/datum/mind/cult_nh_mind in cult.current_antagonists) + if(!cult_nh_mind.current) + continue + if(cult_nh_mind.current.stat) + continue + var/turf/pos = get_turf(cult_nh_mind.current) + if(pos.z != src.z) + continue + cultists += cult_nh_mind.current if(cultists.len) acquire(pick(cultists)) return diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 8d59679474..4fdcbe811f 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -138,7 +138,7 @@ if(output_used < 0.0001) // either from no charge or set to 0 outputting(0) investigate_log("lost power and turned off","singulo") - else if(output_attempt && charge > output_level && output_level > 0) + else if(output_attempt && output_level > 0) outputting = 1 else output_used = 0 @@ -218,6 +218,8 @@ add_fingerprint(user) ui_interact(user) +/obj/machinery/power/smes/attack_ghost(mob/user) + ui_interact(user) /obj/machinery/power/smes/attack_hand(mob/user) add_fingerprint(user) @@ -273,7 +275,8 @@ s.set_up(5, 1, src) s.start() building_terminal = 0 - return 0 + if(usr.stunned) + return 0 new /obj/item/stack/cable_coil(loc,10) user.visible_message(\ "[user.name] cut the cables and dismantled the power terminal.",\ diff --git a/code/modules/power/smes_construction.dm b/code/modules/power/smes_construction.dm index 99180db13d..3fe4f511eb 100644 --- a/code/modules/power/smes_construction.dm +++ b/code/modules/power/smes_construction.dm @@ -5,16 +5,63 @@ // This is subtype of SMES that should be normally used. It can be constructed, deconstructed and hacked. // It also supports RCON System which allows you to operate it remotely, if properly set. -//Construction Item +//MAGNETIC COILS - These things actually store and transmit power within the SMES. Different types have different /obj/item/weapon/smes_coil name = "superconductive magnetic coil" - desc = "Heavy duty superconductive magnetic coil, mainly used in construction of SMES units." + desc = "Standard superconductive magnetic coil with average capacity and I/O rating." icon = 'icons/obj/stock_parts.dmi' icon_state = "smes_coil" // Just few icons patched together. If someone wants to make better icon, feel free to do so! w_class = 4.0 // It's LARGE (backpack size) var/ChargeCapacity = 5000000 var/IOCapacity = 250000 +// 20% Charge Capacity, 60% I/O Capacity. Used for substation/outpost SMESs. +/obj/item/weapon/smes_coil/weak + name = "basic superconductive magnetic coil" + desc = "Cheaper model of standard superconductive magnetic coil. It's capacity and I/O rating are considerably lower." + ChargeCapacity = 1000000 + IOCapacity = 150000 + +// 1000% Charge Capacity, 20% I/O Capacity +/obj/item/weapon/smes_coil/super_capacity + name = "superconductive capacitance coil" + desc = "Specialised version of standard superconductive magnetic coil. This one has significantly stronger containment field, allowing for significantly larger power storage. It's IO rating is much lower, however." + ChargeCapacity = 50000000 + IOCapacity = 50000 + +// 10% Charge Capacity, 400% I/O Capacity. Technically turns SMES into large super capacitor.Ideal for shields. +/obj/item/weapon/smes_coil/super_io + name = "superconductive transmission coil" + desc = "Specialised version of standard superconductive magnetic coil. While this one won't store almost any power, it rapidly transfers power, making it useful in systems which require large throughput." + ChargeCapacity = 500000 + IOCapacity = 1000000 + + +// SMES SUBTYPES - THESE ARE MAPPED IN AND CONTAIN DIFFERENT TYPES OF COILS + +// These are used on individual outposts as backup should power line be cut, or engineering outpost lost power. +// 1M Charge, 150K I/O +/obj/machinery/power/smes/buildable/outpost_substation/New() + ..(0) + component_parts += new /obj/item/weapon/smes_coil/weak(src) + recalc_coils() + +// This one is pre-installed on engineering shuttle. Allows rapid charging/discharging for easier transport of power to outpost +// 11M Charge, 2.5M I/O +/obj/machinery/power/smes/buildable/power_shuttle/New() + ..(0) + component_parts += new /obj/item/weapon/smes_coil/super_io(src) + component_parts += new /obj/item/weapon/smes_coil/super_io(src) + component_parts += new /obj/item/weapon/smes_coil(src) + recalc_coils() + + + + + + +// END SMES SUBTYPES + // SMES itself /obj/machinery/power/smes/buildable var/max_coils = 6 //30M capacity, 1.5MW input/output when fully upgraded /w default coils @@ -52,20 +99,24 @@ else // RCON wire cut usr << "Connection error: Destination Unreachable." + // Cyborgs standing next to the SMES can play with the wiring. + if(istype(usr, /mob/living/silicon/robot) && Adjacent(usr) && open_hatch) + wires.Interact(usr) + // Proc: New() // Parameters: None // Description: Adds standard components for this SMES, and forces recalculation of properties. -/obj/machinery/power/smes/buildable/New() +/obj/machinery/power/smes/buildable/New(var/install_coils = 1) component_parts = list() component_parts += new /obj/item/stack/cable_coil(src,30) component_parts += new /obj/item/weapon/circuitboard/smes(src) src.wires = new /datum/wires/smes(src) // Allows for mapped-in SMESs with larger capacity/IO - for(var/i = 1, i <= cur_coils, i++) - component_parts += new /obj/item/weapon/smes_coil(src) - - recalc_coils() + if(install_coils) + for(var/i = 1, i <= cur_coils, i++) + component_parts += new /obj/item/weapon/smes_coil(src) + recalc_coils() ..() // Proc: attack_hand() @@ -318,14 +369,14 @@ // Parameters: None // Description: Switches the input on/off depending on previous setting /obj/machinery/power/smes/buildable/proc/toggle_input() - input_attempt = !input_attempt + inputting(!input_attempt) update_icon() // Proc: toggle_output() // Parameters: None // Description: Switches the output on/off depending on previous setting /obj/machinery/power/smes/buildable/proc/toggle_output() - output_attempt = !output_attempt + outputting(!output_attempt) update_icon() // Proc: set_input() diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 9220f847b9..01f6a55044 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -6,73 +6,159 @@ flags = CONDUCT slot_flags = SLOT_BELT throwforce = 1 - w_class = 1.0 - var/caliber = "" //Which kind of guns it can be loaded into - var/projectile_type = ""//The bullet type to create when New() is called - var/obj/item/projectile/BB = null //The loaded bullet + w_class = 1 + var/caliber = "" //Which kind of guns it can be loaded into + var/projectile_type //The bullet type to create when New() is called + var/obj/item/projectile/BB = null //The loaded bullet - make it so that the projectiles are created only when needed? + var/spent_icon = null +/obj/item/ammo_casing/New() + ..() + if(ispath(projectile_type)) + BB = new projectile_type(src) + pixel_x = rand(-10, 10) + pixel_y = rand(-10, 10) - New() - ..() - if(projectile_type) - BB = new projectile_type(src) - pixel_x = rand(-10.0, 10) - pixel_y = rand(-10.0, 10) - set_dir(pick(cardinal)) - +//removes the projectile from the ammo casing +/obj/item/ammo_casing/proc/expend() + . = BB + BB = null + set_dir(pick(cardinal)) //spin spent casings + update_icon() /obj/item/ammo_casing/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/screwdriver)) - if(BB) - if(initial(BB.name) == "bullet") - var/tmp_label = "" - var/label_text = sanitize(copytext(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label), 1, MAX_NAME_LEN)) - if(length(label_text) > 20) - user << "\red The inscription can be at most 20 characters long." - else - if(label_text == "") - user << "\blue You scratch the inscription off of [initial(BB)]." - BB.name = initial(BB.name) - else - user << "\blue You inscribe \"[label_text]\" into \the [initial(BB.name)]." - BB.name = "[initial(BB.name)] \"[label_text]\"" - else - user << "\blue You can only inscribe a metal bullet." //because inscribing beanbags is silly - else + if(!BB) user << "\blue There is no bullet in the casing to inscribe anything into." + return + + var/tmp_label = "" + var/label_text = sanitizeSafe(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label), MAX_NAME_LEN) + if(length(label_text) > 20) + user << "\red The inscription can be at most 20 characters long." + else if(!label_text) + user << "\blue You scratch the inscription off of [initial(BB)]." + BB.name = initial(BB.name) + else + user << "\blue You inscribe \"[label_text]\" into \the [initial(BB.name)]." + BB.name = "[initial(BB.name)] (\"[label_text]\")" + +/obj/item/ammo_casing/update_icon() + if(spent_icon && !BB) + icon_state = spent_icon /obj/item/ammo_casing/examine(mob/user) ..() if (!BB) user << "This one is spent." -//Boxes of ammo +//Gun loading types +#define SINGLE_CASING 1 //The gun only accepts ammo_casings. ammo_magazines should never have this as their mag_type. +#define SPEEDLOADER 2 //Transfers casings from the mag to the gun when used. +#define MAGAZINE 4 //The magazine item itself goes inside the gun + +//An item that holds casings and can be used to put them inside guns /obj/item/ammo_magazine - name = "ammo box (.357)" - desc = "A box of ammo" + name = "magazine" + desc = "A magazine for some kind of gun." icon_state = "357" icon = 'icons/obj/ammo.dmi' flags = CONDUCT slot_flags = SLOT_BELT item_state = "syringe_kit" - matter = list("metal" = 50000) - throwforce = 2 - w_class = 2.0 + matter = list("metal" = 500) + throwforce = 5 + w_class = 2 throw_speed = 4 throw_range = 10 + var/list/stored_ammo = list() - var/ammo_type = "/obj/item/ammo_casing" + var/mag_type = SPEEDLOADER //ammo_magazines can only be used with compatible guns. This is not a bitflag, the load_method var on guns is. + var/caliber = "357" var/max_ammo = 7 + + var/ammo_type = /obj/item/ammo_casing //ammo type that is initially loaded + var/initial_ammo = null + var/multiple_sprites = 0 + //because BYOND doesn't support numbers as keys in associative lists + var/list/icon_keys = list() //keys + var/list/ammo_states = list() //values +/obj/item/ammo_magazine/New() + if(multiple_sprites) + initialize_magazine_icondata(src) - New() - for(var/i = 1, i <= max_ammo, i++) + if(isnull(initial_ammo)) + initial_ammo = max_ammo + + if(initial_ammo) + for(var/i in 1 to initial_ammo) stored_ammo += new ammo_type(src) + update_icon() + +/obj/item/ammo_magazine/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W, /obj/item/ammo_casing)) + var/obj/item/ammo_casing/C = W + if(C.caliber != caliber) + user << "[C] does not fit into [src]." + return + if(stored_ammo.len >= max_ammo) + user << "[src] is full!" + return + user.remove_from_mob(C) + C.loc = src + stored_ammo.Insert(1, C) //add to the head of the list update_icon() - +/obj/item/ammo_magazine/attack_self(mob/user) + if(!stored_ammo.len) + user << "[src] is already empty!" + return + user << "You empty [src]." + for(var/obj/item/ammo_casing/C in stored_ammo) + C.loc = user.loc + C.set_dir(pick(cardinal)) + stored_ammo.Cut() update_icon() - if(multiple_sprites) - icon_state = "[initial(icon_state)]-[stored_ammo.len]" - desc = "There are [stored_ammo.len] shell\s left!" + +/obj/item/ammo_magazine/update_icon() + if(multiple_sprites) + //find the lowest key greater than or equal to stored_ammo.len + var/new_state = null + for(var/idx in 1 to icon_keys.len) + var/ammo_count = icon_keys[idx] + if (ammo_count >= stored_ammo.len) + new_state = ammo_states[idx] + break + icon_state = (new_state)? new_state : initial(icon_state) + +/obj/item/ammo_magazine/examine(mob/user) + ..() + user << "There [(stored_ammo.len > 1)? "are" : "is"] [stored_ammo.len] round\s left!" + +//magazine icon state caching +/var/global/list/magazine_icondata_keys = list() +/var/global/list/magazine_icondata_states = list() + +/proc/initialize_magazine_icondata(var/obj/item/ammo_magazine/M) + var/typestr = "[M.type]" + if(!(typestr in magazine_icondata_keys) || !(typestr in magazine_icondata_states)) + magazine_icondata_cache_add(M) + + M.icon_keys = magazine_icondata_keys[typestr] + M.ammo_states = magazine_icondata_states[typestr] + +/proc/magazine_icondata_cache_add(var/obj/item/ammo_magazine/M) + var/list/icon_keys = list() + var/list/ammo_states = list() + var/list/states = icon_states(M.icon) + for(var/i = 0, i <= M.max_ammo, i++) + var/ammo_state = "[M.icon_state]-[i]" + if(ammo_state in states) + icon_keys += i + ammo_states += ammo_state + + magazine_icondata_keys["[M.type]"] = icon_keys + magazine_icondata_states["[M.type]"] = ammo_states + diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index f0daf2eebb..e25d8f39f1 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -1,38 +1,200 @@ /obj/item/ammo_magazine/a357 - name = "ammo box (.357)" - desc = "A box of .357 ammo" - icon_state = "357" - ammo_type = "/obj/item/ammo_casing/a357" + //name = "ammo box (.357)" + //desc = "A box of .357 ammo" + //icon_state = "357" + name = "speed loader (.357)" + icon_state = "T38" + caliber = "357" + ammo_type = /obj/item/ammo_casing/a357 + matter = list("metal" = 1260) max_ammo = 7 multiple_sprites = 1 /obj/item/ammo_magazine/c38 name = "speed loader (.38)" icon_state = "38" - ammo_type = "/obj/item/ammo_casing/c38" + caliber = "38" + matter = list("metal" = 360) + ammo_type = /obj/item/ammo_casing/c38 max_ammo = 6 multiple_sprites = 1 +/obj/item/ammo_magazine/c38/rubber + name = "speed loader (.38 rubber)" + ammo_type = /obj/item/ammo_casing/c38r /obj/item/ammo_magazine/c45m name = "magazine (.45)" icon_state = "45" - ammo_type = "/obj/item/ammo_casing/c45" + mag_type = MAGAZINE + ammo_type = /obj/item/ammo_casing/c45 + matter = list("metal" = 525) //metal costs are very roughly based around 1 .45 casing = 75 metal + caliber = ".45" max_ammo = 7 multiple_sprites = 1 -/obj/item/ammo_magazine/c45/empty - max_ammo = 0 +/obj/item/ammo_magazine/c45m/empty + initial_ammo = 0 -/obj/item/ammo_magazine/c45r +/obj/item/ammo_magazine/c45m/rubber name = "magazine (.45 rubber)" - icon_state = "45" - ammo_type = "/obj/item/ammo_casing/c45r" + ammo_type = /obj/item/ammo_casing/c45r + +/obj/item/ammo_magazine/c45m/flash + name = "magazine (.45 flash)" + ammo_type = "/obj/item/ammo_casing/c45f" + +/obj/item/ammo_magazine/mc9mm + name = "magazine (9mm)" + icon_state = "9x19p" + origin_tech = "combat=2" + mag_type = MAGAZINE + matter = list("metal" = 600) + caliber = "9mm" + ammo_type = /obj/item/ammo_casing/c9mm + max_ammo = 10 + multiple_sprites = 1 + +/obj/item/ammo_magazine/mc9mm/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/mc9mm/flash + ammo_type = /obj/item/ammo_casing/c9mmf + +/obj/item/ammo_magazine/c9mm + name = "ammunition Box (9mm)" + icon_state = "9mm" + origin_tech = "combat=2" + matter = list("metal" = 1800) + caliber = "9mm" + ammo_type = /obj/item/ammo_casing/c9mm + max_ammo = 30 + +/obj/item/ammo_magazine/c9mm/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/mc9mmt + name = "top mounted magazine (9mm)" + icon_state = "9mmt" + mag_type = MAGAZINE + ammo_type = /obj/item/ammo_casing/c9mm + matter = list("metal" = 1200) + caliber = "9mm" + max_ammo = 20 + multiple_sprites = 1 + +/obj/item/ammo_magazine/mc9mmt/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/mc9mmt/rubber + name = "top mounted magazine (9mm rubber)" + ammo_type = /obj/item/ammo_casing/c9mmr + +/obj/item/ammo_magazine/c45 + name = "ammunition Box (.45)" + icon_state = "9mm" + origin_tech = "combat=2" + caliber = ".45" + matter = list("metal" = 2250) + ammo_type = /obj/item/ammo_casing/c45 + max_ammo = 30 + +/obj/item/ammo_magazine/c9mm/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/a12mm + name = "magazine (12mm)" + icon_state = "12mm" + origin_tech = "combat=2" + mag_type = MAGAZINE + caliber = "12mm" + matter = list("metal" = 1500) + ammo_type = "/obj/item/ammo_casing/a12mm" + max_ammo = 20 + multiple_sprites = 1 + +/obj/item/ammo_magazine/a12mm/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/a556 + name = "magazine (5.56mm)" + icon_state = "5.56" + origin_tech = "combat=2" + mag_type = MAGAZINE + caliber = "a556" + matter = list("metal" = 1800) + ammo_type = /obj/item/ammo_casing/a556 + max_ammo = 10 + multiple_sprites = 1 + +/obj/item/ammo_magazine/a556/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/a50 + name = "magazine (.50)" + icon_state = "50ae" + origin_tech = "combat=2" + mag_type = MAGAZINE + caliber = ".50" + matter = list("metal" = 1260) + ammo_type = /obj/item/ammo_casing/a50 max_ammo = 7 multiple_sprites = 1 -/obj/item/ammo_magazine/c45r/empty - max_ammo = 0 +/obj/item/ammo_magazine/a50/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/a75 + name = "ammo magazine (20mm)" + icon_state = "75" + mag_type = MAGAZINE + caliber = "75" + ammo_type = /obj/item/ammo_casing/a75 + multiple_sprites = 1 + max_ammo = 4 + +/obj/item/ammo_magazine/a75/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/a762 + name = "magazine box (7.62mm)" + icon_state = "a762" + origin_tech = "combat=2" + mag_type = MAGAZINE + caliber = "a762" + matter = list("metal" = 4500) + ammo_type = /obj/item/ammo_casing/a762 + max_ammo = 50 + multiple_sprites = 1 + +/obj/item/ammo_magazine/a762/empty + initial_ammo = 0 + +/obj/item/ammo_magazine/c762 + name = "magazine (7.62mm)" + icon_state = "c762" + mag_type = MAGAZINE + caliber = "a762" + matter = list("metal" = 1800) + ammo_type = /obj/item/ammo_casing/a762 + max_ammo = 20 + multiple_sprites = 1 + +/obj/item/ammo_magazine/chameleon + name = "magazine (.45)" + icon_state = "45" + mag_type = MAGAZINE + caliber = ".45" + ammo_type = /obj/item/ammo_casing/chameleon + max_ammo = 7 + multiple_sprites = 1 + matter = list() + +/obj/item/ammo_magazine/chameleon/empty + initial_ammo = 0 + +/* +//unused garbage /obj/item/ammo_magazine/a418 name = "ammo box (.418)" @@ -41,114 +203,10 @@ max_ammo = 7 multiple_sprites = 1 - - /obj/item/ammo_magazine/a666 name = "ammo box (.666)" icon_state = "666" ammo_type = "/obj/item/ammo_casing/a666" max_ammo = 4 multiple_sprites = 1 - - -/obj/item/ammo_magazine/mc9mm - name = "magazine (9mm)" - icon_state = "9x19p" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/c9mm" - max_ammo = 8 - multiple_sprites = 1 - -/obj/item/ammo_magazine/mc9mm/empty - max_ammo = 0 - -/obj/item/ammo_magazine/c9mm - name = "Ammunition Box (9mm)" - icon_state = "9mm" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/c9mm" - max_ammo = 30 - - - -/obj/item/ammo_magazine/c45 - name = "Ammunition Box (.45)" - icon_state = "9mm" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/c45" - max_ammo = 30 - - - -/obj/item/ammo_magazine/a12mm - name = "magazine (12mm)" - icon_state = "12mm" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/a12mm" - max_ammo = 20 - multiple_sprites = 1 - - -/obj/item/ammo_magazine/a12mm/empty - name = "magazine (12mm)" - icon_state = "12mm" - ammo_type = "/obj/item/ammo_casing/12mm" - max_ammo = 0 - -/obj/item/ammo_magazine/a50 - name = "magazine (.50)" - icon_state = "50ae" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/a50" - max_ammo = 7 - multiple_sprites = 1 - -/obj/item/ammo_magazine/a50/empty - name = "magazine (.50)" - icon_state = "50ae" - ammo_type = "/obj/item/ammo_casing/a50" - max_ammo = 0 - -/obj/item/ammo_magazine/a75 - name = "ammo magazine (.75)" - icon_state = "75" - ammo_type = "/obj/item/ammo_casing/a75" - multiple_sprites = 1 - max_ammo = 8 - -/obj/item/ammo_magazine/a75/empty - name = "ammo magazine (.75)" - icon_state = "75" - ammo_type = "/obj/item/ammo_casing/a75" - max_ammo = 0 - -/obj/item/ammo_magazine/a762 - name = "magazine (a762)" - icon_state = "a762" - origin_tech = "combat=2" - ammo_type = "/obj/item/ammo_casing/a762" - max_ammo = 50 - multiple_sprites = 1 - -/obj/item/ammo_magazine/a762/empty - name = "magazine (a762)" - icon_state = "a762" - ammo_type = "/obj/item/ammo_casing/a762" - max_ammo = 0 - multiple_sprites = 1 - -/obj/item/ammo_magazine/chameleon - name = "magazine (.45)" - icon_state = "45" - ammo_type = "/obj/item/ammo_casing/chameleon" - max_ammo = 7 - multiple_sprites = 1 - matter = list() - -/obj/item/ammo_magazine/chameleon/empty - name = "magazine (.45)" - icon_state = "45" - ammo_type = "/obj/item/ammo_casing/chameleon" - max_ammo = 0 - multiple_sprites = 1 - matter = list() +*/ diff --git a/code/modules/projectiles/ammunition/bullets.dm b/code/modules/projectiles/ammunition/bullets.dm index 134b9a6ca3..931555381a 100644 --- a/code/modules/projectiles/ammunition/bullets.dm +++ b/code/modules/projectiles/ammunition/bullets.dm @@ -1,113 +1,156 @@ /obj/item/ammo_casing/a357 desc = "A .357 bullet casing." caliber = "357" - projectile_type = "/obj/item/projectile/bullet" + projectile_type = /obj/item/projectile/bullet/pistol/strong /obj/item/ammo_casing/a50 desc = "A .50AE bullet casing." caliber = ".50" - projectile_type = "/obj/item/projectile/bullet" - -/obj/item/ammo_casing/a418 - desc = "A .418 bullet casing." - caliber = "357" - projectile_type = "/obj/item/projectile/bullet/suffocationbullet" - + projectile_type = /obj/item/projectile/bullet/pistol/strong /obj/item/ammo_casing/a75 - desc = "A .75 bullet casing." + desc = "A 20mm bullet casing." caliber = "75" - projectile_type = "/obj/item/projectile/bullet/gyro" - - -/obj/item/ammo_casing/a666 - desc = "A .666 bullet casing." - caliber = "357" - projectile_type = "/obj/item/projectile/bullet/cyanideround" - + projectile_type = /obj/item/projectile/bullet/gyro /obj/item/ammo_casing/c38 desc = "A .38 bullet casing." caliber = "38" - projectile_type = "/obj/item/projectile/bullet/weakbullet" + projectile_type = /obj/item/projectile/bullet/pistol +/obj/item/ammo_casing/c38r + desc = "A .38 rubber bullet casing." + caliber = "38" + projectile_type = /obj/item/projectile/bullet/pistol/rubber /obj/item/ammo_casing/c9mm desc = "A 9mm bullet casing." caliber = "9mm" - projectile_type = "/obj/item/projectile/bullet/midbullet2" + projectile_type = /obj/item/projectile/bullet/pistol + +/obj/item/ammo_casing/c9mmf + desc = "A 9mm flash shell casing." + caliber = "9mm" + projectile_type = /obj/item/projectile/energy/flash + +/obj/item/ammo_casing/c9mmr + desc = "A 9mm rubber bullet casing." + caliber = "9mm" + projectile_type = /obj/item/projectile/bullet/pistol/rubber /obj/item/ammo_casing/c45 desc = "A .45 bullet casing." caliber = ".45" - projectile_type = "/obj/item/projectile/bullet/midbullet" + projectile_type = /obj/item/projectile/bullet/pistol/medium /obj/item/ammo_casing/c45r desc = "A .45 rubber bullet casing." caliber = ".45" - projectile_type = "/obj/item/projectile/bullet/weakbullet/rubber" + projectile_type = /obj/item/projectile/bullet/pistol/rubber + +/obj/item/ammo_casing/c45f + desc = "A .45 flash shell casing." + caliber = ".45" + projectile_type = /obj/item/projectile/energy/flash /obj/item/ammo_casing/a12mm desc = "A 12mm bullet casing." caliber = "12mm" - projectile_type = "/obj/item/projectile/bullet/midbullet2" + projectile_type = /obj/item/projectile/bullet/pistol/medium /obj/item/ammo_casing/shotgun + name = "shotgun slug" + desc = "A 12 gauge slug." + icon_state = "slshell" + caliber = "shotgun" + projectile_type = /obj/item/projectile/bullet/shotgun + matter = list("metal" = 360) + +/obj/item/ammo_casing/shotgun/pellet name = "shotgun shell" desc = "A 12 gauge shell." icon_state = "gshell" - caliber = "shotgun" - projectile_type = "/obj/item/projectile/bullet" - matter = list("metal" = 12500) - + projectile_type = /obj/item/projectile/bullet/pellet/shotgun + matter = list("metal" = 360) /obj/item/ammo_casing/shotgun/blank name = "shotgun shell" desc = "A blank shell." icon_state = "blshell" - projectile_type = "/obj/item/projectile/bullet/chameleon" - matter = list("metal" = 250) - + projectile_type = /obj/item/projectile/bullet/blank + matter = list("metal" = 90) /obj/item/ammo_casing/shotgun/beanbag name = "beanbag shell" - desc = "A weak beanbag shell." + desc = "A beanbag shell." icon_state = "bshell" - projectile_type = "/obj/item/projectile/bullet/weakbullet/beanbag" - matter = list("metal" = 500) - + projectile_type = /obj/item/projectile/bullet/shotgun/beanbag + matter = list("metal" = 180) +//Can stun in one hit if aimed at the head, but +//is blocked by clothing that stops tasers and is vulnerable to EMP /obj/item/ammo_casing/shotgun/stunshell name = "stun shell" - desc = "A stunning shell." + desc = "A 12 gauge taser cartridge." icon_state = "stunshell" - projectile_type = "/obj/item/projectile/bullet/stunshot" - matter = list("metal" = 2500) + spent_icon = "stunshell-spent" + projectile_type = /obj/item/projectile/energy/electrode/stunshot + matter = list("metal" = 360, "glass" = 720) +/obj/item/ammo_casing/shotgun/stunshell/emp_act(severity) + if(prob(100/severity)) BB = null + update_icon() -/obj/item/ammo_casing/shotgun/dart - name = "shotgun darts" - desc = "A dart for use in shotguns." - icon_state = "dart" - projectile_type = "/obj/item/projectile/energy/dart" - matter = list("metal" = 12500) +//Does not stun, only blinds, but has area of effect. +/obj/item/ammo_casing/shotgun/flash + name = "flash shell" + desc = "A chemical shell used to signal distress or provide illumination." + icon_state = "fshell" + projectile_type = /obj/item/projectile/energy/flash/flare + matter = list("metal" = 90, "glass" = 90) /obj/item/ammo_casing/a762 - desc = "A 7.62 bullet casing." + desc = "A 7.62mm bullet casing." caliber = "a762" - projectile_type = "/obj/item/projectile/bullet/a762" + projectile_type = /obj/item/projectile/bullet/rifle/a762 + +/obj/item/ammo_casing/a145 + name = "shell casing" + desc = "A 14.5mm shell." + icon_state = "lcasing" + spent_icon = "lcasing-spent" + caliber = "14.5mm" + projectile_type = /obj/item/projectile/bullet/rifle/a145 + matter = list("metal" = 1250) + +/obj/item/ammo_casing/a556 + desc = "A 5.56mm bullet casing." + caliber = "a556" + projectile_type = /obj/item/projectile/bullet/rifle/a556 /obj/item/ammo_casing/rocket name = "rocket shell" desc = "A high explosive designed to be fired from a launcher." icon_state = "rocketshell" - projectile_type = "/obj/item/missile" + projectile_type = /obj/item/missile caliber = "rocket" /obj/item/ammo_casing/chameleon name = "chameleon bullets" desc = "A set of bullets for the Chameleon Gun." - projectile_type = "/obj/item/projectile/bullet/chameleon" + projectile_type = /obj/item/projectile/bullet/chameleon caliber = ".45" + +/* +/obj/item/ammo_casing/a418 + desc = "A .418 bullet casing." + caliber = "357" + projectile_type = /obj/item/projectile/bullet/suffocationbullet + +/obj/item/ammo_casing/a666 + desc = "A .666 bullet casing." + caliber = "357" + projectile_type = /obj/item/projectile/bullet/cyanideround +*/ \ No newline at end of file diff --git a/code/modules/projectiles/effects.dm b/code/modules/projectiles/effects.dm new file mode 100644 index 0000000000..066f4cf55d --- /dev/null +++ b/code/modules/projectiles/effects.dm @@ -0,0 +1,126 @@ +/obj/effect/projectile + icon = 'icons/effects/projectiles.dmi' + icon_state = "bolt" + layer = 20 + +/obj/effect/projectile/New(var/turf/location) + if(istype(location)) + loc = location + +/obj/effect/projectile/proc/set_transform(var/matrix/M) + if(istype(M)) + transform = M + +/obj/effect/projectile/proc/activate() + spawn(3) + delete() //see effect_system.dm - sets loc to null and lets GC handle removing these effects + + return + +//---------------------------- +// Laser beam +//---------------------------- +/obj/effect/projectile/laser/tracer + icon_state = "beam" + +/obj/effect/projectile/laser/muzzle + icon_state = "muzzle_laser" + +/obj/effect/projectile/laser/impact + icon_state = "impact_laser" + +//---------------------------- +// Blue laser beam +//---------------------------- +/obj/effect/projectile/laser_blue/tracer + icon_state = "beam_blue" + +/obj/effect/projectile/laser_blue/muzzle + icon_state = "muzzle_blue" + +/obj/effect/projectile/laser_blue/impact + icon_state = "impact_blue" + +//---------------------------- +// Omni laser beam +//---------------------------- +/obj/effect/projectile/laser_omni/tracer + icon_state = "beam_omni" + +/obj/effect/projectile/laser_omni/muzzle + icon_state = "muzzle_omni" + +/obj/effect/projectile/laser_omni/impact + icon_state = "impact_omni" + +//---------------------------- +// Xray laser beam +//---------------------------- +/obj/effect/projectile/xray/tracer + icon_state = "xray" + +/obj/effect/projectile/xray/muzzle + icon_state = "muzzle_xray" + +/obj/effect/projectile/xray/impact + icon_state = "impact_xray" + +//---------------------------- +// Heavy laser beam +//---------------------------- +/obj/effect/projectile/laser_heavy/tracer + icon_state = "beam_heavy" + +/obj/effect/projectile/laser_heavy/muzzle + icon_state = "muzzle_beam_heavy" + +/obj/effect/projectile/laser_heavy/impact + icon_state = "impact_beam_heavy" + +//---------------------------- +// Pulse laser beam +//---------------------------- +/obj/effect/projectile/laser_pulse/tracer + icon_state = "u_laser" + +/obj/effect/projectile/laser_pulse/muzzle + icon_state = "muzzle_u_laser" + +/obj/effect/projectile/laser_pulse/impact + icon_state = "impact_u_laser" + +//---------------------------- +// Pulse muzzle effect only +//---------------------------- +/obj/effect/projectile/pulse/muzzle + icon_state = "muzzle_pulse" + +//---------------------------- +// Emitter beam +//---------------------------- +/obj/effect/projectile/emitter/tracer + icon_state = "emitter" + +/obj/effect/projectile/emitter/muzzle + icon_state = "muzzle_emitter" + +/obj/effect/projectile/emitter/impact + icon_state = "impact_emitter" + +//---------------------------- +// Stun beam +//---------------------------- +/obj/effect/projectile/stun/tracer + icon_state = "stun" + +/obj/effect/projectile/stun/muzzle + icon_state = "muzzle_stun" + +/obj/effect/projectile/stun/impact + icon_state = "impact_stun" + +//---------------------------- +// Bullet +//---------------------------- +/obj/effect/projectile/bullet/muzzle + icon_state = "muzzle_bullet" diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index fc44ed09fc..871ac5395a 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -1,107 +1,124 @@ +//Parent gun type. Guns are weapons that can be aimed at mobs and act over a distance /obj/item/weapon/gun name = "gun" desc = "Its a gun. It's pretty terrible, though." icon = 'icons/obj/gun.dmi' + item_icons = list( + icon_l_hand = 'icons/mob/items/lefthand_guns.dmi', + icon_r_hand = 'icons/mob/items/righthand_guns.dmi', + ) icon_state = "detective" item_state = "gun" flags = CONDUCT - slot_flags = SLOT_BELT + slot_flags = SLOT_BELT|SLOT_HOLSTER matter = list("metal" = 2000) - w_class = 3.0 + w_class = 3 throwforce = 5 throw_speed = 4 throw_range = 5 - force = 5.0 + force = 5 origin_tech = "combat=1" attack_verb = list("struck", "hit", "bashed") + zoomdevicename = "scope" + var/fire_delay = 6 var/fire_sound = 'sound/weapons/Gunshot.ogg' - var/obj/item/projectile/in_chamber = null - var/caliber = "" + var/fire_sound_text = "gunshot" + var/recoil = 0 //screen shake var/silenced = 0 - var/recoil = 0 - var/ejectshell = 1 - var/clumsy_check = 1 - var/tmp/list/mob/living/target //List of who yer targeting. - var/tmp/lock_time = -100 - var/tmp/mouthshoot = 0 ///To stop people from suiciding twice... >.> - var/automatic = 0 //Used to determine if you can target multiple people. + var/accuracy = 0 //accuracy is measured in tiles. +1 accuracy means that everything is effectively one tile closer for the purpose of miss chance, -1 means the opposite. launchers are not supported, at the moment. + var/scoped_accuracy = null + + var/last_fired = 0 + + //aiming system stuff + var/keep_aim = 1 //1 for keep shooting until aim is lowered + //0 for one bullet after tarrget moves and aim is lowered + var/multi_aim = 0 //Used to determine if you can target multiple people. + var/tmp/list/mob/living/aim_targets //List of who yer targeting. var/tmp/mob/living/last_moved_mob //Used to fire faster at more than one person. var/tmp/told_cant_shoot = 0 //So that it doesn't spam them with the fact they cannot hit them. - var/firerate = 0 //0 for keep shooting until aim is lowered - // 1 for one bullet after tarrget moves and aim is lowered - var/fire_delay = 6 - var/last_fired = 0 + var/tmp/lock_time = -100 - proc/ready_to_fire() - if(world.time >= last_fired + fire_delay) - last_fired = world.time - return 1 - else - return 0 +/obj/item/weapon/gun/New() + ..() + if(isnull(scoped_accuracy)) + scoped_accuracy = accuracy - proc/load_into_chamber() +//Returns 1 if the gun is able to be fired +/obj/item/weapon/gun/proc/ready_to_fire() + if(world.time >= last_fired + fire_delay) + last_fired = world.time + return 1 + else return 0 - proc/special_check(var/mob/M) //Placeholder for any special checks, like detective's revolver. - return 1 +//Checks whether a given mob can use the gun +//Any checks that shouldn't result in handle_click_empty() being called if they fail should go here. +//Otherwise, if you want handle_click_empty() to be called, check in consume_next_projectile() and return null there. +/obj/item/weapon/gun/proc/special_check(var/mob/user) + if(!istype(user, /mob/living)) + return 0 + if(!user.IsAdvancedToolUser()) + return 0 + + var/mob/living/M = user + + if(HULK in M.mutations) + M << "Your fingers are much too large for the trigger guard!" + return 0 + if((CLUMSY in M.mutations) && prob(40)) //Clumsy handling + var/obj/P = consume_next_projectile() + if(P) + if(process_projectile(P, user, user, pick("l_foot", "r_foot"))) + handle_post_fire(user, user) + user.visible_message( + "[user] shoots \himself in the foot with \the [src]!", + "You shoot yourself in the foot with \the [src]!" + ) + M.drop_item() + else + handle_click_empty(user) + return 0 + return 1 - emp_act(severity) - for(var/obj/O in contents) - O.emp_act(severity) - -/obj/item/weapon/gun/afterattack(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, flag, params) - if(flag) return //It's adjacent, is the user, or is on the user's person - if(istype(target, /obj/machinery/recharger) && istype(src, /obj/item/weapon/gun/energy)) return//Shouldnt flag take care of this? +/obj/item/weapon/gun/emp_act(severity) + for(var/obj/O in contents) + O.emp_act(severity) +/obj/item/weapon/gun/afterattack(atom/A, mob/living/user, adjacent, params) + if(adjacent) return //A is adjacent, is the user, or is on the user's person //decide whether to aim or shoot normally var/aiming = 0 - if(user && user.client && !(A in target)) + if(user && user.client && !(A in aim_targets)) var/client/C = user.client //If help intent is on and we have clicked on an eligible target, switch to aim mode automatically - if(user.a_intent == "help" && isliving(A) && !C.gun_mode) + if(user.a_intent == I_HELP && isliving(A) && !C.gun_mode) C.ToggleGunMode() if(C.gun_mode) aiming = PreFire(A,user,params) //They're using the new gun system, locate what they're aiming at. if (!aiming) - if(user && user.a_intent == "help") //regardless of what happens, refuse to shoot if help intent is on + if(user && user.a_intent == I_HELP) //regardless of what happens, refuse to shoot if help intent is on user << "\red You refrain from firing your [src] as your intent is set to help." else Fire(A,user,params) //Otherwise, fire normally. -/obj/item/weapon/gun/proc/isHandgun() - return 1 +/obj/item/weapon/gun/attack(atom/A, mob/living/user, def_zone) + if (A == user && user.zone_sel.selecting == "mouth" && !mouthshoot) + handle_suicide(user) + else if(user.a_intent == I_HURT) //point blank shooting + Fire(A, user, pointblank=1) + else + return ..() //Pistolwhippin' -/obj/item/weapon/gun/proc/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0)//TODO: go over this - //Exclude lasertag guns from the CLUMSY check. - if(clumsy_check) - if(istype(user, /mob/living)) - var/mob/living/M = user - if ((CLUMSY in M.mutations) && prob(50)) - M << "[src] blows up in your face." - M.take_organ_damage(0,20) - M.drop_item() - del(src) - return - - if (!user.IsAdvancedToolUser()) - return - if(istype(user, /mob/living)) - var/mob/living/M = user - if (HULK in M.mutations) - M << "Your fingers are much too large for the trigger guard!" - return +/obj/item/weapon/gun/proc/Fire(atom/target, mob/living/user, params, pointblank=0, reflex=0) + if(!user || !target) return add_fingerprint(user) - var/turf/curloc = get_turf(user) - var/turf/targloc = get_turf(target) - if (!istype(targloc) || !istype(curloc)) - return - if(!special_check(user)) return @@ -110,128 +127,155 @@ user << "[src] is not ready to fire again!" return - if(!load_into_chamber()) //CHECK - return click_empty(user) - - if(!in_chamber) + var/obj/projectile = consume_next_projectile(user) + if(!projectile) + handle_click_empty(user) return - in_chamber.firer = user - in_chamber.def_zone = user.zone_sel.selecting - if(targloc == curloc) - user.bullet_act(in_chamber) - del(in_chamber) + user.next_move = world.time + 4 + + if(process_projectile(projectile, user, target, user.zone_sel.selecting, params, pointblank, reflex)) + handle_post_fire(user, target, pointblank, reflex) + update_icon() - return + update_held_icon() - if(recoil) - spawn() - shake_camera(user, recoil + 1, recoil) +//obtains the next projectile to fire +/obj/item/weapon/gun/proc/consume_next_projectile() + return null + +//used by aiming code +/obj/item/weapon/gun/proc/can_hit(atom/target as mob, var/mob/living/user as mob) + if(!special_check(user)) + return 2 + //just assume we can shoot through glass and stuff. No big deal, the player can just choose to not target someone + //on the other side of a window if it makes a difference. Or if they run behind a window, too bad. + return check_trajectory(target, user) + +//called if there was no projectile to shoot +/obj/item/weapon/gun/proc/handle_click_empty(mob/user) + if (user) + user.visible_message("*click click*", "*click*") + else + src.visible_message("*click click*") + playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1) + +//called after successfully firing +/obj/item/weapon/gun/proc/handle_post_fire(mob/user, atom/target, var/pointblank=0, var/reflex=0) if(silenced) playsound(user, fire_sound, 10, 1) else playsound(user, fire_sound, 50, 1) - user.visible_message("[user] fires [src][reflex ? " by reflex":""]!", \ - "You fire [src][reflex ? "by reflex":""]!", \ - "You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!") + user.visible_message( + "[user] fires [src][pointblank ? " point blank at [target]":""][reflex ? " by reflex":""]!", + "You fire [src][reflex ? "by reflex":""]!", + "You hear a [fire_sound_text]!" + ) + + if(recoil) + spawn() + shake_camera(user, recoil+1, recoil) + update_icon() - in_chamber.original = target - in_chamber.loc = get_turf(user) - in_chamber.starting = get_turf(user) - in_chamber.shot_from = src - user.next_move = world.time + 4 - in_chamber.silenced = silenced - in_chamber.current = curloc - in_chamber.yo = targloc.y - curloc.y - in_chamber.xo = targloc.x - curloc.x +//does the actual shooting +/obj/item/weapon/gun/proc/process_projectile(obj/projectile, mob/user, atom/target, var/target_zone, var/params=null, var/pointblank=0, var/reflex=0) + if(!istype(projectile, /obj/item/projectile)) + return 0 //default behaviour only applies to true projectiles + + var/obj/item/projectile/P = projectile + + //shooting while in shock + var/x_offset = 0 + var/y_offset = 0 if(istype(user, /mob/living/carbon)) var/mob/living/carbon/mob = user if(mob.shock_stage > 120) - in_chamber.yo += rand(-2,2) - in_chamber.xo += rand(-2,2) + y_offset = rand(-2,2) + x_offset = rand(-2,2) else if(mob.shock_stage > 70) - in_chamber.yo += rand(-1,1) - in_chamber.xo += rand(-1,1) + y_offset = rand(-1,1) + x_offset = rand(-1,1) + + //Point blank bonus + if(pointblank) + var/damage_mult = 1.3 //default point blank multiplier + + //determine multiplier due to the target being grabbed + if(ismob(target)) + var/mob/M = target + if(M.grabbed_by.len) + var/grabstate = 0 + for(var/obj/item/weapon/grab/G in M.grabbed_by) + grabstate = max(grabstate, G.state) + if(grabstate >= GRAB_NECK) + damage_mult = 3.0 + else if (grabstate >= GRAB_AGGRESSIVE) + damage_mult = 1.5 + + P.damage *= damage_mult if(params) - var/list/mouse_control = params2list(params) - if(mouse_control["icon-x"]) - in_chamber.p_x = text2num(mouse_control["icon-x"]) - if(mouse_control["icon-y"]) - in_chamber.p_y = text2num(mouse_control["icon-y"]) + P.set_clickpoint(params) - spawn() - if(in_chamber) - in_chamber.process() - sleep(1) - in_chamber = null + return !P.launch(target, user, src, target_zone, x_offset, y_offset) - update_icon() - - if(user.hand) - user.update_inv_l_hand() - else - user.update_inv_r_hand() - -/obj/item/weapon/gun/proc/can_fire() - return load_into_chamber() - -/obj/item/weapon/gun/proc/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) - return in_chamber.check_fire(target,user) - -/obj/item/weapon/gun/proc/click_empty(mob/user = null) - if (user) - user.visible_message("*click click*", "\red *click*") - playsound(user, 'sound/weapons/empty.ogg', 100, 1) - else - src.visible_message("*click click*") - playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1) - -/obj/item/weapon/gun/attack(mob/living/M as mob, mob/living/user as mob, def_zone) - //Suicide handling. - if (M == user && user.zone_sel.selecting == "mouth" && !mouthshoot) - mouthshoot = 1 - M.visible_message("\red [user] sticks their gun in their mouth, ready to pull the trigger...") - if(!do_after(user, 40)) - M.visible_message("\blue [user] decided life was worth living") - mouthshoot = 0 - return - if (load_into_chamber()) - user.visible_message("[user] pulls the trigger.") - if(silenced) - playsound(user, fire_sound, 10, 1) - else - playsound(user, fire_sound, 50, 1) - if(istype(in_chamber, /obj/item/projectile/beam/lastertag)) - user.show_message("You feel rather silly, trying to commit suicide with a toy.") - mouthshoot = 0 - return - - in_chamber.on_hit(M) - if (in_chamber.damage_type != HALLOSS) - user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]", sharp=1) - user.death() - else - user << "Ow..." - user.apply_effect(110,AGONY,0) - del(in_chamber) - mouthshoot = 0 - return +//Suicide handling. +/obj/item/weapon/gun/var/mouthshoot = 0 //To stop people from suiciding twice... >.> +/obj/item/weapon/gun/proc/handle_suicide(mob/living/user) + if(!ishuman(user)) + return + var/mob/living/carbon/human/M = user + + mouthshoot = 1 + M.visible_message("\red [user] sticks their gun in their mouth, ready to pull the trigger...") + if(!do_after(user, 40)) + M.visible_message("\blue [user] decided life was worth living") + mouthshoot = 0 + return + var/obj/item/projectile/in_chamber = consume_next_projectile() + if (istype(in_chamber)) + user.visible_message("[user] pulls the trigger.") + if(silenced) + playsound(user, fire_sound, 10, 1) else - click_empty(user) + playsound(user, fire_sound, 50, 1) + if(istype(in_chamber, /obj/item/projectile/beam/lastertag)) + user.show_message("You feel rather silly, trying to commit suicide with a toy.") mouthshoot = 0 return - if (load_into_chamber()) - //Point blank shooting if on harm intent or target we were targeting. - if(user.a_intent == "hurt") - user.visible_message("\red \The [user] fires \the [src] point blank at [M]!") - if(istype(in_chamber)) in_chamber.damage *= 1.3 - Fire(M,user) - return - else if(target && M in target) - Fire(M,user) ///Otherwise, shoot! - return + in_chamber.on_hit(M) + if (in_chamber.damage_type != HALLOSS) + user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]", sharp=1) + user.death() + else + user << "Ow..." + user.apply_effect(110,AGONY,0) + del(in_chamber) + mouthshoot = 0 + return else - return ..() //Pistolwhippin' + handle_click_empty(user) + mouthshoot = 0 + return + +/obj/item/weapon/gun/proc/toggle_scope(var/zoom_amount=2.0) + //looking through a scope limits your periphereal vision + //still, increase the view size by a tiny amount so that sniping isn't too restricted to NSEW + var/zoom_offset = round(world.view * zoom_amount) + var/view_size = round(world.view + zoom_amount) + var/scoped_accuracy_mod = zoom_offset + + zoom(zoom_offset, view_size) + if(zoom) + accuracy = scoped_accuracy + scoped_accuracy_mod + if(recoil) + recoil = round(recoil*zoom_amount+1) //recoil is worse when looking through a scope + +//make sure accuracy and recoil are reset regardless of how the item is unzoomed. +/obj/item/weapon/gun/zoom() + ..() + if(!zoom) + accuracy = initial(accuracy) + recoil = initial(recoil) diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm index fb678d9b4d..9f611e593d 100644 --- a/code/modules/projectiles/guns/alien.dm +++ b/code/modules/projectiles/guns/alien.dm @@ -1,6 +1,7 @@ //Vox pinning weapon. /obj/item/weapon/gun/launcher/spikethrower - name = "Vox spike thrower" + + name = "spike thrower" desc = "A vicious alien projectile weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive." var/last_regen = 0 @@ -24,7 +25,6 @@ ..() /obj/item/weapon/gun/launcher/spikethrower/process() - if(spikes < max_spikes && world.time > last_regen + spike_gen_time) spikes++ last_regen = world.time @@ -32,89 +32,23 @@ /obj/item/weapon/gun/launcher/spikethrower/examine(mob/user) ..(user) - user << "It has [spikes] [spikes == 1 ? "spike" : "spikes"] remaining." + user << "It has [spikes] spike\s remaining." /obj/item/weapon/gun/launcher/spikethrower/update_icon() icon_state = "spikethrower[spikes]" -/obj/item/weapon/gun/launcher/spikethrower/emp_act(severity) - return - /obj/item/weapon/gun/launcher/spikethrower/special_check(user) if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user - if(H.species && H.species.name != "Vox" && H.species.name != "Vox Armalis") - user << "\red \The [src] does not respond to you!" + if(H.species && H.species.name != "Vox") + user << "\The [src] does not respond to you!" return 0 - return 1 + return ..() /obj/item/weapon/gun/launcher/spikethrower/update_release_force() return -/obj/item/weapon/gun/launcher/spikethrower/load_into_chamber() - if(in_chamber) return 1 - if(spikes < 1) return 0 - +/obj/item/weapon/gun/launcher/spikethrower/consume_next_projectile() + if(spikes < 1) return null spikes-- - in_chamber = new /obj/item/weapon/spike(src) - return 1 - -/obj/item/weapon/gun/launcher/spikethrower/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - if(..()) update_icon() - -//This gun only functions for armalis. The on-sprite is too huge to render properly on other sprites. -/obj/item/weapon/gun/energy/noisecannon - name = "alien heavy cannon" - desc = "It's some kind of enormous alien weapon, as long as a man is tall." - - icon = 'icons/obj/gun.dmi' //Actual on-sprite is handled by icon_override. - icon_state = "noisecannon" - item_state = "noisecannon" - recoil = 1 - - force = 10 - projectile_type = "/obj/item/projectile/energy/sonic" - cell_type = "/obj/item/weapon/cell/super" - fire_delay = 40 - fire_sound = 'sound/effects/basscannon.ogg' - - var/mode = 1 - - sprite_sheets = list( - "Vox Armalis" = 'icons/mob/species/armalis/held.dmi' - ) - -/obj/item/weapon/gun/energy/noisecannon/attack_hand(mob/user as mob) - if(loc != user) - var/mob/living/carbon/human/H = user - if(istype(H)) - if(H.species.name == "Vox Armalis") - ..() - return - user << "\red \The [src] is far too large for you to pick up." - return - -/obj/item/weapon/gun/energy/noisecannon/load_into_chamber() //Does not have ammo. - in_chamber = new projectile_type(src) - return 1 - -/obj/item/weapon/gun/energy/noisecannon/update_icon() - return - -//Projectile. -/obj/item/projectile/energy/sonic - name = "distortion" - icon = 'icons/obj/machines/particle_accelerator2.dmi' - icon_state = "particle" - damage = 60 - damage_type = BRUTE - flag = "bullet" - pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE - - embed = 0 - weaken = 5 - stun = 5 - -/obj/item/projectile/energy/sonic/proc/split() - //TODO: create two more projectiles to either side of this one, fire at targets to the side of target turf. - return + return new /obj/item/weapon/spike(src) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 8a38a0325d..994256b12a 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -3,42 +3,89 @@ desc = "A basic energy-based gun." icon_state = "energy" fire_sound = 'sound/weapons/Taser.ogg' + fire_sound_text = "laser blast" var/obj/item/weapon/cell/power_supply //What type of power cell this uses var/charge_cost = 100 //How much energy is needed to fire. - var/cell_type = "/obj/item/weapon/cell" - var/projectile_type = "/obj/item/projectile/beam/practice" + var/cell_type = /obj/item/weapon/cell + var/projectile_type = /obj/item/projectile/beam/practice var/modifystate + var/charge_meter = 1 //if set, the icon state will be chosen based on the current charge + + //self-recharging + var/self_recharge = 0 //if set, the weapon will recharge itself + var/use_external_power = 0 //if set, the weapon will look for an external power source to draw from, otherwise it recharges magically + var/recharge_time = 4 + var/charge_tick = 0 - emp_act(severity) - power_supply.use(round(power_supply.maxcharge / severity)) - update_icon() - ..() - - - New() - ..() - if(cell_type) - power_supply = new cell_type(src) - else - power_supply = new(src) - power_supply.give(power_supply.maxcharge) - return - - - load_into_chamber() - if(in_chamber) return 1 - if(!power_supply) return 0 - if(!power_supply.use(charge_cost)) return 0 - if(!projectile_type) return 0 - in_chamber = new projectile_type(src) - return 1 - - +/obj/item/weapon/gun/energy/emp_act(severity) + ..() update_icon() + +/obj/item/weapon/gun/energy/New() + ..() + if(cell_type) + power_supply = new cell_type(src) + power_supply.give(power_supply.maxcharge) + if(self_recharge) + processing_objects.Add(src) + update_icon() + +/obj/item/weapon/gun/energy/Del() + if(self_recharge) + processing_objects.Remove(src) + ..() + +/obj/item/weapon/gun/energy/process() + if(self_recharge) //Every [recharge_time] ticks, recharge a shot for the cyborg + charge_tick++ + if(charge_tick < recharge_time) return 0 + charge_tick = 0 + + if(!power_supply || power_supply.charge >= power_supply.maxcharge) + return 0 // check if we actually need to recharge + + if(use_external_power) + var/obj/item/weapon/cell/external = get_external_power_supply() + if(!external || !external.use(charge_cost)) //Take power from the borg... + return 0 + + power_supply.give(charge_cost) //... to recharge the shot + update_icon() + return 1 + +/obj/item/weapon/gun/energy/consume_next_projectile() + if(!power_supply) return null + if(!ispath(projectile_type)) return null + if(!power_supply.use(charge_cost)) return null + return new projectile_type(src) + +/obj/item/weapon/gun/energy/proc/get_external_power_supply() + if(isrobot(src.loc)) + var/mob/living/silicon/robot/R = src.loc + return R.cell + if(istype(src.loc, /obj/item/rig_module)) + var/obj/item/rig_module/module = src.loc + if(module.holder && module.holder.wearer) + var/mob/living/carbon/human/H = module.holder.wearer + if(istype(H) && H.back) + var/obj/item/weapon/rig/suit = H.back + if(istype(suit)) + return suit.cell + return null + +/obj/item/weapon/gun/energy/update_icon() + if(charge_meter) var/ratio = power_supply.charge / power_supply.maxcharge - ratio = round(ratio, 0.25) * 100 + + //make sure that rounding down will not give us the empty state even if we have charge for a shot left. + if(power_supply.charge < charge_cost) + ratio = 0 + else + ratio = max(round(ratio, 0.25) * 100, 25) + if(modifystate) icon_state = "[modifystate][ratio]" else icon_state = "[initial(icon_state)][ratio]" + diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 40a4b06689..dffc012998 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -1,173 +1,131 @@ /obj/item/weapon/gun/energy/laser name = "laser carbine" - desc = "A basic weapon designed to kill with concentrated energy bolts." + desc = "A common laser weapon, designed to kill with concentrated energy blasts." icon_state = "laser" item_state = "laser" fire_sound = 'sound/weapons/Laser.ogg' - w_class = 3.0 + slot_flags = SLOT_BELT|SLOT_BACK + w_class = 3 + force = 10 matter = list("metal" = 2000) origin_tech = "combat=3;magnets=2" projectile_type = /obj/item/projectile/beam + fire_delay = 1 //rapid fire + +/obj/item/weapon/gun/energy/laser/mounted + self_recharge = 1 + use_external_power = 1 /obj/item/weapon/gun/energy/laser/practice name = "practice laser gun" desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice." projectile_type = /obj/item/projectile/beam/practice - clumsy_check = 0 -obj/item/weapon/gun/energy/laser/retro +obj/item/weapon/gun/energy/retro name = "retro laser" icon_state = "retro" + item_state = "retro" desc = "An older model of the basic lasergun, no longer used by Nanotrasen's security or military forces. Nevertheless, it is still quite deadly and easy to maintain, making it a favorite amongst pirates and other outlaws." + fire_sound = 'sound/weapons/Laser.ogg' + slot_flags = SLOT_BELT + w_class = 3 + projectile_type = /obj/item/projectile/beam + fire_delay = 10 //old technology - -/obj/item/weapon/gun/energy/laser/captain +/obj/item/weapon/gun/energy/captain name = "antique laser gun" icon_state = "caplaser" + item_state = "caplaser" desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding." - force = 10 + force = 5 + fire_sound = 'sound/weapons/Laser.ogg' + slot_flags = SLOT_BELT + w_class = 3 + projectile_type = /obj/item/projectile/beam origin_tech = null - var/charge_tick = 0 - - - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(100) - update_icon() - return 1 - - - -/obj/item/weapon/gun/energy/laser/cyborg/load_into_chamber() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell) - R.cell.use(100) - in_chamber = new/obj/item/projectile/beam(src) - return 1 - return 0 - - + charge_cost = 200 //to compensate a bit for self-recharging + self_recharge = 1 /obj/item/weapon/gun/energy/lasercannon name = "laser cannon" - desc = "With the L.A.S.E.R. cannon, the lasing medium is enclosed in a tube lined with uranium-235 and subjected to high neutron flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with small laser volumes!" + desc = "With the laser cannon, the lasing medium is enclosed in a tube lined with uranium-235 and subjected to high neutron flux in a nuclear reactor core. This incredible technology may help YOU achieve high excitation rates with small laser volumes!" icon_state = "lasercannon" + item_state = null fire_sound = 'sound/weapons/lasercannonfire.ogg' origin_tech = "combat=4;materials=3;powerstorage=3" - projectile_type = "/obj/item/projectile/beam/heavylaser" - + slot_flags = SLOT_BELT|SLOT_BACK + projectile_type = /obj/item/projectile/beam/heavylaser + charge_cost = 250 fire_delay = 20 - isHandgun() - return 0 - -/obj/item/weapon/gun/energy/lasercannon/cyborg/load_into_chamber() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell) - R.cell.use(250) - in_chamber = new/obj/item/projectile/beam/heavylaser(src) - return 1 - return 0 +/obj/item/weapon/gun/energy/lasercannon/mounted + name = "mounted laser cannon" + self_recharge = 1 + use_external_power = 1 + recharge_time = 10 /obj/item/weapon/gun/energy/xray name = "xray laser gun" desc = "A high-power laser gun capable of expelling concentrated xray blasts." icon_state = "xray" + item_state = "xray" fire_sound = 'sound/weapons/laser3.ogg' origin_tech = "combat=5;materials=3;magnets=2;syndicate=2" - projectile_type = "/obj/item/projectile/beam/xray" + projectile_type = /obj/item/projectile/beam/xray charge_cost = 50 + fire_delay = 1 +/obj/item/weapon/gun/energy/sniperrifle + name = "\improper L.W.A.P. sniper rifle" + desc = "A high-power laser rifle fitted with a SMART aiming-system scope." + icon_state = "sniper" + item_state = "laser" + fire_sound = 'sound/weapons/marauder.ogg' + origin_tech = "combat=6;materials=5;powerstorage=4" + projectile_type = /obj/item/projectile/beam/sniper + slot_flags = SLOT_BACK + charge_cost = 250 + fire_delay = 35 + force = 10 + w_class = 4 + accuracy = -3 //shooting at the hip + scoped_accuracy = 0 + +/obj/item/weapon/gun/energy/sniperrifle/verb/scope() + set category = "Object" + set name = "Use Scope" + set popup_menu = 1 + + toggle_scope(2.0) ////////Laser Tag//////////////////// -/obj/item/weapon/gun/energy/laser/bluetag +/obj/item/weapon/gun/energy/lasertag name = "laser tag gun" + item_state = "laser" + desc = "Standard issue weapon of the Imperial Guard" + origin_tech = "combat=1;magnets=2" + self_recharge = 1 + matter = list("metal" = 2000) + fire_sound = 'sound/weapons/Laser.ogg' + projectile_type = /obj/item/projectile/beam/lastertag/blue + var/required_vest + +/obj/item/weapon/gun/energy/lasertag/special_check(var/mob/living/carbon/human/M) + if(ishuman(M)) + if(!istype(M.wear_suit, required_vest)) + M << "You need to be wearing your laser tag vest!" + return 0 + return ..() + +/obj/item/weapon/gun/energy/lasertag/blue icon_state = "bluetag" - desc = "Standard issue weapon of the Imperial Guard" - projectile_type = "/obj/item/projectile/beam/lastertag/blue" - origin_tech = "combat=1;magnets=2" - clumsy_check = 0 - var/charge_tick = 0 + item_state = "bluetag" + projectile_type = /obj/item/projectile/beam/lastertag/blue + required_vest = /obj/item/clothing/suit/bluetag - special_check(var/mob/living/carbon/human/M) - if(ishuman(M)) - if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag)) - return 1 - M << "\red You need to be wearing your laser tag vest!" - return 0 - - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(100) - update_icon() - return 1 - - - -/obj/item/weapon/gun/energy/laser/redtag - name = "laser tag gun" +/obj/item/weapon/gun/energy/lasertag/red icon_state = "redtag" - desc = "Standard issue weapon of the Imperial Guard" - projectile_type = "/obj/item/projectile/beam/lastertag/red" - origin_tech = "combat=1;magnets=2" - clumsy_check = 0 - var/charge_tick = 0 - - special_check(var/mob/living/carbon/human/M) - if(ishuman(M)) - if(istype(M.wear_suit, /obj/item/clothing/suit/redtag)) - return 1 - M << "\red You need to be wearing your laser tag vest!" - return 0 - - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(100) - update_icon() - return 1 + item_state = "redtag" + projectile_type = /obj/item/projectile/beam/lastertag/red + required_vest = /obj/item/clothing/suit/redtag diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index e2a55a5ed4..6b9f6f0d51 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -1,129 +1,117 @@ /obj/item/weapon/gun/energy/gun name = "energy gun" - desc = "A basic energy-based gun with two settings: Stun and kill." + desc = "An energy-based gun with two settings: Stun and kill." icon_state = "energystun100" item_state = null //so the human update icon uses the icon_state instead. fire_sound = 'sound/weapons/Taser.ogg' charge_cost = 100 //How much energy is needed to fire. - projectile_type = "/obj/item/projectile/beam/stun" + projectile_type = /obj/item/projectile/beam/stun origin_tech = "combat=3;magnets=2" modifystate = "energystun" var/mode = 0 //0 = stun, 1 = kill +/obj/item/weapon/gun/energy/gun/attack_self(mob/living/user as mob) + switch(mode) + if(0) + mode = 1 + charge_cost = 100 + fire_sound = 'sound/weapons/Laser.ogg' + user << "[src.name] is now set to kill." + projectile_type = /obj/item/projectile/beam + modifystate = "energykill" + if(1) + mode = 0 + charge_cost = 100 + fire_sound = 'sound/weapons/Taser.ogg' + user << "[src.name] is now set to stun." + projectile_type = /obj/item/projectile/beam/stun + modifystate = "energystun" + update_icon() + update_held_icon() - attack_self(mob/living/user as mob) - switch(mode) - if(0) - mode = 1 - charge_cost = 100 - fire_sound = 'sound/weapons/Laser.ogg' - user << "\red [src.name] is now set to kill." - projectile_type = "/obj/item/projectile/beam" - modifystate = "energykill" - if(1) - mode = 0 - charge_cost = 100 - fire_sound = 'sound/weapons/Taser.ogg' - user << "\red [src.name] is now set to stun." - projectile_type = "/obj/item/projectile/beam/stun" - modifystate = "energystun" - update_icon() - if(user.l_hand == src) - user.update_inv_l_hand() - else - user.update_inv_r_hand() +/obj/item/weapon/gun/energy/gun/mounted + name = "mounted energy gun" + self_recharge = 1 + use_external_power = 1 /obj/item/weapon/gun/energy/gun/nuclear name = "advanced energy gun" desc = "An energy gun with an experimental miniaturized reactor." icon_state = "nucgun" - origin_tech = "combat=3;materials=5;powerstorage=3" + origin_tech = "combat=3;materials=5;powerstorage=3" + slot_flags = SLOT_BELT + force = 8 //looks heavier than a pistol + self_recharge = 1 var/lightfail = 0 - var/charge_tick = 0 - New() - ..() - processing_objects.Add(src) +//override for failcheck behaviour +/obj/item/weapon/gun/energy/gun/nuclear/process() + charge_tick++ + if(charge_tick < 4) return 0 + charge_tick = 0 + if(!power_supply) return 0 + if((power_supply.charge / power_supply.maxcharge) != 1) + if(!failcheck()) return 0 + power_supply.give(charge_cost) + update_icon() + return 1 - - Del() +/obj/item/weapon/gun/energy/gun/nuclear/proc/failcheck() + lightfail = 0 + if (prob(src.reliability)) return 1 //No failure + if (prob(src.reliability)) + for (var/mob/living/M in range(0,src)) //Only a minor failure, enjoy your radiation if you're in the same tile or carrying it + if (src in M.contents) + M << "Your gun feels pleasantly warm for a moment." + else + M << "You feel a warm sensation." + M.apply_effect(rand(3,120), IRRADIATE) + lightfail = 1 + else + for (var/mob/living/M in range(rand(1,4),src)) //Big failure, TIME FOR RADIATION BITCHES + if (src in M.contents) + M << "Your gun's reactor overloads!" + M << "You feel a wave of heat wash over you." + M.apply_effect(300, IRRADIATE) + crit_fail = 1 //break the gun so it stops recharging processing_objects.Remove(src) - ..() + update_icon() + return 0 - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - if((power_supply.charge / power_supply.maxcharge) != 1) - if(!failcheck()) return 0 - power_supply.give(100) - update_icon() - return 1 +/obj/item/weapon/gun/energy/gun/nuclear/proc/update_charge() + if (crit_fail) + overlays += "nucgun-whee" + return + var/ratio = power_supply.charge / power_supply.maxcharge + ratio = round(ratio, 0.25) * 100 + overlays += "nucgun-[ratio]" +/obj/item/weapon/gun/energy/gun/nuclear/proc/update_reactor() + if(crit_fail) + overlays += "nucgun-crit" + return + if(lightfail) + overlays += "nucgun-medium" + else if ((power_supply.charge/power_supply.maxcharge) <= 0.5) + overlays += "nucgun-light" + else + overlays += "nucgun-clean" - proc - failcheck() - lightfail = 0 - if (prob(src.reliability)) return 1 //No failure - if (prob(src.reliability)) - for (var/mob/living/M in range(0,src)) //Only a minor failure, enjoy your radiation if you're in the same tile or carrying it - if (src in M.contents) - M << "\red Your gun feels pleasantly warm for a moment." - else - M << "\red You feel a warm sensation." - M.apply_effect(rand(3,120), IRRADIATE) - lightfail = 1 - else - for (var/mob/living/M in range(rand(1,4),src)) //Big failure, TIME FOR RADIATION BITCHES - if (src in M.contents) - M << "\red Your gun's reactor overloads!" - M << "\red You feel a wave of heat wash over you." - M.apply_effect(300, IRRADIATE) - crit_fail = 1 //break the gun so it stops recharging - processing_objects.Remove(src) - update_icon() - return 0 +/obj/item/weapon/gun/energy/gun/nuclear/proc/update_mode() + if (mode == 0) + overlays += "nucgun-stun" + else if (mode == 1) + overlays += "nucgun-kill" +/obj/item/weapon/gun/energy/gun/nuclear/emp_act(severity) + ..() + reliability -= round(15/severity) - update_charge() - if (crit_fail) - overlays += "nucgun-whee" - return - var/ratio = power_supply.charge / power_supply.maxcharge - ratio = round(ratio, 0.25) * 100 - overlays += "nucgun-[ratio]" - - - update_reactor() - if(crit_fail) - overlays += "nucgun-crit" - return - if(lightfail) - overlays += "nucgun-medium" - else if ((power_supply.charge/power_supply.maxcharge) <= 0.5) - overlays += "nucgun-light" - else - overlays += "nucgun-clean" - - - update_mode() - if (mode == 0) - overlays += "nucgun-stun" - else if (mode == 1) - overlays += "nucgun-kill" - - - emp_act(severity) - ..() - reliability -= round(15/severity) - - - update_icon() - overlays.Cut() - update_charge() - update_reactor() - update_mode() +/obj/item/weapon/gun/energy/gun/nuclear/update_icon() + overlays.Cut() + update_charge() + update_reactor() + update_mode() diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index 74b6af43c3..82ab47438b 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -1,70 +1,57 @@ /obj/item/weapon/gun/energy/pulse_rifle name = "pulse rifle" - desc = "A heavy-duty, pulse-based energy weapon, preferred by front-line combat personnel." + desc = "A weapon that uses advanced pulse-based beam generation technology to emit powerful laser blasts. Because of its complexity and cost, it is rarely seen in use except by specialists." icon_state = "pulse" item_state = null //so the human update icon uses the icon_state instead. + slot_flags = SLOT_BELT|SLOT_BACK force = 10 fire_sound = 'sound/weapons/pulse.ogg' charge_cost = 200 - projectile_type = "/obj/item/projectile/beam/pulse" - cell_type = "/obj/item/weapon/cell/super" + projectile_type = /obj/item/projectile/beam/pulse + cell_type = /obj/item/weapon/cell/super var/mode = 2 fire_delay = 25 - attack_self(mob/living/user as mob) - switch(mode) - if(2) - mode = 0 - charge_cost = 100 - fire_sound = 'sound/weapons/Taser.ogg' - user << "\red [src.name] is now set to stun." - projectile_type = "/obj/item/projectile/beam/stun" - if(0) - mode = 1 - charge_cost = 100 - fire_sound = 'sound/weapons/Laser.ogg' - user << "\red [src.name] is now set to kill." - projectile_type = "/obj/item/projectile/beam" - if(1) - mode = 2 - charge_cost = 200 - fire_sound = 'sound/weapons/pulse.ogg' - user << "\red [src.name] is now set to DESTROY." - projectile_type = "/obj/item/projectile/beam/pulse" - return - - isHandgun() - return 0 - -/obj/item/weapon/gun/energy/pulse_rifle/cyborg/load_into_chamber() - if(in_chamber) - return 1 - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell) - R.cell.use(charge_cost) - in_chamber = new/obj/item/projectile/beam(src) - return 1 - return 0 +/obj/item/weapon/gun/energy/pulse_rifle/attack_self(mob/living/user as mob) + switch(mode) + if(2) + mode = 0 + charge_cost = 100 + fire_sound = 'sound/weapons/Taser.ogg' + user << "[src.name] is now set to stun." + projectile_type = /obj/item/projectile/beam/stun + if(0) + mode = 1 + charge_cost = 100 + fire_sound = 'sound/weapons/Laser.ogg' + user << "[src.name] is now set to kill." + projectile_type = /obj/item/projectile/beam + if(1) + mode = 2 + charge_cost = 200 + fire_sound = 'sound/weapons/pulse.ogg' + user << "[src.name] is now set to DESTROY." + projectile_type = /obj/item/projectile/beam/pulse +/obj/item/weapon/gun/energy/pulse_rifle/mounted + self_recharge = 1 + use_external_power = 1 /obj/item/weapon/gun/energy/pulse_rifle/destroyer name = "pulse destroyer" - desc = "A heavy-duty, pulse-based energy weapon." - cell_type = "/obj/item/weapon/cell/infinite" + desc = "A heavy-duty, pulse-based energy weapon. Because of its complexity and cost, it is rarely seen in use except by specialists." + cell_type = /obj/item/weapon/cell/infinite fire_delay = 10 - attack_self(mob/living/user as mob) - user << "\red [src.name] has three settings, and they are all DESTROY." - +/obj/item/weapon/gun/energy/pulse_rifle/destroyer/attack_self(mob/living/user as mob) + user << "[src.name] has three settings, and they are all DESTROY." +//WHY? /obj/item/weapon/gun/energy/pulse_rifle/M1911 name = "\improper M1911-P" desc = "It's not the size of the gun, it's the size of the hole it puts through people." + slot_flags = SLOT_BELT|SLOT_HOLSTER icon_state = "m1911-p" - cell_type = "/obj/item/weapon/cell/infinite" + cell_type = /obj/item/weapon/cell/infinite fire_delay = 10 - - isHandgun() - return 1 diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index d5417496bf..c7f74e1d95 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -2,138 +2,72 @@ name = "ion rifle" desc = "A man portable anti-armor weapon designed to disable mechanical threats" icon_state = "ionrifle" + item_state = "ionrifle" fire_sound = 'sound/weapons/Laser.ogg' origin_tech = "combat=2;magnets=4" - w_class = 4.0 + w_class = 4 + force = 10 flags = CONDUCT slot_flags = SLOT_BACK charge_cost = 100 - projectile_type = "/obj/item/projectile/ion" + projectile_type = /obj/item/projectile/ion /obj/item/weapon/gun/energy/ionrifle/emp_act(severity) - if(severity <= 2) - power_supply.use(round(power_supply.maxcharge / severity)) - update_icon() + ..(max(severity, 2)) //so it doesn't EMP itself, I guess + +/obj/item/weapon/gun/energy/ionrifle/update_icon() + ..() + if(power_supply.charge < charge_cost) + item_state = "ionrifle-empty" else - return + item_state = initial(item_state) /obj/item/weapon/gun/energy/decloner name = "biological demolecularisor" desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements." icon_state = "decloner" + item_state = "decloner" fire_sound = 'sound/weapons/pulse3.ogg' origin_tech = "combat=5;materials=4;powerstorage=3" charge_cost = 100 - projectile_type = "/obj/item/projectile/energy/declone" - -obj/item/weapon/gun/energy/staff - name = "staff of change" - desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself" - icon = 'icons/obj/gun.dmi' - icon_state = "staffofchange" - item_state = "staffofchange" - fire_sound = 'sound/weapons/emitter.ogg' - flags = CONDUCT - slot_flags = SLOT_BACK - w_class = 4.0 - charge_cost = 200 - projectile_type = "/obj/item/projectile/change" - origin_tech = null - clumsy_check = 0 - var/charge_tick = 0 - - - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(200) - return 1 - - update_icon() - return - - - click_empty(mob/user = null) - if (user) - user.visible_message("*fizzle*", "\red *fizzle*") - else - src.visible_message("*fizzle*") - playsound(src.loc, 'sound/effects/sparks1.ogg', 100, 1) - -/obj/item/weapon/gun/energy/staff/animate - name = "staff of animation" - desc = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines." - projectile_type = "/obj/item/projectile/animate" - charge_cost = 100 + projectile_type = /obj/item/projectile/energy/declone /obj/item/weapon/gun/energy/floragun name = "floral somatoray" desc = "A tool that discharges controlled radiation which induces mutation in plant cells." icon_state = "floramut100" - item_state = "obj/item/gun.dmi" + item_state = "floramut" fire_sound = 'sound/effects/stealthoff.ogg' charge_cost = 100 - projectile_type = "/obj/item/projectile/energy/floramut" + projectile_type = /obj/item/projectile/energy/floramut origin_tech = "materials=2;biotech=3;powerstorage=3" modifystate = "floramut" - var/charge_tick = 0 + self_recharge = 1 var/mode = 0 //0 = mutate, 1 = yield boost -/obj/item/weapon/gun/energy/floragun/New() - ..() - processing_objects.Add(src) - -/obj/item/weapon/gun/energy/floragun/Del() - processing_objects.Remove(src) - ..() - -/obj/item/weapon/gun/energy/floragun/process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(100) - update_icon() - return 1 - /obj/item/weapon/gun/energy/floragun/attack_self(mob/living/user as mob) switch(mode) if(0) mode = 1 charge_cost = 100 - user << "\red The [src.name] is now set to increase yield." - projectile_type = "/obj/item/projectile/energy/florayield" + user << "The [src.name] is now set to increase yield." + projectile_type = /obj/item/projectile/energy/florayield modifystate = "florayield" if(1) mode = 0 charge_cost = 100 - user << "\red The [src.name] is now set to induce mutations." - projectile_type = "/obj/item/projectile/energy/floramut" + user << "The [src.name] is now set to induce mutations." + projectile_type = /obj/item/projectile/energy/floramut modifystate = "floramut" update_icon() - return + update_held_icon() -/obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, flag) - - if(flag && istype(target,/obj/machinery/portable_atmospherics/hydroponics)) - var/obj/machinery/portable_atmospherics/hydroponics/tray = target - if(load_into_chamber()) - user.visible_message("\red \The [user] fires \the [src] into \the [tray]!") - Fire(target,user) +/obj/item/weapon/gun/energy/floragun/afterattack(obj/target, mob/user, adjacent_flag) + //allow shooting into adjacent hydrotrays regardless of intent + if(adjacent_flag && istype(target,/obj/machinery/portable_atmospherics/hydroponics)) + user.visible_message("\The [user] fires \the [src] into \the [target]!") + Fire(target,user) return - ..() /obj/item/weapon/gun/energy/meteorgun @@ -141,33 +75,14 @@ obj/item/weapon/gun/energy/staff desc = "For the love of god, make sure you're aiming this the right way!" icon_state = "riotgun" item_state = "c20r" + slot_flags = SLOT_BELT|SLOT_BACK w_class = 4 - projectile_type = "/obj/item/projectile/meteor" + projectile_type = /obj/item/projectile/meteor charge_cost = 100 - cell_type = "/obj/item/weapon/cell/potato" - clumsy_check = 0 //Admin spawn only, might as well let clowns use it. - var/charge_tick = 0 - var/recharge_time = 5 //Time it takes for shots to recharge (in ticks) - - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - process() - charge_tick++ - if(charge_tick < recharge_time) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(100) - - update_icon() - return - + cell_type = /obj/item/weapon/cell/potato + self_recharge = 1 + recharge_time = 5 //Time it takes for shots to recharge (in ticks) + charge_meter = 0 /obj/item/weapon/gun/energy/meteorgun/pen name = "meteor pen" @@ -176,34 +91,16 @@ obj/item/weapon/gun/energy/staff icon_state = "pen" item_state = "pen" w_class = 1 + slot_flags = SLOT_BELT /obj/item/weapon/gun/energy/mindflayer name = "mind flayer" - desc = "A prototype weapon recovered from the ruins of Research-Station Epsilon." + desc = "A custom-built weapon of some kind." icon_state = "xray" - projectile_type = "/obj/item/projectile/beam/mindflayer" + projectile_type = /obj/item/projectile/beam/mindflayer fire_sound = 'sound/weapons/Laser.ogg' -obj/item/weapon/gun/energy/staff/focus - name = "mental focus" - desc = "An artefact that channels the will of the user into destructive bolts of force. If you aren't careful with it, you might poke someone's brain out." - icon = 'icons/obj/wizard.dmi' - icon_state = "focus" - item_state = "focus" - projectile_type = "/obj/item/projectile/forcebolt" - /* - attack_self(mob/living/user as mob) - if(projectile_type == "/obj/item/projectile/forcebolt") - charge_cost = 200 - user << "\red The [src.name] will now strike a small area." - projectile_type = "/obj/item/projectile/forcebolt/strong" - else - charge_cost = 100 - user << "\red The [src.name] will now strike only a single person." - projectile_type = "/obj/item/projectile/forcebolt" - */ - /obj/item/weapon/gun/energy/toxgun name = "phoron pistol" desc = "A specialized firearm designed to fire lethal bolts of phoron." @@ -211,25 +108,108 @@ obj/item/weapon/gun/energy/staff/focus fire_sound = 'sound/effects/stealthoff.ogg' w_class = 3.0 origin_tech = "combat=5;phorontech=4" - projectile_type = "/obj/item/projectile/energy/phoron" + projectile_type = /obj/item/projectile/energy/phoron -/obj/item/weapon/gun/energy/sniperrifle - name = "\improper L.W.A.P. sniper rifle" - desc = "A rifle constructed of lightweight materials, fitted with a SMART aiming-system scope." +/* Staves */ + +/obj/item/weapon/gun/energy/staff + name = "staff of change" + desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself" icon = 'icons/obj/gun.dmi' - icon_state = "sniper" - fire_sound = 'sound/weapons/marauder.ogg' - origin_tech = "combat=6;materials=5;powerstorage=4" - projectile_type = "/obj/item/projectile/beam/sniper" + item_icons = null + icon_state = "staffofchange" + item_state = "staffofchange" + fire_sound = 'sound/weapons/emitter.ogg' + flags = CONDUCT slot_flags = SLOT_BACK - charge_cost = 250 - fire_delay = 35 w_class = 4.0 - zoomdevicename = "scope" + charge_cost = 200 + projectile_type = /obj/item/projectile/change + origin_tech = null + self_recharge = 1 + charge_meter = 0 -/obj/item/weapon/gun/energy/sniperrifle/verb/scope() +/obj/item/weapon/gun/energy/staff/handle_click_empty(mob/user = null) + if (user) + user.visible_message("*fizzle*", "*fizzle*") + else + src.visible_message("*fizzle*") + playsound(src.loc, 'sound/effects/sparks1.ogg', 100, 1) + +/obj/item/weapon/gun/energy/staff/animate + name = "staff of animation" + desc = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines." + projectile_type = /obj/item/projectile/animate + charge_cost = 100 + +obj/item/weapon/gun/energy/staff/focus + name = "mental focus" + desc = "An artefact that channels the will of the user into destructive bolts of force. If you aren't careful with it, you might poke someone's brain out." + icon = 'icons/obj/wizard.dmi' + icon_state = "focus" + item_state = "focus" + slot_flags = SLOT_BACK + projectile_type = /obj/item/projectile/forcebolt + /* + attack_self(mob/living/user as mob) + if(projectile_type == "/obj/item/projectile/forcebolt") + charge_cost = 200 + user << "The [src.name] will now strike a small area." + projectile_type = "/obj/item/projectile/forcebolt/strong" + else + charge_cost = 100 + user << "The [src.name] will now strike only a single person." + projectile_type = "/obj/item/projectile/forcebolt" + */ + +/* Adminbus guns */ + +// Serves as a target spotter for the Icarus. +/obj/item/weapon/gun/energy/icarus + name = "rubber ducky" + desc = "It's a cute rubber duck. With an evil gleam in it's eye." + projectile_type = /obj/item/projectile/icarus/pointdefense + icon = 'icons/obj/watercloset.dmi' + item_icons = null + icon_state = "rubberducky" + item_state = "rubberducky" + charge_cost = 0 + silenced = 1 + +/obj/item/weapon/gun/energy/icarus/attack_self(mob/living/user as mob) + if(projectile_type == /obj/item/projectile/icarus/pointdefense) + projectile_type = /obj/item/projectile/icarus/guns + user << "You inform the Icarus to switch to the main guns." + else + projectile_type = /obj/item/projectile/icarus/pointdefense + user << "You inform the Icarus to switch to the point-defense lasers." + + . = ..() + +/obj/item/weapon/gun/energy/icarus/update_icon() + return + +/obj/item/weapon/gun/energy/icarus/verb/SetIcarusAngle() + set src in usr + set name = "Set Firing Angle" + set desc = "Sets the angle from which the icarus will fire." set category = "Object" - set name = "Use Scope" - set popup_menu = 1 - zoom() + Icarus_SetPosition(usr) + + +/obj/item/weapon/gun/energy/variable + name = "abstract weapon" + desc = "It seems to shift and flow as you watch." + charge_cost = 0 + silenced = 1 + +/obj/item/weapon/gun/energy/variable/update_icon() + return + +/obj/item/weapon/gun/energy/variable/attack_self(mob/living/user as mob) + var/type = input(user,"What projectile type?","Projectile", null) as null|anything in typesof(/obj/item/projectile) + if(!type) + return ..() + projectile_type = type + . = ..() diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index 91b64a1de4..1d51f7957e 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -5,51 +5,30 @@ item_state = null //so the human update icon uses the icon_state instead. fire_sound = 'sound/weapons/Taser.ogg' charge_cost = 100 - projectile_type = "/obj/item/projectile/beam/stun" - cell_type = "/obj/item/weapon/cell/crap" + projectile_type = /obj/item/projectile/beam/stun + cell_type = /obj/item/weapon/cell/crap -/obj/item/weapon/gun/energy/taser/cyborg - cell_type = "/obj/item/weapon/cell/secborg" - var/charge_tick = 0 - var/recharge_time = 10 //Time it takes for shots to recharge (in ticks) +/obj/item/weapon/gun/energy/taser/mounted + name = "mounted taser gun" + self_recharge = 1 + use_external_power = 1 - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - process() //Every [recharge_time] ticks, recharge a shot for the cyborg - charge_tick++ - if(charge_tick < recharge_time) return 0 - charge_tick = 0 - - if(!power_supply) return 0 //sanity - if(power_supply.charge >= power_supply.maxcharge) return 0 // check if we actually need to recharge - - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - if(R && R.cell) - R.cell.use(charge_cost) //Take power from the borg... - power_supply.give(charge_cost) //... to recharge the shot - - update_icon() - return 1 +/obj/item/weapon/gun/energy/taser/mounted/cyborg + name = "taser gun" + cell_type = /obj/item/weapon/cell/secborg + recharge_time = 10 //Time it takes for shots to recharge (in ticks) /obj/item/weapon/gun/energy/stunrevolver name = "stun revolver" desc = "A high-tech revolver that fires stun cartridges. The stun cartridges can be recharged using a conventional energy weapon recharger." icon_state = "stunrevolver" - fire_sound = 'sound/weapons/Taser.ogg' + item_state = "stunrevolver" + fire_sound = 'sound/weapons/Gunshot.ogg' origin_tech = "combat=3;materials=3;powerstorage=2" charge_cost = 125 - projectile_type = "/obj/item/projectile/beam/stun" - cell_type = "/obj/item/weapon/cell" - + projectile_type = /obj/item/projectile/energy/electrode/stunshot + cell_type = /obj/item/weapon/cell /obj/item/weapon/gun/energy/crossbow @@ -60,43 +39,22 @@ item_state = "crossbow" matter = list("metal" = 2000) origin_tech = "combat=2;magnets=2;syndicate=5" + slot_flags = SLOT_BELT silenced = 1 fire_sound = 'sound/weapons/Genhit.ogg' - projectile_type = "/obj/item/projectile/energy/bolt" - cell_type = "/obj/item/weapon/cell/crap" - var/charge_tick = 0 - - - New() - ..() - processing_objects.Add(src) - - - Del() - processing_objects.Remove(src) - ..() - - - process() - charge_tick++ - if(charge_tick < 4) return 0 - charge_tick = 0 - if(!power_supply) return 0 - power_supply.give(100) - return 1 - - - update_icon() - return + projectile_type = /obj/item/projectile/energy/bolt + cell_type = /obj/item/weapon/cell/crap + self_recharge = 1 + charge_meter = 0 /obj/item/weapon/gun/energy/crossbow/ninja name = "energy dart thrower" - projectile_type = "/obj/item/projectile/energy/dart" + projectile_type = /obj/item/projectile/energy/dart /obj/item/weapon/gun/energy/crossbow/largecrossbow - name = "Energy Crossbow" + name = "energy crossbow" desc = "A weapon favored by mercenary infiltration teams." - w_class = 4.0 + w_class = 4 force = 10 matter = list("metal" = 200000) - projectile_type = "/obj/item/projectile/energy/bolt/large" + projectile_type = /obj/item/projectile/energy/bolt/large diff --git a/code/modules/projectiles/guns/energy/temperature.dm b/code/modules/projectiles/guns/energy/temperature.dm index 1e61590f21..cd69b9413a 100644 --- a/code/modules/projectiles/guns/energy/temperature.dm +++ b/code/modules/projectiles/guns/energy/temperature.dm @@ -7,74 +7,73 @@ var/current_temperature = T20C charge_cost = 100 origin_tech = "combat=3;materials=4;powerstorage=3;magnets=2" + slot_flags = SLOT_BELT|SLOT_BACK - projectile_type = "/obj/item/projectile/temp" - cell_type = "/obj/item/weapon/cell/crap" + projectile_type = /obj/item/projectile/temp + cell_type = /obj/item/weapon/cell/crap - New() - ..() - processing_objects.Add(src) +/obj/item/weapon/gun/energy/temperature/New() + ..() + processing_objects.Add(src) - Del() - processing_objects.Remove(src) - ..() +/obj/item/weapon/gun/energy/temperature/Del() + processing_objects.Remove(src) + ..() - attack_self(mob/living/user as mob) - user.set_machine(src) - var/temp_text = "" - if(temperature > (T0C - 50)) - temp_text = "[temperature] ([round(temperature-T0C)]°C) ([round(temperature*1.8-459.67)]°F)" +/obj/item/weapon/gun/energy/temperature/attack_self(mob/living/user as mob) + user.set_machine(src) + var/temp_text = "" + if(temperature > (T0C - 50)) + temp_text = "[temperature] ([round(temperature-T0C)]°C) ([round(temperature*1.8-459.67)]°F)" + else + temp_text = "[temperature] ([round(temperature-T0C)]°C) ([round(temperature*1.8-459.67)]°F)" + + var/dat = {"Freeze Gun Configuration:
    + Current output temperature: [temp_text]
    + Target output temperature: - - - [current_temperature] + + +
    + "} + + user << browse(dat, "window=freezegun;size=450x300;can_resize=1;can_close=1;can_minimize=1") + onclose(user, "window=freezegun", src) + + +/obj/item/weapon/gun/energy/temperature/Topic(href, href_list) + if (..()) + return 1 + usr.set_machine(src) + src.add_fingerprint(usr) + + + + if(href_list["temp"]) + var/amount = text2num(href_list["temp"]) + if(amount > 0) + src.current_temperature = min(500, src.current_temperature+amount) else - temp_text = "[temperature] ([round(temperature-T0C)]°C) ([round(temperature*1.8-459.67)]°F)" - - var/dat = {"Freeze Gun Configuration:
    - Current output temperature: [temp_text]
    - Target output temperature: - - - [current_temperature] + + +
    - "} + src.current_temperature = max(0, src.current_temperature+amount) + if (istype(src.loc, /mob)) + attack_self(src.loc) + src.add_fingerprint(usr) + return - user << browse(dat, "window=freezegun;size=450x300;can_resize=1;can_close=1;can_minimize=1") - onclose(user, "window=freezegun", src) +/obj/item/weapon/gun/energy/temperature/process() + switch(temperature) + if(0 to 100) charge_cost = 1000 + if(100 to 250) charge_cost = 500 + if(251 to 300) charge_cost = 100 + if(301 to 400) charge_cost = 500 + if(401 to 500) charge_cost = 1000 - - Topic(href, href_list) - if (..()) - return - usr.set_machine(src) - src.add_fingerprint(usr) - - - - if(href_list["temp"]) - var/amount = text2num(href_list["temp"]) - if(amount > 0) - src.current_temperature = min(500, src.current_temperature+amount) + if(current_temperature != temperature) + var/difference = abs(current_temperature - temperature) + if(difference >= 10) + if(current_temperature < temperature) + temperature -= 10 else - src.current_temperature = max(0, src.current_temperature+amount) - if (istype(src.loc, /mob)) - attack_self(src.loc) - src.add_fingerprint(usr) - return - - - process() - switch(temperature) - if(0 to 100) charge_cost = 1000 - if(100 to 250) charge_cost = 500 - if(251 to 300) charge_cost = 100 - if(301 to 400) charge_cost = 500 - if(401 to 500) charge_cost = 1000 - - if(current_temperature != temperature) - var/difference = abs(current_temperature - temperature) - if(difference >= 10) - if(current_temperature < temperature) - temperature -= 10 - else - temperature += 10 - else - temperature = current_temperature - return + temperature += 10 + else + temperature = current_temperature diff --git a/code/modules/projectiles/guns/launcher.dm b/code/modules/projectiles/guns/launcher.dm new file mode 100644 index 0000000000..98b09e12c7 --- /dev/null +++ b/code/modules/projectiles/guns/launcher.dm @@ -0,0 +1,31 @@ +/obj/item/weapon/gun/launcher + name = "launcher" + desc = "A device that launches things." + w_class = 5.0 + flags = CONDUCT + slot_flags = SLOT_BACK + + var/release_force = 0 + var/throw_distance = 10 + fire_sound_text = "a launcher firing" + +//This normally uses a proc on projectiles and our ammo is not strictly speaking a projectile. +/obj/item/weapon/gun/launcher/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) + return 1 + +//Override this to avoid a runtime with suicide handling. +/obj/item/weapon/gun/launcher/handle_suicide(mob/living/user) + user << "\red Shooting yourself with \a [src] is pretty tricky. You can't seem to manage it." + return + +/obj/item/weapon/gun/launcher/proc/update_release_force(obj/item/projectile) + return 0 + +/obj/item/weapon/gun/launcher/process_projectile(obj/item/projectile, mob/user, atom/target, var/target_zone, var/params=null, var/pointblank=0, var/reflex=0) + update_release_force(projectile) + projectile.loc = get_turf(user) + projectile.throw_at(target, throw_distance, release_force, user) + return 1 + +/obj/item/weapon/gun/launcher/attack_self(mob/living/user as mob) + return diff --git a/code/modules/projectiles/guns/projectile/crossbow.dm b/code/modules/projectiles/guns/launcher/crossbow.dm similarity index 76% rename from code/modules/projectiles/guns/projectile/crossbow.dm rename to code/modules/projectiles/guns/launcher/crossbow.dm index faa3f8509f..860169d7b2 100644 --- a/code/modules/projectiles/guns/projectile/crossbow.dm +++ b/code/modules/projectiles/guns/launcher/crossbow.dm @@ -48,46 +48,43 @@ /obj/item/weapon/gun/launcher/crossbow name = "powered crossbow" desc = "A 2557AD twist on an old classic. Pick up that can." + icon = 'icons/obj/weapons.dmi' icon_state = "crossbow" item_state = "crossbow-solid" fire_sound = 'sound/weapons/punchmiss.ogg' // TODO: Decent THWOK noise. - ejectshell = 0 // No spent shells. - mouthshoot = 1 // No suiciding with this weapon, causes runtimes. fire_sound_text = "a solid thunk" fire_delay = 25 + slot_flags = SLOT_BACK + var/obj/item/bolt var/tension = 0 // Current draw on the bow. var/max_tension = 5 // Highest possible tension. var/release_speed = 5 // Speed per unit of tension. var/obj/item/weapon/cell/cell = null // Used for firing superheated rods. var/current_user // Used to check if the crossbow has changed hands since being drawn. -/obj/item/weapon/gun/launcher/crossbow/emp_act(severity) - if(cell && severity) - cell.use(100*severity) - -/obj/item/weapon/gun/launcher/crossbow/special_check(user) - if(tension <= 0) - user << "\red \The [src] is not drawn back!" - return 0 - return 1 - /obj/item/weapon/gun/launcher/crossbow/update_release_force() release_force = tension*release_speed -/obj/item/weapon/gun/launcher/crossbow/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) +/obj/item/weapon/gun/launcher/crossbow/consume_next_projectile(mob/user=null) + if(tension <= 0) + user << "\red \The [src] is not drawn back!" + return null + return bolt - if(!..()) return //Only do this on a successful shot. +/obj/item/weapon/gun/launcher/crossbow/handle_post_fire(mob/user, atom/target) + bolt = null icon_state = "crossbow" tension = 0 + ..() /obj/item/weapon/gun/launcher/crossbow/attack_self(mob/living/user as mob) if(tension) - if(in_chamber && in_chamber.loc == src) //Just in case they click it the tick after firing. - user.visible_message("[user] relaxes the tension on [src]'s string and removes [in_chamber].","You relax the tension on [src]'s string and remove [in_chamber].") - in_chamber.loc = get_turf(src) - var/obj/item/weapon/arrow/A = in_chamber - in_chamber = null + if(bolt) + user.visible_message("[user] relaxes the tension on [src]'s string and removes [bolt].","You relax the tension on [src]'s string and remove [bolt].") + bolt.loc = get_turf(src) + var/obj/item/weapon/arrow/A = bolt + bolt = null A.removed(user) else user.visible_message("[user] relaxes the tension on [src]'s string.","You relax the tension on [src]'s string.") @@ -98,7 +95,7 @@ /obj/item/weapon/gun/launcher/crossbow/proc/draw(var/mob/user as mob) - if(!in_chamber) + if(!bolt) user << "You don't have anything nocked to [src]." return @@ -106,50 +103,57 @@ return current_user = user - user.visible_message("[user] begins to draw back the string of [src].","You begin to draw back the string of [src].") + user.visible_message("[user] begins to draw back the string of [src].","You begin to draw back the string of [src].") tension = 1 - spawn(25) increase_tension(user) //TODO: This needs to be changed to something less shit. + + while(bolt && tension && current_user == user) + if(!do_after(user, 25)) //crossbow strings don't just magically pull back on their own. + user.visible_message("[usr] stops drawing and relaxes the string of [src].","You stop drawing back and relax the string of [src].") + tension = 0 + icon_state = "crossbow" + return + + tension++ + icon_state = "crossbow-drawn" + + if(tension >= max_tension) + tension = max_tension + usr << "[src] clunks as you draw the string to its maximum tension!" + return + + user.visible_message("[usr] draws back the string of [src]!","You continue drawing back the string of [src]!") /obj/item/weapon/gun/launcher/crossbow/proc/increase_tension(var/mob/user as mob) - if(!in_chamber || !tension || current_user != user) //Arrow has been fired, bow has been relaxed or user has changed. + if(!bolt || !tension || current_user != user) //Arrow has been fired, bow has been relaxed or user has changed. return - tension++ - icon_state = "crossbow-drawn" - - if(tension>=max_tension) - tension = max_tension - usr << "[src] clunks as you draw the string to its maximum tension!" - else - user.visible_message("[usr] draws back the string of [src]!","You continue drawing back the string of [src]!") - spawn(25) increase_tension(user) /obj/item/weapon/gun/launcher/crossbow/attackby(obj/item/W as obj, mob/user as mob) - if(!in_chamber) + if(!bolt) if (istype(W,/obj/item/weapon/arrow)) user.drop_item() - in_chamber = W - in_chamber.loc = src - user.visible_message("[user] slides [in_chamber] into [src].","You slide [in_chamber] into [src].") + bolt = W + bolt.loc = src + user.visible_message("[user] slides [bolt] into [src].","You slide [bolt] into [src].") icon_state = "crossbow-nocked" return else if(istype(W,/obj/item/stack/rods)) var/obj/item/stack/rods/R = W if (R.use(1)) - in_chamber = new /obj/item/weapon/arrow/rod(src) - in_chamber.fingerprintslast = src.fingerprintslast - in_chamber.loc = src + bolt = new /obj/item/weapon/arrow/rod(src) + bolt.fingerprintslast = src.fingerprintslast + bolt.loc = src icon_state = "crossbow-nocked" - user.visible_message("[user] jams [in_chamber] into [src].","You jam [in_chamber] into [src].") + user.visible_message("[user] jams [bolt] into [src].","You jam [bolt] into [src].") superheat_rod(user) return if(istype(W, /obj/item/weapon/cell)) if(!cell) user.drop_item() - W.loc = src cell = W + cell.loc = src user << "You jam [cell] into [src] and wire it to the firing coil." superheat_rod(user) else @@ -168,14 +172,14 @@ ..() /obj/item/weapon/gun/launcher/crossbow/proc/superheat_rod(var/mob/user) - if(!user || !cell || !in_chamber) return + if(!user || !cell || !bolt) return if(cell.charge < 500) return - if(in_chamber.throwforce >= 15) return - if(!istype(in_chamber,/obj/item/weapon/arrow/rod)) return + if(bolt.throwforce >= 15) return + if(!istype(bolt,/obj/item/weapon/arrow/rod)) return - user << "[in_chamber] plinks and crackles as it begins to glow red-hot." - in_chamber.throwforce = 15 - in_chamber.icon_state = "metal-rod-superheated" + user << "[bolt] plinks and crackles as it begins to glow red-hot." + bolt.throwforce = 15 + bolt.icon_state = "metal-rod-superheated" cell.use(500) diff --git a/code/modules/projectiles/guns/launcher/grenade_launcher.dm b/code/modules/projectiles/guns/launcher/grenade_launcher.dm new file mode 100644 index 0000000000..906e428e8d --- /dev/null +++ b/code/modules/projectiles/guns/launcher/grenade_launcher.dm @@ -0,0 +1,116 @@ +/obj/item/weapon/gun/launcher/grenade + name = "grenade launcher" + desc = "A bulky pump-action grenade launcher. Holds up to 6 grenades in a revolving magazine." + icon_state = "riotgun" + item_state = "riotgun" + w_class = 4 + force = 10 + + fire_sound = 'sound/weapons/empty.ogg' + fire_sound_text = "a metallic thunk" + recoil = 0 + throw_distance = 7 + release_force = 5 + + var/obj/item/weapon/grenade/chambered + var/list/grenades = new/list() + var/max_grenades = 5 //holds this + one in the chamber + matter = list("metal" = 2000) + +//revolves the magazine, allowing players to choose between multiple grenade types +/obj/item/weapon/gun/launcher/grenade/proc/pump(mob/M as mob) + playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) + + var/obj/item/weapon/grenade/next + if(grenades.len) + next = grenades[1] //get this first, so that the chambered grenade can still be removed if the grenades list is empty + if(chambered) + grenades += chambered //rotate the revolving magazine + chambered = null + if(next) + grenades -= next //Remove grenade from loaded list. + chambered = next + M << "You pump [src], loading \a [next] into the chamber." + else + M << "You pump [src], but the magazine is empty." + update_icon() + +/obj/item/weapon/gun/launcher/grenade/examine(mob/user) + if(..(user, 2)) + var/grenade_count = grenades.len + (chambered? 1 : 0) + user << "Has [grenade_count] grenade\s remaining." + if(chambered) + user << "\A [chambered] is chambered." + +/obj/item/weapon/gun/launcher/grenade/proc/load(obj/item/weapon/grenade/G, mob/user) + if(grenades.len >= max_grenades) + user << "[src] is full." + return + user.remove_from_mob(G) + G.loc = src + grenades.Insert(1, G) //add to the head of the list, so that it is loaded on the next pump + user.visible_message("[user] inserts \a [G] into [src].", "You insert \a [G] into [src].") + +/obj/item/weapon/gun/launcher/grenade/proc/unload(mob/user) + if(grenades.len) + var/obj/item/weapon/grenade/G = grenades[grenades.len] + grenades.len-- + user.put_in_hands(G) + user.visible_message("[user] removes \a [G] from [src].", "You remove \a [G] from [src].") + else + user << "[src] is empty." + +/obj/item/weapon/gun/launcher/grenade/attack_self(mob/user) + pump(user) + +/obj/item/weapon/gun/launcher/grenade/attackby(obj/item/I, mob/user) + if((istype(I, /obj/item/weapon/grenade))) + load(I, user) + else + ..() + +/obj/item/weapon/gun/launcher/grenade/attack_hand(mob/user) + if(user.get_inactive_hand() == src) + unload(user) + else + ..() + +/obj/item/weapon/gun/launcher/grenade/consume_next_projectile() + if(chambered) + chambered.det_time = 10 + chambered.activate(null) + return chambered + +/obj/item/weapon/gun/launcher/grenade/handle_post_fire(mob/user) + message_admins("[key_name_admin(user)] fired a grenade ([chambered.name]) from a grenade launcher ([src.name]).") + log_game("[key_name_admin(user)] used a grenade ([chambered.name]).") + chambered = null + +//Underslung grenade launcher to be used with the Z8 +/obj/item/weapon/gun/launcher/grenade/underslung + name = "underslung grenade launcher" + desc = "Not much more than a tube and a firing mechanism, this grenade launcher is designed to be fitted to a rifle." + w_class = 3 + force = 5 + max_grenades = 0 + +/obj/item/weapon/gun/launcher/grenade/underslung/attack_self() + return + +//load and unload directly into chambered +/obj/item/weapon/gun/launcher/grenade/underslung/load(obj/item/weapon/grenade/G, mob/user) + if(chambered) + user << "[src] is already loaded." + return + user.remove_from_mob(G) + G.loc = src + chambered = G + user.visible_message("[user] load \a [G] into [src].", "You load \a [G] into [src].") + +/obj/item/weapon/gun/launcher/grenade/underslung/unload(mob/user) + if(chambered) + user.put_in_hands(chambered) + user.visible_message("[user] removes \a [chambered] from [src].", "You remove \a [chambered] from [src].") + chambered = null + else + user << "[src] is empty." \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/pneumatic.dm b/code/modules/projectiles/guns/launcher/pneumatic.dm similarity index 82% rename from code/modules/projectiles/guns/projectile/pneumatic.dm rename to code/modules/projectiles/guns/launcher/pneumatic.dm index a9cdea466c..b1a0f563df 100644 --- a/code/modules/projectiles/guns/projectile/pneumatic.dm +++ b/code/modules/projectiles/guns/launcher/pneumatic.dm @@ -1,9 +1,9 @@ /obj/item/weapon/gun/launcher/pneumatic name = "pneumatic cannon" desc = "A large gas-powered cannon." - icon = 'icons/obj/gun.dmi' icon_state = "pneumatic" item_state = "pneumatic" + slot_flags = SLOT_BELT w_class = 5.0 flags = CONDUCT fire_sound_text = "a loud whoosh of moving air" @@ -12,7 +12,7 @@ var/fire_pressure // Used in fire checks/pressure checks. var/max_w_class = 3 // Hopper intake size. - var/max_combined_w_class = 20 // Total internal storage size. + var/max_storage_space = 20 // Total internal storage size. var/obj/item/weapon/tank/tank = null // Tank of gas for use in firing the cannon. var/obj/item/weapon/storage/tank_container // Something to hold the tank item so we don't accidentally fire it. var/pressure_setting = 10 // Percentage of the gas in the tank used to fire the projectile. @@ -61,17 +61,16 @@ icon_state = "pneumatic-tank" item_state = "pneumatic-tank" user.update_icons() - else if(W.w_class <= max_w_class) - + else if(istype(W) && W.w_class <= max_w_class) var/total_stored = 0 for(var/obj/item/O in src.contents) - total_stored += O.w_class - if(total_stored + W.w_class <= max_combined_w_class) + total_stored += O.get_storage_cost() + if(total_stored + W.get_storage_cost() <= max_storage_space) user.remove_from_mob(W) W.loc = src user << "You shove [W] into the hopper." else - user << "That won't fit into the hopper - it's full." + user << "That won't fit into the hopper - it's too full." return else user << "That won't fit into the hopper." @@ -79,9 +78,6 @@ /obj/item/weapon/gun/launcher/pneumatic/attack_self(mob/user as mob) if(contents.len > 0) var/obj/item/removing = contents[contents.len] - if(removing == in_chamber) - in_chamber = null - removing.loc = get_turf(src) user.put_in_hands(removing) user << "You remove [removing] from the hopper." @@ -89,12 +85,19 @@ user << "There is nothing to remove in \the [src]." return -/obj/item/weapon/gun/launcher/pneumatic/load_into_chamber() +/obj/item/weapon/gun/launcher/pneumatic/consume_next_projectile(mob/user=null) if(!contents.len) - return 0 + return null + if (!tank) + user << "There is no gas tank in [src]!" + return null - in_chamber = contents[1] - return !isnull(in_chamber) + var/fire_pressure = (tank.air_contents.return_pressure()/100)*pressure_setting + if(fire_pressure < minimum_tank_pressure) + user << "There isn't enough gas in the tank to fire [src]." + return null + + return contents[1] /obj/item/weapon/gun/launcher/pneumatic/examine(mob/user) if(!..(user, 2)) @@ -105,31 +108,21 @@ else user << "Nothing is attached to the tank valve!" -/obj/item/weapon/gun/launcher/pneumatic/special_check(user) +/obj/item/weapon/gun/launcher/pneumatic/update_release_force(obj/item/projectile) + if(tank) + release_force = ((fire_pressure*tank.volume)/projectile.w_class)/force_divisor //projectile speed. + if(release_force > 80) release_force = 80 //damage cap. + else + release_force = 0 - if (!tank) - user << "There is no gas tank in [src]!" - return 0 - - fire_pressure = (tank.air_contents.return_pressure()/100)*pressure_setting - if (fire_pressure < minimum_tank_pressure) - user << "There isn't enough gas in the tank to fire [src]." - return 0 - - return 1 - -/obj/item/weapon/gun/launcher/pneumatic/update_release_force() - if(!in_chamber) return - release_force = ((fire_pressure*tank.volume)/in_chamber.w_class)/force_divisor //projectile speed. - if(release_force >80) release_force = 80 //damage cap. - -/obj/item/weapon/gun/launcher/pneumatic/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - - if(!tank || !..()) return //Only do this on a successful shot. - - var/lost_gas_amount = tank.air_contents.total_moles*(pressure_setting/100) - var/datum/gas_mixture/removed = tank.air_contents.remove(lost_gas_amount) - user.loc.assume_air(removed) +/obj/item/weapon/gun/launcher/pneumatic/handle_post_fire() + if(tank) + var/lost_gas_amount = tank.air_contents.total_moles*(pressure_setting/100) + var/datum/gas_mixture/removed = tank.air_contents.remove(lost_gas_amount) + + var/turf/T = get_turf(src.loc) + if(T) T.assume_air(removed) + ..() //Constructable pneumatic cannon. diff --git a/code/modules/projectiles/guns/launcher/rocket.dm b/code/modules/projectiles/guns/launcher/rocket.dm new file mode 100644 index 0000000000..fd86302fb8 --- /dev/null +++ b/code/modules/projectiles/guns/launcher/rocket.dm @@ -0,0 +1,48 @@ +/obj/item/weapon/gun/launcher/rocket + name = "rocket launcher" + desc = "MAGGOT." + icon_state = "rocket" + item_state = "rocket" + w_class = 4.0 + throw_speed = 2 + throw_range = 10 + force = 5.0 + flags = CONDUCT | USEDELAY + slot_flags = 0 + origin_tech = "combat=8;materials=5" + fire_sound = 'sound/effects/bang.ogg' + + release_force = 15 + throw_distance = 30 + var/max_rockets = 1 + var/list/rockets = new/list() + +/obj/item/weapon/gun/launcher/rocket/examine(mob/user) + if(!..(user, 2)) + return + user << "\blue [rockets.len] / [max_rockets] rockets." + +/obj/item/weapon/gun/launcher/rocket/attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/ammo_casing/rocket)) + if(rockets.len < max_rockets) + user.drop_item() + I.loc = src + rockets += I + user << "\blue You put the rocket in [src]." + user << "\blue [rockets.len] / [max_rockets] rockets." + else + usr << "\red [src] cannot hold more rockets." + +/obj/item/weapon/gun/launcher/rocket/consume_next_projectile() + if(rockets.len) + var/obj/item/ammo_casing/rocket/I = rockets[1] + var/obj/item/missile/M = new (src) + M.primed = 1 + rockets -= I + return M + return null + +/obj/item/weapon/gun/launcher/rocket/handle_post_fire(mob/user, atom/target) + message_admins("[key_name_admin(user)] fired a rocket from a rocket launcher ([src.name]) at [target].") + log_game("[key_name_admin(user)] used a rocket launcher ([src.name]) at [target].") + ..() diff --git a/code/modules/projectiles/guns/launcher/syringe_gun.dm b/code/modules/projectiles/guns/launcher/syringe_gun.dm new file mode 100644 index 0000000000..099f8687a3 --- /dev/null +++ b/code/modules/projectiles/guns/launcher/syringe_gun.dm @@ -0,0 +1,137 @@ +/obj/item/weapon/syringe_cartridge + name = "syringe gun cartridge" + desc = "An impact-triggered compressed gas cartridge that can be fitted to a syringe for rapid injection." + icon = 'icons/obj/ammo.dmi' + icon_state = "syringe-cartridge" + var/icon_flight = "syringe-cartridge-flight" //so it doesn't look so weird when shot + matter = list("metal" = 125, "glass" = 375) + flags = CONDUCT + slot_flags = SLOT_BELT + throwforce = 3 + force = 3 + w_class = 1 + var/obj/item/weapon/reagent_containers/syringe/syringe + +/obj/item/weapon/syringe_cartridge/update_icon() + underlays.Cut() + if(syringe) + underlays += image(syringe.icon, src, syringe.icon_state) + underlays += syringe.filling + +/obj/item/weapon/syringe_cartridge/attackby(obj/item/I, mob/user) + if(istype(I, /obj/item/weapon/reagent_containers/syringe)) + syringe = I + user << "You carefully insert [syringe] into [src]." + user.remove_from_mob(syringe) + syringe.loc = src + sharp = 1 + name = "syringe dart" + update_icon() + +/obj/item/weapon/syringe_cartridge/attack_self(mob/user) + if(syringe) + user << "You remove [syringe] from [src]." + user.put_in_hands(syringe) + syringe = null + sharp = initial(sharp) + name = initial(name) + update_icon() + +/obj/item/weapon/syringe_cartridge/proc/prime() + //the icon state will revert back when update_icon() is called from throw_impact() + icon_state = icon_flight + underlays.Cut() + +/obj/item/weapon/syringe_cartridge/throw_impact(atom/hit_atom, var/speed) + ..() //handles embedding for us. Should have a decent chance if thrown fast enough + if(syringe) + //check speed to see if we hit hard enough to trigger the rapid injection + //incidentally, this means syringe_cartridges can be used with the pneumatic launcher + if(speed >= 10 && isliving(hit_atom)) + var/mob/living/L = hit_atom + //unfortuately we don't know where the dart will actually hit, since that's done by the parent. + if(L.can_inject()) + if(syringe.reagents) + syringe.reagents.trans_to(L, 15) + + syringe.break_syringe(iscarbon(hit_atom)? hit_atom : null) + syringe.update_icon() + + icon_state = initial(icon_state) //reset icon state + update_icon() + +/obj/item/weapon/gun/launcher/syringe + name = "syringe gun" + desc = "A spring loaded rifle designed to fit syringes, designed to incapacitate unruly patients from a distance." + icon_state = "syringegun" + item_state = "syringegun" + w_class = 3 + force = 7 + matter = list("metal" = 2000) + slot_flags = SLOT_BELT + + fire_sound = 'sound/weapons/empty.ogg' + fire_sound_text = "a metallic thunk" + recoil = 0 + release_force = 10 + throw_distance = 10 + + var/list/darts = list() + var/max_darts = 1 + var/obj/item/weapon/syringe_cartridge/next + +/obj/item/weapon/gun/launcher/syringe/consume_next_projectile() + if(next) + next.prime() + return next + return null + +/obj/item/weapon/gun/launcher/syringe/handle_post_fire() + ..() + darts -= next + next = null + +/obj/item/weapon/gun/launcher/syringe/attack_self(mob/living/user as mob) + if(next) + user.visible_message("[user] unlatches and carefully relaxes the bolt on [src].", "You unlatch and carefully relax the bolt on [src], unloading the spring.") + next = null + else if(darts.len) + playsound(src.loc, 'sound/weapons/flipblade.ogg', 50, 1) + user.visible_message("[user] draws back the bolt on [src], clicking it into place.", "You draw back the bolt on the [src], loading the spring!") + next = darts[1] + add_fingerprint(user) + +/obj/item/weapon/gun/launcher/syringe/attack_hand(mob/living/user as mob) + if(user.get_inactive_hand() == src) + if(!darts.len) + user << "[src] is empty." + return + if(next) + user << "[src]'s cover is locked shut." + return + var/obj/item/weapon/syringe_cartridge/C = darts[1] + darts -= C + user.put_in_hands(C) + user.visible_message("[user] removes \a [C] from [src].", "You remove \a [C] from [src].") + else + ..() + +/obj/item/weapon/gun/launcher/syringe/attackby(var/obj/item/A as obj, mob/user as mob) + if(istype(A, /obj/item/weapon/syringe_cartridge)) + var/obj/item/weapon/syringe_cartridge/C = A + if(darts.len >= max_darts) + user << "[src] is full!" + return + user.remove_from_mob(C) + C.loc = src + darts += C //add to the end + user.visible_message("[user] inserts \a [C] into [src].", "You insert \a [C] into [src].") + else + ..() + +/obj/item/weapon/gun/launcher/syringe/rapid + name = "syringe gun revolver" + desc = "A modification of the syringe gun design, using a rotating cylinder to store up to five syringes. The spring still needs to be drawn between shots." + icon_state = "rapidsyringegun" + item_state = "rapidsyringegun" + max_darts = 5 diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index f096b819c8..944a9fe99f 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -1,119 +1,205 @@ -#define SPEEDLOADER 0 -#define FROM_BOX 1 -#define MAGAZINE 2 +#define HOLD_CASINGS 0 //do not do anything after firing. Manual action, like pump shotguns, or guns that want to define custom behaviour +#define EJECT_CASINGS 1 //drop spent casings on the ground after firing +#define CYCLE_CASINGS 2 //experimental: cycle casings, like a revolver. Also works for multibarrelled guns /obj/item/weapon/gun/projectile - name = "revolver" - desc = "A classic revolver. Uses 357 ammo" + name = "gun" + desc = "A gun that fires bullets." icon_state = "revolver" - caliber = "357" origin_tech = "combat=2;materials=2" - w_class = 3.0 + w_class = 3 matter = list("metal" = 1000) recoil = 1 - var/ammo_type = "/obj/item/ammo_casing/a357" - var/list/loaded = list() - var/max_shells = 7 - var/load_method = SPEEDLOADER //0 = Single shells or quick loader, 1 = box, 2 = magazine - var/obj/item/ammo_magazine/empty_mag = null + + var/caliber = "357" //determines which casings will fit + var/handle_casings = EJECT_CASINGS //determines how spent casings should be handled + var/load_method = SINGLE_CASING|SPEEDLOADER //1 = Single shells, 2 = box or quick loader, 3 = magazine + var/obj/item/ammo_casing/chambered = null + //For SINGLE_CASING or SPEEDLOADER guns + var/max_shells = 0 //the number of casings that will fit inside + var/ammo_type = null //the type of ammo that the gun comes preloaded with + var/list/loaded = list() //stored ammo + + //For MAGAZINE guns + var/magazine_type = null //the type of magazine that the gun comes preloaded with + var/obj/item/ammo_magazine/ammo_magazine = null //stored magazine + var/auto_eject = 0 //if the magazine should automatically eject itself when empty. + var/auto_eject_sound = null + //TODO generalize ammo icon states for guns + //var/magazine_states = 0 + //var/list/icon_keys = list() //keys + //var/list/ammo_states = list() //values /obj/item/weapon/gun/projectile/New() ..() - for(var/i = 1, i <= max_shells, i++) - loaded += new ammo_type(src) + if(ispath(ammo_type) && (load_method & (SINGLE_CASING|SPEEDLOADER))) + for(var/i in 1 to max_shells) + loaded += new ammo_type(src) + if(ispath(magazine_type) && (load_method & MAGAZINE)) + ammo_magazine = new magazine_type(src) update_icon() - return + +/obj/item/weapon/gun/projectile/consume_next_projectile() + //get the next casing + if(loaded.len) + chambered = loaded[1] //load next casing. + if(handle_casings != HOLD_CASINGS) + loaded -= chambered + else if(ammo_magazine && ammo_magazine.stored_ammo.len) + chambered = ammo_magazine.stored_ammo[1] + if(handle_casings != HOLD_CASINGS) + ammo_magazine.stored_ammo -= chambered + + if (chambered) + return chambered.BB + return null + +/obj/item/weapon/gun/projectile/handle_post_fire() + ..() + if(chambered) + chambered.expend() + process_chambered() + +/obj/item/weapon/gun/projectile/handle_click_empty() + ..() + process_chambered() + +/obj/item/weapon/gun/projectile/proc/process_chambered() + if (!chambered) return + + switch(handle_casings) + if(EJECT_CASINGS) //eject casing onto ground. + chambered.loc = get_turf(src) + if(CYCLE_CASINGS) //cycle the casing back to the end. + if(ammo_magazine) + ammo_magazine.stored_ammo += chambered + else + loaded += chambered + + if(handle_casings != HOLD_CASINGS) + chambered = null -/obj/item/weapon/gun/projectile/load_into_chamber() - if(in_chamber) - return 1 //{R} +//Attempts to load A into src, depending on the type of thing being loaded and the load_method +//Maybe this should be broken up into separate procs for each load method? +/obj/item/weapon/gun/projectile/proc/load_ammo(var/obj/item/A, mob/user) + if(istype(A, /obj/item/ammo_magazine)) + var/obj/item/ammo_magazine/AM = A + if(!(load_method & AM.mag_type) || caliber != AM.caliber) + return //incompatible - if(!loaded.len) - return 0 - var/obj/item/ammo_casing/AC = loaded[1] //load next casing. - loaded -= AC //Remove casing from loaded list. - if(isnull(AC) || !istype(AC)) - return 0 - AC.loc = get_turf(src) //Eject casing onto ground. - if(AC.BB) - in_chamber = AC.BB //Load projectile into chamber. - AC.BB.loc = src //Set projectile loc to gun. - return 1 - return 0 + switch(AM.mag_type) + if(MAGAZINE) + if(ammo_magazine) + user << "[src] already has a magazine loaded." //already a magazine here + return + user.remove_from_mob(AM) + AM.loc = src + ammo_magazine = AM + user.visible_message("[user] inserts [AM] into [src].", "You insert [AM] into [src].") + playsound(src.loc, 'sound/weapons/flipblade.ogg', 50, 1) + if(SPEEDLOADER) + if(loaded.len >= max_shells) + user << "[src] is full!" + return + var/count = 0 + for(var/obj/item/ammo_casing/C in AM.stored_ammo) + if(loaded.len >= max_shells) + break + if(C.caliber == caliber) + C.loc = src + loaded += C + AM.stored_ammo -= C //should probably go inside an ammo_magazine proc, but I guess less proc calls this way... + count++ + if(count) + user.visible_message("[user] reloads [src].", "You load [count] round\s into [src].") + playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1) + AM.update_icon() + else if(istype(A, /obj/item/ammo_casing)) + var/obj/item/ammo_casing/C = A + if(!(load_method & SINGLE_CASING) || caliber != C.caliber) + return //incompatible + if(loaded.len >= max_shells) + user << "[src] is full." + return + user.remove_from_mob(C) + C.loc = src + loaded.Insert(1, C) //add to the head of the list + user.visible_message("[user] inserts \a [C] into [src].", "You insert \a [C] into [src].") + playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1) + + update_icon() + +//attempts to unload src. If allow_dump is set to 0, the speedloader unloading method will be disabled +/obj/item/weapon/gun/projectile/proc/unload_ammo(mob/user, var/allow_dump=1) + if(ammo_magazine) + user.put_in_hands(ammo_magazine) + user.visible_message("[user] removes [ammo_magazine] from [src].", "You remove [ammo_magazine] from [src].") + playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1) + ammo_magazine.update_icon() + ammo_magazine = null + else if(loaded.len) + //presumably, if it can be speed-loaded, it can be speed-unloaded. + if(allow_dump && (load_method & SPEEDLOADER)) + var/count = 0 + var/turf/T = get_turf(user) + if(T) + for(var/obj/item/ammo_casing/C in loaded) + C.loc = T + count++ + loaded.Cut() + if(count) + user.visible_message("[user] unloads [src].", "You unload [count] round\s from [src].") + else if(load_method & SINGLE_CASING) + var/obj/item/ammo_casing/C = loaded[loaded.len] + loaded.len-- + user.put_in_hands(C) + user.visible_message("[user] removes \a [C] from [src].", "You remove \a [C] from [src].") + else + user << "[src] is empty." + update_icon() /obj/item/weapon/gun/projectile/attackby(var/obj/item/A as obj, mob/user as mob) - - var/num_loaded = 0 - if(istype(A, /obj/item/ammo_magazine)) - if((load_method == MAGAZINE) && loaded.len) return - var/obj/item/ammo_magazine/AM = A - if(AM.stored_ammo.len <= 0) - user << "The magazine is empty!" - return - for(var/obj/item/ammo_casing/AC in AM.stored_ammo) - if(loaded.len >= max_shells) - break - if(AC.caliber == caliber && loaded.len < max_shells) - AC.loc = src - AM.stored_ammo -= AC - loaded += AC - num_loaded++ - if(load_method == MAGAZINE) - user.remove_from_mob(AM) - empty_mag = AM - empty_mag.loc = src - if(istype(A, /obj/item/ammo_casing) && load_method == SPEEDLOADER) - var/obj/item/ammo_casing/AC = A - if(AC.caliber == caliber && loaded.len < max_shells) - user.drop_item() - AC.loc = src - loaded += AC - num_loaded++ - if(num_loaded) - user << "\blue You load [num_loaded] shell\s into the gun!" - A.update_icon() - update_icon() - return + load_ammo(A, user) /obj/item/weapon/gun/projectile/attack_self(mob/user as mob) - if (target) - return ..() - if (loaded.len) - if (load_method == SPEEDLOADER) - var/obj/item/ammo_casing/AC = loaded[1] - loaded -= AC - AC.loc = get_turf(src) //Eject casing onto ground. - user << "\blue You unload shell from \the [src]!" - if (load_method == MAGAZINE) - var/obj/item/ammo_magazine/AM = empty_mag - for (var/obj/item/ammo_casing/AC in loaded) - AM.stored_ammo += AC - loaded -= AC - AM.loc = get_turf(src) - empty_mag = null - update_icon() - AM.update_icon() - user << "\blue You unload magazine from \the [src]!" + unload_ammo(user) + +/obj/item/weapon/gun/projectile/attack_hand(mob/user as mob) + if(user.get_inactive_hand() == src) + unload_ammo(user, allow_dump=0) else - user << "\red Nothing loaded in \the [src]!" - + return ..() +/obj/item/weapon/gun/projectile/afterattack(atom/A, mob/living/user) + ..() + if(auto_eject && ammo_magazine && ammo_magazine.stored_ammo && !ammo_magazine.stored_ammo.len) + ammo_magazine.loc = get_turf(src.loc) + user.visible_message( + "[ammo_magazine] falls out and clatters on the floor!", + "[ammo_magazine] falls out and clatters on the floor!" + ) + if(auto_eject_sound) + playsound(user, auto_eject_sound, 40, 1) + ammo_magazine.update_icon() + ammo_magazine = null + update_icon() //make sure to do this after unsetting ammo_magazine /obj/item/weapon/gun/projectile/examine(mob/user) ..(user) user << "Has [getAmmo()] round\s remaining." -// if(in_chamber && !loaded.len) -// user << "However, it has a chambered round." -// if(in_chamber && loaded.len) -// user << "It also has a chambered round." {R} + if(ammo_magazine) + user << "It has \a [ammo_magazine] loaded." return /obj/item/weapon/gun/projectile/proc/getAmmo() var/bullets = 0 - for(var/obj/item/ammo_casing/AC in loaded) - if(istype(AC)) - bullets += 1 + if(loaded) + bullets += loaded.len + if(ammo_magazine && ammo_magazine.stored_ammo) + bullets += ammo_magazine.stored_ammo.len + if(chambered) + bullets += 1 return bullets diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index ee0d8a6427..75bbf810a8 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -2,71 +2,153 @@ name = "submachine gun" desc = "A lightweight, fast firing gun. Uses 9mm rounds." icon_state = "saber" //ugly - w_class = 3.0 - max_shells = 18 + w_class = 3 + load_method = SPEEDLOADER //yup. until someone sprites a magazine for it. + max_shells = 22 caliber = "9mm" origin_tech = "combat=4;materials=2" - ammo_type = "/obj/item/ammo_casing/c9mm" - automatic = 1 - + slot_flags = SLOT_BELT + ammo_type = /obj/item/ammo_casing/c9mm + multi_aim = 1 fire_delay = 0 - isHandgun() - return 0 - - /obj/item/weapon/gun/projectile/automatic/mini_uzi name = "\improper Uzi" desc = "A lightweight, fast firing gun, for when you want someone dead. Uses .45 rounds." icon_state = "mini-uzi" - w_class = 3.0 - max_shells = 16 + w_class = 3 + load_method = SPEEDLOADER //yup. until someone sprites a magazine for it. + max_shells = 15 caliber = ".45" origin_tech = "combat=5;materials=2;syndicate=8" - ammo_type = "/obj/item/ammo_casing/c45" - - isHandgun() - return 1 - + ammo_type = /obj/item/ammo_casing/c45 /obj/item/weapon/gun/projectile/automatic/c20r name = "\improper C-20r SMG" - desc = "A lightweight, fast firing gun, for when you REALLY need someone dead. Uses 12mm rounds. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp" + desc = "A lightweight, fast firing gun, for when you REALLY need someone dead. Uses 12mm pistol rounds. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp" icon_state = "c20r" item_state = "c20r" - w_class = 3.0 - max_shells = 20 + w_class = 3 + force = 10 caliber = "12mm" origin_tech = "combat=5;materials=2;syndicate=8" - ammo_type = "/obj/item/ammo_casing/a12mm" + slot_flags = SLOT_BELT|SLOT_BACK fire_sound = 'sound/weapons/Gunshot_smg.ogg' - load_method = 2 + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/a12mm + auto_eject = 1 + auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg' +/obj/item/weapon/gun/projectile/automatic/c20r/update_icon() + ..() + if(ammo_magazine) + icon_state = "c20r-[round(ammo_magazine.stored_ammo.len,4)]" + else + icon_state = "c20r" + return - New() +/obj/item/weapon/gun/projectile/automatic/sts35 + name = "\improper STS-35 automatic rifle" + desc = "A durable, rugged looking automatic weapon of a make popular on the frontier worlds. Uses 7.62mm rounds. It is unmarked." + icon_state = "arifle" + item_state = null + w_class = 4 + force = 10 + caliber = "a762" + origin_tech = "combat=6;materials=1;syndicate=4" + slot_flags = SLOT_BACK + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/c762 + +/obj/item/weapon/gun/projectile/automatic/sts35/update_icon() + ..() + icon_state = (ammo_magazine)? "arifle-0" : "arifle" + update_held_icon() + +/obj/item/weapon/gun/projectile/automatic/wt550 + name = "\improper W-T 550 Saber" + desc = "A cheap, mass produced Ward-Takahashi PDW. Uses 9mm rounds." + icon_state = "wt550" + item_state = "wt550" + w_class = 3 + caliber = "9mm" + origin_tech = "combat=5;materials=2" + slot_flags = SLOT_BELT + ammo_type = "/obj/item/ammo_casing/c9mmr" + fire_sound = 'sound/weapons/Gunshot_smg.ogg' + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/mc9mmt/rubber + +/obj/item/weapon/gun/projectile/automatic/wt550/update_icon() + ..() + if(ammo_magazine) + icon_state = "wt550-[round(ammo_magazine.stored_ammo.len,4)]" + else + icon_state = "wt550" + return + +/obj/item/weapon/gun/projectile/automatic/z8 + name = "\improper Z8 Bulldog" + desc = "An older model bullpup carbine, made by the now defunct Zendai Foundries. Uses armor piercing 5.56mm rounds. Makes you feel like a space marine when you hold it." + icon_state = "carbine" + item_state = "z8carbine" + w_class = 4 + force = 10 + caliber = "a556" + origin_tech = "combat=8;materials=3" + ammo_type = "/obj/item/ammo_casing/a556" + fire_sound = 'sound/weapons/Gunshot.ogg' + slot_flags = SLOT_BACK + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/a556 + auto_eject = 1 + auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg' + + var/use_launcher = 0 + var/obj/item/weapon/gun/launcher/grenade/underslung/launcher + +/obj/item/weapon/gun/projectile/automatic/z8/New() + ..() + launcher = new(src) + +/obj/item/weapon/gun/projectile/automatic/z8/attack_self(mob/user) + use_launcher = !use_launcher + user << "You switch to [use_launcher? "\the [launcher]" : "firing normally"]." + +/obj/item/weapon/gun/projectile/automatic/z8/attackby(obj/item/I, mob/user) + if((istype(I, /obj/item/weapon/grenade))) + launcher.load(I, user) + else ..() - empty_mag = new /obj/item/ammo_magazine/a12mm/empty(src) - update_icon() - return - - afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) +/obj/item/weapon/gun/projectile/automatic/z8/attack_hand(mob/user) + if(user.get_inactive_hand() == src && use_launcher) + launcher.unload(user) + else ..() - if(!loaded.len && empty_mag) - empty_mag.loc = get_turf(src.loc) - empty_mag = null - playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1) - update_icon() - return - - update_icon() +/obj/item/weapon/gun/projectile/automatic/z8/Fire(atom/target, mob/living/user, params, pointblank=0, reflex=0) + if(use_launcher) + launcher.Fire(target, user, params, pointblank, reflex) + if(!launcher.chambered) + use_launcher = 0 //switch back automatically + else ..() - if(empty_mag) - icon_state = "c20r-[round(loaded.len,4)]" - else - icon_state = "c20r" - return + +/obj/item/weapon/gun/projectile/automatic/z8/update_icon() + ..() + if(ammo_magazine) + icon_state = "carbine-[round(ammo_magazine.stored_ammo.len,2)]" + else + icon_state = "carbine" + return + +/obj/item/weapon/gun/projectile/automatic/z8/examine(mob/user) + ..() + if(launcher.chambered) + user << "\The [launcher] has \a [launcher.chambered] loaded." + else + user << "\The [launcher] is empty." /obj/item/weapon/gun/projectile/automatic/l6_saw name = "\improper L6 SAW" @@ -74,74 +156,39 @@ icon_state = "l6closed100" item_state = "l6closedmag" w_class = 4 + force = 10 slot_flags = 0 max_shells = 50 caliber = "a762" - origin_tech = "combat=5;materials=1;syndicate=2" + origin_tech = "combat=6;materials=1;syndicate=2" + slot_flags = SLOT_BACK ammo_type = "/obj/item/ammo_casing/a762" fire_sound = 'sound/weapons/Gunshot_smg.ogg' - load_method = 2 + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/a762 var/cover_open = 0 - var/mag_inserted = 1 - /obj/item/weapon/gun/projectile/automatic/l6_saw/attack_self(mob/user as mob) cover_open = !cover_open user << "You [cover_open ? "open" : "close"] [src]'s cover." update_icon() - /obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon() - icon_state = "l6[cover_open ? "open" : "closed"][mag_inserted ? round(loaded.len, 25) : "-empty"]" + icon_state = "l6[cover_open ? "open" : "closed"][ammo_magazine ? round(ammo_magazine.stored_ammo.len, 25) : "-empty"]" - -/obj/item/weapon/gun/projectile/automatic/l6_saw/afterattack(atom/target as mob|obj|turf, mob/living/user as mob|obj, flag, params) //what I tried to do here is just add a check to see if the cover is open or not and add an icon_state change because I can't figure out how c-20rs do it with overlays +/obj/item/weapon/gun/projectile/automatic/l6_saw/special_check(mob/user) if(cover_open) - user << "[src]'s cover is open! Close it before firing!" - else - ..() - update_icon() + user << "[src]'s cover is open! Close it before firing!" + return 0 + return ..() - -/obj/item/weapon/gun/projectile/automatic/l6_saw/attack_hand(mob/user as mob) - if(loc != user) - ..() - return //let them pick it up - if(!cover_open || (cover_open && !mag_inserted)) - ..() - else if(cover_open && mag_inserted) - //drop the mag - empty_mag = new /obj/item/ammo_magazine/a762(src) - empty_mag.stored_ammo = loaded - empty_mag.icon_state = "a762-[round(loaded.len, 10)]" - empty_mag.desc = "There are [loaded.len] shells left!" - empty_mag.loc = get_turf(src.loc) - user.put_in_hands(empty_mag) - empty_mag = null - mag_inserted = 0 - loaded = list() - update_icon() - user << "You remove the magazine from [src]." - - -/obj/item/weapon/gun/projectile/automatic/l6_saw/attackby(var/obj/item/A as obj, mob/user as mob) +/obj/item/weapon/gun/projectile/automatic/l6_saw/load_ammo(var/obj/item/A, mob/user) if(!cover_open) - user << "[src]'s cover is closed! You can't insert a new mag!" + user << "You need to open the cover to load [src]." return - else if(cover_open && mag_inserted) - user << "[src] already has a magazine inserted!" - return - else if(cover_open && !mag_inserted) - mag_inserted = 1 - user << "You insert the magazine!" - update_icon() ..() - -/* The thing I found with guns in ss13 is that they don't seem to simulate the rounds in the magazine in the gun. - Afaik, since projectile.dm features a revolver, this would make sense since the magazine is part of the gun. - However, it looks like subsequent guns that use removable magazines don't take that into account and just get - around simulating a removable magazine by adding the casings into the loaded list and spawning an empty magazine - when the gun is out of rounds. Which means you can't eject magazines with rounds in them. The below is a very - rough and poor attempt at making that happen. -Ausops */ - \ No newline at end of file +/obj/item/weapon/gun/projectile/automatic/l6_saw/unload_ammo(mob/user, var/allow_dump=1) + if(!cover_open) + return + ..() diff --git a/code/modules/projectiles/guns/projectile/dartgun.dm b/code/modules/projectiles/guns/projectile/dartgun.dm new file mode 100644 index 0000000000..cf05a005ed --- /dev/null +++ b/code/modules/projectiles/guns/projectile/dartgun.dm @@ -0,0 +1,206 @@ +/obj/item/projectile/bullet/chemdart + name = "dart" + icon_state = "dart" + damage = 5 + sharp = 1 + embed = 1 //the dart is shot fast enough to pierce space suits, so I guess splintering inside the target can be a thing. Should be rare due to low damage. + var/reagent_amount = 15 + kill_count = 15 //shorter range + + muzzle_type = null + +/obj/item/projectile/bullet/chemdart/New() + reagents = new/datum/reagents(reagent_amount) + reagents.my_atom = src + +/obj/item/projectile/bullet/chemdart/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null) + if(blocked < 2 && isliving(target)) + var/mob/living/L = target + if(L.can_inject(target_zone=def_zone)) + reagents.trans_to(L, reagent_amount) + +/obj/item/ammo_casing/chemdart + name = "chemical dart" + desc = "A small hardened, hollow dart." + icon_state = "dart" + caliber = "dart" + projectile_type = /obj/item/projectile/bullet/chemdart + +/obj/item/ammo_casing/chemdart/expend() + del(src) + +/obj/item/ammo_magazine/chemdart + name = "dart cartridge" + desc = "A rack of hollow darts." + icon_state = "darts" + item_state = "rcdammo" + origin_tech = "materials=2" + mag_type = MAGAZINE + caliber = "dart" + ammo_type = /obj/item/ammo_casing/chemdart + max_ammo = 5 + multiple_sprites = 1 + +/obj/item/weapon/gun/projectile/dartgun + name = "dart gun" + desc = "A small gas-powered dartgun, capable of delivering chemical cocktails swiftly across short distances." + icon_state = "dartgun-empty" + item_state = null + + caliber = "dart" + fire_sound = 'sound/weapons/empty.ogg' + fire_sound_text = "a metallic click" + recoil = 0 + silenced = 1 + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/chemdart + auto_eject = 0 + + var/list/beakers = list() //All containers inside the gun. + var/list/mixing = list() //Containers being used for mixing. + var/max_beakers = 3 + var/dart_reagent_amount = 15 + var/container_type = /obj/item/weapon/reagent_containers/glass/beaker + var/list/starting_chems = null + +/obj/item/weapon/gun/projectile/dartgun/dartgun/New() + ..() + if(starting_chems) + for(var/chem in starting_chems) + var/obj/B = new container_type(src) + B.reagents.add_reagent(chem, 60) + beakers += B + update_icon() + +/obj/item/weapon/gun/projectile/dartgun/update_icon() + if(!ammo_magazine) + icon_state = "dartgun-empty" + return 1 + + if(!ammo_magazine.stored_ammo || ammo_magazine.stored_ammo.len) + icon_state = "dartgun-0" + else if(ammo_magazine.stored_ammo.len > 5) + icon_state = "dartgun-5" + else + icon_state = "dartgun-[ammo_magazine.stored_ammo.len]" + return 1 + +/obj/item/weapon/gun/projectile/dartgun/consume_next_projectile() + . = ..() + var/obj/item/projectile/bullet/chemdart/dart = . + if(istype(dart)) + fill_dart(dart) + +/obj/item/weapon/gun/projectile/dartgun/examine(mob/user) + //update_icon() + //if (!..(user, 2)) + // return + ..() + if (beakers.len) + user << "\blue [src] contains:" + for(var/obj/item/weapon/reagent_containers/glass/beaker/B in beakers) + if(B.reagents && B.reagents.reagent_list.len) + for(var/datum/reagent/R in B.reagents.reagent_list) + user << "\blue [R.volume] units of [R.name]" + +/obj/item/weapon/gun/projectile/dartgun/attackby(obj/item/I as obj, mob/user as mob) + if(istype(I, /obj/item/weapon/reagent_containers/glass)) + if(!istype(I, container_type)) + user << "\blue [I] doesn't seem to fit into [src]." + return + if(beakers.len >= max_beakers) + user << "\blue [src] already has [max_beakers] beakers in it - another one isn't going to fit!" + return + var/obj/item/weapon/reagent_containers/glass/beaker/B = I + user.drop_item() + B.loc = src + beakers += B + user << "\blue You slot [B] into [src]." + src.updateUsrDialog() + return 1 + ..() + +//fills the given dart with reagents +/obj/item/weapon/gun/projectile/dartgun/proc/fill_dart(var/obj/item/projectile/bullet/chemdart/dart) + if(mixing.len) + var/mix_amount = dart.reagent_amount/mixing.len + for(var/obj/item/weapon/reagent_containers/glass/beaker/B in mixing) + B.reagents.trans_to(dart, mix_amount) + +/obj/item/weapon/gun/projectile/dartgun/attack_self(mob/user) + user.set_machine(src) + var/dat = "[src] mixing control:

    " + + if (beakers.len) + var/i = 1 + for(var/obj/item/weapon/reagent_containers/glass/beaker/B in beakers) + dat += "Beaker [i] contains: " + if(B.reagents && B.reagents.reagent_list.len) + for(var/datum/reagent/R in B.reagents.reagent_list) + dat += "
    [R.volume] units of [R.name], " + if (check_beaker_mixing(B)) + dat += text("Mixing ") + else + dat += text("Not mixing ") + else + dat += "nothing." + dat += " \[Eject\]
    " + i++ + else + dat += "There are no beakers inserted!

    " + + if(ammo_magazine) + if(ammo_magazine.stored_ammo && ammo_magazine.stored_ammo.len) + dat += "The dart cartridge has [ammo_magazine.stored_ammo.len] shots remaining." + else + dat += "The dart cartridge is empty!" + dat += " \[Eject\]" + + user << browse(dat, "window=dartgun") + onclose(user, "dartgun", src) + +/obj/item/weapon/gun/projectile/dartgun/proc/check_beaker_mixing(var/obj/item/B) + if(!mixing || !beakers) + return 0 + for(var/obj/item/M in mixing) + if(M == B) + return 1 + return 0 + +/obj/item/weapon/gun/projectile/dartgun/Topic(href, href_list) + if(..()) return 1 + src.add_fingerprint(usr) + if(href_list["stop_mix"]) + var/index = text2num(href_list["stop_mix"]) + if(index <= beakers.len) + for(var/obj/item/M in mixing) + if(M == beakers[index]) + mixing -= M + break + else if (href_list["mix"]) + var/index = text2num(href_list["mix"]) + if(index <= beakers.len) + mixing += beakers[index] + else if (href_list["eject"]) + var/index = text2num(href_list["eject"]) + if(index <= beakers.len) + if(beakers[index]) + var/obj/item/weapon/reagent_containers/glass/beaker/B = beakers[index] + usr << "You remove [B] from [src]." + mixing -= B + beakers -= B + B.loc = get_turf(src) + else if (href_list["eject_cart"]) + unload_ammo(usr) + src.updateUsrDialog() + return + +/obj/item/weapon/gun/projectile/dartgun/vox + name = "alien dart gun" + desc = "A small gas-powered dartgun, fitted for nonhuman hands." + +/obj/item/weapon/gun/projectile/dartgun/vox/medical + starting_chems = list("kelotane","bicaridine","anti_toxin") + +/obj/item/weapon/gun/projectile/dartgun/vox/raider + starting_chems = list("space_drugs","stoxin","impedrezene") \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/launcher.dm b/code/modules/projectiles/guns/projectile/launcher.dm deleted file mode 100644 index 6626d809cd..0000000000 --- a/code/modules/projectiles/guns/projectile/launcher.dm +++ /dev/null @@ -1,89 +0,0 @@ -/obj/item/weapon/gun/launcher - name = "launcher" - desc = "A device that launches things." - icon = 'icons/obj/weapons.dmi' - w_class = 5.0 - flags = CONDUCT - slot_flags = SLOT_BACK - - var/release_force = 0 - var/fire_sound_text = "a launcher firing" - -//Check if we're drawing and if the bow is loaded. -/obj/item/weapon/gun/launcher/load_into_chamber() - return (!isnull(in_chamber)) - -//This should not fit in a combat belt or holster. -/obj/item/weapon/gun/launcher/isHandgun() - return 0 - -//Launchers are mechanical, no other impact. -/obj/item/weapon/gun/launcher/emp_act(severity) - return - -//This normally uses a proc on projectiles and our ammo is not strictly speaking a projectile. -/obj/item/weapon/gun/launcher/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) - return - -//Override this to avoid a runtime with suicide handling. -/obj/item/weapon/gun/launcher/attack(mob/living/M as mob, mob/living/user as mob, def_zone) - if (M == user && user.zone_sel.selecting == "mouth") - user << "\red Shooting yourself with \a [src] is pretty tricky. You can't seem to manage it." - return - ..() - -/obj/item/weapon/gun/launcher/proc/update_release_force() - return 0 - -/obj/item/weapon/gun/launcher/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - - if (!user.IsAdvancedToolUser()) - return 0 - - add_fingerprint(user) - - //Make sure target turfs both exist. - var/turf/curloc = get_turf(user) - var/turf/targloc = get_turf(target) - if (!istype(targloc) || !istype(curloc)) - return 0 - - if(!special_check(user)) - return 0 - - if (!ready_to_fire()) - if (world.time % 3) //to prevent spam - user << "[src] is not ready to fire again!" - return 0 - - if(!load_into_chamber()) //CHECK - return click_empty(user) - - if(!in_chamber) - return 0 - - update_release_force() - - playsound(user, fire_sound, 50, 1) - user.visible_message("[user] fires [src][reflex ? " by reflex":""]!", \ - "You fire [src][reflex ? "by reflex":""]!", \ - "You hear [fire_sound_text]!") - - in_chamber.loc = get_turf(user) - in_chamber.throw_at(target,10,release_force) - - sleep(1) - - in_chamber = null - - update_icon() - - if(user.hand) - user.update_inv_l_hand() - else - user.update_inv_r_hand() - - return 1 - -/obj/item/weapon/gun/launcher/attack_self(mob/living/user as mob) - return diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index b963924614..b29f2f3e42 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -1,52 +1,85 @@ +/obj/item/weapon/gun/projectile/colt + name = "\improper Colt M1911" + desc = "A cheap Martian knock-off of a Colt M1911." + magazine_type = /obj/item/ammo_magazine/c45m + icon_state = "colt" + caliber = ".45" + origin_tech = "combat=2;materials=2" + load_method = MAGAZINE + +/obj/item/weapon/gun/projectile/colt/detective + desc = "A cheap Martian knock-off of a Colt M1911. Uses less-than-lethal .45 rounds." + magazine_type = /obj/item/ammo_magazine/c45m/rubber + +/obj/item/weapon/gun/projectile/colt/detective/verb/rename_gun() + set name = "Name Gun" + set category = "Object" + set desc = "Rename your gun. If you're the detective." + + var/mob/M = usr + if(!M.mind) return 0 + if(!M.mind.assigned_role == "Detective") + M << "You don't feel cool enough to name this gun, chump." + return 0 + + var/input = sanitizeSafe(input("What do you want to name the gun?", ,""), MAX_NAME_LEN) + + if(src && input && !M.stat && in_range(M,src)) + name = input + M << "You name the gun [input]. Say hello to your new friend." + return 1 + +/obj/item/weapon/gun/projectile/sec + desc = "A NanoTrasen designed sidearm, found pretty much everywhere humans are. Uses less-than-lethal .45 rounds." + name = "\improper NT Mk58" + icon_state = "secguncomp" + magazine_type = /obj/item/ammo_magazine/c45m/rubber + caliber = ".45" + origin_tech = "combat=2;materials=2" + load_method = MAGAZINE + +/obj/item/weapon/gun/projectile/sec/flash + name = "\improper NT Mk58 signal pistol" + desc = "A NanoTrasen designed sidearm, found pretty much everywhere humans are. Uses .45 signal flash rounds." + magazine_type = /obj/item/ammo_magazine/c45m/flash + +/obj/item/weapon/gun/projectile/sec/wood + desc = "A Nanotrasen designed sidearm, this one has a sweet wooden grip. Uses less-than-lethal .45 rounds." + name = "\improper Custom NT Mk58" + icon_state = "secgundark" + /obj/item/weapon/gun/projectile/silenced name = "silenced pistol" desc = "A small, quiet, easily concealable gun. Uses .45 rounds." icon_state = "silenced_pistol" - w_class = 3.0 - max_shells = 12 + w_class = 3 caliber = ".45" silenced = 1 origin_tech = "combat=2;materials=2;syndicate=8" - ammo_type = "/obj/item/ammo_casing/c45" - - + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/c45m /obj/item/weapon/gun/projectile/deagle name = "desert eagle" desc = "A robust handgun that uses .50 AE ammo" icon_state = "deagle" + item_state = "deagle" force = 14.0 - max_shells = 7 caliber = ".50" - ammo_type ="/obj/item/ammo_casing/a50" - load_method = 2 - New() - ..() - empty_mag = new /obj/item/ammo_magazine/a50/empty(src) - update_icon() - return - - - afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) - ..() - if(!loaded.len && empty_mag) - empty_mag.loc = get_turf(src.loc) - empty_mag = null - playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1) - update_icon() - return + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/a50 + auto_eject = 1 /obj/item/weapon/gun/projectile/deagle/gold desc = "A gold plated gun folded over a million times by superior martian gunsmiths. Uses .50 AE ammo." icon_state = "deagleg" item_state = "deagleg" - - /obj/item/weapon/gun/projectile/deagle/camo desc = "A Deagle brand Deagle for operators operating operationally. Uses .50 AE ammo." icon_state = "deaglecamo" item_state = "deagleg" + auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg' @@ -59,57 +92,37 @@ fire_sound = 'sound/effects/Explosion1.ogg' origin_tech = "combat=3" ammo_type = "/obj/item/ammo_casing/a75" - load_method = 2 - New() - ..() - empty_mag = new /obj/item/ammo_magazine/a75/empty(src) - update_icon() - return + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/a75 + auto_eject = 1 + auto_eject_sound = 'sound/weapons/smg_empty_alarm.ogg' - - afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) - ..() - if(!loaded.len && empty_mag) - empty_mag.loc = get_turf(src.loc) - empty_mag = null - playsound(user, 'sound/weapons/smg_empty_alarm.ogg', 40, 1) - update_icon() - return - - update_icon() - ..() - if(empty_mag) - icon_state = "gyropistolloaded" - else - icon_state = "gyropistol" - return +/obj/item/weapon/gun/projectile/gyropistol/update_icon() + ..() + if(ammo_magazine) + icon_state = "gyropistolloaded" + else + icon_state = "gyropistol" /obj/item/weapon/gun/projectile/pistol name = "\improper Stechtkin pistol" desc = "A small, easily concealable gun. Uses 9mm rounds." icon_state = "pistol" + item_state = null w_class = 2 - max_shells = 8 caliber = "9mm" silenced = 0 origin_tech = "combat=2;materials=2;syndicate=2" - ammo_type = "/obj/item/ammo_casing/c9mm" - load_method = 2 + load_method = MAGAZINE + magazine_type = /obj/item/ammo_magazine/mc9mm -/obj/item/weapon/gun/projectile/pistol/New() - ..() - empty_mag = new /obj/item/ammo_magazine/mc9mm/empty(src) - return - -/obj/item/weapon/gun/projectile/pistol/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) - ..() - if(!loaded.len && empty_mag) - empty_mag.loc = get_turf(src.loc) - empty_mag = null - return +/obj/item/weapon/gun/projectile/pistol/flash + name = "\improper Stechtkin signal pistol" + desc = "A small, easily concealable gun. Uses 9mm signal flash rounds." + magazine_type = /obj/item/ammo_magazine/mc9mm/flash /obj/item/weapon/gun/projectile/pistol/attack_hand(mob/user as mob) - if(loc == user) + if(user.get_inactive_hand() == src) if(silenced) if(user.l_hand != src && user.r_hand != src) ..() @@ -122,7 +135,6 @@ return ..() - /obj/item/weapon/gun/projectile/pistol/attackby(obj/item/I as obj, mob/user as mob) if(istype(I, /obj/item/weapon/silencer)) if(user.l_hand != src && user.r_hand != src) //if we're not in his hands diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index f1eac3e858..f0291de0f8 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -1,184 +1,43 @@ -/obj/item/weapon/gun/projectile/detective +/obj/item/weapon/gun/projectile/revolver + name = "revolver" + desc = "A classic revolver. Uses .357 ammo" + icon_state = "revolver" + item_state = "revolver" + caliber = "357" + origin_tech = "combat=2;materials=2" + handle_casings = CYCLE_CASINGS + max_shells = 7 + ammo_type = /obj/item/ammo_casing/a357 + +/obj/item/weapon/gun/projectile/revolver/mateba + name = "mateba" + desc = "When you absolutely, positively need a 10mm hole in the other guy. Uses .357 ammo." //>10mm hole >.357 + icon_state = "mateba" + origin_tech = "combat=2;materials=2" + +/obj/item/weapon/gun/projectile/revolver/detective name = "revolver" desc = "A cheap Martian knock-off of a Smith & Wesson Model 10. Uses .38-Special rounds." icon_state = "detective" max_shells = 6 caliber = "38" origin_tech = "combat=2;materials=2" - ammo_type = "/obj/item/ammo_casing/c38" + ammo_type = /obj/item/ammo_casing/c38 +/obj/item/weapon/gun/projectile/revolver/detective/verb/rename_gun() + set name = "Name Gun" + set category = "Object" + set desc = "Click to rename your gun. If you're the detective." - special_check(var/mob/living/carbon/human/M) - if(caliber == initial(caliber)) - return 1 - if(prob(70 - (loaded.len * 10))) //minimum probability of 10, maximum of 60 - M << "[src] blows up in your face." - M.take_organ_damage(0,20) - M.drop_item() - del(src) - return 0 + var/mob/M = usr + if(!M.mind) return 0 + if(!M.mind.assigned_role == "Detective") + M << "You don't feel cool enough to name this gun, chump." + return 0 + + var/input = sanitizeSafe(input("What do you want to name the gun?", ,""), MAX_NAME_LEN) + + if(src && input && !M.stat && in_range(M,src)) + name = input + M << "You name the gun [input]. Say hello to your new friend." return 1 - - verb/rename_gun() - set name = "Name Gun" - set category = "Object" - set desc = "Click to rename your gun. If you're the detective." - - var/mob/M = usr - if(!M.mind) return 0 - if(!M.mind.assigned_role == "Detective") - M << "You don't feel cool enough to name this gun, chump." - return 0 - - var/input = stripped_input(usr,"What do you want to name the gun?", ,"", MAX_NAME_LEN) - - if(src && input && !M.stat && in_range(M,src)) - name = input - M << "You name the gun [input]. Say hello to your new friend." - return 1 - - attackby(var/obj/item/A as obj, mob/user as mob) - ..() - if(istype(A, /obj/item/weapon/screwdriver)) - if(caliber == "38") - user << "You begin to reinforce the barrel of [src]." - if(loaded.len) - afterattack(user, user) //you know the drill - playsound(user, fire_sound, 50, 1) - user.visible_message("[src] goes off!", "[src] goes off in your face!") - return - if(do_after(user, 30)) - if(loaded.len) - user << "You can't modify it!" - return - caliber = "357" - desc = "The barrel and chamber assembly seems to have been modified." - user << "You reinforce the barrel of [src]! Now it will fire .357 rounds." - else if (caliber == "357") - user << "You begin to revert the modifications to [src]." - if(loaded.len) - afterattack(user, user) //and again - playsound(user, fire_sound, 50, 1) - user.visible_message("[src] goes off!", "[src] goes off in your face!") - return - if(do_after(user, 30)) - if(loaded.len) - user << "You can't modify it!" - return - caliber = "38" - desc = initial(desc) - user << "You remove the modifications on [src]! Now it will fire .38 rounds." - - -/obj/item/weapon/gun/projectile/detective/semiauto - name = "\improper Colt M1911" - desc = "A cheap Martian knock-off of a Colt M1911. Uses less-than-lethal .45 rounds." - icon_state = "colt" - max_shells = 7 - caliber = ".45" - ammo_type = "/obj/item/ammo_casing/c45r" - load_method = 2 - -/obj/item/weapon/gun/projectile/detective/semiauto/New() - ..() - empty_mag = new /obj/item/ammo_magazine/c45r/empty(src) - return - -/obj/item/weapon/gun/projectile/detective/semiauto/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, flag) - ..() - if(!loaded.len && empty_mag) - empty_mag.loc = get_turf(src.loc) - empty_mag = null - user << "The Magazine falls out and clatters on the floor!" - return - - -/obj/item/weapon/gun/projectile/mateba - name = "mateba" - desc = "When you absolutely, positively need a 10mm hole in the other guy. Uses .357 ammo." //>10mm hole >.357 - icon_state = "mateba" - origin_tech = "combat=2;materials=2" - -// A gun to play Russian Roulette! -// You can spin the chamber to randomize the position of the bullet. - -/obj/item/weapon/gun/projectile/russian - name = "\improper Russian revolver" - desc = "A Russian made revolver. Uses .357 ammo. It has a single slot in it's chamber for a bullet." - max_shells = 6 - origin_tech = "combat=2;materials=2" - -/obj/item/weapon/gun/projectile/russian/New() - Spin() - update_icon() - -/obj/item/weapon/gun/projectile/russian/proc/Spin() - for(var/obj/item/ammo_casing/AC in loaded) - del(AC) - loaded = list() - var/random = rand(1, max_shells) - for(var/i = 1; i <= max_shells; i++) - if(i != random) - loaded += i // Basically null - else - loaded += new ammo_type(src) - - -/obj/item/weapon/gun/projectile/russian/attackby(var/obj/item/A as obj, mob/user as mob) - if(!A) return - - var/num_loaded = 0 - if(istype(A, /obj/item/ammo_magazine)) - - if((load_method == 2) && loaded.len) return - var/obj/item/ammo_magazine/AM = A - for(var/obj/item/ammo_casing/AC in AM.stored_ammo) - if(getAmmo() > 0 || loaded.len >= max_shells) - break - if(AC.caliber == caliber && loaded.len < max_shells) - AC.loc = src - AM.stored_ammo -= AC - loaded += AC - num_loaded++ - break - A.update_icon() - - if(num_loaded) - user.visible_message("[user] loads a single bullet into the revolver and spins the chamber.", "You load a single bullet into the chamber and spin it.") - else - user.visible_message("[user] spins the chamber of the revolver.", "You spin the revolver's chamber.") - if(getAmmo() > 0) - Spin() - update_icon() - return - -/obj/item/weapon/gun/projectile/russian/attack_self(mob/user as mob) - user.visible_message("[user] spins the chamber of the revolver.", "You spin the revolver's chamber.") - if(getAmmo() > 0) - Spin() - -/obj/item/weapon/gun/projectile/russian/attack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj) - if(!loaded.len) - user.visible_message("\red *click*", "\red *click*") - playsound(user, 'sound/weapons/empty.ogg', 100, 1) - return - - if(isliving(target) && isliving(user)) - if(target == user) - var/datum/organ/external/affecting = user.zone_sel.selecting - if(affecting == "head") - - var/obj/item/ammo_casing/AC = loaded[1] - if(!load_into_chamber()) - user.visible_message("\red *click*", "\red *click*") - playsound(user, 'sound/weapons/empty.ogg', 100, 1) - return - if(!in_chamber) - return - var/obj/item/projectile/P = new AC.projectile_type - playsound(user, fire_sound, 50, 1) - user.visible_message("[user.name] fires [src] at \his head!", "You fire [src] at your head!", "You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!") - if(!P.nodamage) - user.apply_damage(300, BRUTE, affecting, sharp=1) // You are dead, dead, dead. - return - ..() diff --git a/code/modules/projectiles/guns/projectile/rocket.dm b/code/modules/projectiles/guns/projectile/rocket.dm deleted file mode 100644 index 27fb15d571..0000000000 --- a/code/modules/projectiles/guns/projectile/rocket.dm +++ /dev/null @@ -1,51 +0,0 @@ -/obj/item/weapon/gun/rocketlauncher - name = "rocket launcher" - desc = "MAGGOT." - icon_state = "rocket" - item_state = "rocket" - w_class = 4.0 - throw_speed = 2 - throw_range = 10 - force = 5.0 - flags = CONDUCT | USEDELAY - slot_flags = 0 - origin_tech = "combat=8;materials=5" - var/projectile = /obj/item/missile - var/missile_speed = 2 - var/missile_range = 30 - var/max_rockets = 1 - var/list/rockets = new/list() - -/obj/item/weapon/gun/rocketlauncher/examine(mob/user) - if(!..(user, 2)) - return - user << "\blue [rockets.len] / [max_rockets] rockets." - -/obj/item/weapon/gun/rocketlauncher/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/ammo_casing/rocket)) - if(rockets.len < max_rockets) - user.drop_item() - I.loc = src - rockets += I - user << "\blue You put the rocket in [src]." - user << "\blue [rockets.len] / [max_rockets] rockets." - else - usr << "\red [src] cannot hold more rockets." - -/obj/item/weapon/gun/rocketlauncher/can_fire() - return rockets.len - -/obj/item/weapon/gun/rocketlauncher/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - if(rockets.len) - var/obj/item/ammo_casing/rocket/I = rockets[1] - var/obj/item/missile/M = new projectile(user.loc) - playsound(user.loc, 'sound/effects/bang.ogg', 50, 1) - M.primed = 1 - M.throw_at(target, missile_range, missile_speed,user) - message_admins("[key_name_admin(user)] fired a rocket from a rocket launcher ([src.name]).") - log_game("[key_name_admin(user)] used a rocket launcher ([src.name]).") - rockets -= I - del(I) - return - else - usr << "\red [src] is empty." diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 6db9300375..fa29d7e8ba 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -10,127 +10,85 @@ slot_flags = SLOT_BACK caliber = "shotgun" origin_tech = "combat=4;materials=2" - ammo_type = "/obj/item/ammo_casing/shotgun/beanbag" + load_method = SINGLE_CASING + ammo_type = /obj/item/ammo_casing/shotgun/beanbag + handle_casings = HOLD_CASINGS var/recentpump = 0 // to prevent spammage - var/pumped = 0 - var/obj/item/ammo_casing/current_shell = null - isHandgun() - return 0 +/obj/item/weapon/gun/projectile/shotgun/pump/consume_next_projectile() + if(chambered) + return chambered.BB + return null - load_into_chamber() - if(in_chamber) - return 1 - return 0 - - - attack_self(mob/living/user as mob) - if(recentpump) return +/obj/item/weapon/gun/projectile/shotgun/pump/attack_self(mob/living/user as mob) + if(world.time >= recentpump + 10) pump(user) - recentpump = 1 - spawn(10) - recentpump = 0 - return + recentpump = world.time +/obj/item/weapon/gun/projectile/shotgun/pump/proc/pump(mob/M as mob) + playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) - proc/pump(mob/M as mob) - playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) - pumped = 0 - if(current_shell)//We have a shell in the chamber - current_shell.loc = get_turf(src)//Eject casing - current_shell = null - if(in_chamber) - in_chamber = null - if(!loaded.len) return 0 + if(chambered)//We have a shell in the chamber + chambered.loc = get_turf(src)//Eject casing + chambered = null + + if(loaded.len) var/obj/item/ammo_casing/AC = loaded[1] //load next casing. loaded -= AC //Remove casing from loaded list. - current_shell = AC - if(AC.BB) - in_chamber = AC.BB //Load projectile into chamber. - update_icon() //I.E. fix the desc - return 1 + chambered = AC + + update_icon() /obj/item/weapon/gun/projectile/shotgun/pump/combat name = "combat shotgun" icon_state = "cshotgun" - max_shells = 8 + item_state = "cshotgun" origin_tech = "combat=5;materials=2" - ammo_type = "/obj/item/ammo_casing/shotgun" + max_shells = 7 //match the ammo box capacity, also it can hold a round in the chamber anyways, for a total of 8. + ammo_type = /obj/item/ammo_casing/shotgun + -//this is largely hacky and bad :( -Pete /obj/item/weapon/gun/projectile/shotgun/doublebarrel name = "double-barreled shotgun" desc = "A true classic." icon_state = "dshotgun" - item_state = "shotgun" + item_state = "dshotgun" + //SPEEDLOADER because rapid unloading. + //In principle someone could make a speedloader for it, so it makes sense. + load_method = SINGLE_CASING|SPEEDLOADER + handle_casings = CYCLE_CASINGS max_shells = 2 - w_class = 4.0 + w_class = 4 force = 10 flags = CONDUCT slot_flags = SLOT_BACK caliber = "shotgun" origin_tech = "combat=3;materials=1" - ammo_type = "/obj/item/ammo_casing/shotgun/beanbag" + ammo_type = /obj/item/ammo_casing/shotgun/beanbag - New() - for(var/i = 1, i <= max_shells, i++) - loaded += new ammo_type(src) +/obj/item/weapon/gun/projectile/shotgun/doublebarrel/flare + name = "signal shotgun" + desc = "A double-barreled shotgun meant to fire signal flash shells." + ammo_type = /obj/item/ammo_casing/shotgun/flash - update_icon() - return - - load_into_chamber() -// if(in_chamber) -// return 1 {R} - if(!loaded.len) - return 0 - - var/obj/item/ammo_casing/AC = loaded[1] //load next casing. - loaded -= AC //Remove casing from loaded list. - AC.desc += " This one is spent." - - if(AC.BB) - in_chamber = AC.BB //Load projectile into chamber. - return 1 - return 0 - - attack_self(mob/living/user as mob) - if(!(locate(/obj/item/ammo_casing/shotgun) in src) && !loaded.len) - user << "\The [src] is empty." - return - - for(var/obj/item/ammo_casing/shotgun/shell in src) //This feels like a hack. //don't code at 3:30am kids!! - if(shell in loaded) - loaded -= shell - shell.loc = get_turf(src.loc) - - user << "You break \the [src]." - update_icon() - - attackby(var/obj/item/A as obj, mob/user as mob) - if(istype(A, /obj/item/ammo_casing) && !load_method) - var/obj/item/ammo_casing/AC = A - if(AC.caliber == caliber && (loaded.len < max_shells) && (contents.len < max_shells)) //forgive me father, for i have sinned - user.drop_item() - AC.loc = src - loaded += AC - user << "You load a shell into \the [src]!" - A.update_icon() - update_icon() - if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter)) - user << "You begin to shorten the barrel of \the [src]." - if(loaded.len) - afterattack(user, user) //will this work? - afterattack(user, user) //it will. we call it twice, for twice the FUN +//this is largely hacky and bad :( -Pete +/obj/item/weapon/gun/projectile/shotgun/doublebarrel/attackby(var/obj/item/A as obj, mob/user as mob) + if(istype(A, /obj/item/weapon/circular_saw) || istype(A, /obj/item/weapon/melee/energy) || istype(A, /obj/item/weapon/pickaxe/plasmacutter)) + user << "You begin to shorten the barrel of \the [src]." + if(loaded.len) + for(var/i in 1 to max_shells) + afterattack(user, user) //will this work? //it will. we call it twice, for twice the FUN playsound(user, fire_sound, 50, 1) - user.visible_message("The shotgun goes off!", "The shotgun goes off in your face!") - return - if(do_after(user, 30)) //SHIT IS STEALTHY EYYYYY - icon_state = "sawnshotgun" - w_class = 3.0 - item_state = "gun" - slot_flags &= ~SLOT_BACK //you can't sling it on your back - slot_flags |= SLOT_BELT //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) - name = "sawn-off shotgun" - desc = "Omar's coming!" - user << "You shorten the barrel of \the [src]!" + user.visible_message("The shotgun goes off!", "The shotgun goes off in your face!") + return + if(do_after(user, 30)) //SHIT IS STEALTHY EYYYYY + icon_state = "sawnshotgun" + w_class = 3 + item_state = "gun" + slot_flags &= ~SLOT_BACK //you can't sling it on your back + slot_flags |= (SLOT_BELT|SLOT_HOLSTER) //but you can wear it on your belt (poorly concealed under a trenchcoat, ideally) - or in a holster, why not. + name = "sawn-off shotgun" + desc = "Omar's coming!" + user << "You shorten the barrel of \the [src]!" + else + ..() \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm new file mode 100644 index 0000000000..6c14edfaa5 --- /dev/null +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -0,0 +1,67 @@ +/obj/item/weapon/gun/projectile/heavysniper + name = "\improper PTR-7 rifle" + desc = "A portable anti-armour rifle fitted with a scope. Originally designed to used against armoured exosuits, it is capable of punching through windows and non-reinforced walls with ease. Fires armor piercing 14.5mm shells." + icon_state = "heavysniper" + item_state = "l6closednomag" //placeholder + w_class = 4 + force = 10 + slot_flags = SLOT_BACK + origin_tech = "combat=8;materials=2;syndicate=8" + caliber = "14.5mm" + recoil = 2 //extra kickback + //fire_sound = 'sound/weapons/sniper.ogg' + handle_casings = HOLD_CASINGS + load_method = SINGLE_CASING + max_shells = 1 + ammo_type = /obj/item/ammo_casing/a145 + //+2 accuracy over the LWAP because only one shot + accuracy = -1 + scoped_accuracy = 2 + var/bolt_open = 0 + +/obj/item/weapon/gun/projectile/heavysniper/update_icon() + if(bolt_open) + icon_state = "heavysniper-open" + else + icon_state = "heavysniper" + +/obj/item/weapon/gun/projectile/heavysniper/attack_self(mob/user as mob) + playsound(src.loc, 'sound/weapons/flipblade.ogg', 50, 1) + bolt_open = !bolt_open + if(bolt_open) + if(chambered) + user << "You work the bolt open, ejecting [chambered]!" + chambered.loc = get_turf(src) + loaded -= chambered + chambered = null + else + user << "You work the bolt open." + else + user << "You work the bolt closed." + bolt_open = 0 + add_fingerprint(user) + update_icon() + +/obj/item/weapon/gun/projectile/heavysniper/special_check(mob/user) + if(bolt_open) + user << "You can't fire [src] while the bolt is open!" + return 0 + return ..() + +/obj/item/weapon/gun/projectile/heavysniper/load_ammo(var/obj/item/A, mob/user) + if(!bolt_open) + return + ..() + +/obj/item/weapon/gun/projectile/heavysniper/unload_ammo(mob/user, var/allow_dump=1) + if(!bolt_open) + return + ..() + +/obj/item/weapon/gun/projectile/heavysniper/verb/scope() + set category = "Object" + set name = "Use Scope" + set popup_menu = 1 + + toggle_scope(2.0) + diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 3b5ed8bd53..3786dda532 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -36,8 +36,10 @@ var/damage = 10 var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here var/nodamage = 0 //Determines if the projectile will skip any damage inflictions - var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid - var/projectile_type = "/obj/item/projectile" + var/taser_effect = 0 //If set then the projectile will apply it's agony damage using stun_effect_act() to mobs it hits, and other damage will be ignored + var/check_armour = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb //Cael - bio and rad are also valid + var/projectile_type = /obj/item/projectile + var/penetrating = 0 //If greater than zero, the projectile will pass through dense objects as specified by on_penetrate() var/kill_count = 50 //This will de-increment every process(). When 0, it will delete the projectile. //Effects var/stun = 0 @@ -49,117 +51,302 @@ var/drowsy = 0 var/agony = 0 var/embed = 0 // whether or not the projectile can embed itself in the mob + + var/hitscan = 0 // whether the projectile should be hitscan - proc/on_hit(var/atom/target, var/blocked = 0) - if(blocked >= 2) return 0//Full block - if(!isliving(target)) return 0 - if(isanimal(target)) return 0 - var/mob/living/L = target - L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked) // add in AGONY! + // effect types to be used + var/muzzle_type + var/tracer_type + var/impact_type + + var/datum/plot_vector/trajectory // used to plot the path of the projectile + var/datum/vector_loc/location // current location of the projectile in pixel space + var/matrix/effect_transform // matrix to rotate and scale projectile effects - putting it here so it doesn't + // have to be recreated multiple times + +//TODO: make it so this is called more reliably, instead of sometimes by bullet_act() and sometimes not +/obj/item/projectile/proc/on_hit(var/atom/target, var/blocked = 0, var/def_zone = null) + if(blocked >= 2) return 0//Full block + if(!isliving(target)) return 0 + if(isanimal(target)) return 0 + var/mob/living/L = target + L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked) // add in AGONY! + return 1 + +//called when the projectile stops flying because it collided with something +/obj/item/projectile/proc/on_impact(var/atom/A) + impact_effect(effect_transform) // generate impact effect + return + +//Checks if the projectile is eligible for embedding. Not that it necessarily will. +/obj/item/projectile/proc/can_embed() + //embed must be enabled and damage type must be brute + if(!embed || damage_type != BRUTE) + return 0 + return 1 + +//return 1 if the projectile should be allowed to pass through after all, 0 if not. +/obj/item/projectile/proc/check_penetrate(var/atom/A) + return 1 + +/obj/item/projectile/proc/check_fire(atom/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not. + check_trajectory(target, user, pass_flags, flags) + +//sets the click point of the projectile using mouse input params +/obj/item/projectile/proc/set_clickpoint(var/params) + var/list/mouse_control = params2list(params) + if(mouse_control["icon-x"]) + p_x = text2num(mouse_control["icon-x"]) + if(mouse_control["icon-y"]) + p_y = text2num(mouse_control["icon-y"]) + +//called to launch a projectile from a gun +/obj/item/projectile/proc/launch(atom/target, mob/user, obj/item/weapon/gun/launcher, var/target_zone, var/x_offset=0, var/y_offset=0) + var/turf/curloc = get_turf(user) + var/turf/targloc = get_turf(target) + if (!istype(targloc) || !istype(curloc)) return 1 - proc/check_fire(var/mob/living/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not. - if(!istype(target) || !istype(user)) - return 0 - var/obj/item/projectile/test/in_chamber = new /obj/item/projectile/test(get_step_to(user,target)) //Making the test.... - in_chamber.target = target - in_chamber.flags = flags //Set the flags... - in_chamber.pass_flags = pass_flags //And the pass flags to that of the real projectile... - in_chamber.firer = user - var/output = in_chamber.process() //Test it! - del(in_chamber) //No need for it anymore - return output //Send it back to the gun! + firer = user + def_zone = user.zone_sel.selecting - Bump(atom/A as mob|obj|turf|area) - if(A == firer) - loc = A.loc - return 0 //cannot shoot yourself + if(user == target) //Shooting yourself + user.bullet_act(src, target_zone) + on_impact(user) + del(src) + return 0 + if(targloc == curloc) //Shooting something in the same turf + target.bullet_act(src, target_zone) + on_impact(target) + del(src) + return 0 - if(bumped) return 0 - var/forcedodge = 0 // force the projectile to pass + original = target + loc = curloc + starting = curloc + current = curloc + yo = targloc.y - curloc.y + y_offset + xo = targloc.x - curloc.x + x_offset - bumped = 1 - if(firer && istype(A, /mob)) - var/mob/M = A - if(!istype(A, /mob/living)) - loc = A.loc - return 0// nope.avi + shot_from = launcher + silenced = launcher.silenced - var/distance = get_dist(starting,loc) - var/miss_modifier = -30 + spawn() + process() - if (istype(shot_from,/obj/item/weapon/gun)) //If you aim at someone beforehead, it'll hit more often. - var/obj/item/weapon/gun/daddy = shot_from //Kinda balanced by fact you need like 2 seconds to aim - if (daddy.target && original in daddy.target) //As opposed to no-delay pew pew - miss_modifier += -30 - def_zone = get_zone_with_miss_chance(def_zone, M, miss_modifier + 15*distance) + return 0 - if(!def_zone) - visible_message("\blue \The [src] misses [M] narrowly!") - forcedodge = -1 - else - if(silenced) - M << "\red You've been shot in the [parse_zone(def_zone)] by the [src.name]!" - else - visible_message("\red [A.name] is hit by the [src.name] in the [parse_zone(def_zone)]!")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter - if(istype(firer, /mob)) - M.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src.type]" - firer.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [M]/[M.ckey] with a [src.type]" - msg_admin_attack("[firer] ([firer.ckey]) shot [M] ([M.ckey]) with a [src] (JMP)") //BS12 EDIT ALG - else - M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a [src]" - msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a [src] (JMP)") //BS12 EDIT ALG +//Used to change the direction of the projectile in flight. +/obj/item/projectile/proc/redirect(var/new_x, var/new_y, var/atom/starting_loc, var/mob/new_firer=null) + original = locate(new_x, new_y, src.z) + starting = starting_loc + current = starting_loc + if(new_firer) + firer = src - if(A) - if (!forcedodge) - forcedodge = A.bullet_act(src, def_zone) // searches for return value - if(forcedodge == -1) // the bullet passes through a dense object! - bumped = 0 // reset bumped variable! - if(istype(A, /turf)) - loc = A - else - loc = A.loc - permutated.Add(A) - return 0 - if(istype(A,/turf)) - for(var/obj/O in A) - O.bullet_act(src) - for(var/mob/M in A) - M.bullet_act(src, def_zone) - density = 0 - invisibility = 101 - del(src) - return 1 + yo = new_y - starting_loc.y + xo = new_x - starting_loc.x +//Called when the projectile intercepts a mob. Returns 1 if the projectile hit the mob, 0 if it missed and should keep flying. +/obj/item/projectile/proc/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier=0) + //accuracy bonus from aiming + if (istype(shot_from, /obj/item/weapon/gun)) + var/obj/item/weapon/gun/daddy = shot_from + miss_modifier -= round(15*daddy.accuracy) + + //If you aim at someone beforehead, it'll hit more often. + //Kinda balanced by fact you need like 2 seconds to aim + //As opposed to no-delay pew pew + if (daddy.aim_targets && original in daddy.aim_targets) + miss_modifier += -30 - CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 + //roll to-hit + miss_modifier = max(miss_modifier + 15*(distance-2), 0) + var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, miss_modifier, ranged_attack=(distance > 1)) + if(!hit_zone) + visible_message("\The [src] misses [target_mob] narrowly!") + return 0 - if(istype(mover, /obj/item/projectile)) - return prob(95) + //set def_zone, so if the projectile ends up hitting someone else later (to be implemented), it is more likely to hit the same part + def_zone = hit_zone + + //hit messages + if(silenced) + target_mob << "You've been hit in the [parse_zone(def_zone)] by \the [src]!" + else + visible_message("\The [target_mob] is hit by \the [src] in the [parse_zone(def_zone)]!")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter + + //admin logs + if(istype(firer, /mob)) + target_mob.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [target_mob]/[target_mob.ckey] with a [src.type]" + firer.attack_log += "\[[time_stamp()]\] [firer]/[firer.ckey] shot [target_mob]/[target_mob.ckey] with a [src.type]" + msg_admin_attack("[firer] ([firer.ckey]) shot [target_mob] ([target_mob.ckey]) with a [src] (JMP)") //BS12 EDIT ALG + else if(firer) + target_mob.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [target_mob]/[target_mob.ckey] with a [src]" + msg_admin_attack("UNKNOWN shot [target_mob] ([target_mob.ckey]) with a [src] (JMP)") //BS12 EDIT ALG + else + target_mob.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [target_mob]/[target_mob.ckey] with a [src]" + msg_admin_attack("UNKNOWN shot [target_mob] ([target_mob.ckey]) with a [src] (JMP)") //BS12 EDIT ALG + + //sometimes bullet_act() will want the projectile to continue flying + if (target_mob.bullet_act(src, def_zone) == -1) + return 0 + + return 1 + +/obj/item/projectile/Bump(atom/A as mob|obj|turf|area, forced=0) + if(A == src) + return 0 //no + + if(A == firer) + loc = A.loc + return 0 //cannot shoot yourself + + if((bumped && !forced) || (A in permutated)) + return 0 + + var/passthrough = 0 //if the projectile should continue flying + var/distance = get_dist(starting,loc) + + bumped = 1 + if(ismob(A)) + var/mob/M = A + if(istype(A, /mob/living)) + //if they have a neck grab on someone, that person gets hit instead + var/obj/item/weapon/grab/G = locate() in M + if(G && G.state >= GRAB_NECK) + visible_message("\The [M] uses [G.affecting] as a shield!") + if(Bump(G.affecting, forced=1)) + return //If Bump() returns 0 (keep going) then we continue on to attack M. + + passthrough = !attack_mob(M, distance) else - return 1 + passthrough = 1 //so ghosts don't stop bullets + else + passthrough = (A.bullet_act(src, def_zone) == -1) //backwards compatibility + if(isturf(A)) + for(var/obj/O in A) + O.bullet_act(src) + for(var/mob/M in A) + attack_mob(M, distance) + //penetrating projectiles can pass through things that otherwise would not let them + if(!passthrough && penetrating > 0) + if(check_penetrate(A)) + passthrough = 1 + penetrating-- - process() - if(kill_count < 1) + //the bullet passes through a dense object! + if(passthrough) + //move ourselves onto A so we can continue on our way. + if(A) + if(istype(A, /turf)) + loc = A + else + loc = A.loc + permutated.Add(A) + bumped = 0 //reset bumped variable! + return 0 + + //stop flying + on_impact(A) + + density = 0 + invisibility = 101 + + del(src) + return 1 + +/obj/item/projectile/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if(air_group || (height==0)) return 1 + + if(istype(mover, /obj/item/projectile)) + return prob(95) //ha + else + return 1 + +/obj/item/projectile/process() + var/first_step = 1 + + //plot the initial trajectory + setup_trajectory() + + spawn while(src) + if(kill_count-- < 1) + on_impact(src.loc) //for any final impact behaviours + del(src) + if((!( current ) || loc == current)) + current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) + if((x == 1 || x == world.maxx || y == 1 || y == world.maxy)) del(src) - kill_count-- - spawn while(src) - if((!( current ) || loc == current)) - current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) - if((x == 1 || x == world.maxx || y == 1 || y == world.maxy)) - del(src) - return - step_towards(src, current) - sleep(1) - if(!bumped && !isturf(original)) - if(loc == get_turf(original)) - if(!(original in permutated)) - Bump(original) - sleep(1) + return + + trajectory.increment() // increment the current location + location = trajectory.return_location(location) // update the locally stored location data + + if(!location) + del(src) // if it's left the world... kill it + + Move(location.return_turf()) + + if(first_step) + muzzle_effect(effect_transform) + first_step = 0 + else + tracer_effect(effect_transform) + + if(!bumped && !isturf(original)) + if(loc == get_turf(original)) + if(!(original in permutated)) + Bump(original) + + if(!hitscan) + sleep(1) //add delay between movement iterations if it's not a hitscan weapon + +/obj/item/projectile/proc/setup_trajectory() + // plot the initial trajectory + trajectory = new() + trajectory.setup(starting, original, pixel_x, pixel_y) + + // generate this now since all visual effects the projectile makes can use it + effect_transform = new() + effect_transform.Scale(trajectory.return_hypotenuse(), 1) + effect_transform.Turn(-trajectory.return_angle()) //no idea why this has to be inverted, but it works + +/obj/item/projectile/proc/muzzle_effect(var/matrix/T) + if(silenced) return + if(ispath(muzzle_type)) + var/obj/effect/projectile/M = new muzzle_type(get_turf(src)) + + if(istype(M)) + M.set_transform(T) + M.pixel_x = location.pixel_x + M.pixel_y = location.pixel_y + M.activate() + +/obj/item/projectile/proc/tracer_effect(var/matrix/M) + if(ispath(tracer_type)) + var/obj/effect/projectile/P = new tracer_type(location.loc) + + if(istype(P)) + P.set_transform(M) + P.pixel_x = location.pixel_x + P.pixel_y = location.pixel_y + P.activate() + +/obj/item/projectile/proc/impact_effect(var/matrix/M) + if(ispath(tracer_type)) + var/obj/effect/projectile/P = new impact_type(location.loc) + + if(istype(P)) + P.set_transform(M) + P.pixel_x = location.pixel_x + P.pixel_y = location.pixel_y + P.activate() + +//"Tracing" projectile /obj/item/projectile/test //Used to see if you can hit them. invisibility = 101 //Nope! Can't see me! yo = null @@ -167,36 +354,58 @@ var/target = null var/result = 0 //To pass the message back to the gun. - Bump(atom/A as mob|obj|turf|area) - if(A == firer) - loc = A.loc - return //cannot shoot yourself - if(istype(A, /obj/item/projectile)) - return - if(istype(A, /mob/living)) - result = 2 //We hit someone, return 1! - return - result = 1 +/obj/item/projectile/test/Bump(atom/A as mob|obj|turf|area) + if(A == firer) + loc = A.loc + return //cannot shoot yourself + if(istype(A, /obj/item/projectile)) return + if(istype(A, /mob/living)) + result = 2 //We hit someone, return 1! + return + result = 1 + return - process() - var/turf/curloc = get_turf(src) - var/turf/targloc = get_turf(target) - if(!curloc || !targloc) - return 0 - yo = targloc.y - curloc.y - xo = targloc.x - curloc.x - target = targloc - while(src) //Loop on through! - if(result) - return (result - 1) - if((!( target ) || loc == target)) - target = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) //Finding the target turf at map edge - step_towards(src, target) - var/mob/living/M = locate() in get_turf(src) - if(istype(M)) //If there is someting living... - return 1 //Return 1 - else - M = locate() in get_step(src,target) - if(istype(M)) - return 1 +/obj/item/projectile/test/process() + var/turf/curloc = get_turf(src) + var/turf/targloc = get_turf(target) + if(!curloc || !targloc) + return 0 + yo = targloc.y - curloc.y + xo = targloc.x - curloc.x + target = targloc + + //plot the initial trajectory + setup_trajectory() + + while(src) //Loop on through! + if(result) + return (result - 1) + if((!( target ) || loc == target)) + target = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) //Finding the target turf at map edge + + trajectory.increment() // increment the current location + location = trajectory.return_location(location) // update the locally stored location data + + Move(location.return_turf()) + + var/mob/living/M = locate() in get_turf(src) + if(istype(M)) //If there is someting living... + return 1 //Return 1 + else + M = locate() in get_step(src,target) + if(istype(M)) + return 1 + +/proc/check_trajectory(atom/target as mob, var/mob/living/user as mob, var/pass_flags=PASSTABLE|PASSGLASS|PASSGRILLE, flags=null) //Checks if you can hit them or not. + if(!istype(target) || !istype(user)) + return 0 + var/obj/item/projectile/test/trace = new /obj/item/projectile/test(get_step_to(user,target)) //Making the test.... + trace.target = target + if(!isnull(flags)) + trace.flags = flags //Set the flags... + trace.pass_flags = pass_flags //And the pass flags to that of the real projectile... + trace.firer = user + var/output = trace.process() //Test it! + del(trace) //No need for it anymore + return output //Send it back to the gun! diff --git a/code/modules/projectiles/projectile/animate.dm b/code/modules/projectiles/projectile/animate.dm index 490227d233..0f92729ad4 100644 --- a/code/modules/projectiles/projectile/animate.dm +++ b/code/modules/projectiles/projectile/animate.dm @@ -4,7 +4,7 @@ damage = 0 damage_type = BURN nodamage = 1 - flag = "energy" + check_armour = "energy" /obj/item/projectile/animate/Bump(var/atom/change) if((istype(change, /obj/item) || istype(change, /obj/structure)) && !is_type_in_list(change, protected_objects)) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index b811eb9281..cbe1ad5625 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -1,84 +1,17 @@ -var/list/beam_master = list() -//Use: Caches beam state images and holds turfs that had these images overlaid. -//Structure: -//beam_master -// icon_states/dirs of beams -// image for that beam -// references for fired beams -// icon_states/dirs for each placed beam image -// turfs that have that icon_state/dir - /obj/item/projectile/beam name = "laser" icon_state = "laser" pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE damage = 40 damage_type = BURN - flag = "laser" + check_armour = "laser" eyeblur = 4 var/frequency = 1 - process() - var/reference = "\ref[src]" //So we do not have to recalculate it a ton - var/first = 1 //So we don't make the overlay in the same tile as the firer - spawn while(src) //Move until we hit something + hitscan = 1 - if((!( current ) || loc == current)) //If we pass our target - current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) - if((x == 1 || x == world.maxx || y == 1 || y == world.maxy)) - del(src) //Delete if it passes the world edge - return - step_towards(src, current) //Move~ - - if(kill_count < 1) - del(src) - kill_count-- - - if(!bumped && !isturf(original)) - if(loc == get_turf(original)) - if(!(original in permutated)) - Bump(original) - - if(!first) //Add the overlay as we pass over tiles - var/target_dir = get_dir(src, current) //So we don't call this too much - - //If the icon has not been added yet - if( !("[icon_state][target_dir]" in beam_master) ) - var/image/I = image(icon,icon_state,10,target_dir) //Generate it. - beam_master["[icon_state][target_dir]"] = I //And cache it! - - //Finally add the overlay - src.loc.overlays += beam_master["[icon_state][target_dir]"] - - //Add the turf to a list in the beam master so they can be cleaned up easily. - if(reference in beam_master) - var/list/turf_master = beam_master[reference] - if("[icon_state][target_dir]" in turf_master) - var/list/turfs = turf_master["[icon_state][target_dir]"] - turfs += loc - else - turf_master["[icon_state][target_dir]"] = list(loc) - else - var/list/turfs = list() - turfs["[icon_state][target_dir]"] = list(loc) - beam_master[reference] = turfs - else - first = 0 - cleanup(reference) - return - - Del() - cleanup("\ref[src]") - ..() - - proc/cleanup(reference) //Waits .3 seconds then removes the overlay. - src = null //we're getting deleted! this will keep the code running - spawn(3) - var/list/turf_master = beam_master[reference] - for(var/laser_state in turf_master) - var/list/turfs = turf_master[laser_state] - for(var/turf/T in turfs) - T.overlays -= beam_master[laser_state] - return + muzzle_type = /obj/effect/projectile/laser/muzzle + tracer_type = /obj/effect/projectile/laser/tracer + impact_type = /obj/effect/projectile/laser/impact /obj/item/projectile/beam/practice name = "laser" @@ -86,31 +19,49 @@ var/list/beam_master = list() pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE damage = 0 damage_type = BURN - flag = "laser" + check_armour = "laser" eyeblur = 2 - /obj/item/projectile/beam/heavylaser name = "heavy laser" icon_state = "heavylaser" damage = 60 + muzzle_type = /obj/effect/projectile/laser_heavy/muzzle + tracer_type = /obj/effect/projectile/laser_heavy/tracer + impact_type = /obj/effect/projectile/laser_heavy/impact + /obj/item/projectile/beam/xray name = "xray beam" icon_state = "xray" damage = 30 + muzzle_type = /obj/effect/projectile/xray/muzzle + tracer_type = /obj/effect/projectile/xray/tracer + impact_type = /obj/effect/projectile/xray/impact + /obj/item/projectile/beam/pulse name = "pulse" icon_state = "u_laser" damage = 50 + muzzle_type = /obj/effect/projectile/laser_pulse/muzzle + tracer_type = /obj/effect/projectile/laser_pulse/tracer + impact_type = /obj/effect/projectile/laser_pulse/impact + +/obj/item/projectile/beam/pulse/on_hit(var/atom/target, var/blocked = 0) + if(isturf(target)) + target.ex_act(2) + ..() /obj/item/projectile/beam/emitter name = "emitter beam" icon_state = "emitter" - damage = 30 + damage = 0 // The actual damage is computed in /code/modules/power/singularity/emitter.dm + muzzle_type = /obj/effect/projectile/emitter/muzzle + tracer_type = /obj/effect/projectile/emitter/tracer + impact_type = /obj/effect/projectile/emitter/impact /obj/item/projectile/beam/lastertag/blue name = "lasertag beam" @@ -118,14 +69,18 @@ var/list/beam_master = list() pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE damage = 0 damage_type = BURN - flag = "laser" + check_armour = "laser" - on_hit(var/atom/target, var/blocked = 0) - if(istype(target, /mob/living/carbon/human)) - var/mob/living/carbon/human/M = target - if(istype(M.wear_suit, /obj/item/clothing/suit/redtag)) - M.Weaken(5) - return 1 + muzzle_type = /obj/effect/projectile/laser_blue/muzzle + tracer_type = /obj/effect/projectile/laser_blue/tracer + impact_type = /obj/effect/projectile/laser_blue/impact + +/obj/item/projectile/beam/lastertag/blue/on_hit(var/atom/target, var/blocked = 0) + if(istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/M = target + if(istype(M.wear_suit, /obj/item/clothing/suit/redtag)) + M.Weaken(5) + return 1 /obj/item/projectile/beam/lastertag/red name = "lasertag beam" @@ -133,14 +88,14 @@ var/list/beam_master = list() pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE damage = 0 damage_type = BURN - flag = "laser" + check_armour = "laser" - on_hit(var/atom/target, var/blocked = 0) - if(istype(target, /mob/living/carbon/human)) - var/mob/living/carbon/human/M = target - if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag)) - M.Weaken(5) - return 1 +/obj/item/projectile/beam/lastertag/red/on_hit(var/atom/target, var/blocked = 0) + if(istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/M = target + if(istype(M.wear_suit, /obj/item/clothing/suit/bluetag)) + M.Weaken(5) + return 1 /obj/item/projectile/beam/lastertag/omni//A laser tag bolt that stuns EVERYONE name = "lasertag beam" @@ -148,26 +103,39 @@ var/list/beam_master = list() pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE damage = 0 damage_type = BURN - flag = "laser" + check_armour = "laser" - on_hit(var/atom/target, var/blocked = 0) - if(istype(target, /mob/living/carbon/human)) - var/mob/living/carbon/human/M = target - if((istype(M.wear_suit, /obj/item/clothing/suit/bluetag))||(istype(M.wear_suit, /obj/item/clothing/suit/redtag))) - M.Weaken(5) - return 1 + muzzle_type = /obj/effect/projectile/laser_omni/muzzle + tracer_type = /obj/effect/projectile/laser_omni/tracer + impact_type = /obj/effect/projectile/laser_omni/impact + +/obj/item/projectile/beam/lastertag/omni/on_hit(var/atom/target, var/blocked = 0) + if(istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/M = target + if((istype(M.wear_suit, /obj/item/clothing/suit/bluetag))||(istype(M.wear_suit, /obj/item/clothing/suit/redtag))) + M.Weaken(5) + return 1 /obj/item/projectile/beam/sniper name = "sniper beam" icon_state = "xray" damage = 60 - stun = 5 - weaken = 5 - stutter = 5 + stun = 3 + weaken = 3 + stutter = 3 + + muzzle_type = /obj/effect/projectile/xray/muzzle + tracer_type = /obj/effect/projectile/xray/tracer + impact_type = /obj/effect/projectile/xray/impact /obj/item/projectile/beam/stun name = "stun beam" icon_state = "stun" nodamage = 1 + taser_effect = 1 agony = 40 damage_type = HALLOSS + + muzzle_type = /obj/effect/projectile/stun/muzzle + tracer_type = /obj/effect/projectile/stun/tracer + impact_type = /obj/effect/projectile/stun/impact diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index d1216d1559..977c9e26f4 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -4,66 +4,182 @@ damage = 60 damage_type = BRUTE nodamage = 0 - flag = "bullet" + check_armour = "bullet" embed = 1 sharp = 1 + var/mob_passthrough_check = 0 + + muzzle_type = /obj/effect/projectile/bullet/muzzle - on_hit(var/atom/target, var/blocked = 0) - if (..(target, blocked)) - var/mob/living/L = target - shake_camera(L, 3, 2) +/obj/item/projectile/bullet/on_hit(var/atom/target, var/blocked = 0) + if (..(target, blocked)) + var/mob/living/L = target + shake_camera(L, 3, 2) -/obj/item/projectile/bullet/weakbullet // "rubber" bullets +/obj/item/projectile/bullet/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier) + if(penetrating > 0 && damage > 20 && prob(damage)) + mob_passthrough_check = 1 + else + mob_passthrough_check = 0 + return ..() + +/obj/item/projectile/bullet/can_embed() + //prevent embedding if the projectile is passing through the mob + if(mob_passthrough_check) + return 0 + return ..() + +/obj/item/projectile/bullet/check_penetrate(var/atom/A) + if(!A || !A.density) return 1 //if whatever it was got destroyed when we hit it, then I guess we can just keep going + + if(istype(A, /obj/mecha)) + return 1 //mecha have their own penetration handling + + if(ismob(A)) + if(!mob_passthrough_check) + return 0 + if(iscarbon(A)) + damage *= 0.7 //squishy mobs absorb KE + return 1 + + var/chance = 0 + if(istype(A, /turf/simulated/wall)) + var/turf/simulated/wall/W = A + chance = round(damage/W.damage_cap*180) + else if(istype(A, /obj/machinery/door)) + var/obj/machinery/door/D = A + chance = round(damage/D.maxhealth*180) + if(D.glass) chance *= 2 + else if(istype(A, /obj/structure/girder) || istype(A, /obj/structure/cultgirder)) + chance = 100 + else if(istype(A, /obj/machinery) || istype(A, /obj/structure)) + chance = 25 + + if(prob(chance)) + if(A.opacity) + //display a message so that people on the other side aren't so confused + A.visible_message("\The [src] pierces through \the [A]!") + return 1 + + return 0 + +//For projectiles that actually represent clouds of projectiles +/obj/item/projectile/bullet/pellet + name = "shrapnel" //'shrapnel' sounds more dangerous (i.e. cooler) than 'pellet' + damage = 20 + //icon_state = "bullet" //TODO: would be nice to have it's own icon state + var/pellets = 4 //number of pellets + var/range_step = 2 //effective pellet count decreases every few tiles + var/base_spread = 90 //lower means the pellets spread more across body parts + var/spread_step = 10 //higher means the pellets spread more across body parts with distance + +/obj/item/projectile/bullet/pellet/Bumped() + . = ..() + bumped = 0 //can hit all mobs in a tile. pellets is decremented inside attack_mob so this should be fine. + +/obj/item/projectile/bullet/pellet/attack_mob(var/mob/living/target_mob, var/distance) + if (pellets < 0) return 1 + + var/pellet_loss = round((distance - 1)/range_step) //pellets lost due to distance + var/total_pellets = max(pellets - pellet_loss, 1) + var/spread = max(base_spread - (spread_step*distance), 0) + var/hits = 0 + for (var/i in 1 to total_pellets) + //pellet hits spread out across different zones, but 'aim at' the targeted zone with higher probability + //whether the pellet actually hits the def_zone or a different zone should still be determined by the parent using get_zone_with_miss_chance(). + var/old_zone = def_zone + def_zone = ran_zone(def_zone, spread) + if (..()) hits++ + def_zone = old_zone //restore the original zone the projectile was aimed at + + pellets -= hits //each hit reduces the number of pellets left + if (hits >= total_pellets || pellets <= 0) + return 1 + return 0 + +/* short-casing projectiles, like the kind used in pistols or SMGs */ + +/obj/item/projectile/bullet/pistol + damage = 20 + +/obj/item/projectile/bullet/pistol/medium + damage = 25 + +/obj/item/projectile/bullet/pistol/strong //revolvers and matebas + damage = 60 + +/obj/item/projectile/bullet/pistol/rubber //"rubber" bullets + name = "rubber bullet" damage = 10 agony = 40 embed = 0 sharp = 0 -/obj/item/projectile/bullet/weakbullet/beanbag //because beanbags are not bullets +/* shotgun projectiles */ + +/obj/item/projectile/bullet/shotgun + name = "slug" + damage = 60 + +/obj/item/projectile/bullet/shotgun/beanbag //because beanbags are not bullets name = "beanbag" damage = 20 agony = 60 embed = 0 sharp = 0 -/obj/item/projectile/bullet/weakbullet/rubber - name = "rubber bullet" +//Should do about 80 damage at 1 tile distance (adjacent), and 50 damage at 3 tiles distance. +//Overall less damage than slugs in exchange for more damage at very close range and more embedding +/obj/item/projectile/bullet/pellet/shotgun + name = "shrapnel" + damage = 13 + pellets = 6 + range_step = 1 + spread_step = 10 -/obj/item/projectile/bullet/midbullet - damage = 20 +/* "Rifle" rounds */ -/obj/item/projectile/bullet/midbullet2 - damage = 25 +/obj/item/projectile/bullet/rifle/a762 + damage = 30 + penetrating = 1 + +/obj/item/projectile/bullet/rifle/a145 + damage = 80 + stun = 3 + weaken = 3 + penetrating = 5 + +/obj/item/projectile/bullet/rifle/a556 + damage = 40 + penetrating = 1 + +/* Miscellaneous */ /obj/item/projectile/bullet/suffocationbullet//How does this even work? name = "co bullet" damage = 20 damage_type = OXY - /obj/item/projectile/bullet/cyanideround name = "poison bullet" damage = 40 damage_type = TOX - -/obj/item/projectile/bullet/burstbullet//I think this one needs something for the on hit +/obj/item/projectile/bullet/burstbullet name = "exploding bullet" damage = 20 embed = 0 edge = 1 +/obj/item/projectile/bullet/gyro/on_hit(var/atom/target, var/blocked = 0) + if(isturf(target)) + explosion(target, -1, 0, 2) + ..() -/obj/item/projectile/bullet/stunshot - name = "stunshot" - damage = 5 - agony = 80 - stutter = 10 +/obj/item/projectile/bullet/blank + invisibility = 101 + damage = 1 embed = 0 - sharp = 0 - -/obj/item/projectile/bullet/a762 - damage = 25 /obj/item/projectile/bullet/chameleon damage = 1 // stop trying to murderbone with a fake gun dumbass!!! diff --git a/code/modules/projectiles/projectile/change.dm b/code/modules/projectiles/projectile/change.dm index 215c117342..24feb08771 100644 --- a/code/modules/projectiles/projectile/change.dm +++ b/code/modules/projectiles/projectile/change.dm @@ -4,43 +4,47 @@ damage = 0 damage_type = BURN nodamage = 1 - flag = "energy" + check_armour = "energy" - on_hit(var/atom/change) - wabbajack(change) +/obj/item/projectile/change/on_hit(var/atom/change) + wabbajack(change) - -/obj/item/projectile/change/proc/wabbajack (mob/M as mob in living_mob_list) +/obj/item/projectile/change/proc/wabbajack(var/mob/M) if(istype(M, /mob/living) && M.stat != DEAD) - if(M.monkeyizing) return - if(M.has_brain_worms()) return //Borer stuff - RR - - M.monkeyizing = 1 - M.canmove = 0 - M.icon = null - M.overlays.Cut() - M.invisibility = 101 + if(M.monkeyizing) + return + if(M.has_brain_worms()) + return //Borer stuff - RR if(istype(M, /mob/living/silicon/robot)) var/mob/living/silicon/robot/Robot = M - if(Robot.mmi) del(Robot.mmi) - Robot.notify_ai(1) + if(Robot.mmi) + del(Robot.mmi) else for(var/obj/item/W in M) if(istype(W, /obj/item/weapon/implant)) //TODO: Carn. give implants a dropped() or something del(W) continue - W.layer = initial(W.layer) - W.loc = M.loc - W.dropped(M) + M.drop_from_inventory(W) var/mob/living/new_mob - var/randomize = pick("monkey","robot","slime","xeno","human") + var/options = list("robot", "slime") + for(var/t in all_species) + options += t + options -= "Xenomorph Queen" + options -= "Xenomorph" + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.species) + options -= H.species.name + else if(isrobot(M)) + options -= "robot" + else if(isslime(M)) + options -= "slime" + + var/randomize = pick(options) switch(randomize) - if("monkey") - new_mob = new /mob/living/carbon/monkey(M.loc) - new_mob.universal_speak = 1 if("robot") new_mob = new /mob/living/silicon/robot(M.loc) new_mob.gender = M.gender @@ -52,36 +56,42 @@ if("slime") new_mob = new /mob/living/carbon/slime(M.loc) new_mob.universal_speak = 1 - if("xeno") - var/alien_caste = pick("Hunter","Sentinel","Drone","Larva") - new_mob = create_new_xenomorph(alien_caste,M.loc) - new_mob.universal_speak = 1 - if("human") - new_mob = new /mob/living/carbon/human(M.loc, pick(all_species)) - if(M.gender == MALE) - new_mob.gender = MALE - new_mob.name = pick(first_names_male) - else - new_mob.gender = FEMALE - new_mob.name = pick(first_names_female) - new_mob.name += " [pick(last_names)]" - new_mob.real_name = new_mob.name - - var/datum/preferences/A = new() //Randomize appearance for the human - A.randomize_appearance_for(new_mob) else - return + var/mob/living/carbon/human/H + if(ishuman(M)) + H = M + else + new_mob = new /mob/living/carbon/human(M.loc) + H = new_mob - for (var/obj/effect/proc_holder/spell/S in M.spell_list) - new_mob.spell_list += new S.type + if(M.gender == MALE) + H.gender = MALE + H.name = pick(first_names_male) + else + H.gender = FEMALE + H.name = pick(first_names_female) + H.name += " [pick(last_names)]" + H.real_name = H.name - new_mob.a_intent = "hurt" - if(M.mind) - M.mind.transfer_to(new_mob) + H.set_species(randomize) + H.universal_speak = 1 + var/datum/preferences/A = new() //Randomize appearance for the human + A.randomize_appearance_for(H) + + if(new_mob) + for (var/obj/effect/proc_holder/spell/S in M.spell_list) + new_mob.spell_list += new S.type + + new_mob.a_intent = "hurt" + if(M.mind) + M.mind.transfer_to(new_mob) + else + new_mob.key = M.key + + new_mob << "Your form morphs into that of \a [lowertext(randomize)]." + + del(M) + return else - new_mob.key = M.key - - new_mob << "Your form morphs into that of a [randomize]." - - del(M) - return new_mob + M << "Your form morphs into that of \a [lowertext(randomize)]." + return \ No newline at end of file diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index b94bda70ad..2a114e9067 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -3,9 +3,43 @@ icon_state = "spark" damage = 0 damage_type = BURN - flag = "energy" + check_armour = "energy" +//releases a burst of light on impact or after travelling a distance +/obj/item/projectile/energy/flash + name = "chemical shell" + icon_state = "bullet" + damage = 5 + kill_count = 15 //if the shell hasn't hit anything after travelling this far it just explodes. + var/flash_range = 0 + var/brightness = 7 + var/light_duration = 5 + +/obj/item/projectile/energy/flash/on_impact(var/atom/A) + var/turf/T = flash_range? src.loc : get_turf(A) + if(!istype(T)) return + + //blind adjacent people + for (var/mob/living/carbon/M in viewers(T, flash_range)) + if(M.eyecheck() < 1) + flick("e_flash", M.flash) + + //snap pop + playsound(src, 'sound/effects/snap.ogg', 50, 1) + src.visible_message("\The [src] explodes in a bright flash!") + + new /obj/effect/decal/cleanable/ash(src.loc) //always use src.loc so that ash doesn't end up inside windows + new /obj/effect/effect/sparks(T) + new /obj/effect/effect/smoke/illumination(T, brightness=max(flash_range*2, brightness), lifetime=light_duration) + +//blinds people like the flash round, but can also be used for temporary illumination +/obj/item/projectile/energy/flash/flare + damage = 10 + flash_range = 1 + brightness = 9 //similar to a flare + light_duration = 200 + /obj/item/projectile/energy/electrode name = "electrode" icon_state = "spark" @@ -15,11 +49,16 @@ weaken = 10 stutter = 10 */ + taser_effect = 1 agony = 40 damage_type = HALLOSS //Damage will be handled on the MOB side, to prevent window shattering. - +/obj/item/projectile/energy/electrode/stunshot + name = "stunshot" + damage = 5 + taser_effect = 1 + agony = 80 /obj/item/projectile/energy/declone name = "declone" diff --git a/code/modules/projectiles/projectile/force.dm b/code/modules/projectiles/projectile/force.dm index 4dffe4ce89..71b7d34d04 100644 --- a/code/modules/projectiles/projectile/force.dm +++ b/code/modules/projectiles/projectile/force.dm @@ -3,7 +3,7 @@ icon = 'icons/obj/projectiles.dmi' icon_state = "ice_1" damage = 20 - flag = "energy" + check_armour = "energy" /obj/item/projectile/forcebolt/strong name = "force bolt" diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 49cd420994..fc69f6ec94 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -4,7 +4,7 @@ damage = 0 damage_type = BURN nodamage = 1 - flag = "energy" + check_armour = "energy" on_hit(var/atom/target, var/blocked = 0) @@ -16,7 +16,7 @@ name ="explosive bolt" icon_state= "bolter" damage = 50 - flag = "bullet" + check_armour = "bullet" sharp = 1 edge = 1 @@ -30,7 +30,7 @@ damage = 0 damage_type = BURN nodamage = 1 - flag = "energy" + check_armour = "energy" var/temperature = 300 @@ -47,7 +47,7 @@ damage = 0 damage_type = BRUTE nodamage = 1 - flag = "bullet" + check_armour = "bullet" Bump(atom/A as mob|obj|turf|area) if(A == firer) @@ -76,7 +76,7 @@ damage = 0 damage_type = TOX nodamage = 1 - flag = "energy" + check_armour = "energy" on_hit(var/atom/target, var/blocked = 0) var/mob/living/M = target @@ -115,7 +115,7 @@ damage = 0 damage_type = TOX nodamage = 1 - flag = "energy" + check_armour = "energy" on_hit(var/atom/target, var/blocked = 0) var/mob/M = target @@ -137,3 +137,16 @@ var/mob/living/carbon/human/M = target M.adjustBrainLoss(20) M.hallucination += 20 + +/obj/item/projectile/icarus/pointdefense/process() + Icarus_FireLaser(get_turf(original)) + spawn + del src + + return + +/obj/item/projectile/icarus/guns/process() + Icarus_FireCannon(get_turf(original)) + spawn + del src + return diff --git a/code/modules/projectiles/targeting.dm b/code/modules/projectiles/targeting.dm index 59c5c02802..388b53a256 100644 --- a/code/modules/projectiles/targeting.dm +++ b/code/modules/projectiles/targeting.dm @@ -1,10 +1,10 @@ /obj/item/weapon/gun/verb/toggle_firerate() - set name = "Toggle Firerate" + set name = "Toggle Continue Aiming" set category = "Object" - firerate = !firerate + keep_aim = !keep_aim - if (firerate) + if (keep_aim) loc << "You will now continue firing when your target moves." else loc << "You will now only fire once, then lower your aim, when your target moves." @@ -12,7 +12,7 @@ /obj/item/weapon/gun/verb/lower_aim() set name = "Lower Aim" set category = "Object" - if(target) + if(aim_targets) stop_aim() usr.visible_message("\blue \The [usr] lowers \the [src]...") @@ -34,13 +34,13 @@ user.client.remove_gun_icons() return ..() -//Removes lock fro mall targets +//Removes lock from all targets /obj/item/weapon/gun/proc/stop_aim() - if(target) - for(var/mob/living/M in target) + if(aim_targets) + for(var/mob/living/M in aim_targets) if(M) M.NotTargeted(src) //Untargeting people. - del(target) + del(aim_targets) //Compute how to fire..... //Return 1 if a target was found, 0 otherwise. @@ -49,13 +49,13 @@ if(lock_time > world.time - 2) return user.set_dir(get_cardinal_dir(src, A)) - if(isliving(A) && !(A in target)) + if(isliving(A) && !(A in aim_targets)) Aim(A) //Clicked a mob, aim at them return 1 //Didn't click someone, check if there is anyone along that guntrace var/mob/living/M = GunTrace(usr.x,usr.y,A.x,A.y,usr.z,usr) //Find dat mob. - if(isliving(M) && (M in view(user)) && !(M in target)) + if(isliving(M) && (M in view(user)) && !(M in aim_targets)) Aim(M) //Aha! Aim at them! return 1 @@ -63,13 +63,13 @@ //Aiming at the target mob. /obj/item/weapon/gun/proc/Aim(var/mob/living/M) - if(!target || !(M in target)) + if(!aim_targets || !(M in aim_targets)) lock_time = world.time - if(target && !automatic) //If they're targeting someone and they have a non automatic weapon. - for(var/mob/living/L in target) + if(aim_targets && !multi_aim) //If they're targeting someone and they have a non multi_aim weapon. + for(var/mob/living/L in aim_targets) if(L) L.NotTargeted(src) - del(target) + del(aim_targets) usr.visible_message("\red [usr] turns \the [src] on [M]!") else usr.visible_message("\red [usr] aims \a [src] at [M]!") @@ -85,34 +85,31 @@ return //reflex firing is disabled when help intent is set - if (M.a_intent == "help") + if (M.a_intent == I_HELP) M << "\red You refrain from firing your [src] as your intent is set to help." return M.last_move_intent = world.time - if(can_fire()) - var/firing_check = can_hit(T,usr) //0 if it cannot hit them, 1 if it is capable of hitting, and 2 if a special check is preventing it from firing. - if(firing_check > 0) - if(firing_check == 1) - Fire(T,usr, reflex = 1) - else if(!told_cant_shoot) - M << "\red They can't be hit from here!" - told_cant_shoot = 1 - spawn(30) - told_cant_shoot = 0 - else - click_empty(M) + var/firing_check = can_hit(T,usr) //0 if it cannot hit them, 1 if it is capable of hitting, and 2 if a special check is preventing it from firing. + if(firing_check > 0) + if(firing_check == 1) + Fire(T,usr, reflex = 1) + else if(!told_cant_shoot) + M << "\red They can't be hit from here!" + told_cant_shoot = 1 + spawn(30) + told_cant_shoot = 0 usr.set_dir(get_cardinal_dir(src, T)) - if (!firerate) // If firerate is set to lower aim after one shot, untarget the target + if (!keep_aim) // If keep_aim is set to lower aim after one shot, untarget the target T.NotTargeted(src) //Yay, math! #define SIGN(X) ((X<0)?-1:1) -proc/GunTrace(X1,Y1,X2,Y2,Z=1,exc_obj,PX1=16,PY1=16,PX2=16,PY2=16) +/proc/GunTrace(X1,Y1,X2,Y2,Z=1,exc_obj,PX1=16,PY1=16,PX2=16,PY2=16) //bluh << "Tracin' [X1],[Y1] to [X2],[Y2] on floor [Z]." var/turf/T var/mob/living/M @@ -150,19 +147,19 @@ proc/GunTrace(X1,Y1,X2,Y2,Z=1,exc_obj,PX1=16,PY1=16,PX2=16,PY2=16) //Targeting management procs -mob/var +/mob/var list/targeted_by target_time = -100 last_move_intent = -100 last_target_click = -5 target_locked = null -mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory. - if(!I.target) - I.target = list(src) - else if(I.automatic && I.target.len < 5) //Automatic weapon, they can hold down a room. - I.target += src - else if(I.target.len >= 5) +/mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory. + if(!I.aim_targets) + I.aim_targets = list(src) + else if(I.multi_aim && I.aim_targets.len < 5) //multi_aim weapon, they can hold down a room. + I.aim_targets += src + else if(I.aim_targets.len >= 5) if(ismob(I.loc)) I.loc << "You can only target 5 people at once!" return @@ -223,43 +220,43 @@ mob/living/proc/Targeted(var/obj/item/weapon/gun/I) //Self explanitory. I.last_moved_mob = src sleep(1) -mob/living/proc/NotTargeted(var/obj/item/weapon/gun/I) +/mob/living/proc/NotTargeted(var/obj/item/weapon/gun/I) if(!I.silenced) for(var/mob/living/M in viewers(src)) M << 'sound/weapons/TargetOff.ogg' targeted_by -= I - I.target.Remove(src) //De-target them - if(!I.target.len) - del(I.target) + I.aim_targets.Remove(src) //De-target them + if(!I.aim_targets.len) + del(I.aim_targets) var/mob/living/T = I.loc //Remove the targeting icons - if(T && ismob(T) && !I.target) + if(T && ismob(T) && !I.aim_targets) T.client.remove_gun_icons() if(!targeted_by.len) del target_locked //Remove the overlay del targeted_by spawn(1) update_targeted() -mob/living/Move() +/mob/living/Move() . = ..() for(var/obj/item/weapon/gun/G in targeted_by) //Handle moving out of the gunner's view. var/mob/living/M = G.loc if(!(M in view(src))) NotTargeted(G) for(var/obj/item/weapon/gun/G in src) //Handle the gunner loosing sight of their target/s - if(G.target) - for(var/mob/living/M in G.target) + if(G.aim_targets) + for(var/mob/living/M in G.aim_targets) if(M && !(M in view(src))) M.NotTargeted(G) //If you move out of range, it isn't going to still stay locked on you any more. -client/var +/client/var target_can_move = 0 target_can_run = 0 target_can_click = 0 gun_mode = 0 //These are called by the on-screen buttons, adjusting what the victim can and cannot do. -client/proc/add_gun_icons() +/client/proc/add_gun_icons() screen += usr.item_use_icon screen += usr.gun_move_icon if (target_can_move) @@ -267,14 +264,15 @@ client/proc/add_gun_icons() -client/proc/remove_gun_icons() +/client/proc/remove_gun_icons() if(!usr) return 1 // Runtime prevention on N00k agents spawning with SMG screen -= usr.item_use_icon screen -= usr.gun_move_icon if (target_can_move) screen -= usr.gun_run_icon -client/verb/ToggleGunMode() +/client/verb/ToggleGunMode() + set name = "Toggle Gun Mode" set hidden = 1 gun_mode = !gun_mode if(gun_mode) @@ -288,7 +286,7 @@ client/verb/ToggleGunMode() usr.gun_setting_icon.icon_state = "gun[gun_mode]" -client/verb/AllowTargetMove() +/client/verb/AllowTargetMove() set hidden=1 //Changing client's permissions @@ -310,8 +308,8 @@ client/verb/AllowTargetMove() //Handling change for all the guns on client for(var/obj/item/weapon/gun/G in usr) G.lock_time = world.time + 5 - if(G.target) - for(var/mob/living/M in G.target) + if(G.aim_targets) + for(var/mob/living/M in G.aim_targets) if(target_can_move) M << "Your character may now walk at the discretion of their targeter." if(!target_can_run) @@ -320,7 +318,7 @@ client/verb/AllowTargetMove() else M << "\red Your character will now be shot if they move." -mob/living/proc/set_m_intent(var/intent) +/mob/living/proc/set_m_intent(var/intent) if (intent != "walk" && intent != "run") return 0 m_intent = intent @@ -346,14 +344,14 @@ client/verb/AllowTargetRun() //Handling change for all the guns on client for(var/obj/item/weapon/gun/G in src) G.lock_time = world.time + 5 - if(G.target) - for(var/mob/living/M in G.target) + if(G.aim_targets) + for(var/mob/living/M in G.aim_targets) if(target_can_run) M << "Your character may now run at the discretion of their targeter." else M << "\red Your character will now be shot if they run." -client/verb/AllowTargetClick() +/client/verb/AllowTargetClick() set hidden=1 //Changing client's permissions @@ -370,8 +368,8 @@ client/verb/AllowTargetClick() //Handling change for all the guns on client for(var/obj/item/weapon/gun/G in src) G.lock_time = world.time + 5 - if(G.target) - for(var/mob/living/M in G.target) + if(G.aim_targets) + for(var/mob/living/M in G.aim_targets) if(target_can_click) M << "Your character may now use items at the discretion of their targeter." else diff --git a/code/modules/random_map/mining_distribution.dm b/code/modules/random_map/mining_distribution.dm new file mode 100644 index 0000000000..76c3b5bcc0 --- /dev/null +++ b/code/modules/random_map/mining_distribution.dm @@ -0,0 +1,242 @@ +#define MIN_SURFACE_COUNT 500 +#define MIN_RARE_COUNT 200 +#define MIN_DEEP_COUNT 100 +#define RESOURCE_HIGH_MAX 4 +#define RESOURCE_HIGH_MIN 2 +#define RESOURCE_MID_MAX 3 +#define RESOURCE_MID_MIN 1 +#define RESOURCE_LOW_MAX 1 +#define RESOURCE_LOW_MIN 0 + +/* +Surface minerals: + silicates + iron + gold + silver +Rare minerals: + uranium + diamond +Deep minerals: + phoron + osmium (platinum) + tritium (hydrogen) +*/ + +/datum/random_map/ore + + descriptor = "resource distribution map" + real_size = 65 // Must be (power of 2)+1 for diamond-square. + cell_range = 255 // These values are used to seed ore values rather than to determine a turf type. + iterations = 0 // We'll handle iterating on our end (recursive, with args). + + var/chunk_size = 4 // Size each cell represents on map + var/random_variance_chance = 25 // % chance of applying random_element. + var/random_element = 0.5 // Determines the variance when smoothing out cell values. + var/deep_val = 0.8 // Threshold for deep metals, set in new as percentage of cell_range. + var/rare_val = 0.7 // Threshold for rare metal, set in new as percentage of cell_range. + var/cell_base // Set in New() + var/initial_cell_range // Set in New() + +/datum/random_map/ore/New() + rare_val = cell_range * rare_val + deep_val = cell_range * deep_val + + initial_cell_range = cell_range/5 + cell_base = cell_range/2 + ..() + +/datum/random_map/ore/check_map_sanity() + + var/rare_count = 0 + var/surface_count = 0 + var/deep_count = 0 + + // Increment map sanity counters. + for(var/value in map) + if(value < rare_val) + surface_count++ + else if(value < deep_val) + rare_count++ + else + deep_count++ + // Sanity check. + if(surface_count < MIN_SURFACE_COUNT) + world << "Insufficient surface minerals. Rerolling..." + return 0 + else if(rare_count < MIN_RARE_COUNT) + world << "Insufficient rare minerals. Rerolling..." + return 0 + else if(deep_count < MIN_DEEP_COUNT) + world << "Insufficient deep minerals. Rerolling..." + return 0 + else + return 1 + +//Halfassed diamond-square algorithm with some fuckery since it's a single dimension array. +/datum/random_map/ore/seed_map() + + // Instantiate the grid. + for(var/x = 1, x <= real_size, x++) + for(var/y = 1, y <= real_size, y++) + map[get_map_cell(x,y)] = 0 + + // Now dump in the actual random data. + map[get_map_cell(1,1)] = cell_base+rand(initial_cell_range) + map[get_map_cell(1,real_size)] = cell_base+rand(initial_cell_range) + map[get_map_cell(real_size,real_size)] = cell_base+rand(initial_cell_range) + map[get_map_cell(real_size,1)] = cell_base+rand(initial_cell_range) + iterate(1,1,1,(real_size-1)) // Start the recursion here. + +/datum/random_map/ore/display_map(atom/user) + + if(!user) + user = world + + for(var/x = 1, x <= real_size, x++) + var/line = "" + for(var/y = 1, y <= real_size, y++) + var/current_cell = get_map_cell(x,y) + if(within_bounds(current_cell) && map[current_cell]) + if(map[current_cell] < rare_val) + line += "S" + else if(map[current_cell] < deep_val) + line += "R" + else + line += "D" + else + line += "X" + user << line + +/datum/random_map/ore/iterate(var/iteration,var/x,var/y,var/input_size) + + // Infinite loop check! + if(iteration>=iterate_before_fail) + world << "Iteration count exceeded, aborting." + return + + var/isize = input_size + var/hsize = round(input_size/2) + + /* + (x,y+isize)----(x+hsize,y+isize)----(x+size,y+isize) + | | | + | | | + | | | + (x,y+hsize)----(x+hsize,y+hsize)----(x+isize,y) + | | | + | | | + | | | + (x,y)----------(x+hsize,y)----------(x+isize,y) + */ + // Central edge values become average of corners. + map[get_map_cell(x+hsize,y+isize)] = round((\ + map[get_map_cell(x,y+isize)] + \ + map[get_map_cell(x+isize,y+isize)] \ + )/2) + + map[get_map_cell(x+hsize,y)] = round(( \ + map[get_map_cell(x,y)] + \ + map[get_map_cell(x+isize,y)] \ + )/2) + + map[get_map_cell(x,y+hsize)] = round(( \ + map[get_map_cell(x,y+isize)] + \ + map[get_map_cell(x,y)] \ + )/2) + + map[get_map_cell(x+isize,y+hsize)] = round(( \ + map[get_map_cell(x+isize,y+isize)] + \ + map[get_map_cell(x+isize,y)] \ + )/2) + + // Centre value becomes the average of all other values + possible random variance. + var/current_cell = get_map_cell(x+hsize,y+hsize) + map[current_cell] = round((map[get_map_cell(x+hsize,y+isize)]+map[get_map_cell(x+hsize,y)]+map[get_map_cell(x,y+hsize)]+map[get_map_cell(x+isize,y)])/4) + + if(prob(random_variance_chance)) + map[current_cell] *= (rand(1,2)==1 ? (1.0-random_element) : (1.0+random_element)) + map[current_cell] = max(0,min(cell_range,map[current_cell])) + + // Recurse until size is too small to subdivide. + if(isize>3) + sleep(-1) + iteration++ + iterate(iteration, x, y, hsize) + iterate(iteration, x+hsize, y, hsize) + iterate(iteration, x, y+hsize, hsize) + iterate(iteration, x+hsize, y+hsize, hsize) + +/datum/random_map/ore/apply_to_map() + for(var/x = 0, x < real_size, x++) + if((origin_x + x) > limit_x) continue + for(var/y = 0, y < real_size, y++) + if((origin_y + y) > limit_y) continue + sleep(-1) + apply_to_turf(x,y) + +/datum/random_map/ore/apply_to_turf(var/x,var/y) + + var/tx = origin_x+((x-1)*chunk_size) + var/ty = origin_y+((y-1)*chunk_size) + + for(var/i=0,ilimit_y) + continue + for(var/j=0,jlimit_x) + continue + + var/turf/T = locate(tx+j, ty+i, origin_z) + if(!T || !T.has_resources) + continue + + sleep(-1) + + T.resources = list() + T.resources["silicates"] = rand(3,5) + T.resources["carbonaceous rock"] = rand(3,5) + + var/current_cell = map[get_map_cell(x,y)] + if(current_cell < rare_val) // Surface metals. + T.resources["iron"] = rand(RESOURCE_HIGH_MIN, RESOURCE_HIGH_MAX) + T.resources["gold"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX) + T.resources["silver"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX) + T.resources["uranium"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX) + T.resources["diamond"] = 0 + T.resources["phoron"] = 0 + T.resources["osmium"] = 0 + T.resources["hydrogen"] = 0 + else if(current_cell < deep_val) // Rare metals. + T.resources["gold"] = rand(RESOURCE_MID_MIN, RESOURCE_MID_MAX) + T.resources["silver"] = rand(RESOURCE_MID_MIN, RESOURCE_MID_MAX) + T.resources["uranium"] = rand(RESOURCE_MID_MIN, RESOURCE_MID_MAX) + T.resources["phoron"] = rand(RESOURCE_MID_MIN, RESOURCE_MID_MAX) + T.resources["osmium"] = rand(RESOURCE_MID_MIN, RESOURCE_MID_MAX) + T.resources["hydrogen"] = 0 + T.resources["diamond"] = 0 + T.resources["iron"] = 0 + else // Deep metals. + T.resources["uranium"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX) + T.resources["diamond"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX) + T.resources["phoron"] = rand(RESOURCE_HIGH_MIN, RESOURCE_HIGH_MAX) + T.resources["osmium"] = rand(RESOURCE_HIGH_MIN, RESOURCE_HIGH_MAX) + T.resources["hydrogen"] = rand(RESOURCE_MID_MIN, RESOURCE_MID_MAX) + T.resources["iron"] = 0 + T.resources["gold"] = 0 + T.resources["silver"] = 0 + + return + +/datum/random_map/ore/cleanup() + return 1 + +#undef MIN_SURFACE_COUNT +#undef MIN_RARE_COUNT +#undef MIN_DEEP_COUNT +#undef RESOURCE_HIGH_MAX +#undef RESOURCE_HIGH_MIN +#undef RESOURCE_MID_MAX +#undef RESOURCE_MID_MIN +#undef RESOURCE_LOW_MAX +#undef RESOURCE_LOW_MIN \ No newline at end of file diff --git a/code/modules/random_map/random_map.dm b/code/modules/random_map/random_map.dm new file mode 100644 index 0000000000..e6f4ec1409 --- /dev/null +++ b/code/modules/random_map/random_map.dm @@ -0,0 +1,173 @@ +#define ORE_COUNT 1000 +/* + This module is used to generate the debris fields/distribution maps/procedural stations. +*/ + +var/global/list/random_maps = list() + +/datum/random_map + var/descriptor = "asteroid" // Display name. + var/real_size = 246 // Size of each edge (must be square :(). + var/cell_range = 2 // Random range for initial cells. + var/iterations = 5 // Number of times to apply the automata rule. + var/max_attempts = 5 // Fail if a sane map isn't generated by this point. + var/raw_map_size // Used for creating new maps each iteration. Value must be real_size^2 + var/list/map = list() // Actual map. + var/origin_x = 1 // Origin point, left. + var/origin_y = 1 // Origin point, bottom. + var/origin_z = 1 // Target Z-level. + var/limit_x = 256 // Maximum x bound. + var/limit_y = 256 // Maximum y bound. + var/iterate_before_fail = 120 // Infinite loop safeguard. + +/datum/random_map/proc/get_map_cell(var/x,var/y) + return ((y-1)*real_size)+x + +/datum/random_map/proc/display_map(atom/user) + + if(!user) + user = world + + for(var/x = 1, x <= real_size, x++) + var/line = "" + for(var/y = 1, y <= real_size, y++) + var/current_cell = get_map_cell(x,y) + if(within_bounds(current_cell)) + if(map[current_cell] == 2) + line += "#" + else + line += "." + user << line + +/datum/random_map/New(var/seed, var/tx, var/ty, var/tz, var/tlx, var/tly) + + // Store this for debugging. + random_maps |= src + + // Initialize map. + set_map_size() + + // Get origins for applying the map later. + if(tx) origin_x = tx + if(ty) origin_y = ty + if(tz) origin_z = tz + if(tlx) limit_x = tlx + if(tly) limit_y = tly + + // testing needed to see how reliable this is (asynchronous calls, called during worldgen), DM ref is not optimistic + if(seed) rand_seed(seed) + + var/start_time = world.timeofday + world << "Generating [descriptor]." + for(var/i = 0;i[capitalize(descriptor)] generation completed in [round(0.1*(world.timeofday-start_time),0.1)] seconds." + return + world << "[capitalize(descriptor)] generation failed in [round(0.1*(world.timeofday-start_time),0.1)] seconds: could not produce sane map." + +/datum/random_map/proc/within_bounds(var/val) + return (val>0) && (val<=raw_map_size) + +/datum/random_map/proc/set_map_size(var/raw_size) + if(!raw_size) + raw_size = real_size * real_size + raw_map_size = raw_size + map.len = raw_map_size + +/datum/random_map/proc/seed_map() + for(var/x = 1, x <= real_size, x++) + for(var/y = 1, y <= real_size, y++) + var/current_cell = get_map_cell(x,y) + if(prob(55)) + map[current_cell] = 2 + else + map[current_cell] = 1 + +/datum/random_map/proc/clear_map() + for(var/x = 1, x <= real_size, x++) + for(var/y = 1, y <= real_size, y++) + map[get_map_cell(x,y)] = 0 + +/datum/random_map/proc/generate() + seed_map() + for(var/i=1;i<=iterations;i++) + iterate(i) + if(check_map_sanity()) + cleanup() + apply_to_map() + return 1 + return 0 + +/datum/random_map/proc/iterate(var/iteration) + var/list/next_map[raw_map_size] + for(var/x = 1, x <= real_size, x++) + for(var/y = 1, y <= real_size, y++) + var/current_cell = get_map_cell(x,y) + // Sanity check. + if(!within_bounds(current_cell)) + continue + // Copy over original value. + next_map[current_cell] = map[current_cell] + // Check all neighbors. + var/count = 0 + for(var/cell in list(current_cell,get_map_cell(x+1,y+1),get_map_cell(x-1,y-1),get_map_cell(x+1,y-1),get_map_cell(x-1,y+1),get_map_cell(x-1,y),get_map_cell(x,y-1),get_map_cell(x+1,y),get_map_cell(x,y+1))) + if(within_bounds(cell) && map[cell] == 2) + count++ + if(count>=5) + next_map[current_cell] = 2 // becomes a wall + else + next_map[current_cell] = 1 // becomes a floor + map = next_map + +/datum/random_map/proc/check_map_sanity() + return 1 + +/datum/random_map/proc/apply_to_map() + for(var/x = 0, x < real_size, x++) + if((origin_x + x) > limit_x) continue + for(var/y = 0, y < real_size, y++) + if((origin_y + y) > limit_y) continue + sleep(-1) + apply_to_turf(origin_x+x,origin_y+y) + +/datum/random_map/proc/apply_to_turf(var/x,var/y) + var/current_cell = get_map_cell(x,y) + if(!within_bounds(current_cell)) + return + var/turf/T = locate(x,y,origin_z) + if(!T || !istype(T,/turf/unsimulated/mask)) + return + switch(map[current_cell]) + if(1) + T.ChangeTurf(/turf/simulated/floor/plating/airless/asteroid) + if(2) + T.ChangeTurf(/turf/simulated/mineral) + if(3) + T.ChangeTurf(/turf/simulated/mineral/random) + if(4) + T.ChangeTurf(/turf/simulated/mineral/random/high_chance) + +/datum/random_map/proc/cleanup() + + sleep(-1) + // Create ore. + var/ore_count = ORE_COUNT + while(ore_count) + var/check_cell = get_map_cell(rand(1,real_size),rand(1,real_size)) + if(!(within_bounds(check_cell)) || map[check_cell] != 2) + continue + if(prob(25)) + map[check_cell] = 4 + else + map[check_cell] = 3 + ore_count-- + + sleep(-1) + + // Place random asteroid rooms. + var/rooms_placed = 0 + for(var/i = 0, i < max_secret_rooms, i++) + if(make_mining_asteroid_secret()) + rooms_placed++ + world << "Placed [rooms_placed] secrets." + return 1 \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index 78a48cf8e0..6c6c194af5 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -79,9 +79,9 @@ datum if(A.volume > the_volume) the_volume = A.volume the_reagent = A - + return the_reagent - + get_master_reagent_name() var/the_name = null var/the_volume = 0 @@ -353,8 +353,11 @@ datum if(C.result) feedback_add_details("chemical_reaction","[C.result]|[C.result_amount*multiplier]") multiplier = max(multiplier, 1) //this shouldnt happen ... - add_reagent(C.result, C.result_amount*multiplier) - set_data(C.result, preserved_data) + if(!isnull(C.resultcolor)) //paints + add_reagent(C.result, C.result_amount*multiplier, C.resultcolor) + else + add_reagent(C.result, C.result_amount*multiplier) + set_data(C.result, preserved_data) //add secondary products for(var/S in C.secondary_results) @@ -458,7 +461,7 @@ datum else R.reaction_obj(A, R.volume+volume_modifier) return - add_reagent(var/reagent, var/amount, var/list/data=null, var/safety = 0) + add_reagent(var/reagent, var/amount, var/data=null, var/safety = 0) if(!isnum(amount)) return 1 update_total() if(total_volume + amount > maximum_volume) amount = (maximum_volume - total_volume) //Doesnt fit in. Make it disappear. Shouldnt happen. Will happen. @@ -469,7 +472,6 @@ datum if (R.id == reagent) R.volume += amount update_total() - my_atom.on_reagent_change() // mix dem viruses if(R.id == "blood" && reagent == "blood") @@ -495,9 +497,23 @@ datum if(!istype(D, /datum/disease/advance)) preserve += D R.data["viruses"] = preserve - + if(R.id == "paint" && reagent == "paint") + if(R.color && data) + var/list/mix = new /list(2) + //fill the list + var/datum/reagent/paint/P = chemical_reagents_list["paint"] + var/datum/reagent/paint/P1 = new P.type() + P1.color = R.color + P1.volume = R.volume - amount //since we just increased that + var/datum/reagent/paint/P2 = new P.type() + P2.color = data + P2.volume = amount + mix[1] = P1 + mix[2] = P2 + R.color = mix_color_from_reagents(mix) if(!safety) handle_reactions() + my_atom.on_reagent_change() return 0 var/datum/reagent/D = chemical_reagents_list[reagent] @@ -507,7 +523,10 @@ datum reagent_list += R R.holder = src R.volume = amount - SetViruses(R, data) // Includes setting data + if(reagent == "paint") + R.color = data + else + SetViruses(R, data) // Includes setting data for blood //debug //world << "Adding data" @@ -611,6 +630,7 @@ datum my_atom.reagents = null copy_data(var/datum/reagent/current_reagent) + if (current_reagent.id == "paint") return current_reagent.color if (!current_reagent || !current_reagent.data) return null if (!istype(current_reagent.data, /list)) return current_reagent.data diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index afe1eb3ef7..4c857a51c3 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -2,249 +2,10 @@ #define LIQUID 2 #define GAS 3 -#define CHEM_DISPENSER_ENERGY_COST 0.1 //How many energy points do we use per unit of chemical? - -/obj/machinery/chem_dispenser - name = "chem dispenser" - density = 1 - anchored = 1 - icon = 'icons/obj/chemical.dmi' - icon_state = "dispenser" - use_power = 0 - idle_power_usage = 40 - var/ui_title = "Chem Dispenser 5000" - var/energy = 100 - var/max_energy = 100 - var/amount = 30 - var/accept_glass = 0 //At 0 ONLY accepts glass containers. Kinda misleading varname. - var/atom/beaker = null - var/recharged = 0 - var/hackedcheck = 0 - var/list/dispensable_reagents = list("hydrogen","lithium","carbon","nitrogen","oxygen","fluorine", - "sodium","aluminum","silicon","phosphorus","sulfur","chlorine","potassium","iron", - "copper","mercury","radium","water","ethanol","sugar","sacid","tungsten") - -/obj/machinery/chem_dispenser/proc/recharge() - if(stat & (BROKEN|NOPOWER)) return - var/addenergy = 1 - var/oldenergy = energy - energy = min(energy + addenergy, max_energy) - if(energy != oldenergy) - use_power(CHEM_SYNTH_ENERGY / CHEM_DISPENSER_ENERGY_COST) // This thing uses up "alot" of power (this is still low as shit for creating reagents from thin air) - nanomanager.update_uis(src) // update all UIs attached to src - -/obj/machinery/chem_dispenser/power_change() - ..() - nanomanager.update_uis(src) // update all UIs attached to src - -/obj/machinery/chem_dispenser/process() - if(recharged <= 0) - recharge() - recharged = 15 - else - recharged -= 1 - -/obj/machinery/chem_dispenser/New() - ..() - recharge() - dispensable_reagents = sortList(dispensable_reagents) +#define BOTTLE_SPRITES list("bottle-1", "bottle-2", "bottle-3", "bottle-4") //list of available bottle sprites +#define REAGENTS_PER_SHEET 20 -/obj/machinery/chem_dispenser/ex_act(severity) - switch(severity) - if(1.0) - del(src) - return - if(2.0) - if (prob(50)) - del(src) - return - -/obj/machinery/chem_dispenser/blob_act() - if (prob(50)) - del(src) - -/obj/machinery/chem_dispenser/meteorhit() - del(src) - return - - /** - * The ui_interact proc is used to open and update Nano UIs - * If ui_interact is not used then the UI will not update correctly - * ui_interact is currently defined for /atom/movable - * - * @param user /mob The mob who is interacting with this ui - * @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main") - * - * @return nothing - */ -/obj/machinery/chem_dispenser/ui_interact(mob/user, ui_key = "main",var/datum/nanoui/ui = null, var/force_open = 1) - if(stat & (BROKEN|NOPOWER)) return - if(user.stat || user.restrained()) return - - // this is the data which will be sent to the ui - var/data[0] - data["amount"] = amount - data["energy"] = round(energy) - data["maxEnergy"] = round(max_energy) - data["isBeakerLoaded"] = beaker ? 1 : 0 - data["glass"] = accept_glass - var beakerContents[0] - var beakerCurrentVolume = 0 - if(beaker && beaker:reagents && beaker:reagents.reagent_list.len) - for(var/datum/reagent/R in beaker:reagents.reagent_list) - beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list... - beakerCurrentVolume += R.volume - data["beakerContents"] = beakerContents - - if (beaker) - data["beakerCurrentVolume"] = beakerCurrentVolume - data["beakerMaxVolume"] = beaker:volume - else - data["beakerCurrentVolume"] = null - data["beakerMaxVolume"] = null - - var chemicals[0] - for (var/re in dispensable_reagents) - var/datum/reagent/temp = chemical_reagents_list[re] - if(temp) - chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("dispense" = temp.id)))) // list in a list because Byond merges the first list... - data["chemicals"] = chemicals - - // update the ui if it exists, returns null if no ui is passed/found - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if (!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "chem_dispenser.tmpl", ui_title, 390, 655) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - -/obj/machinery/chem_dispenser/Topic(href, href_list) - if(stat & (NOPOWER|BROKEN)) - return 0 // don't update UIs attached to this object - - if(href_list["amount"]) - amount = round(text2num(href_list["amount"]), 5) // round to nearest 5 - if (amount < 0) // Since the user can actually type the commands himself, some sanity checking - amount = 0 - if (amount > 120) - amount = 120 - - if(href_list["dispense"]) - if (dispensable_reagents.Find(href_list["dispense"]) && beaker != null && beaker.is_open_container()) - var/obj/item/weapon/reagent_containers/B = src.beaker - var/datum/reagents/R = B.reagents - var/space = R.maximum_volume - R.total_volume - - //uses 1 energy per 10 units. - var/added_amount = min(amount, energy / CHEM_DISPENSER_ENERGY_COST, space) - R.add_reagent(href_list["dispense"], added_amount) - energy = max(energy - added_amount * CHEM_DISPENSER_ENERGY_COST, 0) - - if(href_list["ejectBeaker"]) - if(beaker) - var/obj/item/weapon/reagent_containers/B = beaker - B.loc = loc - beaker = null - - add_fingerprint(usr) - return 1 // update UIs attached to this object - -/obj/machinery/chem_dispenser/attackby(var/obj/item/weapon/reagent_containers/B as obj, var/mob/user as mob) - if(isrobot(user)) - return - if(src.beaker) - user << "Something is already loaded into the machine." - return - if(istype(B, /obj/item/weapon/reagent_containers/glass) || istype(B, /obj/item/weapon/reagent_containers/food)) - if(!accept_glass && istype(B,/obj/item/weapon/reagent_containers/food)) - user << "This machine only accepts beakers" - src.beaker = B - user.drop_item() - B.loc = src - user << "You set [B] on the machine." - nanomanager.update_uis(src) // update all UIs attached to src - return - -/obj/machinery/chem_dispenser/attack_ai(mob/user as mob) - return src.attack_hand(user) - -/obj/machinery/chem_dispenser/attack_hand(mob/user as mob) - if(stat & BROKEN) - return - ui_interact(user) - -/obj/machinery/chem_dispenser/soda - icon_state = "soda_dispenser" - name = "soda fountain" - desc = "A drink fabricating machine, capable of producing many sugary drinks with just one touch." - ui_title = "Soda Dispens-o-matic" - energy = 100 - accept_glass = 1 - max_energy = 100 - dispensable_reagents = list("water","ice","coffee","cream","tea","icetea","cola","spacemountainwind","dr_gibb","space_up","tonic","sodawater","lemon_lime","sugar","orangejuice","limejuice","watermelonjuice") - -/obj/machinery/chem_dispenser/soda/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob) - ..() - if(istype(B, /obj/item/device/multitool)) - if(hackedcheck == 0) - user << "You change the mode from 'McNano' to 'Pizza King'." - dispensable_reagents += list("thirteenloko","grapesoda") - hackedcheck = 1 - return - - else - user << "You change the mode from 'Pizza King' to 'McNano'." - dispensable_reagents -= list("thirteenloko","grapesoda") - hackedcheck = 0 - return - -/obj/machinery/chem_dispenser/beer - icon_state = "booze_dispenser" - name = "booze dispenser" - ui_title = "Booze Portal 9001" - energy = 100 - accept_glass = 1 - max_energy = 100 - desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one." - dispensable_reagents = list("lemon_lime","sugar","orangejuice","limejuice","sodawater","tonic","beer","kahlua","whiskey","wine","vodka","gin","rum","tequilla","vermouth","cognac","ale","mead") - -/obj/machinery/chem_dispenser/beer/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob) - ..() - - if(istype(B, /obj/item/device/multitool)) - if(hackedcheck == 0) - user << "You disable the 'nanotrasen-are-cheap-bastards' lock, enabling hidden and very expensive boozes." - dispensable_reagents += list("goldschlager","patron","watermelonjuice","berryjuice") - hackedcheck = 1 - return - - else - user << "You re-enable the 'nanotrasen-are-cheap-bastards' lock, disabling hidden and very expensive boozes." - dispensable_reagents -= list("goldschlager","patron","watermelonjuice","berryjuice") - hackedcheck = 0 - return - -/obj/machinery/chem_dispenser/meds - name = "chem dispenser magic" - density = 1 - anchored = 1 - icon = 'icons/obj/chemical.dmi' - icon_state = "dispenser" - use_power = 0 - idle_power_usage = 40 - ui_title = "Chem Dispenser 9000" - energy = 100 - max_energy = 100 - amount = 30 - accept_glass = 0 //At 0 ONLY accepts glass containers. Kinda misleading varname. - beaker = null - recharged = 0 - hackedcheck = 0 - dispensable_reagents = list("inaprovaline","ryetalyn","paracetamol","tramadol","oxycodone","sterilizine","leporazine","kelotane","dermaline","dexalin","dexalinp","tricordrazine","anti_toxin","synaptizine","hyronalin","arithrazine","alkysine","imidazoline","peridaxon","bicaridine","hyperzine","rezadone","spaceacillin","ethylredoxrazine","stoxin","chloralhydrate","cryoxadone","clonexadone") ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -262,7 +23,7 @@ var/condi = 0 var/useramount = 30 // Last used amount var/pillamount = 10 - var/bottlesprite = "1" //yes, strings + var/bottlesprite = "bottle-1" //yes, strings var/pillsprite = "1" var/client/has_sprites = list() var/max_pill_count = 20 @@ -417,7 +178,7 @@ var/amount_per_pill = reagents.total_volume/count if (amount_per_pill > 60) amount_per_pill = 60 - var/name = reject_bad_text(input(usr,"Name:","Name your pill!","[reagents.get_master_reagent_name()] ([amount_per_pill] units)")) + var/name = sanitizeSafe(input(usr,"Name:","Name your pill!","[reagents.get_master_reagent_name()] ([amount_per_pill] units)"), MAX_NAME_LEN) if(reagents.total_volume/count < 1) //Sanity checking. return @@ -436,13 +197,13 @@ else if (href_list["createbottle"]) if(!condi) - var/name = reject_bad_text(input(usr,"Name:","Name your bottle!",reagents.get_master_reagent_name())) + var/name = sanitizeSafe(input(usr,"Name:","Name your bottle!",reagents.get_master_reagent_name()), MAX_NAME_LEN) var/obj/item/weapon/reagent_containers/glass/bottle/P = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc) if(!name) name = reagents.get_master_reagent_name() P.name = "[name] bottle" P.pixel_x = rand(-7, 7) //random position P.pixel_y = rand(-7, 7) - P.icon_state = "bottle-"+bottlesprite + P.icon_state = bottlesprite reagents.trans_to(P,60) P.update_icon() else @@ -457,10 +218,9 @@ usr << browse(dat, "window=chem_master") return else if(href_list["change_bottle"]) - #define MAX_BOTTLE_SPRITE 4 //max icon state of the bottle sprites var/dat = "" - for(var/i = 1 to MAX_BOTTLE_SPRITE) - dat += "" + for(var/sprite in BOTTLE_SPRITES) + dat += "" dat += "
    " usr << browse(dat, "window=chem_master") return @@ -484,8 +244,8 @@ has_sprites += user.client for(var/i = 1 to MAX_PILL_SPRITE) usr << browse_rsc(icon('icons/obj/chemical.dmi', "pill" + num2text(i)), "pill[i].png") - for(var/i = 1 to MAX_BOTTLE_SPRITE) - usr << browse_rsc(icon('icons/obj/chemical.dmi', "bottle-" + num2text(i)), "bottle-[i].png") + for(var/sprite in BOTTLE_SPRITES) + usr << browse_rsc(icon('icons/obj/chemical.dmi', sprite), "[sprite].png") var/dat = "" if(!beaker) dat = "Please insert beaker.
    " @@ -529,7 +289,7 @@ if(!condi) dat += "

    Create pill (60 units max)
    " dat += "Create multiple pills
    " - dat += "Create bottle (60 units max)" + dat += "Create bottle (60 units max)" else dat += "Create bottle (50 units max)" if(!condi) @@ -635,7 +395,7 @@ else if (href_list["create_virus_culture"]) if(!wait) var/obj/item/weapon/reagent_containers/glass/bottle/B = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc) - B.icon_state = "bottle3" + B.icon_state = "bottle-1" var/type = text2path(href_list["create_virus_culture"])//the path is received as string - converting var/datum/disease/D = null if(!type) @@ -646,11 +406,12 @@ if(type in diseases) // Make sure this is a disease D = new type(0, null) var/list/data = list("viruses"=list(D)) - var/name = sanitize(copytext(input(usr,"Name:","Name the culture",D.name), 1, MAX_NAME_LEN)) + var/name = sanitizeSafe(input(usr,"Name:","Name the culture",D.name)) if(!name || name == " ") name = D.name B.name = "[name] culture bottle" B.desc = "A small bottle. Contains [D.agent] culture in synthblood medium." B.reagents.add_reagent("blood",20,data) + B.update_icon() src.updateUsrDialog() wait = 1 spawn(1000) @@ -674,7 +435,7 @@ src.updateUsrDialog() return else if(href_list["name_disease"]) - var/new_name = stripped_input(usr, "Name the Disease", "New Name", "", MAX_NAME_LEN) + var/new_name = sanitizeSafe(input(usr, "Name the Disease", "New Name", ""), MAX_NAME_LEN) if(stat & (NOPOWER|BROKEN)) return if(usr.stat || usr.restrained()) return if(!in_range(src, usr)) return @@ -824,54 +585,15 @@ var/inuse = 0 var/obj/item/weapon/reagent_containers/beaker = null var/limit = 10 - var/list/blend_items = list ( - - //Sheets - /obj/item/stack/sheet/mineral/phoron = list("phoron" = 20), - /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20), - /obj/item/stack/sheet/mineral/silver = list("silver" = 20), - /obj/item/stack/sheet/mineral/gold = list("gold" = 20), - /obj/item/weapon/grown/nettle/death = list("pacid" = 0), - /obj/item/weapon/grown/nettle = list("sacid" = 0), - - //Blender Stuff - /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0), - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0), - /obj/item/weapon/reagent_containers/food/snacks/grown/corn = list("cornoil" = 0), - ///obj/item/weapon/reagent_containers/food/snacks/grown/wheat = list("flour" = -5), - /obj/item/weapon/reagent_containers/food/snacks/grown/ricestalk = list("rice" = -5), - /obj/item/weapon/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0), - /obj/item/weapon/reagent_containers/food/snacks/grown/plastellium = list("plasticide" = 5), - - - //archaeology! - /obj/item/weapon/rocksliver = list("ground_rock" = 50), - - - - //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.! - /obj/item/weapon/reagent_containers/pill = list(), - /obj/item/weapon/reagent_containers/food = list() - ) - - var/list/juice_items = list ( - - //Juicer Stuff - /obj/item/weapon/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0), - /obj/item/weapon/reagent_containers/food/snacks/grown/carrot = list("carrotjuice" = 0), - /obj/item/weapon/reagent_containers/food/snacks/grown/berries = list("berryjuice" = 0), - /obj/item/weapon/reagent_containers/food/snacks/grown/banana = list("banana" = 0), - /obj/item/weapon/reagent_containers/food/snacks/grown/potato = list("potato" = 0), - /obj/item/weapon/reagent_containers/food/snacks/grown/lemon = list("lemonjuice" = 0), - /obj/item/weapon/reagent_containers/food/snacks/grown/orange = list("orangejuice" = 0), - /obj/item/weapon/reagent_containers/food/snacks/grown/lime = list("limejuice" = 0), - /obj/item/weapon/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0), - /obj/item/weapon/reagent_containers/food/snacks/grown/grapes = list("grapejuice" = 0), - /obj/item/weapon/reagent_containers/food/snacks/grown/poisonberries = list("poisonberryjuice" = 0), - ) - - var/list/holdingitems = list() + var/list/sheet_reagents = list( + /obj/item/stack/sheet/mineral/iron = "iron", + /obj/item/stack/sheet/mineral/uranium = "uranium", + /obj/item/stack/sheet/mineral/phoron = "phoron", + /obj/item/stack/sheet/mineral/gold = "gold", + /obj/item/stack/sheet/mineral/silver = "silver", + /obj/item/stack/sheet/mineral/mhydrogen = "hydrogen" + ) /obj/machinery/reagentgrinder/New() ..() @@ -882,10 +604,8 @@ icon_state = "juicer"+num2text(!isnull(beaker)) return - /obj/machinery/reagentgrinder/attackby(var/obj/item/O as obj, var/mob/user as mob) - if (istype(O,/obj/item/weapon/reagent_containers/glass) || \ istype(O,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass) || \ istype(O,/obj/item/weapon/reagent_containers/food/drinks/shaker)) @@ -904,25 +624,35 @@ usr << "The machine cannot hold anymore items." return 1 - //Fill machine with the plantbag! - if(istype(O, /obj/item/weapon/storage/bag/plants)) + if(!istype(O)) + return - for (var/obj/item/weapon/reagent_containers/food/snacks/grown/G in O.contents) + if(istype(O,/obj/item/weapon/storage/bag/plants)) + var/failed = 1 + for(var/obj/item/G in O.contents) + if(!G.reagents || !G.reagents.total_volume) + continue + failed = 0 O.contents -= G G.loc = src holdingitems += G - if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill - user << "You fill the All-In-One grinder to the brim." + if(holdingitems && holdingitems.len >= limit) break + if(failed) + user << "Nothing in the plant bag is usable." + return 1 + if(!O.contents.len) - user << "You empty the plant bag into the All-In-One grinder." + user << "You empty \the [O] into \the [src]." + else + user << "You fill \the [src] from \the [O]." src.updateUsrDialog() return 0 - if (!is_type_in_list(O, blend_items) && !is_type_in_list(O, juice_items)) - user << "Cannot refine into a reagent." + if(!sheet_reagents[O.type] && (!O.reagents || !O.reagents.total_volume)) + user << "\The [O] is not suitable for blending." return 1 user.remove_from_mob(O) @@ -971,8 +701,7 @@ [beaker_contents]
    "} if (is_beaker_ready && !is_chamber_empty && !(stat & (NOPOWER|BROKEN))) - dat += "Grind the reagents
    " - dat += "Juice the reagents

    " + dat += "Process the reagents
    " if(holdingitems && holdingitems.len > 0) dat += "Eject the reagents
    " if (beaker) @@ -991,8 +720,6 @@ switch(href_list["action"]) if ("grind") grind() - if("juice") - juice() if("eject") eject() if ("detach") @@ -1022,175 +749,49 @@ holdingitems -= O holdingitems = list() -/obj/machinery/reagentgrinder/proc/is_allowed(var/obj/item/weapon/reagent_containers/O) - for (var/i in blend_items) - if(istype(O, i)) - return 1 - return 0 - -/obj/machinery/reagentgrinder/proc/get_allowed_by_id(var/obj/item/weapon/grown/O) - for (var/i in blend_items) - if (istype(O, i)) - return blend_items[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_snack_by_id(var/obj/item/weapon/reagent_containers/food/snacks/O) - for(var/i in blend_items) - if(istype(O, i)) - return blend_items[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_id(var/obj/item/weapon/reagent_containers/food/snacks/O) - for(var/i in juice_items) - if(istype(O, i)) - return juice_items[i] - -/obj/machinery/reagentgrinder/proc/get_grownweapon_amount(var/obj/item/weapon/grown/O) - if (!istype(O)) - return 5 - else if (O.potency == -1) - return 5 - else - return round(O.potency) - -/obj/machinery/reagentgrinder/proc/get_juice_amount(var/obj/item/weapon/reagent_containers/food/snacks/grown/O) - if (!istype(O)) - return 5 - else if (O.potency == -1) - return 5 - else - return round(5*sqrt(O.potency)) - /obj/machinery/reagentgrinder/proc/remove_object(var/obj/item/O) holdingitems -= O del(O) -/obj/machinery/reagentgrinder/proc/juice() - power_change() - if(stat & (NOPOWER|BROKEN)) - return - if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) - return - playsound(src.loc, 'sound/machines/juicer.ogg', 20, 1) - inuse = 1 - spawn(50) - inuse = 0 - interact(usr) - //Snacks - for (var/obj/item/weapon/reagent_containers/food/snacks/O in holdingitems) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - - var/allowed = get_allowed_juice_by_id(O) - if(isnull(allowed)) - break - - for (var/r_id in allowed) - - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = get_juice_amount(O) - - beaker.reagents.add_reagent(r_id, min(amount, space)) - - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - - remove_object(O) - /obj/machinery/reagentgrinder/proc/grind() power_change() if(stat & (NOPOWER|BROKEN)) return + + // Sanity check. if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) return + playsound(src.loc, 'sound/machines/blender.ogg', 50, 1) inuse = 1 + + // Reset the machine. spawn(60) inuse = 0 interact(usr) - //Snacks and Plants - for (var/obj/item/weapon/reagent_containers/food/snacks/O in holdingitems) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/allowed = get_allowed_snack_by_id(O) - if(isnull(allowed)) - break + // Process. + for (var/obj/item/O in holdingitems) - for (var/r_id in allowed) + if(!O || !istype(O)) + holdingitems -= null + continue - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if(amount <= 0) - if(amount == 0) - if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - else - if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) + var/remaining_volume = beaker.reagents.maximum_volume - beaker.reagents.total_volume + if(sheet_reagents[O.type]) + var/obj/item/stack/stack = O + if(istype(stack)) + var/amount_to_take = max(0,min(stack.amount,round(remaining_volume/REAGENTS_PER_SHEET))) + if(amount_to_take) + stack.use(amount_to_take) + beaker.reagents.add_reagent(sheet_reagents[stack.type], (amount_to_take*REAGENTS_PER_SHEET)) + continue - else - O.reagents.trans_id_to(beaker, r_id, min(amount, space)) - - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - - if(O.reagents.reagent_list.len == 0) + O.reagents.trans_to(beaker, min(O.reagents.total_volume, remaining_volume)) + if(O.reagents.total_volume == 0) remove_object(O) - - //Sheets - for (var/obj/item/stack/sheet/O in holdingitems) - var/allowed = get_allowed_by_id(O) if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) break - for(var/i = 1; i <= round(O.amount, 1); i++) - for (var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - beaker.reagents.add_reagent(r_id,min(amount, space)) - if (space < amount) - break - if (i == round(O.amount, 1)) - remove_object(O) - break - //Plants - for (var/obj/item/weapon/grown/O in holdingitems) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/allowed = get_allowed_by_id(O) - for (var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if (amount == 0) - if (O.reagents != null && O.reagents.has_reagent(r_id)) - beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space)) - else - beaker.reagents.add_reagent(r_id,min(amount, space)) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O) - - //xenoarch - for(var/obj/item/weapon/rocksliver/O in holdingitems) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/allowed = get_allowed_by_id(O) - for (var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - beaker.reagents.add_reagent(r_id,min(amount, space), O.geological_data) - - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O) - - //Everything else - Transfers reagents from it into beaker - for (var/obj/item/weapon/reagent_containers/O in holdingitems) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/amount = O.reagents.total_volume - O.reagents.trans_to(beaker, amount) - if(!O.reagents.total_volume) - remove_object(O) +#undef REAGENTS_PER_SHEET diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index f58a39bd6c..1399fdd14a 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -88,7 +88,7 @@ datum on_new(var/data) return - // Called when two reagents of the same are mixing. + // Called when two reagents of the same are mixing. <-- Blatant lies on_merge(var/data) return @@ -98,7 +98,7 @@ datum blood - data = new/list("donor"=null,"viruses"=null,"species"="Human","blood_DNA"=null,"blood_type"=null,"blood_colour"= "#A10808","resistances"=null,"trace_chem"=null, "antibodies" = null) + data = new/list("donor"=null,"viruses"=null,"species"="Human","blood_DNA"=null,"blood_type"=null,"blood_colour"= "#A10808","resistances"=null,"trace_chem"=null, "antibodies" = list()) name = "Blood" id = "blood" reagent_state = LIQUID @@ -153,9 +153,6 @@ datum if(!self.data["donor"] || istype(self.data["donor"], /mob/living/carbon/human)) blood_splatter(T,self,1) - else if(istype(self.data["donor"], /mob/living/carbon/monkey)) - var/obj/effect/decal/cleanable/blood/B = blood_splatter(T,self,1) - if(B) B.blood_DNA["Non-Human DNA"] = "A+" else if(istype(self.data["donor"], /mob/living/carbon/alien)) var/obj/effect/decal/cleanable/blood/B = blood_splatter(T,self,1) if(B) B.blood_DNA["UNKNOWN DNA STRUCTURE"] = "X*" @@ -192,6 +189,13 @@ datum M.resistances += self.data return + woodpulp + name = "Wood Pulp" + id = "woodpulp" + description = "A mass of wood fibers." + reagent_state = LIQUID + color = "#B97A57" + #define WATER_LATENT_HEAT 19000 // How much heat is removed when applied to a hot turf, in J/unit (19000 makes 120 u of water roughly equivalent to 4L) water name = "Water" @@ -258,10 +262,15 @@ datum if(!cube.wrapped) cube.Expand() - reaction_mob(var/mob/M, var/method=TOUCH, var/volume) + reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume) if (istype(M, /mob/living/carbon/slime)) var/mob/living/carbon/slime/S = M - S.apply_water() + S.apply_water(volume) + if(method == TOUCH && isliving(M)) + M.adjust_fire_stacks(-(volume / 10)) + if(M.fire_stacks <= 0) + M.ExtinguishMob() + return water/holywater name = "Holy Water" @@ -275,11 +284,8 @@ datum on_mob_life(var/mob/living/M as mob) if(ishuman(M)) - if((M.mind in ticker.mode.cult) && prob(10)) - M << "\blue A cooling sensation from inside you brings you an untold calmness." - ticker.mode.remove_cultist(M.mind) - for(var/mob/O in viewers(M, null)) - O.show_message(text("\blue []'s eyes blink and become clearer.", M), 1) // So observers know it worked. + if(M.mind && cult.is_antagonist(M.mind) && prob(10)) + cult.remove_antagonist(M.mind) holder.remove_reagent(src.id, 10 * REAGENTS_METABOLISM) //high metabolism to prevent extended uncult rolls. return @@ -364,7 +370,7 @@ datum W.loc = M.loc W.dropped(M) var/mob/living/carbon/slime/new_mob = new /mob/living/carbon/slime(M.loc) - new_mob.a_intent = "hurt" + new_mob.a_intent = I_HURT new_mob.universal_speak = 1 if(M.mind) M.mind.transfer_to(new_mob) @@ -427,7 +433,7 @@ datum holder.remove_reagent(src.id, 0.25 * REAGENTS_METABOLISM) return -/* silicate + silicate name = "Silicate" id = "silicate" description = "A compound that can be used to reinforce glass." @@ -437,31 +443,9 @@ datum reaction_obj(var/obj/O, var/volume) src = null if(istype(O,/obj/structure/window)) - if(O:silicate <= 200) - - O:silicate += volume - O:health += volume * 3 - - if(!O:silicateIcon) - var/icon/I = icon(O.icon,O.icon_state,O.dir) - - var/r = (volume / 100) + 1 - var/g = (volume / 70) + 1 - var/b = (volume / 50) + 1 - I.SetIntensity(r,g,b) - O.icon = I - O:silicateIcon = I - else - var/icon/I = O:silicateIcon - - var/r = (volume / 100) + 1 - var/g = (volume / 70) + 1 - var/b = (volume / 50) + 1 - I.SetIntensity(r,g,b) - O.icon = I - O:silicateIcon = I - - return*/ + var/obj/structure/window/W = O + W.apply_silicate(volume) + return oxygen name = "Oxygen" @@ -682,15 +666,13 @@ datum for (var/ID in C.virus2) var/datum/disease2/disease/V = C.virus2[ID] if(prob(5)) - M:antibodies |= V.antigen + C.antibodies |= V.antigen if(prob(50)) M.radiation += 50 // curing it that way may kill you instead var/absorbed - if(istype(C,/mob/living/carbon)) - var/mob/living/carbon/H = C - var/datum/organ/internal/diona/nutrients/rad_organ = locate() in H.internal_organs - if(rad_organ && !rad_organ.is_broken()) - absorbed = 1 + var/datum/organ/internal/diona/nutrients/rad_organ = locate() in C.internal_organs + if(rad_organ && !rad_organ.is_broken()) + absorbed = 1 if(!absorbed) M.adjustToxLoss(100) ..() @@ -933,6 +915,12 @@ datum M.adjustToxLoss(1) ..() return + reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with welding fuel to make them easy to ignite! + if(!istype(M, /mob/living)) + return + if(method == TOUCH) + M.adjust_fire_stacks(volume / 10) + return space_cleaner name = "Space cleaner" @@ -1537,6 +1525,84 @@ datum ..() return +//////////////////////////Ground crayons///////////////////// + + + crayon_dust + name = "Crayon dust" + id = "crayon_dust" + description = "Intensely coloured powder obtained by grinding crayons." + reagent_state = LIQUID + color = "#888888" + overdose = 5 + + red + name = "Red crayon dust" + id = "crayon_dust_red" + color = "#FE191A" + + orange + name = "Orange crayon dust" + id = "crayon_dust_orange" + color = "#FFBE4F" + + yellow + name = "Yellow crayon dust" + id = "crayon_dust_yellow" + color = "#FDFE7D" + + green + name = "Green crayon dust" + id = "crayon_dust_green" + color = "#18A31A" + + blue + name = "Blue crayon dust" + id = "crayon_dust_blue" + color = "#247CFF" + + purple + name = "Purple crayon dust" + id = "crayon_dust_purple" + color = "#CC0099" + + grey //Mime + name = "Grey crayon dust" + id = "crayon_dust_grey" + color = "#808080" + + brown //Rainbow + name = "Brown crayon dust" + id = "crayon_dust_brown" + color = "#846F35" + +//////////////////////////Paint////////////////////////////// + + paint + name = "Paint" + id = "paint" + description = "This paint will stick to almost any object." + reagent_state = LIQUID + color = "#808080" + overdose = 15 + + reaction_turf(var/turf/T, var/volume) + ..() + if(istype(T) && !istype(T, /turf/space)) + T.color = color + + reaction_obj(var/obj/O, var/volume) + ..() + if(istype(O,/obj)) + O.color = color + + reaction_mob(var/mob/M, var/method=TOUCH, var/volume) + ..() + if(istype(M,/mob) && !istype(M,/mob/dead)) + //painting ghosts: not allowed + M.color = color + + //////////////////////////Poison stuff/////////////////////// toxin @@ -1615,6 +1681,12 @@ datum src = null T.assume_gas("volatile_fuel", volume, T20C) return + reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with plasma is stronger than fuel! + if(!istype(M, /mob/living)) + return + if(method == TOUCH) + M.adjust_fire_stacks(volume / 5) + return toxin/lexorin name = "Lexorin" @@ -1631,8 +1703,8 @@ datum if(!M) M = holder.my_atom if(prob(33)) M.take_organ_damage(1*REM, 0) - M.adjustOxyLoss(3) - if(prob(20)) M.emote("gasp") + if(M.losebreath < 15) + M.losebreath++ ..() return @@ -1777,10 +1849,12 @@ datum var/obj/effect/alien/weeds/alien_weeds = O alien_weeds.health -= rand(15,35) // Kills alien weeds pretty fast alien_weeds.healthcheck() - else if(istype(O,/obj/effect/glowshroom)) //even a small amount is enough to kill it + else if(istype(O,/obj/effect/plant)) //even a small amount is enough to kill it del(O) - else if(istype(O,/obj/effect/plantsegment)) - if(prob(50)) del(O) //Kills kudzu too. + else if(istype(O,/obj/effect/plant)) + if(prob(50)) + var/obj/effect/plant/plant = O + plant.die_off() else if(istype(O,/obj/machinery/portable_atmospherics/hydroponics)) var/obj/machinery/portable_atmospherics/hydroponics/tray = O @@ -1980,17 +2054,6 @@ datum del (H.glasses) H.update_inv_glasses(0) - else if(ismonkey(M)) - var/mob/living/carbon/monkey/MK = M - if(MK.wear_mask) - if(!MK.wear_mask.unacidable) - MK << "Your mask melts away but protects you from the acid!" - del (MK.wear_mask) - MK.update_inv_wear_mask(0) - else - MK << "Your mask protects you from the acid." - return - if(!M.unacidable) if(istype(M, /mob/living/carbon/human) && volume >= 10) var/mob/living/carbon/human/H = M @@ -2009,7 +2072,7 @@ datum M.take_organ_damage(min(6*toxpwr, volume * toxpwr)) reaction_obj(var/obj/O, var/volume) - if((istype(O,/obj/item) || istype(O,/obj/effect/glowshroom)) && prob(meltprob * 3)) + if((istype(O,/obj/item) || istype(O,/obj/effect/plant)) && prob(meltprob * 3)) if(!O.unacidable) var/obj/effect/decal/cleanable/molten_item/I = new/obj/effect/decal/cleanable/molten_item(O.loc) I.desc = "Looks like this was \an [O] some time ago." @@ -2041,22 +2104,31 @@ datum if(!M) M = holder.my_atom if(prob(50)) M.heal_organ_damage(1,0) M.nutrition += nutriment_factor // For hunger and fatness -/* - // If overeaten - vomit and fall down - // Makes you feel bad but removes reagents and some effect - // from your body - if (M.nutrition > 650) - M.nutrition = rand (250, 400) - M.weakened += rand(2, 10) - M.jitteriness += rand(0, 5) - M.dizziness = max (0, (M.dizziness - rand(0, 15))) - M.druggy = max (0, (M.druggy - rand(0, 15))) - M.adjustToxLoss(rand(-15, -5))) - M.updatehealth() -*/ ..() return + nutriment/protein // Bad for Skrell! + name = "animal protein" + id = "protein" + color = "#440000" + + on_mob_life(var/mob/living/M, var/alien) + if(alien && alien == IS_SKRELL) + M.adjustToxLoss(0.5) + M.nutrition -= nutriment_factor + ..() + + nutriment/egg // Also bad for skrell. Not a child of protein because it might mess up, not sure. + name = "egg yolk" + id = "egg" + color = "#FFFFAA" + + on_mob_life(var/mob/living/M, var/alien) + if(alien && alien == IS_SKRELL) + M.adjustToxLoss(0.5) + M.nutrition -= nutriment_factor + ..() + lipozine name = "Lipozine" // The anti-nutriment. id = "lipozine" @@ -2442,7 +2514,6 @@ datum ..() return -/* We're back to flour bags flour name = "flour" id = "flour" @@ -2460,7 +2531,6 @@ datum src = null if(!istype(T, /turf/space)) new /obj/effect/decal/cleanable/flour(T) -*/ rice name = "Rice" @@ -2569,7 +2639,7 @@ datum name = "Carrot juice" id = "carrotjuice" description = "It is just like a carrot but without crunching." - color = "#973800" // rgb: 151, 56, 0 + color = "#FF8C00" // rgb: 255, 140, 0 glass_icon_state = "carrotjuice" glass_name = "glass of carrot juice" @@ -2639,7 +2709,7 @@ datum name = "Watermelon Juice" id = "watermelonjuice" description = "Delicious juice made from watermelon." - color = "#863333" // rgb: 134, 51, 51 + color = "#B83333" // rgb: 184, 51, 51 glass_icon_state = "glass_red" glass_name = "glass of watermelon juice" @@ -2649,7 +2719,7 @@ datum name = "Lemon Juice" id = "lemonjuice" description = "This juice is VERY sour." - color = "#863333" // rgb: 175, 175, 0 + color = "#AFAF00" // rgb: 175, 175, 0 glass_icon_state = "lemonjuice" glass_name = "glass of lemon juice" @@ -2659,7 +2729,7 @@ datum name = "Banana Juice" id = "banana" description = "The raw essence of a banana." - color = "#863333" // rgb: 175, 175, 0 + color = "#C3AF00" // rgb: 195, 175, 0 glass_icon_state = "banana" glass_name = "glass of banana juice" @@ -3288,6 +3358,12 @@ datum usr << "It wasn't enough..." return + reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume)//Splashing people with ethanol isn't quite as good as fuel. + if(!istype(M, /mob/living)) + return + if(method == TOUCH) + M.adjust_fire_stacks(volume / 15) + return ethanol/beer name = "Beer" id = "beer" diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index df9c8a219a..fc8c129140 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -4,6 +4,7 @@ datum var/name = null var/id = null var/result = null + var/resultcolor = null //for paint var/list/required_reagents = new/list() var/list/required_catalysts = new/list() @@ -55,14 +56,14 @@ datum empulse(location, round(created_volume / 24), round(created_volume / 14), 1) holder.clear_reagents() return -/* + silicate name = "Silicate" id = "silicate" result = "silicate" required_reagents = list("aluminum" = 1, "silicon" = 1, "oxygen" = 1) result_amount = 3 -*/ + stoxin name = "Soporific" id = "stoxin" @@ -131,7 +132,7 @@ datum name = "Water" id = "water" result = "water" - required_reagents = list("oxygen" = 2, "hydrogen" = 1) + required_reagents = list("oxygen" = 1, "hydrogen" = 2) result_amount = 1 thermite @@ -585,6 +586,14 @@ datum required_reagents = list("capsaicin" = 2) required_catalysts = list("phoron" = 5) result_amount = 1 + + ketchup + name = "Ketchup" + id = "ketchup" + result = "ketchup" + required_reagents = list("tomatojuice" = 2, "water" = 1, "sugar" = 1) + result_amount = 4 + /////////////////////////////////////////////////////////////////////////////////// // foam and foam precursor @@ -1344,6 +1353,200 @@ datum var/obj/effect/golemrune/Z = new /obj/effect/golemrune Z.loc = get_turf(holder.my_atom) Z.announce_to_ghosts() + +//////////////////////////////////////////PAINT/////////////////////////////////////////// +//Crayon dust -> paint + red_paint + name = "Red paint" + id = "red_paint" + result = "paint" + resultcolor = "#FE191A" + required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_red" = 1) + result_amount = 5 + + orange_paint + name = "Orange paint" + id = "orange_paint" + result = "paint" + resultcolor = "#FFBE4F" + required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_orange" = 1) + result_amount = 5 + + yellow_paint + name = "Yellow paint" + id = "yellow_paint" + result = "paint" + resultcolor = "#FDFE7D" + required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_yellow" = 1) + result_amount = 5 + + green_paint + name = "Green paint" + id = "green_paint" + result = "paint" + resultcolor = "#18A31A" + required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_green" = 1) + result_amount = 5 + + blue_paint + name = "Blue paint" + id = "blue_paint" + result = "paint" + resultcolor = "#247CFF" + required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_blue" = 1) + result_amount = 5 + + purple_paint + name = "Purple paint" + id = "purple_paint" + result = "paint" + resultcolor = "#CC0099" + required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_purple" = 1) + result_amount = 5 + + grey_paint //mime + name = "Grey paint" + id = "grey_paint" + result = "paint" + resultcolor = "#808080" + required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_grey" = 1) + result_amount = 5 + + brown_paint + name = "Brown paint" + id = "brown_paint" + result = "paint" + resultcolor = "#846F35" + required_reagents = list("plasticide" = 1, "water" = 3, "crayon_dust_brown" = 1) + result_amount = 5 + +//Ghetto reactions + +/* Ideally the paint should take on the blood's colour (for each of the species) + but I could not think of a way. - RKF + + blood_paint + name = "Blood paint" + id = "blood_paint" + result = "paint" + resultcolor = "#C80000" + required_reagents = list("plasticide" = 1, "water" = 3, "blood" = 2) + result_amount = 5 +*/ + milk_paint + name = "Milk paint" + id = "milk_paint" + result = "paint" + resultcolor = "#F0F8FF" + required_reagents = list("plasticide" = 1, "water" = 3, "milk" = 5) + result_amount = 5 + + orange_juice_paint + name = "Orange juice paint" + id = "orange_juice_paint" + result = "paint" + resultcolor = "#E78108" + required_reagents = list("plasticide" = 1, "water" = 3, "orangejuice" = 5) + result_amount = 5 + + tomato_juice_paint + name = "Tomato juice paint" + id = "tomato_juice_paint" + result = "paint" + resultcolor = "#731008" + required_reagents = list("plasticide" = 1, "water" = 3, "tomatojuice" = 5) + result_amount = 5 + + lime_juice_paint + name = "Lime juice paint" + id = "lime_juice_paint" + result = "paint" + resultcolor = "#365E30" + required_reagents = list("plasticide" = 1, "water" = 3, "limejuice" = 5) + result_amount = 5 + + carrot_juice_paint + name = "Carrot juice paint" + id = "carrot_juice_paint" + result = "paint" + resultcolor = "#973800" + required_reagents = list("plasticide" = 1, "water" = 3, "carrotjuice" = 5) + result_amount = 5 + + berry_juice_paint + name = "Berry juice paint" + id = "berry_juice_paint" + result = "paint" + resultcolor = "#990066" + required_reagents = list("plasticide" = 1, "water" = 3, "berryjuice" = 5) + result_amount = 5 + + grape_juice_paint + name = "Grape juice paint" + id = "grape_juice_paint" + result = "paint" + resultcolor = "#863333" + required_reagents = list("plasticide" = 1, "water" = 3, "grapejuice" = 5) + result_amount = 5 + + poisonberry_juice_paint + name = "Poison berry juice paint" + id = "poisonberry_juice_paint" + result = "paint" + resultcolor = "#863353" + required_reagents = list("plasticide" = 1, "water" = 3, "poisonberryjuice" = 5) + result_amount = 5 + + watermelon_juice_paint + name = "Watermelon juice paint" + id = "watermelon_juice_paint" + result = "paint" + resultcolor = "#B83333" + required_reagents = list("plasticide" = 1, "water" = 3, "watermelonjuice" = 5) + result_amount = 5 + + lemon_juice_paint + name = "Lemon juice paint" + id = "lemon_juice_paint" + result = "paint" + resultcolor = "#AFAF00" + required_reagents = list("plasticide" = 1, "water" = 3, "lemonjuice" = 5) + result_amount = 5 + + banana_juice_paint + name = "Banana juice paint" + id = "banana_juice_paint" + result = "paint" + resultcolor = "#C3AF00" + required_reagents = list("plasticide" = 1, "water" = 3, "banana" = 5) + result_amount = 5 + + potato_juice_paint + name = "Potato juice paint" + id = "potato_juice_paint" + result = "paint" + resultcolor = "#302000" + required_reagents = list("plasticide" = 1, "water" = 3, "potatojuice" = 5) + result_amount = 5 + +//Other paint + + carbon_paint + name = "Carbon paint" + id = "carbon_paint" + result = "paint" + resultcolor = "#333333" + required_reagents = list("plasticide" = 1, "water" = 3, "carbon" = 1) + result_amount = 5 + + aluminum_paint + name = "Aluminum paint" + id = "aluminum_paint" + result = "paint" + resultcolor = "#F0F8FF" + required_reagents = list("plasticide" = 1, "water" = 3, "aluminum" = 1) + result_amount = 5 + //////////////////////////////////////////FOOD MIXTURES//////////////////////////////////// tofu @@ -1409,6 +1612,26 @@ datum new /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel(location) return + meatball + name = "Meatball" + id = "meatball" + result = null + required_reagents = list("protein" = 3, "flour" = 5) + result_amount = 3 + on_reaction(var/datum/reagents/holder, var/created_volume) + new /obj/item/weapon/reagent_containers/food/snacks/meatball(get_turf(holder.my_atom)) + return + + dough + name = "Dough" + id = "dough" + result = null + required_reagents = list("egg" = 3, "flour" = 10) + result_amount = 1 + on_reaction(var/datum/reagents/holder, var/created_volume) + new /obj/item/weapon/reagent_containers/food/snacks/dough(get_turf(holder.my_atom)) + return + syntiflesh name = "Syntiflesh" id = "syntiflesh" diff --git a/code/modules/reagents/dartgun.dm b/code/modules/reagents/dartgun.dm deleted file mode 100644 index d256f4f5f3..0000000000 --- a/code/modules/reagents/dartgun.dm +++ /dev/null @@ -1,293 +0,0 @@ -/obj/item/weapon/dart_cartridge - name = "dart cartridge" - desc = "A rack of hollow darts." - icon = 'icons/obj/ammo.dmi' - icon_state = "darts-5" - item_state = "rcdammo" - opacity = 0 - density = 0 - anchored = 0.0 - origin_tech = "materials=2" - var/darts = 5 - -/obj/item/weapon/dart_cartridge/update_icon() - if(!darts) - icon_state = "darts-0" - else if(darts > 5) - icon_state = "darts-5" - else - icon_state = "darts-[darts]" - return 1 - -/obj/item/weapon/gun/dartgun - name = "dart gun" - desc = "A small gas-powered dartgun, capable of delivering chemical cocktails swiftly across short distances." - icon_state = "dartgun-empty" - - var/list/beakers = list() //All containers inside the gun. - var/list/mixing = list() //Containers being used for mixing. - var/obj/item/weapon/dart_cartridge/cartridge = null //Container of darts. - var/max_beakers = 3 - var/dart_reagent_amount = 15 - var/container_type = /obj/item/weapon/reagent_containers/glass/beaker - var/list/starting_chems = null - -/obj/item/weapon/gun/dartgun/update_icon() - - if(!cartridge) - icon_state = "dartgun-empty" - return 1 - - if(!cartridge.darts) - icon_state = "dartgun-0" - else if(cartridge.darts > 5) - icon_state = "dartgun-5" - else - icon_state = "dartgun-[cartridge.darts]" - return 1 - -/obj/item/weapon/gun/dartgun/New() - - ..() - if(starting_chems) - for(var/chem in starting_chems) - var/obj/B = new container_type(src) - B.reagents.add_reagent(chem, 50) - beakers += B - cartridge = new /obj/item/weapon/dart_cartridge(src) - update_icon() - -/obj/item/weapon/gun/dartgun/examine(mob/user) - update_icon() - if (!..(user, 2)) - return - if (beakers.len) - user << "\blue [src] contains:" - for(var/obj/item/weapon/reagent_containers/glass/beaker/B in beakers) - if(B.reagents && B.reagents.reagent_list.len) - for(var/datum/reagent/R in B.reagents.reagent_list) - user << "\blue [R.volume] units of [R.name]" - -/obj/item/weapon/gun/dartgun/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/weapon/dart_cartridge)) - - var/obj/item/weapon/dart_cartridge/D = I - - if(!D.darts) - user << "\blue [D] is empty." - return 0 - - if(cartridge) - if(cartridge.darts <= 0) - src.remove_cartridge() - else - user << "\blue There's already a cartridge in [src]." - return 0 - - user.drop_item() - cartridge = D - D.loc = src - user << "\blue You slot [D] into [src]." - update_icon() - return - if(istype(I, /obj/item/weapon/reagent_containers/glass)) - if(!istype(I, container_type)) - user << "\blue [I] doesn't seem to fit into [src]." - return - if(beakers.len >= max_beakers) - user << "\blue [src] already has [max_beakers] beakers in it - another one isn't going to fit!" - return - var/obj/item/weapon/reagent_containers/glass/beaker/B = I - user.drop_item() - B.loc = src - beakers += B - user << "\blue You slot [B] into [src]." - src.updateUsrDialog() - -/obj/item/weapon/gun/dartgun/can_fire() - if(!cartridge) - return 0 - else - return cartridge.darts - -/obj/item/weapon/gun/dartgun/proc/has_selected_beaker_reagents() - return 0 - -/obj/item/weapon/gun/dartgun/proc/remove_cartridge() - if(cartridge) - usr << "\blue You pop the cartridge out of [src]." - var/obj/item/weapon/dart_cartridge/C = cartridge - C.loc = get_turf(src) - C.update_icon() - cartridge = null - src.update_icon() - -/obj/item/weapon/gun/dartgun/proc/get_mixed_syringe() - if (!cartridge) - return 0 - if(!cartridge.darts) - return 0 - - var/obj/item/weapon/reagent_containers/syringe/dart = new(src) - - if(mixing.len) - var/mix_amount = dart_reagent_amount/mixing.len - for(var/obj/item/weapon/reagent_containers/glass/beaker/B in mixing) - B.reagents.trans_to(dart,mix_amount) - - return dart - -/obj/item/weapon/gun/dartgun/proc/fire_dart(atom/target, mob/user) - if (locate (/obj/structure/table, src.loc)) - return - else - var/turf/trg = get_turf(target) - var/obj/effect/syringe_gun_dummy/D = new/obj/effect/syringe_gun_dummy(get_turf(src)) - var/obj/item/weapon/reagent_containers/syringe/S = get_mixed_syringe() - if(!S) - user << "\red There are no darts in [src]!" - return - if(!S.reagents) - user << "\red There are no reagents available!" - return - cartridge.darts-- - src.update_icon() - S.reagents.trans_to(D, S.reagents.total_volume) - del(S) - D.icon_state = "syringeproj" - D.name = "syringe" - D.flags |= NOREACT - playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1) - - for(var/i=0, i<6, i++) - if(!D) break - if(D.loc == trg) break - step_towards(D,trg) - - if(D) - for(var/mob/living/carbon/M in D.loc) - if(!istype(M,/mob/living/carbon)) continue - if(M == user) continue - //Syringe gun attack logging by Yvarov - var/R - if(D.reagents) - for(var/datum/reagent/A in D.reagents.reagent_list) - R += A.id + " (" - R += num2text(A.volume) + ")," - if (istype(M, /mob)) - M.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] shot [M]/[M.ckey] with a dartgun ([R])" - user.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] shot [M]/[M.ckey] with a dartgun ([R])" - msg_admin_attack("[user] ([user.ckey]) shot [M] ([M.ckey]) with a dartgun ([R]) (JMP)") - - else - M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a dartgun ([R])" - msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a dartgun ([R]) (JMP)") - - if(D.reagents) - D.reagents.trans_to(M, 15) - M << "You feel a slight prick." - - del(D) - break - if(D) - for(var/atom/A in D.loc) - if(A == user) continue - if(A.density) del(D) - - sleep(1) - - if (D) spawn(10) del(D) - - return - -/obj/item/weapon/gun/dartgun/afterattack(obj/target, mob/user , flag) - if(!isturf(target.loc) || target == user) return - ..() - -/obj/item/weapon/gun/dartgun/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) - return 1 - -/obj/item/weapon/gun/dartgun/attack_self(mob/user) - - user.set_machine(src) - var/dat = "[src] mixing control:

    " - - if (beakers.len) - var/i = 1 - for(var/obj/item/weapon/reagent_containers/glass/beaker/B in beakers) - dat += "Beaker [i] contains: " - if(B.reagents && B.reagents.reagent_list.len) - for(var/datum/reagent/R in B.reagents.reagent_list) - dat += "
    [R.volume] units of [R.name], " - if (check_beaker_mixing(B)) - dat += text("Mixing ") - else - dat += text("Not mixing ") - else - dat += "nothing." - dat += " \[Eject\]
    " - i++ - else - dat += "There are no beakers inserted!

    " - - if(cartridge) - if(cartridge.darts) - dat += "The dart cartridge has [cartridge.darts] shots remaining." - else - dat += "The dart cartridge is empty!" - dat += " \[Eject\]" - - user << browse(dat, "window=dartgun") - onclose(user, "dartgun", src) - -/obj/item/weapon/gun/dartgun/proc/check_beaker_mixing(var/obj/item/B) - if(!mixing || !beakers) - return 0 - for(var/obj/item/M in mixing) - if(M == B) - return 1 - return 0 - -/obj/item/weapon/gun/dartgun/Topic(href, href_list) - src.add_fingerprint(usr) - if(href_list["stop_mix"]) - var/index = text2num(href_list["stop_mix"]) - if(index <= beakers.len) - for(var/obj/item/M in mixing) - if(M == beakers[index]) - mixing -= M - break - else if (href_list["mix"]) - var/index = text2num(href_list["mix"]) - if(index <= beakers.len) - mixing += beakers[index] - else if (href_list["eject"]) - var/index = text2num(href_list["eject"]) - if(index <= beakers.len) - if(beakers[index]) - var/obj/item/weapon/reagent_containers/glass/beaker/B = beakers[index] - usr << "You remove [B] from [src]." - mixing -= B - beakers -= B - B.loc = get_turf(src) - else if (href_list["eject_cart"]) - remove_cartridge() - src.updateUsrDialog() - return - -/obj/item/weapon/gun/dartgun/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - if(cartridge) - spawn(0) fire_dart(target,user) - else - usr << "\red [src] is empty." - - -/obj/item/weapon/gun/dartgun/vox - name = "alien dart gun" - desc = "A small gas-powered dartgun, fitted for nonhuman hands." - -/obj/item/weapon/gun/dartgun/vox/medical - starting_chems = list("kelotane","bicaridine","anti_toxin") - -/obj/item/weapon/gun/dartgun/vox/raider - starting_chems = list("space_drugs","stoxin","impedrezene") \ No newline at end of file diff --git a/code/modules/reagents/dispenser/_defines.dm b/code/modules/reagents/dispenser/_defines.dm new file mode 100644 index 0000000000..60c12cdba6 --- /dev/null +++ b/code/modules/reagents/dispenser/_defines.dm @@ -0,0 +1,8 @@ +#define CARTRIDGE_VOLUME_LARGE 500 +#define CARTRIDGE_VOLUME_MEDIUM 250 +#define CARTRIDGE_VOLUME_SMALL 100 + +// Chemistry dispenser starts with 21 +// ERT dispenser starts with 28 +#define DISPENSER_MAX_CARTRIDGES 30 + diff --git a/code/modules/reagents/dispenser/cartridge.dm b/code/modules/reagents/dispenser/cartridge.dm new file mode 100644 index 0000000000..fdb5e1fe76 --- /dev/null +++ b/code/modules/reagents/dispenser/cartridge.dm @@ -0,0 +1,90 @@ +/obj/item/weapon/reagent_containers/chem_disp_cartridge + name = "chemical dispenser cartridge" + desc = "This goes in a chemical dispenser." + icon_state = "cartridge" + + w_class = 3 + + volume = CARTRIDGE_VOLUME_LARGE + amount_per_transfer_from_this = 50 + // Large, but inaccurate. Use a chem dispenser or beaker for accuracy. + possible_transfer_amounts = list(50, 100) + + var/spawn_reagent = null + var/label = "" + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/New() + ..() + if(spawn_reagent) + reagents.add_reagent(spawn_reagent, volume) + var/datum/reagent/R = chemical_reagents_list[spawn_reagent] + setLabel(R.name) + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/examine(mob/user) + ..() + user << "It has a capacity of [volume] units." + if(reagents.total_volume <= 0) + user << "It is empty." + else + user << "It contains [reagents.total_volume] units of liquid." + if(!is_open_container()) + user << "The cap is sealed." + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/verb/setLabel(L as text) + set name = "Set Cartridge Label" + set category = "Object" + set src in view(usr, 1) + if(L) + if(usr) + usr << "You set the label on \the [src] to '[L]'." + + label = L + name = "[initial(name)] - '[L]'" + else + if(usr) + usr << "You clear the label on \the [src]." + label = "" + name = initial(name) + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/attack_self() + ..() + if (is_open_container()) + usr << "You put the cap on \the [src]." + flags ^= OPENCONTAINER + else + usr << "You take the cap off \the [src]." + flags |= OPENCONTAINER + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/afterattack(obj/target, mob/user , flag) + if (!is_open_container() || !flag) + return + + else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us. + target.add_fingerprint(user) + + if(!target.reagents.total_volume && target.reagents) + user << "\The [target] is empty." + return + + if(reagents.total_volume >= reagents.maximum_volume) + user << "\The [src] is full." + return + + var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this) + user << "You fill \the [src] with [trans] units of the contents of \the [target]." + + else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it. + + if(!reagents.total_volume) + user << "\The [src] is empty." + return + + if(target.reagents.total_volume >= target.reagents.maximum_volume) + user << "\The [target] is full." + return + + var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this) + user << "You transfer [trans] units of the solution to \the [target]." + + else + return ..() \ No newline at end of file diff --git a/code/modules/reagents/dispenser/cartridge_presets.dm b/code/modules/reagents/dispenser/cartridge_presets.dm new file mode 100644 index 0000000000..007660c1e9 --- /dev/null +++ b/code/modules/reagents/dispenser/cartridge_presets.dm @@ -0,0 +1,94 @@ +/obj/item/weapon/reagent_containers/chem_disp_cartridge + small + volume = CARTRIDGE_VOLUME_SMALL + + medium + volume = CARTRIDGE_VOLUME_MEDIUM + + // Multiple + water spawn_reagent = "water" + sugar spawn_reagent = "sugar" + + // Chemistry + hydrogen spawn_reagent = "hydrogen" + lithium spawn_reagent = "lithium" + carbon spawn_reagent = "carbon" + nitrogen spawn_reagent = "nitrogen" + oxygen spawn_reagent = "oxygen" + fluorine spawn_reagent = "fluorine" + sodium spawn_reagent = "sodium" + aluminum spawn_reagent = "aluminum" + silicon spawn_reagent = "silicon" + phosphorus spawn_reagent = "phosphorus" + sulfur spawn_reagent = "sulfur" + chlorine spawn_reagent = "chlorine" + potassium spawn_reagent = "potassium" + iron spawn_reagent = "iron" + copper spawn_reagent = "copper" + mercury spawn_reagent = "mercury" + radium spawn_reagent = "radium" + ethanol spawn_reagent = "ethanol" + sacid spawn_reagent = "sacid" + tungsten spawn_reagent = "tungsten" + + // Bar, alcoholic + beer spawn_reagent = "beer" + kahlua spawn_reagent = "kahlua" + whiskey spawn_reagent = "whiskey" + wine spawn_reagent = "wine" + vodka spawn_reagent = "vodka" + gin spawn_reagent = "gin" + rum spawn_reagent = "rum" + tequila spawn_reagent = "tequilla" + vermouth spawn_reagent = "vermouth" + cognac spawn_reagent = "cognac" + ale spawn_reagent = "ale" + mead spawn_reagent = "mead" + + // Bar, soft + ice spawn_reagent = "ice" + coffee spawn_reagent = "coffee" + cream spawn_reagent = "cream" + tea spawn_reagent = "tea" + icetea spawn_reagent = "icetea" + cola spawn_reagent = "cola" + smw spawn_reagent = "spacemountainwind" + dr_gibb spawn_reagent = "dr_gibb" + spaceup spawn_reagent = "space_up" + tonic spawn_reagent = "tonic" + sodawater spawn_reagent = "sodawater" + lemon_lime spawn_reagent = "lemon_lime" + orange spawn_reagent = "orangejuice" + lime spawn_reagent = "limejuice" + watermelon spawn_reagent = "watermelonjuice" + + // ERT + inaprov spawn_reagent = "inaprovaline" + ryetalyn spawn_reagent = "ryetalyn" + paracetamol spawn_reagent = "paracetamol" + tramadol spawn_reagent = "tramadol" + oxycodone spawn_reagent = "oxycodone" + sterilizine spawn_reagent = "sterilizine" + leporazine spawn_reagent = "leporazine" + kelotane spawn_reagent = "kelotane" + dermaline spawn_reagent = "dermaline" + dexalin spawn_reagent = "dexalin" + dexalin/small volume = CARTRIDGE_VOLUME_SMALL // For the medicine cartridge crate, so it's not too easy to get large amounts of dexalin + dexalin_p spawn_reagent = "dexalinp" + tricord spawn_reagent = "tricordrazine" + dylovene spawn_reagent = "anti_toxin" + synaptizine spawn_reagent = "synaptizine" + hyronalin spawn_reagent = "hyronalin" + arithrazine spawn_reagent = "arithrazine" + alkysine spawn_reagent = "alkysine" + imidazoline spawn_reagent = "imidazoline" + peridaxon spawn_reagent = "peridaxon" + bicaridine spawn_reagent = "bicaridine" + hyperzine spawn_reagent = "hyperzine" + rezadone spawn_reagent = "rezadone" + spaceacillin spawn_reagent = "spaceacillin" + ethylredox spawn_reagent = "ethylredoxrazine" + sleeptox spawn_reagent = "stoxin" + chloral spawn_reagent = "chloralhydrate" + cryoxadone spawn_reagent = "cryoxadone" + clonexadone spawn_reagent = "clonexadone" diff --git a/code/modules/reagents/dispenser/dispenser2.dm b/code/modules/reagents/dispenser/dispenser2.dm new file mode 100644 index 0000000000..fb7299fcd9 --- /dev/null +++ b/code/modules/reagents/dispenser/dispenser2.dm @@ -0,0 +1,175 @@ +/obj/machinery/chemical_dispenser + name = "chemical dispenser" + icon = 'icons/obj/chemical.dmi' + icon_state = "dispenser" + + var/list/spawn_cartridges = null // Set to a list of types to spawn one of each on New() + + var/list/cartridges = list() // Associative, label -> cartridge + var/obj/item/weapon/reagent_containers/container = null + + var/ui_title = "Chemical Dispenser" + + var/accept_drinking = 0 + var/amount = 30 + + use_power = 1 + idle_power_usage = 100 + density = 1 + anchored = 1 + +/obj/machinery/chemical_dispenser/New() + ..() + + if(spawn_cartridges) + for(var/type in spawn_cartridges) + add_cartridge(new type(src)) + +/obj/machinery/chemical_dispenser/examine(mob/user) + ..() + user << "It has [cartridges.len] cartridges installed, and has space for [DISPENSER_MAX_CARTRIDGES - cartridges.len] more." + +/obj/machinery/chemical_dispenser/proc/add_cartridge(obj/item/weapon/reagent_containers/chem_disp_cartridge/C, mob/user) + if(!istype(C)) + if(user) + user << "\The [C] will not fit in \the [src]!" + return + + if(cartridges.len >= DISPENSER_MAX_CARTRIDGES) + if(user) + user << "\The [src] does not have any slots open for \the [C] to fit into!" + return + + if(!C.label) + if(user) + user << "\The [C] does not have a label!" + return + + if(cartridges[C.label]) + if(user) + user << "\The [src] already contains a cartridge with that label!" + return + + if(user) + user.drop_from_inventory(C) + user << "You add \the [C] to \the [src]." + + C.loc = src + cartridges[C.label] = C + cartridges = sortAssoc(cartridges) + nanomanager.update_uis(src) + +/obj/machinery/chemical_dispenser/proc/remove_cartridge(label) + . = cartridges[label] + cartridges -= label + nanomanager.update_uis(src) + +/obj/machinery/chemical_dispenser/attackby(obj/item/weapon/W, mob/user) + if(istype(W, /obj/item/weapon/wrench)) + playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) + user << "You begin to [anchored ? "un" : ""]fasten \the [src]." + if (do_after(user, 20)) + user.visible_message( + "\The [user] [anchored ? "un" : ""]fastens \the [src].", + "You have [anchored ? "un" : ""]fastened \the [src].", + "You hear a ratchet.") + anchored = !anchored + else + user << "You decide not to [anchored ? "un" : ""]fasten \the [src]." + + else if(istype(W, /obj/item/weapon/reagent_containers/chem_disp_cartridge)) + add_cartridge(W, user) + + else if(istype(W, /obj/item/weapon/screwdriver)) + var/label = input(user, "Which cartridge would you like to remove?", "Chemical Dispenser") as null|anything in cartridges + if(!label) return + var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = remove_cartridge(label) + if(C) + user << "You remove \the [C] from \the [src]." + C.loc = loc + + else if(istype(W, /obj/item/weapon/reagent_containers/glass) || istype(W, /obj/item/weapon/reagent_containers/food)) + var/obj/item/weapon/reagent_containers/RC = W + + if(!accept_drinking && istype(RC,/obj/item/weapon/reagent_containers/food)) + user << "This machine only accepts beakers!" + return + + if(!RC.is_open_container()) + user << "You don't see how \the [src] could dispense reagents into \the [RC]." + return + + container = RC + user.drop_from_inventory(RC) + RC.loc = src + user << "You set \the [RC] on \the [src]." + nanomanager.update_uis(src) // update all UIs attached to src + + else + return ..() + +/obj/machinery/chemical_dispenser/ui_interact(mob/user, ui_key = "main",var/datum/nanoui/ui = null, var/force_open = 1) + if(stat & (BROKEN|NOPOWER)) return + if(user.stat || user.restrained()) return + + // this is the data which will be sent to the ui + var/data[0] + data["amount"] = amount + data["isBeakerLoaded"] = container ? 1 : 0 + data["glass"] = accept_drinking + var beakerD[0] + if(container && container.reagents && container.reagents.reagent_list.len) + for(var/datum/reagent/R in container.reagents.reagent_list) + beakerD[++beakerD.len] = list("name" = R.name, "volume" = R.volume) + data["beakerContents"] = beakerD + + if(container) + data["beakerCurrentVolume"] = container.reagents.total_volume + data["beakerMaxVolume"] = container.reagents.maximum_volume + else + data["beakerCurrentVolume"] = null + data["beakerMaxVolume"] = null + + var chemicals[0] + for(var/label in cartridges) + var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] + chemicals[++chemicals.len] = list("label" = label, "amount" = C.reagents.total_volume) + data["chemicals"] = chemicals + + // update the ui if it exists, returns null if no ui is passed/found + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "chem_disp.tmpl", ui_title, 390, 680) + ui.set_initial_data(data) + ui.open() + +/obj/machinery/chemical_dispenser/Topic(href, href_list) + if(stat & (NOPOWER|BROKEN)) + return 0 // don't update UIs attached to this object + + if(href_list["amount"]) + amount = round(text2num(href_list["amount"]), 1) // round to nearest 1 + amount = max(0, min(120, amount)) // Since the user can actually type the commands himself, some sanity checking + + else if(href_list["dispense"]) + var/label = href_list["dispense"] + if(cartridges[label] && container && container.is_open_container()) + var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] + C.reagents.trans_to(container, amount) + + else if(href_list["ejectBeaker"]) + if(container) + var/obj/item/weapon/reagent_containers/B = container + B.loc = loc + container = null + + add_fingerprint(usr) + return 1 // update UIs attached to this object + +/obj/machinery/chemical_dispenser/attack_ai(mob/user as mob) + src.attack_hand(user) + +/obj/machinery/chemical_dispenser/attack_hand(mob/user as mob) + if(stat & BROKEN) + return + ui_interact(user) \ No newline at end of file diff --git a/code/modules/reagents/dispenser/dispenser_presets.dm b/code/modules/reagents/dispenser/dispenser_presets.dm new file mode 100644 index 0000000000..60d3050692 --- /dev/null +++ b/code/modules/reagents/dispenser/dispenser_presets.dm @@ -0,0 +1,115 @@ +/obj/machinery/chemical_dispenser/full + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten + ) + +/obj/machinery/chemical_dispenser/ert + name = "medicine dispenser" + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/inaprov, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ryetalyn, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/paracetamol, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tramadol, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxycodone, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sterilizine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/leporazine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/kelotane, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dermaline, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin_p, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tricord, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dylovene, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/synaptizine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hyronalin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/arithrazine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/alkysine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/imidazoline, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/peridaxon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/bicaridine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hyperzine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/rezadone, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceacillin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethylredox, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sleeptox, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/chloral, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cryoxadone, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/clonexadone + ) + +/obj/machinery/chemical_dispenser/bar_soft + name = "soft drink dispenser" + desc = "A soda machine." + icon_state = "soda_dispenser" + ui_title = "Soda Dispenser" + accept_drinking = 1 + +/obj/machinery/chemical_dispenser/bar_soft/full + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon + ) + +/obj/machinery/chemical_dispenser/bar_alc + name = "booze dispenser" + desc = "A beer machine. Like a soda machine, but more fun!" + icon_state = "booze_dispenser" + ui_title = "Booze Dispenser" + accept_drinking = 1 + +/obj/machinery/chemical_dispenser/bar_alc/full + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead + ) diff --git a/code/modules/reagents/dispenser/supply.dm b/code/modules/reagents/dispenser/supply.dm new file mode 100644 index 0000000000..f208991712 --- /dev/null +++ b/code/modules/reagents/dispenser/supply.dm @@ -0,0 +1,211 @@ +/datum/supply_packs/chemistry_dispenser + name = "Reagent dispenser" + contains = list( + /obj/machinery/chemical_dispenser{anchored = 0} + ) + cost = 25 + containertype = /obj/structure/largecrate + containername = "reagent dispenser crate" + group = "Reagents" + +/datum/supply_packs/beer_dispenser + name = "Booze dispenser" + contains = list( + /obj/machinery/chemical_dispenser/bar_alc{anchored = 0} + ) + cost = 25 + containertype = /obj/structure/largecrate + containername = "booze dispenser crate" + group = "Reagents" + +/datum/supply_packs/soda_dispenser + name = "Soda dispenser" + contains = list( + /obj/machinery/chemical_dispenser/bar_soft{anchored = 0} + ) + cost = 25 + containertype = /obj/structure/largecrate + containername = "soda dispenser crate" + group = "Reagents" + +/datum/supply_packs/reagents + name = "Chemistry dispenser refill" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten + ) + cost = 150 + containertype = /obj/structure/closet/crate/secure + containername = "chemical crate" + access = list(access_chemistry) + group = "Reagents" + +/datum/supply_packs/alcohol_reagents + name = "Bar alcoholic dispenser refill" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead + ) + cost = 50 + containertype = /obj/structure/closet/crate/secure + containername = "alcoholic drinks crate" + access = list(access_bar) + group = "Reagents" + +/datum/supply_packs/softdrink_reagents + name = "Bar soft drink dispenser refill" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon + ) + cost = 50 + containertype = /obj/structure/closet/crate + containername = "soft drinks crate" + group = "Reagents" + +/datum/supply_packs/dispenser_cartridges + name = "Empty dispenser cartridges" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge + ) + cost = 15 + containertype = /obj/structure/closet/crate + containername = "dispenser cartridge crate" + group = "Reagents" + +#define SEC_PACK(_tname, _type, _name, _cname, _cost, _access)\ + /datum/supply_packs/dispenser_cartridges{\ + _tname {\ + name = _name ;\ + containername = _cname ;\ + containertype = /obj/structure/closet/crate/secure;\ + access = list( _access );\ + cost = _cost ;\ + contains = list( _type , _type );\ + group = "Reagent Cartridges"\ + }\ + } +#define PACK(_tname, _type, _name, _cname, _cost)\ + /datum/supply_packs/dispenser_cartridges{\ + _tname {\ + name = _name ;\ + containername = _cname ;\ + containertype = /obj/structure/closet/crate/secure;\ + cost = _cost ;\ + contains = list( _type , _type );\ + group = "Reagent Cartridges"\ + }\ + } + +// Chemistry-restricted (raw reagents excluding sugar/water) +// Datum path Contents type Supply pack name Container name Cost Container access +SEC_PACK(hydrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, "Reagent refill - Hydrogen", "hydrogen reagent cartridge crate", 15, access_chemistry) +SEC_PACK(lithium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, "Reagent refill - Lithium", "lithium reagent cartridge crate", 15, access_chemistry) +SEC_PACK(carbon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, "Reagent refill - Carbon", "carbon reagent cartridge crate", 15, access_chemistry) +SEC_PACK(nitrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, "Reagent refill - Nitrogen", "nitrogen reagent cartridge crate", 15, access_chemistry) +SEC_PACK(oxygen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, "Reagent refill - Oxygen", "oxygen reagent cartridge crate", 15, access_chemistry) +SEC_PACK(fluorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, "Reagent refill - Fluorine", "fluorine reagent cartridge crate", 15, access_chemistry) +SEC_PACK(sodium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, "Reagent refill - Sodium", "sodium reagent cartridge crate", 15, access_chemistry) +SEC_PACK(aluminium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, "Reagent refill - Aluminum", "aluminum reagent cartridge crate", 15, access_chemistry) +SEC_PACK(silicon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, "Reagent refill - Silicon", "silicon reagent cartridge crate", 15, access_chemistry) +SEC_PACK(phosphorus,/obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, "Reagent refill - Phosphorus", "phosphorus reagent cartridge crate", 15, access_chemistry) +SEC_PACK(sulfur, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, "Reagent refill - Sulfur", "sulfur reagent cartridge crate", 15, access_chemistry) +SEC_PACK(chlorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, "Reagent refill - Chlorine", "chlorine reagent cartridge crate", 15, access_chemistry) +SEC_PACK(potassium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, "Reagent refill - Potassium", "potassium reagent cartridge crate", 15, access_chemistry) +SEC_PACK(iron, /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, "Reagent refill - Iron", "iron reagent cartridge crate", 15, access_chemistry) +SEC_PACK(copper, /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, "Reagent refill - Copper", "copper reagent cartridge crate", 15, access_chemistry) +SEC_PACK(mercury, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, "Reagent refill - Mercury", "mercury reagent cartridge crate", 15, access_chemistry) +SEC_PACK(radium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, "Reagent refill - Radium", "radium reagent cartridge crate", 15, access_chemistry) +SEC_PACK(ethanol, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, "Reagent refill - Ethanol", "ethanol reagent cartridge crate", 15, access_chemistry) +SEC_PACK(sacid, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, "Reagent refill - Sulfuric Acid", "sulfuric acid reagent cartridge crate", 15, access_chemistry) +SEC_PACK(tungsten, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten, "Reagent refill - Tungsten", "tungsten reagent cartridge crate", 15, access_chemistry) + +// Bar-restricted (alcoholic drinks) +// Datum path Contents type Supply pack name Container name Cost Container access +SEC_PACK(beer, /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, "Reagent refill - Beer", "beer reagent cartridge crate", 15, access_bar) +SEC_PACK(kahlua, /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, "Reagent refill - Kahlua", "kahlua reagent cartridge crate", 15, access_bar) +SEC_PACK(whiskey, /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, "Reagent refill - Whiskey", "whiskey reagent cartridge crate", 15, access_bar) +SEC_PACK(wine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, "Reagent refill - Wine", "wine reagent cartridge crate", 15, access_bar) +SEC_PACK(vodka, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, "Reagent refill - Vodka", "vodka reagent cartridge crate", 15, access_bar) +SEC_PACK(gin, /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, "Reagent refill - Gin", "gin reagent cartridge crate", 15, access_bar) +SEC_PACK(rum, /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, "Reagent refill - Rum", "rum reagent cartridge crate", 15, access_bar) +SEC_PACK(tequila, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, "Reagent refill - Tequila", "tequila reagent cartridge crate", 15, access_bar) +SEC_PACK(vermouth, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, "Reagent refill - Vermouth", "vermouth reagent cartridge crate", 15, access_bar) +SEC_PACK(cognac, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, "Reagent refill - Cognac", "cognac reagent cartridge crate", 15, access_bar) +SEC_PACK(ale, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, "Reagent refill - Ale", "ale reagent cartridge crate", 15, access_bar) +SEC_PACK(mead, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead, "Reagent refill - Mead", "mead reagent cartridge crate", 15, access_bar) + +// Unrestricted (water, sugar, non-alcoholic drinks) +// Datum path Contents type Supply pack name Container name Cost +PACK(water, /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, "Reagent refill - Water", "water reagent cartridge crate", 15) +PACK(sugar, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, "Reagent refill - Sugar", "sugar reagent cartridge crate", 15) +PACK(ice, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, "Reagent refill - Ice", "ice reagent cartridge crate", 15) +PACK(tea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, "Reagent refill - Tea", "tea reagent cartridge crate", 15) +PACK(icetea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, "Reagent refill - Iced Tea", "iced tea reagent cartridge crate", 15) +PACK(cola, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, "Reagent refill - Space Cola", "\improper Space Cola reagent cartridge crate", 15) +PACK(smw, /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, "Reagent refill - Space Mountain Wind", "\improper Space Mountain Wind reagent cartridge crate", 15) +PACK(dr_gibb, /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, "Reagent refill - Dr. Gibb", "\improper Dr. Gibb reagent cartridge crate", 15) +PACK(spaceup, /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, "Reagent refill - Space-Up", "\improper Space-Up reagent cartridge crate", 15) +PACK(tonic, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, "Reagent refill - Tonic Water", "tonic water reagent cartridge crate", 15) +PACK(sodawater, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, "Reagent refill - Soda Water", "soda water reagent cartridge crate", 15) +PACK(lemon_lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, "Reagent refill - Lemon-Lime Juice", "lemon-lime juice reagent cartridge crate", 15) +PACK(orange, /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, "Reagent refill - Orange Juice", "orange juice reagent cartridge crate", 15) +PACK(lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, "Reagent refill - Lime Juice", "lime juice reagent cartridge crate", 15) +PACK(watermelon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, "Reagent refill - Watermelon Juice", "watermelon juice reagent cartridge crate", 15) + +#undef SEC_PACK +#undef PACK diff --git a/code/modules/reagents/grenade_launcher.dm b/code/modules/reagents/grenade_launcher.dm deleted file mode 100644 index b96455a178..0000000000 --- a/code/modules/reagents/grenade_launcher.dm +++ /dev/null @@ -1,63 +0,0 @@ - - -/obj/item/weapon/gun/grenadelauncher - name = "grenade launcher" - icon = 'icons/obj/gun.dmi' - icon_state = "riotgun" - item_state = "riotgun" - w_class = 4.0 - throw_speed = 2 - throw_range = 10 - force = 5.0 - var/list/grenades = new/list() - var/max_grenades = 3 - matter = list("metal" = 2000) - - examine(mob/user) - if(..(user, 2)) - user << "\blue [grenades] / [max_grenades] Grenades." - - attackby(obj/item/I as obj, mob/user as mob) - - if((istype(I, /obj/item/weapon/grenade))) - if(grenades.len < max_grenades) - user.drop_item() - I.loc = src - grenades += I - user << "\blue You put the grenade in the grenade launcher." - user << "\blue [grenades.len] / [max_grenades] Grenades." - else - usr << "\red The grenade launcher cannot hold more grenades." - - afterattack(obj/target, mob/user , flag) - - if (istype(target, /obj/item/weapon/storage/backpack )) - return - - else if (locate (/obj/structure/table, src.loc)) - return - - else if(target == user) - return - - if(grenades.len) - spawn(0) fire_grenade(target,user) - else - usr << "\red The grenade launcher is empty." - - proc - fire_grenade(atom/target, mob/user) - for(var/mob/O in viewers(world.view, user)) - O.show_message(text("\red [] fired a grenade!", user), 1) - user << "\red You fire the grenade launcher!" - var/obj/item/weapon/grenade/chem_grenade/F = grenades[1] //Now with less copypasta! - grenades -= F - F.loc = user.loc - F.throw_at(target, 30, 2, user) - message_admins("[key_name_admin(user)] fired a grenade ([F.name]) from a grenade launcher ([src.name]).") - log_game("[key_name_admin(user)] used a grenade ([src.name]).") - F.active = 1 - F.icon_state = initial(icon_state) + "_active" - playsound(user.loc, 'sound/weapons/armbomb.ogg', 75, 1, -3) - spawn(15) - F.prime() \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 827c400898..72bb60b4c6 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -28,8 +28,8 @@ return /obj/item/weapon/reagent_containers/attack(mob/M as mob, mob/user as mob, def_zone) - if (can_operate(M)) //Checks if mob is lying down on table for surgery - if (do_surgery(M,user,src)) + if(can_operate(M)) //Checks if mob is lying down on table for surgery + if(do_surgery(M,user,src)) return // this prevented pills, food, and other things from being picked up by bags. diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 11fd71e620..1cfe480ff9 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -21,7 +21,7 @@ user << "\red [target] is full." return - if(!target.is_open_container() && !ismob(target) && !istype(target,/obj/item/weapon/reagent_containers/food) && !istype(target, /obj/item/clothing/mask/cigarette)) //You can inject humans and food but you cant remove the shit. + if(!target.is_open_container() && !ismob(target) && !istype(target,/obj/item/weapon/reagent_containers/food) && !istype(target, /obj/item/clothing/mask/smokable/cigarette)) //You can inject humans and food but you cant remove the shit. user << "\red You cannot directly fill this object." return diff --git a/code/modules/reagents/reagent_containers/food/drinks.dm b/code/modules/reagents/reagent_containers/food/drinks.dm index e42ef09ac1..58b11a61ac 100644 --- a/code/modules/reagents/reagent_containers/food/drinks.dm +++ b/code/modules/reagents/reagent_containers/food/drinks.dm @@ -173,20 +173,6 @@ ..() reagents.add_reagent("milk", 50) -/* Flour is no longer a reagent -/obj/item/weapon/reagent_containers/food/drinks/flour - name = "flour sack" - desc = "A big bag of flour. Good for baking!" - icon = 'icons/obj/food.dmi' - icon_state = "flour" - item_state = "flour" - New() - ..() - reagents.add_reagent("flour", 30) - src.pixel_x = rand(-10.0, 10) - src.pixel_y = rand(-10.0, 10) -*/ - /obj/item/weapon/reagent_containers/food/drinks/soymilk name = "SoyMilk" desc = "It's soy milk. White and nutritious goodness!" diff --git a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm index 52a4ba12ba..22c0bf6da8 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm @@ -37,7 +37,7 @@ if(!target) return - if(user.a_intent != "hurt" || !isGlass) + if(user.a_intent != I_HURT || !isGlass) return ..() diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index 0ce1f1ee21..3cf8800e1d 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -9,6 +9,8 @@ var/trash = null var/slice_path var/slices_num + var/dried_type = null + var/dry = 0 center_of_mass = list("x"=15, "y"=15) w_class = 2 @@ -32,9 +34,10 @@ return /obj/item/weapon/reagent_containers/food/snacks/attack(mob/M as mob, mob/user as mob, def_zone) - if(!reagents.total_volume) //Shouldn't be needed but it checks to see if it has anything left in it. - user << "\red None of [src] left, oh no!" - M.drop_from_inventory(src) //so icons update :[ + + if(!reagents.total_volume) + user << "None of [src] left!" + user.drop_from_inventory(src) del(src) return 0 @@ -106,9 +109,6 @@ return 0 -/obj/item/weapon/reagent_containers/food/snacks/afterattack(obj/target, mob/user, proximity) - return ..() - /obj/item/weapon/reagent_containers/food/snacks/examine(mob/user) if(!..(user, 1)) return @@ -205,7 +205,7 @@ /obj/item/weapon/reagent_containers/food/snacks/attack_generic(var/mob/living/user) if(!isanimal(user) && !isalien(user)) return - user.visible_message("[user] nibbles away at the [src].","You nibble away at the [src].") + user.visible_message("[user] nibbles away at \the [src].","You nibble away at \the [src].") bitecount++ if(reagents && user.reagents) reagents.trans_to_ingest(user, bitesize) @@ -465,31 +465,41 @@ icon_state = "egg" filling_color = "#FDFFD1" - New() +/obj/item/weapon/reagent_containers/food/snacks/egg/New() + ..() + reagents.add_reagent("egg", 3) + +/obj/item/weapon/reagent_containers/food/snacks/egg/afterattack(obj/O as obj, mob/user as mob, proximity) + if(istype(O,/obj/machinery/microwave)) + return ..() + if(!(proximity && O.is_open_container())) + return + user << "You crack \the [src] into \the [O]." + reagents.trans_to(O, reagents.total_volume) + user.drop_from_inventory(src) + del(src) + +/obj/item/weapon/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) + ..() + new/obj/effect/decal/cleanable/egg_smudge(src.loc) + src.reagents.reaction(hit_atom, TOUCH) + src.visible_message("\red [src.name] has been squashed.","\red You hear a smack.") + del(src) + +/obj/item/weapon/reagent_containers/food/snacks/egg/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype( W, /obj/item/toy/crayon )) + var/obj/item/toy/crayon/C = W + var/clr = C.colourName + + if(!(clr in list("blue","green","mime","orange","purple","rainbow","red","yellow"))) + usr << "\blue The egg refuses to take on this color!" + return + + usr << "\blue You color \the [src] [clr]" + icon_state = "egg-[clr]" + item_color = clr + else ..() - reagents.add_reagent("nutriment", 1) - - throw_impact(atom/hit_atom) - ..() - new/obj/effect/decal/cleanable/egg_smudge(src.loc) - src.reagents.reaction(hit_atom, TOUCH) - src.visible_message("\red [src.name] has been squashed.","\red You hear a smack.") - del(src) - - attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype( W, /obj/item/toy/crayon )) - var/obj/item/toy/crayon/C = W - var/clr = C.colourName - - if(!(clr in list("blue","green","mime","orange","purple","rainbow","red","yellow"))) - usr << "\blue The egg refuses to take on this color!" - return - - usr << "\blue You color \the [src] [clr]" - icon_state = "egg-[clr]" - item_color = clr - else - ..() /obj/item/weapon/reagent_containers/food/snacks/egg/blue icon_state = "egg-blue" @@ -531,7 +541,7 @@ New() ..() - reagents.add_reagent("nutriment", 2) + reagents.add_reagent("protein", 3) reagents.add_reagent("sodiumchloride", 1) reagents.add_reagent("blackpepper", 1) bitesize = 1 @@ -544,18 +554,21 @@ New() ..() - reagents.add_reagent("nutriment", 2) + reagents.add_reagent("protein", 2) /obj/item/weapon/reagent_containers/food/snacks/flour - name = "flour" - desc = "A small bag filled with some flour." + name = "flour sack" + desc = "A big bag of flour. Good for baking!" + icon = 'icons/obj/food.dmi' icon_state = "flour" + item_state = "flour" New() ..() - reagents.add_reagent("nutriment", 1) + reagents.add_reagent("flour", 30) + src.pixel_x = rand(-10.0, 10) + src.pixel_y = rand(-10.0, 10) /obj/item/weapon/reagent_containers/food/snacks/organ - name = "organ" desc = "It's good for you." icon = 'icons/obj/surgery.dmi' @@ -564,7 +577,7 @@ New() ..() - reagents.add_reagent("nutriment", rand(3,5)) + reagents.add_reagent("protein", rand(3,5)) reagents.add_reagent("toxin", rand(1,3)) src.bitesize = 3 @@ -610,7 +623,7 @@ New() ..() - reagents.add_reagent("nutriment", 3) + reagents.add_reagent("protein", 3) reagents.add_reagent("carpotoxin", 3) src.bitesize = 6 @@ -622,7 +635,7 @@ New() ..() - reagents.add_reagent("nutriment", 4) + reagents.add_reagent("protein", 4) reagents.add_reagent("carpotoxin", 3) bitesize = 3 @@ -657,7 +670,7 @@ New() ..() - reagents.add_reagent("nutriment", 12) + reagents.add_reagent("protein", 12) reagents.add_reagent("hyperzine", 5) src.bitesize = 3 @@ -669,7 +682,8 @@ New() ..() - reagents.add_reagent("nutriment", 3) + reagents.add_reagent("protein", 6) + reagents.add_reagent("pacid",6) src.bitesize = 6 /obj/item/weapon/reagent_containers/food/snacks/meatball @@ -680,7 +694,7 @@ New() ..() - reagents.add_reagent("nutriment", 3) + reagents.add_reagent("protein", 3) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/sausage @@ -691,9 +705,26 @@ New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 6) bitesize = 2 +/obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket + name = "\improper Sin-pocket" + desc = "The food of choice for the veteran. Do NOT overconsume." + filling_color = "#6D6D00" + heated_reagents = list("doctorsdelight" = 5, "hyperzine" = 0.75, "synaptizine" = 0.25) + var/has_been_heated = 0 + +/obj/item/weapon/reagent_containers/food/snacks/donkpocket/sinpocket/attack_self(mob/user) + if(has_been_heated) + user << "The heating chemicals have already been spent." + return + has_been_heated = 1 + user.visible_message("[user] crushes \the [src] package.", "You crush \the [src] package and feel a comfortable heat build up.") + spawn(200) + user << "You think \the [src] is ready to eat about now." + heat() + /obj/item/weapon/reagent_containers/food/snacks/donkpocket name = "Donk-pocket" desc = "The food of choice for the seasoned traitor." @@ -702,15 +733,26 @@ New() ..() - reagents.add_reagent("nutriment", 4) + reagents.add_reagent("nutriment", 2) + reagents.add_reagent("protein", 2) var/warm = 0 - proc/cooltime() //Not working, derp? + var/list/heated_reagents = list("tricordrazine" = 5) + proc/heat() + warm = 1 + for(var/reagent in heated_reagents) + reagents.add_reagent(reagent, heated_reagents[reagent]) + bitesize = 6 + name = "Warm " + name + cooltime() + + proc/cooltime() if (src.warm) - spawn( 4200 ) + spawn(4200) src.warm = 0 - src.reagents.del_reagent("tricordrazine") - src.name = "donk-pocket" + for(var/reagent in heated_reagents) + src.reagents.del_reagent(reagent) + src.name = initial(name) return /obj/item/weapon/reagent_containers/food/snacks/brainburger @@ -721,7 +763,7 @@ New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 6) reagents.add_reagent("alkysine", 6) bitesize = 2 @@ -748,7 +790,7 @@ icon_state = "hburger" New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 6) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/cheeseburger @@ -757,6 +799,7 @@ icon_state = "cheeseburger" New() ..() + reagents.add_reagent("protein", 2) reagents.add_reagent("nutriment", 2) /obj/item/weapon/reagent_containers/food/snacks/monkeyburger @@ -767,7 +810,8 @@ New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 3) + reagents.add_reagent("nutriment", 3) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/fishburger @@ -778,7 +822,7 @@ New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 6) reagents.add_reagent("carpotoxin", 3) bitesize = 3 @@ -826,7 +870,7 @@ New() ..() - reagents.add_reagent("nutriment", 8) + reagents.add_reagent("protein", 8) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/clownburger @@ -837,11 +881,6 @@ New() ..() -/* - var/datum/disease/F = new /datum/disease/pierrot_throat(0) - var/list/data = list("viruses"= list(F)) - reagents.add_reagent("blood", 4, data) -*/ reagents.add_reagent("nutriment", 6) bitesize = 2 @@ -866,7 +905,7 @@ //var/herp = 0 New() ..() - reagents.add_reagent("nutriment", 8) + reagents.add_reagent("protein", 8) bitesize = 1 /obj/item/weapon/reagent_containers/food/snacks/muffin @@ -943,7 +982,7 @@ New() ..() - reagents.add_reagent("nutriment", 10) + reagents.add_reagent("protein", 10) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/soylenviridians @@ -968,7 +1007,7 @@ New() ..() - reagents.add_reagent("nutriment", 10) + reagents.add_reagent("protein", 10) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/tofupie @@ -1023,7 +1062,7 @@ New() ..() - reagents.add_reagent("nutriment", 10) + reagents.add_reagent("protein", 10) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/wingfangchu @@ -1035,7 +1074,7 @@ New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 6) bitesize = 2 @@ -1048,7 +1087,7 @@ New() ..() - reagents.add_reagent("nutriment", 8) + reagents.add_reagent("protein", 8) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/monkeykabob @@ -1060,7 +1099,7 @@ New() ..() - reagents.add_reagent("nutriment", 8) + reagents.add_reagent("protein", 8) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/tofukabob @@ -1077,14 +1116,15 @@ /obj/item/weapon/reagent_containers/food/snacks/cubancarp name = "Cuban Carp" - desc = "A grifftastic sandwich that burns your tongue and then leaves it numb!" + desc = "A sandwich that burns your tongue and then leaves it numb!" icon_state = "cubancarp" trash = /obj/item/trash/plate filling_color = "#E9ADFF" New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 3) + reagents.add_reagent("nutriment", 3) reagents.add_reagent("carpotoxin", 3) reagents.add_reagent("capsaicin", 3) bitesize = 3 @@ -1118,7 +1158,7 @@ New() ..() - reagents.add_reagent("nutriment", 4) + reagents.add_reagent("protein", 4) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/no_raisin @@ -1176,7 +1216,8 @@ New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("nutriment", 3) + reagents.add_reagent("protein", 3) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/fries @@ -1223,7 +1264,8 @@ New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 2) + reagents.add_reagent("nutriment", 4) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/fortunecookie @@ -1258,7 +1300,7 @@ New() ..() - reagents.add_reagent("nutriment", 4) + reagents.add_reagent("protein", 4) reagents.add_reagent("sodiumchloride", 1) reagents.add_reagent("blackpepper", 1) bitesize = 3 @@ -1312,7 +1354,7 @@ New() ..() - reagents.add_reagent("nutriment", 8) + reagents.add_reagent("protein", 8) reagents.add_reagent("water", 5) bitesize = 5 @@ -1330,13 +1372,13 @@ /obj/item/weapon/reagent_containers/food/snacks/bloodsoup name = "Tomato soup" - desc = "Smells like copper" + desc = "Smells like copper." icon_state = "tomatosoup" filling_color = "#FF0000" New() ..() - reagents.add_reagent("nutriment", 2) + reagents.add_reagent("protein", 2) reagents.add_reagent("blood", 10) reagents.add_reagent("water", 5) bitesize = 5 @@ -1452,7 +1494,8 @@ New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 3) + reagents.add_reagent("nutriment", 3) reagents.add_reagent("capsaicin", 3) reagents.add_reagent("tomatojuice", 2) bitesize = 5 @@ -1467,7 +1510,8 @@ trash = /obj/item/trash/snack_bowl New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 3) + reagents.add_reagent("nutriment", 3) reagents.add_reagent("frostoil", 3) reagents.add_reagent("tomatojuice", 2) bitesize = 5 @@ -1497,11 +1541,11 @@ filling_color = "#ADAC7F" var/wrapped = 0 - var/monkey_type = /mob/living/carbon/monkey + var/monkey_type = "Monkey" New() ..() - reagents.add_reagent("nutriment",10) + reagents.add_reagent("protein", 10) afterattack(obj/O as obj, mob/user as mob, proximity) if(!proximity) return @@ -1515,6 +1559,7 @@ if(wrapped) Unwrap(user) + /* On_Consume(var/mob/M) M << "Something inside of you suddently expands!" @@ -1540,7 +1585,7 @@ else //someone is having a bad day E.createwound(CUT, 30) E.embed(surprise) - else if (ismonkey(M)) + else if (issmall(M)) M.visible_message("[M] suddenly tears in half!") var/mob/living/carbon/monkey/ook = new monkey_type(M.loc) ook.name = "malformed [ook.name]" @@ -1548,11 +1593,13 @@ ook.add_blood(M) M.gib() ..() + */ proc/Expand() for(var/mob/M in viewers(src,7)) M << "\red \The [src] expands!" - new monkey_type(src) + var/mob/living/carbon/human/H = new (src) + H.set_species(monkey_type) del(src) proc/Unwrap(mob/user as mob) @@ -1567,29 +1614,29 @@ icon_state = "monkeycubewrap" wrapped = 1 - /obj/item/weapon/reagent_containers/food/snacks/monkeycube/farwacube name = "farwa cube" - monkey_type = /mob/living/carbon/monkey/tajara + monkey_type = "Farwa" + /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube name = "farwa cube" - monkey_type =/mob/living/carbon/monkey/tajara - + monkey_type = "Farwa" /obj/item/weapon/reagent_containers/food/snacks/monkeycube/stokcube name = "stok cube" - monkey_type = /mob/living/carbon/monkey/unathi + monkey_type = "Stok" + /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube name = "stok cube" - monkey_type =/mob/living/carbon/monkey/unathi - + monkey_type = "Stok" /obj/item/weapon/reagent_containers/food/snacks/monkeycube/neaeracube name = "neaera cube" - monkey_type = /mob/living/carbon/monkey/skrell + monkey_type = "Neara" + /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube name = "neaera cube" - monkey_type =/mob/living/carbon/monkey/skrell + monkey_type = "Neara" /obj/item/weapon/reagent_containers/food/snacks/spellburger @@ -1611,7 +1658,8 @@ New() ..() - reagents.add_reagent("nutriment", 14) + reagents.add_reagent("protein", 10) + reagents.add_reagent("nutriment", 4) bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/enchiladas @@ -1623,7 +1671,8 @@ New() ..() - reagents.add_reagent("nutriment",8) + reagents.add_reagent("protein", 6) + reagents.add_reagent("nutriment",2) reagents.add_reagent("capsaicin", 6) bitesize = 4 @@ -1636,7 +1685,7 @@ New() ..() - reagents.add_reagent("nutriment", 10) + reagents.add_reagent("protein", 10) reagents.add_reagent("banana", 5) reagents.add_reagent("blackpepper", 1) reagents.add_reagent("sodiumchloride", 1) @@ -1663,7 +1712,8 @@ New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 3) + reagents.add_reagent("nutriment", 3) reagents.add_reagent("carpotoxin", 3) bitesize = 3 @@ -1676,7 +1726,8 @@ New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 3) + reagents.add_reagent("nutriment", 3) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/toastedsandwich @@ -1688,7 +1739,8 @@ New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 3) + reagents.add_reagent("nutriment", 3) reagents.add_reagent("carbon", 2) bitesize = 2 @@ -1701,7 +1753,8 @@ New() ..() - reagents.add_reagent("nutriment", 7) + reagents.add_reagent("protein", 4) + reagents.add_reagent("nutriment", 3) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/tomatosoup @@ -1738,7 +1791,8 @@ New() ..() - reagents.add_reagent("nutriment", 10) + reagents.add_reagent("protein", 4) + reagents.add_reagent("nutriment", 6) reagents.add_reagent("tomatojuice", 5) reagents.add_reagent("imidazoline", 5) reagents.add_reagent("water", 5) @@ -1834,7 +1888,7 @@ /obj/item/weapon/reagent_containers/food/snacks/ricepudding name = "Rice Pudding" - desc = "Where's the Jam!" + desc = "Where's the jam?" icon_state = "rpudding" trash = /obj/item/trash/snack_bowl filling_color = "#FFFBDB" @@ -1866,7 +1920,8 @@ New() ..() - reagents.add_reagent("nutriment", 8) + reagents.add_reagent("protein", 4) + reagents.add_reagent("nutriment", 4) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/spesslaw @@ -1877,7 +1932,8 @@ New() ..() - reagents.add_reagent("nutriment", 8) + reagents.add_reagent("protein", 4) + reagents.add_reagent("nutriment", 4) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/poppypretzel @@ -1912,7 +1968,8 @@ New() ..() - reagents.add_reagent("nutriment", 50) + reagents.add_reagent("protein", 25) + reagents.add_reagent("nutriment", 25) bitesize = 10 /obj/item/weapon/reagent_containers/food/snacks/candiedapple @@ -2041,7 +2098,7 @@ New() ..() - reagents.add_reagent("nutriment", 5) + reagents.add_reagent("protein", 5) bitesize = 1 /obj/item/weapon/reagent_containers/food/snacks/beetsoup @@ -2053,19 +2110,7 @@ New() ..() - switch(rand(1,6)) - if(1) - name = "borsch" - if(2) - name = "bortsch" - if(3) - name = "borstch" - if(4) - name = "borsh" - if(5) - name = "borshch" - if(6) - name = "borscht" + name = pick(list("borsch","bortsch","borstch","borsh","borshch","borscht")) reagents.add_reagent("nutriment", 8) bitesize = 2 @@ -2090,7 +2135,8 @@ New() ..() - reagents.add_reagent("nutriment", 8) + reagents.add_reagent("protein", 2) + reagents.add_reagent("nutriment", 6) bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/appletart @@ -2123,7 +2169,8 @@ filling_color = "#FF7575" New() ..() - reagents.add_reagent("nutriment", 30) + reagents.add_reagent("protein", 20) + reagents.add_reagent("nutriment", 10) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/meatbreadslice @@ -2143,7 +2190,8 @@ filling_color = "#8AFF75" New() ..() - reagents.add_reagent("nutriment", 30) + reagents.add_reagent("protein", 20) + reagents.add_reagent("nutriment", 10) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/xenomeatbreadslice @@ -2226,7 +2274,8 @@ filling_color = "#E6AEDB" New() ..() - reagents.add_reagent("nutriment", 25) + reagents.add_reagent("protein", 25) + reagents.add_reagent("nutriment", 5) reagents.add_reagent("alkysine", 10) bitesize = 2 @@ -2247,7 +2296,8 @@ filling_color = "#FAF7AF" New() ..() - reagents.add_reagent("nutriment", 25) + reagents.add_reagent("protein", 15) + reagents.add_reagent("nutriment", 10) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/cheesecakeslice @@ -2362,7 +2412,7 @@ filling_color = "#FFF700" New() ..() - reagents.add_reagent("nutriment", 20) + reagents.add_reagent("protein", 20) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/cheesewedge @@ -2387,7 +2437,7 @@ /obj/item/weapon/reagent_containers/food/snacks/birthdaycakeslice name = "Birthday Cake slice" - desc = "A slice of your birthday" + desc = "A slice of your birthday." icon_state = "birthdaycakeslice" trash = /obj/item/trash/plate filling_color = "#FFD6D6" @@ -2424,7 +2474,8 @@ filling_color = "#FFF896" New() ..() - reagents.add_reagent("nutriment", 20) + reagents.add_reagent("protein", 15) + reagents.add_reagent("nutriment", 5) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/creamcheesebreadslice @@ -2509,7 +2560,8 @@ slices_num = 6 New() ..() - reagents.add_reagent("nutriment", 40) + reagents.add_reagent("nutriment", 35) + reagents.add_reagent("protein", 5) reagents.add_reagent("tomatojuice", 6) bitesize = 2 @@ -2528,7 +2580,7 @@ slices_num = 6 New() ..() - reagents.add_reagent("nutriment", 50) + reagents.add_reagent("protein", 50) reagents.add_reagent("tomatojuice", 6) bitesize = 2 @@ -2548,6 +2600,7 @@ New() ..() reagents.add_reagent("nutriment", 35) + reagents.add_reagent("protein", 5) bitesize = 2 /obj/item/weapon/reagent_containers/food/snacks/mushroompizzaslice @@ -2566,6 +2619,7 @@ New() ..() reagents.add_reagent("nutriment", 30) + reagents.add_reagent("protein", 5) reagents.add_reagent("tomatojuice", 6) reagents.add_reagent("imidazoline", 12) bitesize = 2 @@ -2725,7 +2779,7 @@ if( src.open ) return - var/t = input("Enter what you want to add to the tag:", "Write", null, null) as text + var/t = sanitize(input("Enter what you want to add to the tag:", "Write", null, null) as text, 30) var/obj/item/pizzabox/boxtotagto = src if( boxes.len > 0 ) @@ -2772,23 +2826,6 @@ /////////////////////////////////////////// // new old food stuff from bs12 /////////////////////////////////////////// - -// Flour + egg = dough -/obj/item/weapon/reagent_containers/food/snacks/flour/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/egg)) - new /obj/item/weapon/reagent_containers/food/snacks/dough(src) - user << "You make some dough." - del(W) - del(src) - -// Egg + flour = dough -/obj/item/weapon/reagent_containers/food/snacks/egg/attackby(obj/item/weapon/W as obj, mob/user as mob) - if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/flour)) - new /obj/item/weapon/reagent_containers/food/snacks/dough(src) - user << "You make some dough." - del(W) - del(src) - /obj/item/weapon/reagent_containers/food/snacks/dough name = "dough" desc = "A piece of dough." @@ -2797,6 +2834,7 @@ bitesize = 2 New() ..() + reagents.add_reagent("protein", 1) reagents.add_reagent("nutriment", 3) // Dough + rolling pin = flat dough @@ -2816,6 +2854,7 @@ slices_num = 3 New() ..() + reagents.add_reagent("protein", 1) reagents.add_reagent("nutriment", 3) /obj/item/weapon/reagent_containers/food/snacks/doughslice @@ -2823,6 +2862,8 @@ desc = "A building block of an impressive dish." icon = 'icons/obj/food_ingredients.dmi' icon_state = "doughslice" + slice_path = /obj/item/weapon/reagent_containers/food/snacks/spagetti + slices_num = 1 bitesize = 2 New() ..() @@ -2889,7 +2930,8 @@ bitesize = 3 New() ..() - reagents.add_reagent("nutriment", 7) + reagents.add_reagent("protein", 3) + reagents.add_reagent("nutriment", 4) /obj/item/weapon/reagent_containers/food/snacks/rawcutlet name = "raw cutlet" @@ -2899,7 +2941,7 @@ bitesize = 1 New() ..() - reagents.add_reagent("nutriment", 1) + reagents.add_reagent("protein", 1) /obj/item/weapon/reagent_containers/food/snacks/cutlet name = "cutlet" @@ -2909,7 +2951,7 @@ bitesize = 2 New() ..() - reagents.add_reagent("nutriment", 2) + reagents.add_reagent("protein", 2) /obj/item/weapon/reagent_containers/food/snacks/rawmeatball name = "raw meatball" @@ -2919,7 +2961,7 @@ bitesize = 2 New() ..() - reagents.add_reagent("nutriment", 2) + reagents.add_reagent("protein", 2) /obj/item/weapon/reagent_containers/food/snacks/hotdog name = "hotdog" @@ -2928,7 +2970,7 @@ bitesize = 2 New() ..() - reagents.add_reagent("nutriment", 6) + reagents.add_reagent("protein", 6) /obj/item/weapon/reagent_containers/food/snacks/flatbread name = "flatbread" @@ -2959,3 +3001,39 @@ ..() reagents.add_reagent("nutriment", 3) +/obj/item/weapon/reagent_containers/food/snacks/liquidfood + name = "\improper LiquidFood Ration" + desc = "A prepackaged grey slurry of all the essential nutrients for a spacefarer on the go. Should this be crunchy?" + icon_state = "liquidfood" + trash = /obj/item/trash/liquidfood + filling_color = "#A8A8A8" + + New() + ..() + reagents.add_reagent("nutriment", 20) + reagents.add_reagent("iron", 3) + bitesize = 4 + + +/obj/item/weapon/reagent_containers/food/snacks/tastybread + name = "bread tube" + desc = "Bread in a tube. Chewy...and surprisingly tasty." + icon_state = "tastybread" + trash = /obj/item/trash/tastybread + filling_color = "#A66829" + + New() + ..() + reagents.add_reagent("nutriment", 6) + bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/skrellsnacks + name = "\improper SkrellSnax" + desc = "Cured fungus shipped all the way from Jargon 4, almost like jerky! Almost." + icon_state = "skrellsnacks" + filling_color = "#A66829" + + New() + ..() + reagents.add_reagent("nutriment", 10) + bitesize = 3 diff --git a/code/modules/reagents/reagent_containers/food/snacks/grown.dm b/code/modules/reagents/reagent_containers/food/snacks/grown.dm deleted file mode 100644 index d570f13861..0000000000 --- a/code/modules/reagents/reagent_containers/food/snacks/grown.dm +++ /dev/null @@ -1,632 +0,0 @@ - - -// *********************************************************** -// Foods that are produced from hydroponics ~~~~~~~~~~ -// Data from the seeds carry over to these grown foods -// *********************************************************** - -//Grown foods -//Subclass so we can pass on values -/obj/item/weapon/reagent_containers/food/snacks/grown/ - var/plantname - var/potency = -1 - icon = 'icons/obj/harvest.dmi' - New(newloc,newpotency) - if (!isnull(newpotency)) - potency = newpotency - ..() - src.pixel_x = rand(-5.0, 5) - src.pixel_y = rand(-5.0, 5) - -/obj/item/weapon/reagent_containers/food/snacks/grown/New() - ..() - - //Handle some post-spawn var stuff. - spawn(1) - // Fill the object up with the appropriate reagents. - if(!isnull(plantname)) - var/datum/seed/S = seed_types[plantname] - if(!S || !S.chems) - return - - potency = S.potency - - for(var/rid in S.chems) - var/list/reagent_data = S.chems[rid] - var/rtotal = reagent_data[1] - if(reagent_data.len > 1 && potency > 0) - rtotal += round(potency/reagent_data[2]) - reagents.add_reagent(rid,max(1,rtotal)) - - if(reagents.total_volume > 0) - bitesize = 1+round(reagents.total_volume / 2, 1) - -/obj/item/weapon/reagent_containers/food/snacks/grown/corn - name = "ear of corn" - desc = "Needs some butter!" - plantname = "corn" - icon_state = "corn" - potency = 40 - filling_color = "#FFEE00" - trash = /obj/item/weapon/corncob - -/obj/item/weapon/reagent_containers/food/snacks/grown/cherries - name = "cherries" - desc = "Great for toppings!" - icon_state = "cherry" - filling_color = "#FF0000" - gender = PLURAL - plantname = "cherry" - -/obj/item/weapon/reagent_containers/food/snacks/grown/poppy - name = "poppy" - desc = "Long-used as a symbol of rest, peace, and death." - icon_state = "poppy" - potency = 30 - filling_color = "#CC6464" - plantname = "poppies" - -/obj/item/weapon/reagent_containers/food/snacks/grown/harebell - name = "harebell" - desc = "\"I'll sweeten thy sad grave: thou shalt not lack the flower that's like thy face, pale primrose, nor the azured hare-bell, like thy veins; no, nor the leaf of eglantine, whom not to slander, out-sweeten’d not thy breath.\"" - icon_state = "harebell" - potency = 1 - filling_color = "#D4B2C9" - plantname = "harebells" - -/obj/item/weapon/reagent_containers/food/snacks/grown/potato - name = "potato" - desc = "Boil 'em! Mash 'em! Stick 'em in a stew!" - icon_state = "potato" - potency = 25 - filling_color = "#E6E8DA" - plantname = "potato" - -/obj/item/weapon/reagent_containers/food/snacks/grown/potato/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = W - if(C.use(5)) - user << "You add some cable to the potato and slide it inside the battery encasing." - var/obj/item/weapon/cell/potato/pocell = new /obj/item/weapon/cell/potato(user.loc) - pocell.maxcharge = src.potency * 10 - pocell.charge = pocell.maxcharge - del(src) - return - -/obj/item/weapon/reagent_containers/food/snacks/grown/grapes - name = "bunch of grapes" - desc = "Nutritious!" - icon_state = "grapes" - filling_color = "#A332AD" - plantname = "grapes" - -/obj/item/weapon/reagent_containers/food/snacks/grown/greengrapes - name = "bunch of green grapes" - desc = "Nutritious!" - icon_state = "greengrapes" - potency = 25 - filling_color = "#A6FFA3" - plantname = "greengrapes" - -/obj/item/weapon/reagent_containers/food/snacks/grown/peanut - name = "peanut" - desc = "Nuts!" - icon_state = "peanut" - filling_color = "857e27" - potency = 25 - plantname = "peanut" - -/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage - name = "cabbage" - desc = "Ewwwwwwwwww. Cabbage." - icon_state = "cabbage" - potency = 25 - filling_color = "#A2B5A1" - plantname = "cabbage" - -/obj/item/weapon/reagent_containers/food/snacks/grown/berries - name = "bunch of berries" - desc = "Nutritious!" - icon_state = "berrypile" - filling_color = "#C2C9FF" - plantname = "berries" - -/obj/item/weapon/reagent_containers/food/snacks/grown/plastellium - name = "clump of plastellium" - desc = "Hmm, needs some processing" - icon_state = "plastellium" - filling_color = "#C4C4C4" - plantname = "plastic" - -/obj/item/weapon/reagent_containers/food/snacks/grown/shand - name = "S'rendarr's Hand leaf" - desc = "A leaf sample from a lowland thicket shrub. Smells strongly like wax." - icon_state = "shand" - filling_color = "#70C470" - plantname = "shand" - -/obj/item/weapon/reagent_containers/food/snacks/grown/mtear - name = "sprig of Messa's Tear" - desc = "A mountain climate herb with a soft, cold blue flower, known to contain an abundance of healing chemicals." - icon_state = "mtear" - filling_color = "#70C470" - plantname = "mtear" - -/obj/item/weapon/reagent_containers/food/snacks/grown/mtear/attack_self(mob/user as mob) - if(istype(user.loc,/turf/space)) - return - var/obj/item/stack/medical/ointment/tajaran/poultice = new /obj/item/stack/medical/ointment/tajaran(user.loc) - - poultice.heal_burn = potency - del(src) - - user << "You mash the petals into a poultice." - -/obj/item/weapon/reagent_containers/food/snacks/grown/shand/attack_self(mob/user as mob) - if(istype(user.loc,/turf/space)) - return - var/obj/item/stack/medical/bruise_pack/tajaran/poultice = new /obj/item/stack/medical/bruise_pack/tajaran(user.loc) - - poultice.heal_brute = potency - del(src) - - user << "You mash the leaves into a poultice." - -/obj/item/weapon/reagent_containers/food/snacks/grown/glowberries - name = "bunch of glow-berries" - desc = "Nutritious!" - var/light_on = 1 - var/brightness_on = 2 //luminosity when on - filling_color = "#D3FF9E" - icon_state = "glowberrypile" - plantname = "glowberries" - -/obj/item/weapon/reagent_containers/food/snacks/grown/glowberries/Del() - if(istype(loc,/mob)) - loc.SetLuminosity(round(loc.luminosity - potency/5,1)) - ..() - -/obj/item/weapon/reagent_containers/food/snacks/grown/glowberries/pickup(mob/user) - src.SetLuminosity(0) - user.SetLuminosity(round(user.luminosity + (potency/5),1)) - -/obj/item/weapon/reagent_containers/food/snacks/grown/glowberries/dropped(mob/user) - user.SetLuminosity(round(user.luminosity - (potency/5),1)) - src.SetLuminosity(round(potency/5,1)) - -/obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod - name = "cocoa pod" - desc = "Can be ground into cocoa powder." - icon_state = "cocoapod" - potency = 50 - filling_color = "#9C8E54" - plantname = "cocoa" - -/obj/item/weapon/reagent_containers/food/snacks/grown/sugarcane - name = "sugarcane" - desc = "Sickly sweet." - icon_state = "sugarcane" - potency = 50 - filling_color = "#C0C9AD" - plantname = "sugarcane" - -/obj/item/weapon/reagent_containers/food/snacks/grown/poisonberries - name = "bunch of poison-berries" - desc = "Taste so good, you could die!" - icon_state = "poisonberrypile" - gender = PLURAL - potency = 15 - filling_color = "#B422C7" - plantname = "poisonberries" - -/obj/item/weapon/reagent_containers/food/snacks/grown/deathberries - name = "bunch of death-berries" - desc = "Taste so good, you could die!" - icon_state = "deathberrypile" - gender = PLURAL - potency = 50 - filling_color = "#4E0957" - plantname = "deathberries" - -/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris - name = "ambrosia vulgaris branch" - desc = "This is a plant containing various healing chemicals." - icon_state = "ambrosiavulgaris" - potency = 10 - filling_color = "#125709" - plantname = "ambrosia" - -/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus - name = "ambrosia deus branch" - desc = "Eating this makes you feel immortal!" - icon_state = "ambrosiadeus" - potency = 10 - filling_color = "#229E11" - plantname = "ambrosiadeus" - -/obj/item/weapon/reagent_containers/food/snacks/grown/apple - name = "apple" - desc = "It's a little piece of Eden." - icon_state = "apple" - potency = 15 - filling_color = "#DFE88B" - plantname = "apple" - -/obj/item/weapon/reagent_containers/food/snacks/grown/apple/poisoned - name = "apple" - desc = "It's a little piece of Eden." - icon_state = "apple" - potency = 15 - filling_color = "#B3BD5E" - plantname = "poisonapple" - -/obj/item/weapon/reagent_containers/food/snacks/grown/goldapple - name = "golden apple" - desc = "Emblazoned upon the apple is the word 'Kallisti'." - icon_state = "goldapple" - potency = 15 - filling_color = "#F5CB42" - plantname = "goldapple" - -/obj/item/weapon/reagent_containers/food/snacks/grown/watermelon - name = "watermelon" - desc = "It's full of watery goodness." - icon_state = "watermelon" - potency = 10 - filling_color = "#FA2863" - slice_path = /obj/item/weapon/reagent_containers/food/snacks/watermelonslice - slices_num = 5 - plantname = "watermelon" - -/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin - name = "pumpkin" - desc = "It's large and scary." - icon_state = "pumpkin" - potency = 10 - filling_color = "#FAB728" - plantname = "pumpkin" - -/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/weapon/W as obj, mob/user as mob) - ..() - if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || istype(W, /obj/item/weapon/twohanded/fireaxe) || istype(W, /obj/item/weapon/kitchen/utensil/knife) || istype(W, /obj/item/weapon/kitchenknife) || istype(W, /obj/item/weapon/melee/energy)) - user.show_message("You carve a face into [src]!", 1) - new /obj/item/clothing/head/pumpkinhead (user.loc) - del(src) - return - -/obj/item/weapon/reagent_containers/food/snacks/grown/lime - name = "lime" - desc = "It's so sour, your face will twist." - icon_state = "lime" - potency = 20 - filling_color = "#28FA59" - plantname = "lime" - -/obj/item/weapon/reagent_containers/food/snacks/grown/lemon - name = "lemon" - desc = "When life gives you lemons, be grateful they aren't limes." - icon_state = "lemon" - potency = 20 - filling_color = "#FAF328" - plantname = "lemon" - -/obj/item/weapon/reagent_containers/food/snacks/grown/orange - name = "orange" - desc = "It's a tangy fruit." - icon_state = "orange" - potency = 20 - filling_color = "#FAAD28" - plantname = "orange" - -/obj/item/weapon/reagent_containers/food/snacks/grown/whitebeet - name = "white-beet" - desc = "You can't beat white-beet." - icon_state = "whitebeet" - potency = 15 - filling_color = "#FFFCCC" - plantname = "whitebeet" - -/obj/item/weapon/reagent_containers/food/snacks/grown/banana - name = "banana" - desc = "It's an excellent prop for a comedy." - icon = 'icons/obj/items.dmi' - icon_state = "banana" - item_state = "banana" - filling_color = "#FCF695" - trash = /obj/item/weapon/bananapeel - plantname = "banana" - -/obj/item/weapon/reagent_containers/food/snacks/grown/chili - name = "chili" - desc = "It's spicy! Wait... IT'S BURNING ME!!" - icon_state = "chilipepper" - filling_color = "#FF0000" - plantname = "chili" - -/obj/item/weapon/reagent_containers/food/snacks/grown/eggplant - name = "eggplant" - desc = "Maybe there's a chicken inside?" - icon_state = "eggplant" - filling_color = "#550F5C" - plantname = "eggplant" - -/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans - name = "soybeans" - desc = "It's pretty bland, but oh the possibilities..." - gender = PLURAL - filling_color = "#E6E8B7" - icon_state = "soybeans" - plantname = "soybean" - -/obj/item/weapon/reagent_containers/food/snacks/grown/tomato - name = "tomato" - desc = "I say to-mah-to, you say tom-mae-to." - icon_state = "tomato" - filling_color = "#FF0000" - potency = 10 - plantname = "tomato" - -/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/throw_impact(atom/hit_atom) - ..() - new/obj/effect/decal/cleanable/tomato_smudge(src.loc) - src.visible_message("The [src.name] has been squashed.","You hear a smack.") - del(src) - return - -/obj/item/weapon/reagent_containers/food/snacks/grown/killertomato - name = "killer-tomato" - desc = "I say to-mah-to, you say tom-mae-to... OH GOD IT'S EATING MY LEGS!!" - icon_state = "killertomato" - potency = 10 - filling_color = "#FF0000" - potency = 30 - plantname = "killertomato" - -/obj/item/weapon/reagent_containers/food/snacks/grown/killertomato/attack_self(mob/user as mob) - if(istype(user.loc,/turf/space)) - return - new /mob/living/simple_animal/tomato(user.loc) - del(src) - - user << "You plant the killer-tomato." - -/obj/item/weapon/reagent_containers/food/snacks/grown/bloodtomato - name = "blood-tomato" - desc = "So bloody...so...very...bloody....AHHHH!!!!" - icon_state = "bloodtomato" - potency = 10 - filling_color = "#FF0000" - plantname = "bloodtomato" - -/obj/item/weapon/reagent_containers/food/snacks/grown/bloodtomato/throw_impact(atom/hit_atom) - ..() - new/obj/effect/decal/cleanable/blood/splatter(src.loc) - src.visible_message("The [src.name] has been squashed.","You hear a smack.") - src.reagents.reaction(get_turf(hit_atom)) - for(var/atom/A in get_turf(hit_atom)) - src.reagents.reaction(A) - del(src) - return - -/obj/item/weapon/reagent_containers/food/snacks/grown/bluetomato - name = "blue-tomato" - desc = "I say blue-mah-to, you say blue-mae-to." - icon_state = "bluetomato" - potency = 10 - filling_color = "#586CFC" - plantname = "bluetomato" - -/obj/item/weapon/reagent_containers/food/snacks/grown/bluetomato/throw_impact(atom/hit_atom) - ..() - new/obj/effect/decal/cleanable/blood/oil(src.loc) - src.visible_message("The [src.name] has been squashed.","You hear a smack.") - src.reagents.reaction(get_turf(hit_atom)) - for(var/atom/A in get_turf(hit_atom)) - src.reagents.reaction(A) - del(src) - return - -/obj/item/weapon/reagent_containers/food/snacks/grown/bluetomato/Crossed(AM as mob|obj) - if (istype(AM, /mob/living)) - var/mob/living/M = AM - M.slip("the [src]!") - -/obj/item/weapon/reagent_containers/food/snacks/grown/wheat - name = "wheat" - desc = "Sigh... wheat... a-grain?" - gender = PLURAL - icon_state = "wheat" - filling_color = "#F7E186" - plantname = "wheat" - -/obj/item/weapon/reagent_containers/food/snacks/grown/ricestalk - name = "rice stalk" - desc = "Rice to see you." - gender = PLURAL - icon_state = "rice" - filling_color = "#FFF8DB" - plantname = "rice" - -/obj/item/weapon/reagent_containers/food/snacks/grown/kudzupod - name = "kudzu pod" - desc = "Pueraria Virallis: An invasive species with vines that rapidly creep and wrap around whatever they contact." - icon_state = "kudzupod" - filling_color = "#59691B" - plantname = "kudzu" - -/obj/item/weapon/reagent_containers/food/snacks/grown/icepepper - name = "ice-pepper" - desc = "It's a mutant strain of chili" - icon_state = "icepepper" - potency = 20 - filling_color = "#66CEED" - plantname = "icechili" - -/obj/item/weapon/reagent_containers/food/snacks/grown/carrot - name = "carrot" - desc = "It's good for the eyes!" - icon_state = "carrot" - potency = 10 - filling_color = "#FFC400" - plantname = "carrot" - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/reishi - name = "reishi" - desc = "Ganoderma lucidum: A special fungus believed to help relieve stress." - icon_state = "reishi" - potency = 10 - filling_color = "#FF4800" - plantname = "reishi" - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita - name = "fly amanita" - desc = "Amanita Muscaria: Learn poisonous mushrooms by heart. Only pick mushrooms you know." - icon_state = "amanita" - potency = 10 - filling_color = "#FF0000" - plantname = "amanita" - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/angel - name = "destroying angel" - desc = "Amanita Virosa: Deadly poisonous basidiomycete fungus filled with alpha amatoxins." - icon_state = "angel" - potency = 35 - filling_color = "#FFDEDE" - plantname = "destroyingangel" - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap - name = "liberty-cap" - desc = "Psilocybe Semilanceata: Liberate yourself!" - icon_state = "libertycap" - potency = 15 - filling_color = "#F714BE" - plantname = "libertycap" - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet - name = "plump-helmet" - desc = "Plumus Hellmus: Plump, soft and s-so inviting~" - icon_state = "plumphelmet" - filling_color = "#F714BE" - plantname = "plumphelmet" - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/walkingmushroom - name = "walking mushroom" - desc = "Plumus Locomotus: The beginning of the great walk." - icon_state = "walkingmushroom" - filling_color = "#FFBFEF" - potency = 30 - plantname = "walkingmushroom" - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/walkingmushroom/attack_self(mob/user as mob) - if(istype(user.loc,/turf/space)) - return - new /mob/living/simple_animal/mushroom(user.loc) - del(src) - - user << "You plant the walking mushroom." - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/chanterelle - name = "chanterelle cluster" - desc = "Cantharellus Cibarius: These jolly yellow little shrooms sure look tasty!" - icon_state = "chanterelle" - filling_color = "#FFE991" - plantname = "mushrooms" - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom - name = "glowshroom cluster" - desc = "Mycena Bregprox: This species of mushroom glows in the dark. Or does it?" - icon_state = "glowshroom" - filling_color = "#DAFF91" - potency = 30 - plantname = "glowshroom" - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/attack_self(mob/user as mob) - if(istype(user.loc,/turf/space)) - return - var/obj/effect/glowshroom/planted = new /obj/effect/glowshroom(user.loc) - - planted.delay = 50 - planted.endurance = 100 - planted.potency = potency - del(src) - - user << "You plant the glowshroom." - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/Del() - if(istype(loc,/mob)) - loc.SetLuminosity(round(loc.luminosity - potency/10,1)) - ..() - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/pickup(mob/user) - SetLuminosity(0) - user.SetLuminosity(round(user.luminosity + (potency/10),1)) - -/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/glowshroom/dropped(mob/user) - user.SetLuminosity(round(user.luminosity - (potency/10),1)) - SetLuminosity(round(potency/10,1)) - - -// ************************************* -// Complex Grown Object Defines - -// Putting these at the bottom so they don't clutter the list up. -Cheridan -// ************************************* - -/obj/item/weapon/reagent_containers/food/snacks/grown/bluespacetomato - name = "blue-space tomato" - desc = "So lubricated, you might slip through space-time." - icon_state = "bluespacetomato" - potency = 20 - origin_tech = "bluespace=3" - filling_color = "#91F8FF" - plantname = "bluespacetomato" - -/obj/item/weapon/reagent_containers/food/snacks/grown/bluespacetomato/throw_impact(atom/hit_atom) - ..() - var/mob/M = usr - var/outer_teleport_radius = potency/10 //Plant potency determines radius of teleport. - var/inner_teleport_radius = potency/15 - var/list/turfs = new/list() - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - if(inner_teleport_radius < 1) //Wasn't potent enough, it just splats. - new/obj/effect/decal/cleanable/blood/oil(src.loc) - src.visible_message("The [src.name] has been squashed.","You hear a smack.") - del(src) - return - for(var/turf/T in orange(M,outer_teleport_radius)) - if(T in orange(M,inner_teleport_radius)) continue - if(istype(T,/turf/space)) continue - if(T.density) continue - if(T.x>world.maxx-outer_teleport_radius || T.xworld.maxy-outer_teleport_radius || T.yThe [src.name] has been squashed, causing a distortion in space-time.
    ","You hear a splat and a crackle.") - del(src) - return \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/food/snacks/meat.dm b/code/modules/reagents/reagent_containers/food/snacks/meat.dm index efd73c3a4e..d703a6acb7 100644 --- a/code/modules/reagents/reagent_containers/food/snacks/meat.dm +++ b/code/modules/reagents/reagent_containers/food/snacks/meat.dm @@ -6,7 +6,7 @@ filling_color = "#FF1C1C" New() ..() - reagents.add_reagent("nutriment", 3) + reagents.add_reagent("protein", 9) src.bitesize = 3 /obj/item/weapon/reagent_containers/food/snacks/meat/attackby(obj/item/weapon/W as obj, mob/user as mob) diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index 7394c72880..12b56021d4 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -12,13 +12,14 @@ amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,25,30,60) volume = 60 + w_class = 2 flags = OPENCONTAINER var/label_text = "" var/list/can_be_placed_into = list( /obj/machinery/chem_master/, - /obj/machinery/chem_dispenser/, + /obj/machinery/chemical_dispenser, /obj/machinery/reagentgrinder, /obj/structure/table, /obj/structure/closet, @@ -137,7 +138,7 @@ attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/device/flashlight/pen)) - var/tmp_label = sanitize(copytext(input(user, "Enter a label for [src.name]","Label",src.label_text), 1, MAX_NAME_LEN)) + var/tmp_label = sanitizeSafe(input(user, "Enter a label for [src.name]","Label",src.label_text), MAX_NAME_LEN) if(length(tmp_label) > 10) user << "\red The label can be at most 10 characters long." else @@ -194,7 +195,7 @@ if(80 to 90) filling.icon_state = "[icon_state]80" if(91 to INFINITY) filling.icon_state = "[icon_state]100" - filling.icon += mix_color_from_reagents(reagents.reagent_list) + filling.color = mix_color_from_reagents(reagents.reagent_list) overlays += filling if (!is_open_container()) @@ -253,12 +254,6 @@ reagents.add_reagent("sacid", 60) update_icon() -/obj/item/weapon/reagent_containers/glass/beaker/slime - New() - ..() - reagents.add_reagent("slimejelly", 60) - update_icon() - /obj/item/weapon/reagent_containers/glass/bucket desc = "It's a bucket." name = "bucket" diff --git a/code/modules/reagents/reagent_containers/glass/bottle.dm b/code/modules/reagents/reagent_containers/glass/bottle.dm index 44afd28407..ab01d11eaf 100644 --- a/code/modules/reagents/reagent_containers/glass/bottle.dm +++ b/code/modules/reagents/reagent_containers/glass/bottle.dm @@ -9,7 +9,7 @@ item_state = "atoxinbottle" amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,25,30,60) - flags = OPENCONTAINER + flags = 0 volume = 60 on_reagent_change() @@ -30,7 +30,7 @@ New() ..() if(!icon_state) - icon_state = "bottle-[rand(1.4)]" + icon_state = "bottle-[rand(1,4)]" update_icon() overlays.Cut() @@ -48,7 +48,7 @@ if(80 to 90) filling.icon_state = "[icon_state]-80" if(91 to INFINITY) filling.icon_state = "[icon_state]-100" - filling.icon += mix_color_from_reagents(reagents.reagent_list) + filling.color = mix_color_from_reagents(reagents.reagent_list) overlays += filling if (!is_open_container()) @@ -59,186 +59,203 @@ name = "inaprovaline bottle" desc = "A small bottle. Contains inaprovaline - used to stabilize patients." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" + icon_state = "bottle-4" New() ..() reagents.add_reagent("inaprovaline", 60) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/toxin name = "toxin bottle" desc = "A small bottle of toxins. Do not drink, it is poisonous." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle12" + icon_state = "bottle-3" New() ..() reagents.add_reagent("toxin", 60) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/cyanide name = "cyanide bottle" desc = "A small bottle of cyanide. Bitter almonds?" icon = 'icons/obj/chemical.dmi' - icon_state = "bottle12" + icon_state = "bottle-3" New() ..() - reagents.add_reagent("cyanide", 60) + reagents.add_reagent("cyanide", 30) //volume changed to match chloral + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/stoxin name = "soporific bottle" desc = "A small bottle of soporific. Just the fumes make you sleepy." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle20" + icon_state = "bottle-3" New() ..() reagents.add_reagent("stoxin", 60) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/chloralhydrate name = "Chloral Hydrate Bottle" desc = "A small bottle of Choral Hydrate. Mickey's Favorite!" icon = 'icons/obj/chemical.dmi' - icon_state = "bottle20" + icon_state = "bottle-3" New() ..() reagents.add_reagent("chloralhydrate", 30) //Intentionally low since it is so strong. Still enough to knock someone out. + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/antitoxin name = "dylovene bottle" desc = "A small bottle of dylovene. Counters poisons, and repairs damage. A wonder drug." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle17" + icon_state = "bottle-4" New() ..() reagents.add_reagent("anti_toxin", 60) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/mutagen name = "unstable mutagen bottle" desc = "A small bottle of unstable mutagen. Randomly changes the DNA structure of whoever comes in contact." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle20" + icon_state = "bottle-1" New() ..() reagents.add_reagent("mutagen", 60) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/ammonia name = "ammonia bottle" desc = "A small bottle." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle20" + icon_state = "bottle-1" New() ..() reagents.add_reagent("ammonia", 60) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/diethylamine name = "diethylamine bottle" desc = "A small bottle." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle17" + icon_state = "bottle-4" New() ..() reagents.add_reagent("diethylamine", 60) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/flu_virion name = "Flu virion culture bottle" desc = "A small bottle. Contains H13N1 flu virion culture in synthblood medium." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" New() ..() var/datum/disease/F = new /datum/disease/advance/flu(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/epiglottis_virion name = "Epiglottis virion culture bottle" desc = "A small bottle. Contains Epiglottis virion culture in synthblood medium." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" New() ..() var/datum/disease/F = new /datum/disease/advance/voice_change(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/liver_enhance_virion name = "Liver enhancement virion culture bottle" desc = "A small bottle. Contains liver enhancement virion culture in synthblood medium." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" New() ..() var/datum/disease/F = new /datum/disease/advance/heal(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/hullucigen_virion name = "Hullucigen virion culture bottle" desc = "A small bottle. Contains hullucigen virion culture in synthblood medium." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" New() ..() var/datum/disease/F = new /datum/disease/advance/hullucigen(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/pierrot_throat name = "Pierrot's Throat culture bottle" desc = "A small bottle. Contains H0NI<42 virion culture in synthblood medium." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" New() ..() var/datum/disease/F = new /datum/disease/pierrot_throat(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/cold name = "Rhinovirus culture bottle" desc = "A small bottle. Contains XY-rhinovirus culture in synthblood medium." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" New() ..() var/datum/disease/advance/F = new /datum/disease/advance/cold(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/random name = "Random culture bottle" desc = "A small bottle. Contains a random disease." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" New() ..() var/datum/disease/advance/F = new(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/retrovirus name = "Retrovirus culture bottle" desc = "A small bottle. Contains a retrovirus culture in a synthblood medium." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" New() ..() var/datum/disease/F = new /datum/disease/dna_retrovirus(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/gbs name = "GBS culture bottle" desc = "A small bottle. Contains Gravitokinetic Bipotential SADS+ culture in synthblood medium."//Or simply - General BullShit icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" amount_per_transfer_from_this = 5 New() @@ -248,23 +265,25 @@ var/datum/disease/F = new /datum/disease/gbs var/list/data = list("virus"= F) R.add_reagent("blood", 20, data) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/fake_gbs name = "GBS culture bottle" desc = "A small bottle. Contains Gravitokinetic Bipotential SADS- culture in synthblood medium."//Or simply - General BullShit icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" New() ..() var/datum/disease/F = new /datum/disease/fake_gbs(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /* /obj/item/weapon/reagent_containers/glass/bottle/rhumba_beat name = "Rhumba Beat culture bottle" desc = "A small bottle. Contains The Rhumba Beat culture in synthblood medium."//Or simply - General BullShit icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" amount_per_transfer_from_this = 5 New() @@ -280,44 +299,48 @@ name = "Brainrot culture bottle" desc = "A small bottle. Contains Cryptococcus Cosmosis culture in synthblood medium." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" New() ..() var/datum/disease/F = new /datum/disease/brainrot(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/magnitis name = "Magnitis culture bottle" desc = "A small bottle. Contains a small dosage of Fukkos Miracos." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" New() ..() var/datum/disease/F = new /datum/disease/magnitis(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/wizarditis name = "Wizarditis culture bottle" desc = "A small bottle. Contains a sample of Rincewindus Vulgaris." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" New() ..() var/datum/disease/F = new /datum/disease/wizarditis(0) var/list/data = list("viruses"= list(F)) reagents.add_reagent("blood", 20, data) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/pacid name = "Polytrinic Acid Bottle" desc = "A small bottle. Contains a small amount of Polytrinic Acid" icon = 'icons/obj/chemical.dmi' - icon_state = "bottle17" + icon_state = "bottle-4" New() ..() reagents.add_reagent("pacid", 60) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/adminordrazine name = "Adminordrazine Bottle" @@ -327,21 +350,24 @@ New() ..() reagents.add_reagent("adminordrazine", 60) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/capsaicin name = "Capsaicin Bottle" desc = "A small bottle. Contains hot sauce." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle3" + icon_state = "bottle-4" New() ..() reagents.add_reagent("capsaicin", 60) + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/frostoil name = "Frost Oil Bottle" desc = "A small bottle. Contains cold sauce." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle17" + icon_state = "bottle-4" New() ..() - reagents.add_reagent("frostoil", 60) \ No newline at end of file + reagents.add_reagent("frostoil", 60) + update_icon() diff --git a/code/modules/reagents/reagent_containers/glass/bottle/robot.dm b/code/modules/reagents/reagent_containers/glass/bottle/robot.dm index 7c8bf02a5b..3a95b3cd1c 100644 --- a/code/modules/reagents/reagent_containers/glass/bottle/robot.dm +++ b/code/modules/reagents/reagent_containers/glass/bottle/robot.dm @@ -11,23 +11,24 @@ name = "internal inaprovaline bottle" desc = "A small bottle. Contains inaprovaline - used to stabilize patients." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle16" + icon_state = "bottle-4" reagent = "inaprovaline" New() ..() reagents.add_reagent("inaprovaline", 60) - return + update_icon() /obj/item/weapon/reagent_containers/glass/bottle/robot/antitoxin name = "internal anti-toxin bottle" desc = "A small bottle of Anti-toxins. Counters poisons, and repairs damage, a wonder drug." icon = 'icons/obj/chemical.dmi' - icon_state = "bottle17" + icon_state = "bottle-4" reagent = "anti_toxin" New() ..() reagents.add_reagent("anti_toxin", 60) - return \ No newline at end of file + update_icon() + diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 34ce53a2b6..4d23bb30ed 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -190,6 +190,38 @@ ..() reagents.add_reagent("dexalin", 15) +/obj/item/weapon/reagent_containers/pill/dexalin_plus + name = "Dexalin Plus pill" + desc = "Used to treat extreme oxygen deprivation." + icon_state = "pill8" + New() + ..() + reagents.add_reagent("dexalinp", 15) + +/obj/item/weapon/reagent_containers/pill/dermaline + name = "Dermaline pill" + desc = "Used to treat burn wounds." + icon_state = "pill12" + New() + ..() + reagents.add_reagent("dermaline", 15) + +/obj/item/weapon/reagent_containers/pill/dylovene + name = "Dylovene pill" + desc = "A broad-spectrum anti-toxin." + icon_state = "pill13" + New() + ..() + reagents.add_reagent("anti_toxin", 15) + +/obj/item/weapon/reagent_containers/pill/inaprovaline + name = "Inaprovaline pill" + desc = "Used to stabilize patients." + icon_state = "pill20" + New() + ..() + reagents.add_reagent("inaprovaline", 30) + /obj/item/weapon/reagent_containers/pill/bicaridine name = "Bicaridine pill" desc = "Used to treat physical injuries." @@ -216,3 +248,11 @@ reagents.add_reagent("impedrezene", 10) reagents.add_reagent("synaptizine", 5) reagents.add_reagent("hyperzine", 5) + +/obj/item/weapon/reagent_containers/pill/spaceacillin + name = "Spaceacillin pill" + desc = "Contains antiviral agents." + icon_state = "pill19" + New() + ..() + reagents.add_reagent("spaceacillin", 15) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 91dbebc27c..1a25162526 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -21,7 +21,7 @@ ..() src.verbs -= /obj/item/weapon/reagent_containers/verb/set_APTFT -/obj/item/weapon/reagent_containers/spray/afterattack(atom/A as mob|obj, mob/user as mob) +/obj/item/weapon/reagent_containers/spray/afterattack(atom/A as mob|obj, mob/user as mob, proximity) if(istype(A, /obj/item/weapon/storage) || istype(A, /obj/structure/table) || istype(A, /obj/structure/closet) \ || istype(A, /obj/item/weapon/reagent_containers) || istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart)) return @@ -46,7 +46,7 @@ user << "\The [src] is empty!" return - Spray_at(A) + Spray_at(A, user, proximity) playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6) @@ -61,28 +61,39 @@ log_game("[key_name(user)] fired Space lube from \a [src].") return -/obj/item/weapon/reagent_containers/spray/proc/Spray_at(atom/A as mob|obj) - var/obj/effect/decal/chempuff/D = new/obj/effect/decal/chempuff(get_turf(src)) - D.create_reagents(amount_per_transfer_from_this) - reagents.trans_to(D, amount_per_transfer_from_this, 1/spray_size) - D.icon += mix_color_from_reagents(D.reagents.reagent_list) +/obj/item/weapon/reagent_containers/spray/proc/Spray_at(atom/A as mob|obj, mob/user as mob, proximity) + if (A.density && proximity) + A.visible_message("[usr] sprays [A] with [src].") + var/obj/D = new/obj() + D.create_reagents(amount_per_transfer_from_this) + reagents.trans_to(D, amount_per_transfer_from_this) + D.icon += mix_color_from_reagents(D.reagents.reagent_list) + spawn(0) + D.reagents.reaction(A) + sleep(5) + del(D) + else + var/obj/effect/decal/chempuff/D = new/obj/effect/decal/chempuff(get_turf(src)) + D.create_reagents(amount_per_transfer_from_this) + reagents.trans_to(D, amount_per_transfer_from_this, 1/spray_size) + D.icon += mix_color_from_reagents(D.reagents.reagent_list) - var/turf/A_turf = get_turf(A)//BS12 + var/turf/A_turf = get_turf(A)//BS12 - spawn(0) - for(var/i=0, i= target.reagents.maximum_volume) @@ -217,15 +218,15 @@ item_state = "syringe_[rounded_vol]" if(reagents.total_volume) - var/image/filling = image('icons/obj/reagentfillings.dmi', src, "syringe10") + filling = image('icons/obj/reagentfillings.dmi', src, "syringe10") filling.icon_state = "syringe[rounded_vol]" - filling.icon += mix_color_from_reagents(reagents.reagent_list) + filling.color = mix_color_from_reagents(reagents.reagent_list) overlays += filling - /obj/item/weapon/reagent_containers/syringe/proc/syringestab(mob/living/carbon/target as mob, mob/living/carbon/user as mob) + proc/syringestab(mob/living/carbon/target as mob, mob/living/carbon/user as mob) user.attack_log += "\[[time_stamp()]\] Attacked [target.name] ([target.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])" target.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])" @@ -268,13 +269,19 @@ src.reagents.reaction(target, INGEST) var/syringestab_amount_transferred = rand(0, (reagents.total_volume - 5)) //nerfed by popular demand src.reagents.trans_to(target, syringestab_amount_transferred) + src.break_syringe(target, user) + + proc/break_syringe(mob/living/carbon/target, mob/living/carbon/user) src.desc += " It is broken." src.mode = SYRINGE_BROKEN - src.add_blood(target) - src.add_fingerprint(usr) + if(target) + src.add_blood(target) + if(user) + src.add_fingerprint(user) src.update_icon() + /obj/item/weapon/reagent_containers/ld50_syringe name = "Lethal Injection Syringe" desc = "A syringe used for lethal injections." diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 0156625886..0a42e8dee3 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -146,7 +146,7 @@ /obj/structure/reagent_dispensers/fueltank/bullet_act(var/obj/item/projectile/Proj) - if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet)) + if(Proj.damage_type == BRUTE || Proj.damage_type == BURN) if(istype(Proj.firer)) message_admins("[key_name_admin(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) (JMP).") log_game("[key_name(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]).") @@ -238,3 +238,15 @@ New() ..() reagents.add_reagent("virusfood", 1000) + +/obj/structure/reagent_dispensers/acid + name = "Sulphuric Acid Dispenser" + desc = "A dispenser of acid for industrial processes." + icon = 'icons/obj/objects.dmi' + icon_state = "acidtank" + amount_per_transfer_from_this = 10 + anchored = 1 + + New() + ..() + reagents.add_reagent("sacid", 1000) diff --git a/code/modules/reagents/syringe_gun.dm b/code/modules/reagents/syringe_gun.dm deleted file mode 100644 index faecb79868..0000000000 --- a/code/modules/reagents/syringe_gun.dm +++ /dev/null @@ -1,137 +0,0 @@ - - - -/obj/item/weapon/gun/syringe - name = "syringe gun" - desc = "A spring loaded rifle designed to fit syringes, designed to incapacitate unruly patients from a distance." - icon = 'icons/obj/gun.dmi' - icon_state = "syringegun" - item_state = "syringegun" - w_class = 3.0 - throw_speed = 2 - throw_range = 10 - force = 4.0 - var/list/syringes = new/list() - var/max_syringes = 1 - matter = list("metal" = 2000) - -/obj/item/weapon/gun/syringe/examine(mob/user) - if(..(user, 2)) - user << "\blue [syringes.len] / [max_syringes] syringes." - -/obj/item/weapon/gun/syringe/attackby(obj/item/I as obj, mob/user as mob) - if(istype(I, /obj/item/weapon/reagent_containers/syringe)) - var/obj/item/weapon/reagent_containers/syringe/S = I - if(S.mode != 2)//SYRINGE_BROKEN in syringes.dm - if(syringes.len < max_syringes) - user.drop_item() - I.loc = src - syringes += I - user << "\blue You put the syringe in [src]." - user << "\blue [syringes.len] / [max_syringes] syringes." - else - usr << "\red [src] cannot hold more syringes." - else - usr << "\red This syringe is broken!" - - -/obj/item/weapon/gun/syringe/afterattack(obj/target, mob/user , flag) - if(!isturf(target.loc) || target == user) return - ..() - -/obj/item/weapon/gun/syringe/can_fire() - return syringes.len - -/obj/item/weapon/gun/syringe/can_hit(var/mob/living/target as mob, var/mob/living/user as mob) - return 1 //SHOOT AND LET THE GOD GUIDE IT (probably will hit a wall anyway) - -/obj/item/weapon/gun/syringe/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) - if(syringes.len) - spawn(0) fire_syringe(target,user) - else - usr << "\red [src] is empty." - -/obj/item/weapon/gun/syringe/proc/fire_syringe(atom/target, mob/user) - if (locate (/obj/structure/table, src.loc)) - return - else - var/turf/trg = get_turf(target) - var/obj/effect/syringe_gun_dummy/D = new/obj/effect/syringe_gun_dummy(get_turf(src)) - var/obj/item/weapon/reagent_containers/syringe/S = syringes[1] - if((!S) || (!S.reagents)) //ho boy! wot runtimes! - return - S.reagents.trans_to(D, S.reagents.total_volume) - syringes -= S - del(S) - D.icon_state = "syringeproj" - D.name = "syringe" - playsound(user.loc, 'sound/items/syringeproj.ogg', 50, 1) - - for(var/i=0, i<6, i++) - if(!D) break - if(D.loc == trg) break - step_towards(D,trg) - - if(D) - for(var/mob/living/carbon/M in D.loc) - if(!istype(M,/mob/living/carbon)) continue - if(M == user) continue - //Syringe gun attack logging by Yvarov - var/R - if(D.reagents) - for(var/datum/reagent/A in D.reagents.reagent_list) - R += A.id + " (" - R += num2text(A.volume) + ")," - if (istype(M, /mob)) - M.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] shot [M]/[M.ckey] with a syringegun ([R])" - user.attack_log += "\[[time_stamp()]\] [user]/[user.ckey] shot [M]/[M.ckey] with a syringegun ([R])" - msg_admin_attack("[user] ([user.ckey]) shot [M] ([M.ckey]) with a syringegun ([R]) (JMP)") - - else - M.attack_log += "\[[time_stamp()]\] UNKNOWN SUBJECT (No longer exists) shot [M]/[M.ckey] with a syringegun ([R])" - msg_admin_attack("UNKNOWN shot [M] ([M.ckey]) with a syringegun ([R]) (JMP)") - - var/mob/living/T - if(istype(M,/mob/living)) - T = M - - M.visible_message("[M] is hit by the syringe!") - - if(T && istype(T) && T.can_inject()) - if(D.reagents) - D.reagents.trans_to(M, 15) - else - M.visible_message("The syringe bounces off [M]!") - - del(D) - break - if(D) - for(var/atom/A in D.loc) - if(A == user) continue - if(A.density) del(D) - - sleep(1) - - if (D) spawn(10) del(D) - - return - -/obj/item/weapon/gun/syringe/rapidsyringe - name = "rapid syringe gun" - desc = "A modification of the syringe gun design, using a rotating cylinder to store up to four syringes." - icon_state = "rapidsyringegun" - max_syringes = 4 - - -/obj/effect/syringe_gun_dummy - name = "" - desc = "" - icon = 'icons/obj/chemical.dmi' - icon_state = "null" - anchored = 1 - density = 0 - - New() - var/datum/reagents/R = new/datum/reagents(15) - reagents = R - R.my_atom = src \ No newline at end of file diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 34dbe0998f..e1a5407d0a 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -5,9 +5,9 @@ // Automatically recharges air (unless off), will flush when ready if pre-set // Can hold items and human size things, no other draggables // Toilets are a type of disposal bin for small objects only and work on magic. By magic, I mean torque rotation -#define SEND_PRESSURE 50 //kPa +#define SEND_PRESSURE 50 + ONE_ATMOSPHERE //kPa - assume the inside of a dispoal pipe is 1 atm #define PRESSURE_TANK_VOLUME 70 //L - a 0.3 m diameter * 1 m long cylindrical tank. Happens to be the same volume as the regular oxygen tanks, so seems appropriate. -#define PUMP_MAX_FLOW_RATE 50 //L/s - 8 m/s using a 15 cm by 15 cm inlet +#define PUMP_MAX_FLOW_RATE 100 //L/s - 4 m/s using a 15 cm by 15 cm inlet /obj/machinery/disposal name = "disposal unit" diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 5b375ed8f7..7a7622dd77 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -43,7 +43,7 @@ else if(istype(W, /obj/item/weapon/pen)) switch(alert("What would you like to alter?",,"Title","Description", "Cancel")) if("Title") - var/str = trim(sanitize(copytext(input(usr,"Label text?","Set label",""),1,MAX_NAME_LEN))) + var/str = sanitizeSafe(input(usr,"Label text?","Set label",""), MAX_NAME_LEN) if(!str || !length(str)) usr << " Invalid text." return @@ -57,7 +57,7 @@ else nameset = 1 if("Description") - var/str = trim(sanitize(copytext(input(usr,"Label text?","Set label",""),1,MAX_MESSAGE_LEN))) + var/str = sanitize(input(usr,"Label text?","Set label","")) if(!str || !length(str)) usr << "\red Invalid text." return @@ -150,7 +150,7 @@ else if(istype(W, /obj/item/weapon/pen)) switch(alert("What would you like to alter?",,"Title","Description", "Cancel")) if("Title") - var/str = trim(sanitize(copytext(input(usr,"Label text?","Set label",""),1,MAX_NAME_LEN))) + var/str = sanitizeSafe(input(usr,"Label text?","Set label",""), MAX_NAME_LEN) if(!str || !length(str)) usr << " Invalid text." return @@ -165,7 +165,7 @@ nameset = 1 if("Description") - var/str = trim(sanitize(copytext(input(usr,"Label text?","Set label",""),1,MAX_MESSAGE_LEN))) + var/str = sanitize(input(usr,"Label text?","Set label","")) if(!str || !length(str)) usr << "\red Invalid text." return diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index e64504cf51..a16e5653a9 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -14,138 +14,136 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). var/diamond_amount = 0 var/uranium_amount = 0 var/max_material_amount = 75000.0 + var/mat_efficiency = 1 use_power = 1 idle_power_usage = 30 active_power_usage = 2500 - New() - ..() - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/circuit_imprinter(src) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) - component_parts += new /obj/item/weapon/stock_parts/manipulator(src) - component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src) - component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src) - RefreshParts() - +/obj/machinery/r_n_d/circuit_imprinter/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/circuit_imprinter(src) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src) + component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src) RefreshParts() - var/T = 0 - for(var/obj/item/weapon/reagent_containers/glass/G in component_parts) - T += G.reagents.maximum_volume - var/datum/reagents/R = new/datum/reagents(T) //Holder for the reagents used as materials. - reagents = R - R.my_atom = src - T = 0 - for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) - T += M.rating - max_material_amount = T * 75000.0 +/obj/machinery/r_n_d/circuit_imprinter/RefreshParts() + var/T = 0 + for(var/obj/item/weapon/reagent_containers/glass/G in component_parts) + T += G.reagents.maximum_volume + var/datum/reagents/R = new/datum/reagents(T) //Holder for the reagents used as materials. + reagents = R + R.my_atom = src + T = 0 + for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) + T += M.rating + max_material_amount = T * 75000.0 + T = 0 + for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + T += M.rating + mat_efficiency = 1 - (T - 1) / 4 - blob_act() - if (prob(50)) - del(src) +/obj/machinery/r_n_d/circuit_imprinter/update_icon() + if(panel_open) + icon_state = "circuit_imprinter_t" + else + icon_state = "circuit_imprinter" - meteorhit() +/obj/machinery/r_n_d/circuit_imprinter/blob_act() + if(prob(50)) del(src) + +/obj/machinery/r_n_d/circuit_imprinter/meteorhit() + del(src) + return + +/obj/machinery/r_n_d/circuit_imprinter/proc/TotalMaterials() + return g_amount + gold_amount + diamond_amount + uranium_amount + +/obj/machinery/r_n_d/circuit_imprinter/dismantle() + for(var/obj/I in component_parts) + if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker)) + reagents.trans_to(I, reagents.total_volume) + if(g_amount >= 3750) + var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(loc) + G.amount = round(g_amount / 3750) + if(gold_amount >= 2000) + var/obj/item/stack/sheet/mineral/gold/G = new /obj/item/stack/sheet/mineral/gold(loc) + G.amount = round(gold_amount / 2000) + if(diamond_amount >= 2000) + var/obj/item/stack/sheet/mineral/diamond/G = new /obj/item/stack/sheet/mineral/diamond(loc) + G.amount = round(diamond_amount / 2000) + if(uranium_amount >= 2000) + var/obj/item/stack/sheet/mineral/uranium/G = new /obj/item/stack/sheet/mineral/uranium(loc) + G.amount = round(uranium_amount / 2000) + ..() + +/obj/machinery/r_n_d/circuit_imprinter/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(shocked) + shock(user, 50) + if(default_deconstruction_screwdriver(user, O)) + if(linked_console) + linked_console.linked_imprinter = null + linked_console = null return + if(default_deconstruction_crowbar(user, O)) + return + if(default_part_replacement(user, O)) + return + if(panel_open) + user << "You can't load \the [src] while it's opened." + return 1 + if(disabled) + user << "\The [src] appears to not be working!" + return + if(!linked_console) + user << "\The [src] must be linked to an R&D console first!" + return 1 + if(O.is_open_container()) + return 0 + if(!istype(O, /obj/item/stack/sheet/glass) && !istype(O, /obj/item/stack/sheet/mineral/gold) && !istype(O, /obj/item/stack/sheet/mineral/diamond) && !istype(O, /obj/item/stack/sheet/mineral/uranium)) + user << "You cannot insert this item into \the [src]!" + return 1 + if(stat) + return 1 + if(busy) + user << "\The [src] is busy. Please wait for completion of previous operation." + return 1 + var/obj/item/stack/sheet/stack = O + if((TotalMaterials() + stack.perunit) > max_material_amount) + user << "\The [src] is full. Please remove glass from \the [src] in order to insert more." + return 1 - proc/TotalMaterials() - return g_amount + gold_amount + diamond_amount + uranium_amount + var/amount = round(input("How many sheets do you want to add?") as num) + if(amount < 0) + amount = 0 + if(amount == 0) + return + if(amount > stack.amount) + amount = min(stack.amount, round((max_material_amount - TotalMaterials()) / stack.perunit)) - attackby(var/obj/item/O as obj, var/mob/user as mob) - if (shocked) - shock(user,50) - if (istype(O, /obj/item/weapon/screwdriver)) - if (!opened) - opened = 1 - if(linked_console) - linked_console.linked_imprinter = null - linked_console = null - icon_state = "circuit_imprinter_t" - user << "You open the maintenance hatch of [src]." - else - opened = 0 - icon_state = "circuit_imprinter" - user << "You close the maintenance hatch of [src]." - return - if (opened) - if(istype(O, /obj/item/weapon/crowbar)) - playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) - var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc) - M.state = 2 - M.icon_state = "box_1" - for(var/obj/I in component_parts) - if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker)) - reagents.trans_to(I, reagents.total_volume) - if(I.reliability != 100 && crit_fail) - I.crit_fail = 1 - I.loc = src.loc - if(g_amount >= 3750) - var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src.loc) - G.amount = round(g_amount / 3750) - if(gold_amount >= 2000) - var/obj/item/stack/sheet/mineral/gold/G = new /obj/item/stack/sheet/mineral/gold(src.loc) - G.amount = round(gold_amount / 2000) - if(diamond_amount >= 2000) - var/obj/item/stack/sheet/mineral/diamond/G = new /obj/item/stack/sheet/mineral/diamond(src.loc) - G.amount = round(diamond_amount / 2000) - if(uranium_amount >= 2000) - var/obj/item/stack/sheet/mineral/uranium/G = new /obj/item/stack/sheet/mineral/uranium(src.loc) - G.amount = round(uranium_amount / 2000) - del(src) - return 1 - else - user << "\red You can't load the [src.name] while it's opened." - return 1 - if (disabled) - user << "\The [name] appears to not be working!" - return - if (!linked_console) - user << "\The [name] must be linked to an R&D console first!" - return 1 - if (O.is_open_container()) - return 0 - if (!istype(O, /obj/item/stack/sheet/glass) && !istype(O, /obj/item/stack/sheet/mineral/gold) && !istype(O, /obj/item/stack/sheet/mineral/diamond) && !istype(O, /obj/item/stack/sheet/mineral/uranium)) - user << "\red You cannot insert this item into the [name]!" - return 1 - if (stat) - return 1 - if (busy) - user << "\red The [name] is busy. Please wait for completion of previous operation." - return 1 - var/obj/item/stack/sheet/stack = O - if ((TotalMaterials() + stack.perunit) > max_material_amount) - user << "\red The [name] is full. Please remove glass from the protolathe in order to insert more." - return 1 - - var/amount = round(input("How many sheets do you want to add?") as num) - if(amount < 0) - amount = 0 - if(amount == 0) - return - if(amount > stack.amount) - amount = min(stack.amount, round((max_material_amount-TotalMaterials())/stack.perunit)) - - busy = 1 - use_power(max(1000, (3750*amount/10))) - var/stacktype = stack.type - stack.use(amount) - if(do_after(usr,16)) - user << "\blue You add [amount] sheets to the [src.name]." - switch(stacktype) - if(/obj/item/stack/sheet/glass) - g_amount += amount * 3750 - if(/obj/item/stack/sheet/mineral/gold) - gold_amount += amount * 2000 - if(/obj/item/stack/sheet/mineral/diamond) - diamond_amount += amount * 2000 - if(/obj/item/stack/sheet/mineral/uranium) - uranium_amount += amount * 2000 - else - new stacktype(src.loc, amount) - busy = 0 - src.updateUsrDialog() + busy = 1 + use_power(max(1000, (3750 * amount / 10))) + var/stacktype = stack.type + stack.use(amount) + if(do_after(usr, 16)) + user << "You add [amount] sheets to \the [src]." + switch(stacktype) + if(/obj/item/stack/sheet/glass) + g_amount += amount * 3750 + if(/obj/item/stack/sheet/mineral/gold) + gold_amount += amount * 2000 + if(/obj/item/stack/sheet/mineral/diamond) + diamond_amount += amount * 2000 + if(/obj/item/stack/sheet/mineral/uranium) + uranium_amount += amount * 2000 + else + new stacktype(loc, amount) + busy = 0 + updateUsrDialog() //This is to stop these machines being hackable via clicking. /obj/machinery/r_n_d/circuit_imprinter/attack_hand(mob/user as mob) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 40de21081d..86eb5cce55 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -358,7 +358,7 @@ datum/design/aimodule/safeguard build_path = /obj/item/weapon/aiModule/safeguard datum/design/aimodule/onehuman - name = "OneHuman" + name = "OneCrewMember" id = "onehuman" req_tech = list("programming" = 4, "materials" = 6) build_path = /obj/item/weapon/aiModule/oneHuman @@ -451,7 +451,7 @@ datum/design/circuit/tcom/server name = "server mainframe" id = "tcom-server" build_path = /obj/item/weapon/circuitboard/telecomms/server - + datum/design/circuit/tcom/processor name = "processor unit" id = "tcom-processor" @@ -760,6 +760,14 @@ datum/design/item/stock_part/AssembleDesignDesc() if(!desc) desc = "A stock part used in the construction of various devices." +/datum/design/item/stock_part/RPED + name = "Rapid Part Exchange Device" + desc = "Special mechanical module made to store, sort, and apply standard machine parts." + id = "rped" + req_tech = list("engineering" = 3, "materials" = 3) + materials = list("$metal" = 15000, "$glass" = 5000) + build_path = /obj/item/weapon/storage/part_replacer + datum/design/item/stock_part/basic_capacitor build_type = PROTOLATHE | AUTOLATHE id = "basic_capacitor" @@ -971,6 +979,18 @@ datum/design/circuit/secure_airlock req_tech = list("programming" = 3) build_path = /obj/item/weapon/airlock_electronics/secure +datum/design/circuit/biogenerator + name = "biogenerator" + id = "biogenerator" + req_tech = list("programming" = 2) + build_path = /obj/item/weapon/circuitboard/biogenerator + +datum/design/circuit/recharge_station + name = "cyborg recharge station" + id = "recharge_station" + req_tech = list("programming" = 3, "engineering" = 2) + build_path = /obj/item/weapon/circuitboard/recharge_station + ///////////////////////////////////////// ////////Power Stuff Circuitboards//////// ///////////////////////////////////////// @@ -1292,7 +1312,7 @@ datum/design/item/weapon/rapidsyringe id = "rapidsyringe" req_tech = list("combat" = 3, "materials" = 3, "engineering" = 3, "biotech" = 2) materials = list("$metal" = 5000, "$glass" = 1000) - build_path = /obj/item/weapon/gun/syringe/rapidsyringe + build_path = /obj/item/weapon/gun/launcher/syringe/rapid /* datum/design/item/weapon/largecrossbow name = "Energy Crossbow" @@ -1547,7 +1567,7 @@ datum/design/item/mesons req_tech = list("magnets" = 2, "engineering" = 2) materials = list("$metal" = 50, "$glass" = 50) build_path = /obj/item/clothing/glasses/meson - + datum/design/item/binaryencrypt name = "Binary encryption key" desc = "Allows for deciphering the binary channel on-the-fly." diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index aef24dd8be..7b7445f099 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -12,6 +12,7 @@ Note: Must be placed within 3 tiles of the R&D Console icon_state = "d_analyzer" var/obj/item/weapon/loaded_item = null var/decon_mod = 1 + var/min_reliability = 90 use_power = 1 idle_power_usage = 30 @@ -29,9 +30,9 @@ Note: Must be placed within 3 tiles of the R&D Console /obj/machinery/r_n_d/destructive_analyzer/RefreshParts() var/T = 0 for(var/obj/item/weapon/stock_parts/S in src) - T += S.rating * 0.1 - T = between (0, T, 1) - decon_mod = T + T += S.rating + decon_mod = T * 0.1 + min_reliability = 93 - T /obj/machinery/r_n_d/destructive_analyzer/meteorhit() del(src) @@ -43,65 +44,58 @@ Note: Must be placed within 3 tiles of the R&D Console temp_list[O] = text2num(temp_list[O]) return temp_list +/obj/machinery/r_n_d/destructive_analyzer/update_icon() + if(panel_open) + icon_state = "d_analyzer_t" + else if(loaded_item) + icon_state = "d_analyzer_l" + else + icon_state = "d_analyzer" /obj/machinery/r_n_d/destructive_analyzer/attackby(var/obj/O as obj, var/mob/user as mob) - if (shocked) - shock(user,50) - if (istype(O, /obj/item/weapon/screwdriver)) - if (!opened) - opened = 1 - if(linked_console) - linked_console.linked_destroy = null - linked_console = null - icon_state = "d_analyzer_t" - user << "You open the maintenance hatch of [src]." - else - opened = 0 - icon_state = "d_analyzer" - user << "You close the maintenance hatch of [src]." + if(shocked) + shock(user, 50) + if(default_deconstruction_screwdriver(user, O)) + if(linked_console) + linked_console.linked_destroy = null + linked_console = null return - if (opened) - if(istype(O, /obj/item/weapon/crowbar)) - playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) - var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc) - M.state = 2 - M.icon_state = "box_1" - for(var/obj/I in component_parts) - I.loc = src.loc - del(src) - return 1 - else - user << "\red You can't load the [src.name] while it's opened." - return 1 - if (disabled) + if(default_deconstruction_crowbar(user, O)) return - if (!linked_console) - user << "\red The destructive analyzer must be linked to an R&D console first!" + if(default_part_replacement(user, O)) return - if (busy) - user << "\red The destructive analyzer is busy right now." + if(panel_open) + user << "You can't load \the [src] while it's opened." + return 1 + if(disabled) return - if (istype(O, /obj/item) && !loaded_item) + if(!linked_console) + user << "\The [src] must be linked to an R&D console first!" + return + if(busy) + user << "\The [src] is busy right now." + return + if(istype(O, /obj/item) && !loaded_item) if(isrobot(user)) //Don't put your module items in there! return if(!O.origin_tech) - user << "\red This doesn't seem to have a tech origin!" + user << "This doesn't seem to have a tech origin!" return var/list/temp_tech = ConvertReqString2List(O.origin_tech) - if (temp_tech.len == 0) - user << "\red You cannot deconstruct this item!" + if(temp_tech.len == 0) + user << "You cannot deconstruct this item!" return - if(O.reliability < 90 && O.crit_fail == 0) - usr << "\red Item is neither reliable enough nor broken enough to learn from." + if(O.reliability < min_reliability && O.crit_fail == 0) + usr << "Item is neither reliable enough nor broken enough to learn from." return busy = 1 loaded_item = O user.drop_item() O.loc = src - user << "\blue You add the [O.name] to the machine!" + user << "You add \the [O] to \the [src]!" flick("d_analyzer_la", src) spawn(10) - icon_state = "d_analyzer_l" + update_icon() busy = 0 return 1 return diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index f23176de96..22df4b82dd 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -25,6 +25,8 @@ Note: Must be placed west/left of and R&D console to function. var/uranium_amount = 0.0 var/diamond_amount = 0.0 + var/mat_efficiency = 1 + /obj/machinery/r_n_d/protolathe/New() ..() component_parts = list() @@ -51,80 +53,78 @@ Note: Must be placed west/left of and R&D console to function. for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) T += M.rating max_material_storage = T * 75000 + T = 0 + for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + T += M.rating + mat_efficiency = 1 - (T - 2) / 8 + +/obj/machinery/r_n_d/protolathe/dismantle() + for(var/obj/I in component_parts) + if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker)) + reagents.trans_to(I, reagents.total_volume) + if(m_amount >= 3750) + var/obj/item/stack/sheet/metal/G = new /obj/item/stack/sheet/metal(loc) + G.amount = round(m_amount / G.perunit) + if(g_amount >= 3750) + var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(loc) + G.amount = round(g_amount / G.perunit) + if(phoron_amount >= 2000) + var/obj/item/stack/sheet/mineral/phoron/G = new /obj/item/stack/sheet/mineral/phoron(loc) + G.amount = round(phoron_amount / G.perunit) + if(silver_amount >= 2000) + var/obj/item/stack/sheet/mineral/silver/G = new /obj/item/stack/sheet/mineral/silver(loc) + G.amount = round(silver_amount / G.perunit) + if(gold_amount >= 2000) + var/obj/item/stack/sheet/mineral/gold/G = new /obj/item/stack/sheet/mineral/gold(loc) + G.amount = round(gold_amount / G.perunit) + if(uranium_amount >= 2000) + var/obj/item/stack/sheet/mineral/uranium/G = new /obj/item/stack/sheet/mineral/uranium(loc) + G.amount = round(uranium_amount / G.perunit) + if(diamond_amount >= 2000) + var/obj/item/stack/sheet/mineral/diamond/G = new /obj/item/stack/sheet/mineral/diamond(loc) + G.amount = round(diamond_amount / G.perunit) + ..() + +/obj/machinery/r_n_d/protolathe/update_icon() + if(panel_open) + icon_state = "protolathe_t" + else + icon_state = "protolathe" /obj/machinery/r_n_d/protolathe/attackby(var/obj/item/O as obj, var/mob/user as mob) - if (shocked) - shock(user,50) - if (O.is_open_container()) - return 1 - if (istype(O, /obj/item/weapon/screwdriver)) - if (!opened) - opened = 1 - if(linked_console) - linked_console.linked_lathe = null - linked_console = null - icon_state = "protolathe_t" - user << "You open the maintenance hatch of [src]." - else - opened = 0 - icon_state = "protolathe" - user << "You close the maintenance hatch of [src]." + if(shocked) + shock(user, 50) + if(default_deconstruction_screwdriver(user, O)) + if(linked_console) + linked_console.linked_lathe = null + linked_console = null return - if (opened) - if(istype(O, /obj/item/weapon/crowbar)) - playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) - var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc) - M.state = 2 - M.icon_state = "box_1" - for(var/obj/I in component_parts) - if(istype(I, /obj/item/weapon/reagent_containers/glass/beaker)) - reagents.trans_to(I, reagents.total_volume) - if(I.reliability != 100 && crit_fail) - I.crit_fail = 1 - I.loc = src.loc - if(m_amount >= 3750) - var/obj/item/stack/sheet/metal/G = new /obj/item/stack/sheet/metal(src.loc) - G.amount = round(m_amount / G.perunit) - if(g_amount >= 3750) - var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src.loc) - G.amount = round(g_amount / G.perunit) - if(phoron_amount >= 2000) - var/obj/item/stack/sheet/mineral/phoron/G = new /obj/item/stack/sheet/mineral/phoron(src.loc) - G.amount = round(phoron_amount / G.perunit) - if(silver_amount >= 2000) - var/obj/item/stack/sheet/mineral/silver/G = new /obj/item/stack/sheet/mineral/silver(src.loc) - G.amount = round(silver_amount / G.perunit) - if(gold_amount >= 2000) - var/obj/item/stack/sheet/mineral/gold/G = new /obj/item/stack/sheet/mineral/gold(src.loc) - G.amount = round(gold_amount / G.perunit) - if(uranium_amount >= 2000) - var/obj/item/stack/sheet/mineral/uranium/G = new /obj/item/stack/sheet/mineral/uranium(src.loc) - G.amount = round(uranium_amount / G.perunit) - if(diamond_amount >= 2000) - var/obj/item/stack/sheet/mineral/diamond/G = new /obj/item/stack/sheet/mineral/diamond(src.loc) - G.amount = round(diamond_amount / G.perunit) - del(src) - return 1 - else - user << "\red You can't load the [src.name] while it's opened." - return 1 - if (disabled) + if(default_deconstruction_crowbar(user, O)) return - if (!linked_console) - user << "\The protolathe must be linked to an R&D console first!" + if(default_part_replacement(user, O)) + return + if(O.is_open_container()) return 1 - if (busy) - user << "\red The protolathe is busy. Please wait for completion of previous operation." + if(panel_open) + user << "You can't load \the [src] while it's opened." return 1 - if (!istype(O, /obj/item/stack/sheet)) - user << "\red You cannot insert this item into the protolathe!" + if(disabled) + return + if(!linked_console) + user << "\The [src] must be linked to an R&D console first!" return 1 - if (stat) + if(busy) + user << "\The [src] is busy. Please wait for completion of previous operation." + return 1 + if(!istype(O, /obj/item/stack/sheet)) + user << "You cannot insert this item into \the [src]!" + return 1 + if(stat) return 1 if(istype(O,/obj/item/stack/sheet)) var/obj/item/stack/sheet/S = O - if (TotalMaterials() + S.perunit > max_material_storage) - user << "\red The protolathe's material bin is full. Please remove material before adding more." + if(TotalMaterials() + S.perunit > max_material_storage) + user << "\The [src]'s material bin is full. Please remove material before adding more." return 1 var/obj/item/stack/sheet/stack = O @@ -137,20 +137,20 @@ Note: Must be placed west/left of and R&D console to function. return if(amount > stack.get_amount()) amount = stack.get_amount() - if(max_material_storage - TotalMaterials() < (amount*stack.perunit))//Can't overfill - amount = min(stack.amount, round((max_material_storage-TotalMaterials())/stack.perunit)) + if(max_material_storage - TotalMaterials() < (amount * stack.perunit))//Can't overfill + amount = min(stack.amount, round((max_material_storage - TotalMaterials()) / stack.perunit)) - src.overlays += "protolathe_[stack.name]" + overlays += "protolathe_[stack.name]" sleep(10) - src.overlays -= "protolathe_[stack.name]" + overlays -= "protolathe_[stack.name]" icon_state = "protolathe" busy = 1 - use_power(max(1000, (3750*amount/10))) + use_power(max(1000, (3750 * amount / 10))) var/stacktype = stack.type stack.use(amount) - if (do_after(user, 16)) - user << "\blue You add [amount] sheets to the [src.name]." + if(do_after(user, 16)) + user << "You add [amount] sheets to \the [src]." icon_state = "protolathe" switch(stacktype) if(/obj/item/stack/sheet/metal) @@ -168,9 +168,9 @@ Note: Must be placed west/left of and R&D console to function. if(/obj/item/stack/sheet/mineral/diamond) diamond_amount += amount * 2000 else - new stacktype(src.loc, amount) + new stacktype(loc, amount) busy = 0 - src.updateUsrDialog() + updateUsrDialog() return //This is to stop these machines being hackable via clicking. diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 3f40be01df..1ad86378b0 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -1,5 +1,3 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33 - /* Research and Development (R&D) Console @@ -27,8 +25,6 @@ cause a ton of data to be lost, an admin can go send it back. - The second method is with Technology Disks and Design Disks. Each of these disks can hold a single technology or design datum in it's entirety. You can then take the disk to any R&D console and upload it's data to it. This method is a lot more secure (since it won't update every console in existence) but it's more of a hassle to do. Also, the disks can be stolen. - - */ /obj/machinery/computer/rdconsole @@ -97,7 +93,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, /obj/machinery/computer/rdconsole/proc/SyncRDevices() //Makes sure it is properly sync'ed up with the devices attached to it (if any). for(var/obj/machinery/r_n_d/D in oview(3,src)) - if(D.linked_console != null || D.disabled || D.opened) + if(D.linked_console != null || D.disabled || D.panel_open) continue if(istype(D, /obj/machinery/r_n_d/destructive_analyzer)) if(linked_destroy == null) @@ -166,7 +162,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, /obj/machinery/computer/rdconsole/Topic(href, href_list) if(..()) - return + return 1 add_fingerprint(usr) @@ -259,7 +255,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, usr <<"\red The destructive analyzer appears to be empty." screen = 1.0 return - if(linked_destroy.loaded_item.reliability >= 90) + if(linked_destroy.loaded_item.reliability >= linked_destroy.min_reliability) var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) for(var/T in temp_tech) files.UpdateTech(T, temp_tech[T]) @@ -351,21 +347,21 @@ won't update every console in existence) but it's more of a hassle to do. Also, for(var/M in being_built.materials) switch(M) if("$metal") - linked_lathe.m_amount = max(0, (linked_lathe.m_amount-being_built.materials[M])) + linked_lathe.m_amount = max(0, (linked_lathe.m_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) if("$glass") - linked_lathe.g_amount = max(0, (linked_lathe.g_amount-being_built.materials[M])) + linked_lathe.g_amount = max(0, (linked_lathe.g_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) if("$gold") - linked_lathe.gold_amount = max(0, (linked_lathe.gold_amount-being_built.materials[M])) + linked_lathe.gold_amount = max(0, (linked_lathe.gold_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) if("$silver") - linked_lathe.silver_amount = max(0, (linked_lathe.silver_amount-being_built.materials[M])) + linked_lathe.silver_amount = max(0, (linked_lathe.silver_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) if("$phoron") - linked_lathe.phoron_amount = max(0, (linked_lathe.phoron_amount-being_built.materials[M])) + linked_lathe.phoron_amount = max(0, (linked_lathe.phoron_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) if("$uranium") - linked_lathe.uranium_amount = max(0, (linked_lathe.uranium_amount-being_built.materials[M])) + linked_lathe.uranium_amount = max(0, (linked_lathe.uranium_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) if("$diamond") - linked_lathe.diamond_amount = max(0, (linked_lathe.diamond_amount-being_built.materials[M])) + linked_lathe.diamond_amount = max(0, (linked_lathe.diamond_amount-being_built.materials[M]*linked_lathe.mat_efficiency)) else - linked_lathe.reagents.remove_reagent(M, being_built.materials[M]) + linked_lathe.reagents.remove_reagent(M, being_built.materials[M]*linked_lathe.mat_efficiency) if(being_built.build_path) var/obj/new_item = new being_built.build_path(src) @@ -379,6 +375,10 @@ won't update every console in existence) but it's more of a hassle to do. Also, L.name += " ([new_item.name])"*/ else new_item.loc = linked_lathe.loc + if(linked_lathe.mat_efficiency != 1) // No matter out of nowhere + if(new_item.matter && new_item.matter.len > 0) + for(var/i in new_item.matter) + new_item.matter[i] = new_item.matter[i] * linked_lathe.mat_efficiency linked_lathe.busy = 0 screen = 3.1 errored = 0 @@ -405,15 +405,15 @@ won't update every console in existence) but it's more of a hassle to do. Also, for(var/M in being_built.materials) switch(M) if("$glass") - linked_imprinter.g_amount = max(0, (linked_imprinter.g_amount-being_built.materials[M])) + linked_imprinter.g_amount = max(0, (linked_imprinter.g_amount-being_built.materials[M]*linked_imprinter.mat_efficiency)) if("$gold") - linked_imprinter.gold_amount = max(0, (linked_imprinter.gold_amount-being_built.materials[M])) + linked_imprinter.gold_amount = max(0, (linked_imprinter.gold_amount-being_built.materials[M]*linked_imprinter.mat_efficiency)) if("$diamond") - linked_imprinter.diamond_amount = max(0, (linked_imprinter.diamond_amount-being_built.materials[M])) + linked_imprinter.diamond_amount = max(0, (linked_imprinter.diamond_amount-being_built.materials[M]*linked_imprinter.mat_efficiency)) if("$uranium") - linked_imprinter.uranium_amount = max(0, (linked_imprinter.uranium_amount-being_built.materials[M])) + linked_imprinter.uranium_amount = max(0, (linked_imprinter.uranium_amount-being_built.materials[M]*linked_imprinter.mat_efficiency)) else - linked_imprinter.reagents.remove_reagent(M, being_built.materials[M]) + linked_imprinter.reagents.remove_reagent(M, being_built.materials[M]*linked_imprinter.mat_efficiency) var/obj/new_item = new being_built.build_path(src) new_item.reliability = being_built.reliability if(linked_imprinter.hacked) being_built.reliability = max((reliability / 2), 0) @@ -523,9 +523,50 @@ won't update every console in existence) but it's more of a hassle to do. Also, spawn(20) screen = 1.6 updateUsrDialog() + + else if (href_list["print"]) //Print research information + screen = 0.5 + spawn(20) + var/obj/item/weapon/paper/PR = new/obj/item/weapon/paper + PR.name = "list of researched technologies" + PR.info = "
    [station_name()] Science Laboratories" + PR.info += "

    [ (text2num(href_list["print"]) == 2) ? "Detailed" : ] Research Progress Report

    " + PR.info += "report prepared at [worldtime2text()] station time

    " + if(text2num(href_list["print"]) == 2) + PR.info += GetResearchListInfo() + else + PR.info += GetResearchLevelsInfo() + PR.info_links = PR.info + PR.icon_state = "paper_words" + PR.loc = src.loc + spawn(10) + screen = ((text2num(href_list["print"]) == 2) ? 5.0 : 1.1) + updateUsrDialog() + updateUsrDialog() return +/obj/machinery/computer/rdconsole/proc/GetResearchLevelsInfo() + var/dat + dat += "
      " + for(var/datum/tech/T in files.known_tech) + dat += "
    • " + dat += "[T.name]" + dat += "
        " + dat += "
      • Level: [T.level]" + dat += "
      • Summary: [T.desc]" + dat += "
      " + return dat + +/obj/machinery/computer/rdconsole/proc/GetResearchListInfo() + var/dat + dat += "
        " + for(var/datum/design/D in files.known_designs) + if(D.build_path) + dat += "
      • [D.name]: [D.desc]" + dat += "
      " + return dat + /obj/machinery/computer/rdconsole/attack_hand(mob/user as mob) if(stat & (BROKEN|NOPOWER)) return @@ -570,6 +611,9 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(0.4) dat += "Imprinting Circuit. Please Wait..." + if(0.5) + dat += "Printing Research Information. Please Wait..." + if(1.0) //Main Menu dat += "Main Menu:

      " dat += "Loaded disk: " @@ -593,16 +637,10 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "
    " if(1.1) //Research viewer - dat += "Main Menu
    " + dat += "Main Menu || " + dat += "Print This Page
    " dat += "Current Research Levels:

    " - dat += "
      " - for(var/datum/tech/T in files.known_tech) - dat += "
    • " - dat += "[T.name]" - dat += "
        " - dat += "
      • Level: [T.level]" - dat += "
      • Summary: [T.desc]" - dat += "
      " + dat += GetResearchLevelsInfo() dat += "
    " if(1.2) //Technology Disk Menu @@ -718,6 +756,10 @@ won't update every console in existence) but it's more of a hassle to do. Also, var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) for(var/T in temp_tech) dat += "
  • [CallTechName(T)] [temp_tech[T]]" + for(var/datum/tech/F in files.known_tech) + if(F.name == CallTechName(T)) + dat += " (Current: [F.level])" + break dat += "" dat += "
    Deconstruct Item || " dat += "Eject Item || " @@ -741,31 +783,33 @@ won't update every console in existence) but it's more of a hassle to do. Also, var/temp_dat var/check_materials = 1 for(var/M in D.materials) - temp_dat += ", [D.materials[M]] [CallMaterialName(M)]" + temp_dat += ", [D.materials[M]*linked_lathe.mat_efficiency] [CallMaterialName(M)]" if(copytext(M, 1, 2) == "$") switch(M) if("$glass") - if(D.materials[M] > linked_lathe.g_amount) check_materials = 0 + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.g_amount) check_materials = 0 if("$metal") - if(D.materials[M] > linked_lathe.m_amount) check_materials = 0 + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.m_amount) check_materials = 0 if("$gold") - if(D.materials[M] > linked_lathe.gold_amount) check_materials = 0 + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.gold_amount) check_materials = 0 if("$silver") - if(D.materials[M] > linked_lathe.silver_amount) check_materials = 0 + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.silver_amount) check_materials = 0 if("$phoron") - if(D.materials[M] > linked_lathe.phoron_amount) check_materials = 0 + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.phoron_amount) check_materials = 0 if("$uranium") - if(D.materials[M] > linked_lathe.uranium_amount) check_materials = 0 + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.uranium_amount) check_materials = 0 if("$diamond") - if(D.materials[M] > linked_lathe.diamond_amount) check_materials = 0 - else if (!linked_lathe.reagents.has_reagent(M, D.materials[M])) + if(D.materials[M]*linked_lathe.mat_efficiency > linked_lathe.diamond_amount) check_materials = 0 + else if (!linked_lathe.reagents.has_reagent(M, D.materials[M]*linked_lathe.mat_efficiency)) check_materials = 0 if(temp_dat) temp_dat = " \[[copytext(temp_dat,3)]\]" - if (check_materials) + if(check_materials) dat += "
  • [D.name][temp_dat]" else dat += "
  • [D.name][temp_dat]" + if(D.reliability < 100) + dat += " (Reliability: [D.reliability])" dat += "" if(3.2) //Protolathe Material Storage Sub-menu @@ -835,18 +879,18 @@ won't update every console in existence) but it's more of a hassle to do. Also, var/temp_dat var/check_materials = 1 for(var/M in D.materials) - temp_dat += ", [D.materials[M]] [CallMaterialName(M)]" + temp_dat += ", [D.materials[M]*linked_imprinter.mat_efficiency] [CallMaterialName(M)]" if(copytext(M, 1, 2) == "$") switch(M) if("$glass") - if(D.materials[M] > linked_imprinter.g_amount) check_materials = 0 + if(D.materials[M]*linked_imprinter.mat_efficiency > linked_imprinter.g_amount) check_materials = 0 if("$gold") - if(D.materials[M] > linked_imprinter.gold_amount) check_materials = 0 + if(D.materials[M]*linked_imprinter.mat_efficiency > linked_imprinter.gold_amount) check_materials = 0 if("$diamond") - if(D.materials[M] > linked_imprinter.diamond_amount) check_materials = 0 + if(D.materials[M]*linked_imprinter.mat_efficiency > linked_imprinter.diamond_amount) check_materials = 0 if("$uranium") - if(D.materials[M] > linked_imprinter.uranium_amount) check_materials = 0 - else if (!linked_imprinter.reagents.has_reagent(M, D.materials[M])) + if(D.materials[M]*linked_imprinter.mat_efficiency > linked_imprinter.uranium_amount) check_materials = 0 + else if (!linked_imprinter.reagents.has_reagent(M, D.materials[M]*linked_imprinter.mat_efficiency)) check_materials = 0 if(temp_dat) temp_dat = " \[[copytext(temp_dat,3)]\]" @@ -854,6 +898,8 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "
  • [D.name][temp_dat]" else dat += "
  • [D.name][temp_dat]" + if(D.reliability < 100) + dat += " (Reliability: [D.reliability])" dat += "" if(4.2) @@ -897,14 +943,10 @@ won't update every console in existence) but it's more of a hassle to do. Also, ///////////////////Research Information Browser//////////////////// if(5.0) - dat += "Main Menu
    " + dat += "Main Menu || " + dat += "Print This Page
    " dat += "List of Researched Technologies and Designs:" - dat += "
      " - for(var/datum/design/D in files.known_designs) - if(D.build_path) - dat += "
    • [D.name]: [D.desc]" - dat += "
    " - + dat += GetResearchListInfo() user << browse("Research and Development Console
    [dat]", "window=rdconsole;size=850x600") onclose(user, "rdconsole") @@ -912,9 +954,8 @@ won't update every console in existence) but it's more of a hassle to do. Also, /obj/machinery/computer/rdconsole/robotics name = "Robotics R&D Console" id = 2 - req_access = null - req_access_txt = "29" + req_access = list(access_robotics) /obj/machinery/computer/rdconsole/core name = "Core R&D Console" - id = 1 \ No newline at end of file + id = 1 diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm index 04f1536c25..4f0b81e531 100644 --- a/code/modules/research/rdmachines.dm +++ b/code/modules/research/rdmachines.dm @@ -17,7 +17,6 @@ var/hack_wire var/disable_wire var/shock_wire - var/opened = 0 var/obj/machinery/computer/rdconsole/linked_console /obj/machinery/r_n_d/New() @@ -39,7 +38,7 @@ /obj/machinery/r_n_d/attack_hand(mob/user as mob) if (shocked) shock(user,50) - if(opened) + if(panel_open) var/dat as text dat += "[src.name] Wires:
    " for(var/wire in src.wires) diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index 99b4719e28..6a5311e62b 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -103,7 +103,7 @@ /obj/machinery/r_n_d/server/proc/produce_heat() if (!produces_heat) return - + if (!use_power) return @@ -118,7 +118,7 @@ if(removed) var/heat_produced = idle_power_usage //obviously can't produce more heat than the machine draws from it's power source - + removed.add_thermal_energy(heat_produced) env.merge(removed) @@ -129,16 +129,16 @@ if (shocked) shock(user,50) if (istype(O, /obj/item/weapon/screwdriver)) - if (!opened) - opened = 1 + if (!panel_open) + panel_open = 1 icon_state = "server_o" user << "You open the maintenance hatch of [src]." else - opened = 0 + panel_open = 0 icon_state = "server" user << "You close the maintenance hatch of [src]." return - if (opened) + if (panel_open) if(istype(O, /obj/item/weapon/crowbar)) griefProtection() playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) @@ -205,7 +205,7 @@ /obj/machinery/computer/rdservercontrol/Topic(href, href_list) if(..()) - return + return 1 add_fingerprint(usr) usr.set_machine(src) diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_autocloner.dm b/code/modules/research/xenoarchaeology/artifact/artifact_autocloner.dm index 9c3cc70eeb..4daf56e056 100644 --- a/code/modules/research/xenoarchaeology/artifact/artifact_autocloner.dm +++ b/code/modules/research/xenoarchaeology/artifact/artifact_autocloner.dm @@ -39,8 +39,7 @@ /mob/living/simple_animal/slime,\ /mob/living/simple_animal/crab,\ /mob/living/simple_animal/mouse,\ - /mob/living/simple_animal/hostile/retaliate/goat,\ - /mob/living/carbon/monkey\ + /mob/living/simple_animal/hostile/retaliate/goat\ ) //todo: how the hell is the asteroid permanently powered? diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm index 77074be63f..0c81a604a2 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm @@ -1,49 +1,49 @@ - -/datum/artifact_effect/hurt - effecttype = "hurt" - effect_type = 5 - -/datum/artifact_effect/hurt/DoEffectTouch(var/mob/toucher) - if(toucher) - var/weakness = GetAnomalySusceptibility(toucher) - if(iscarbon(toucher) && prob(weakness * 100)) - var/mob/living/carbon/C = toucher - C << "\red A painful discharge of energy strikes you!" - C.adjustOxyLoss(rand(5,25) * weakness) - C.adjustToxLoss(rand(5,25) * weakness) - C.adjustBruteLoss(rand(5,25) * weakness) - C.adjustFireLoss(rand(5,25) * weakness) - C.adjustBrainLoss(rand(5,25) * weakness) - C.radiation += 25 * weakness - C.nutrition -= min(50 * weakness, C.nutrition) - C.make_dizzy(6 * weakness) - C.weakened += 6 * weakness - -/datum/artifact_effect/hurt/DoEffectAura() - if(holder) - var/turf/T = get_turf(holder) - for (var/mob/living/carbon/C in range(src.effectrange,T)) - var/weakness = GetAnomalySusceptibility(C) - if(prob(weakness * 100)) - if(prob(10)) - C << "\red You feel a painful force radiating from something nearby." - C.adjustBruteLoss(1 * weakness) - C.adjustFireLoss(1 * weakness) - C.adjustToxLoss(1 * weakness) - C.adjustOxyLoss(1 * weakness) - C.adjustBrainLoss(1 * weakness) - C.updatehealth() - -/datum/artifact_effect/hurt/DoEffectPulse() - if(holder) - var/turf/T = get_turf(holder) - for (var/mob/living/carbon/C in range(effectrange, T)) - var/weakness = GetAnomalySusceptibility(C) - if(prob(weakness * 100)) - C << "\red A wave of painful energy strikes you!" - C.adjustBruteLoss(3 * weakness) - C.adjustFireLoss(3 * weakness) - C.adjustToxLoss(3 * weakness) - C.adjustOxyLoss(3 * weakness) - C.adjustBrainLoss(3 * weakness) - C.updatehealth() + +/datum/artifact_effect/hurt + effecttype = I_HURT + effect_type = 5 + +/datum/artifact_effect/hurt/DoEffectTouch(var/mob/toucher) + if(toucher) + var/weakness = GetAnomalySusceptibility(toucher) + if(iscarbon(toucher) && prob(weakness * 100)) + var/mob/living/carbon/C = toucher + C << "\red A painful discharge of energy strikes you!" + C.adjustOxyLoss(rand(5,25) * weakness) + C.adjustToxLoss(rand(5,25) * weakness) + C.adjustBruteLoss(rand(5,25) * weakness) + C.adjustFireLoss(rand(5,25) * weakness) + C.adjustBrainLoss(rand(5,25) * weakness) + C.radiation += 25 * weakness + C.nutrition -= min(50 * weakness, C.nutrition) + C.make_dizzy(6 * weakness) + C.weakened += 6 * weakness + +/datum/artifact_effect/hurt/DoEffectAura() + if(holder) + var/turf/T = get_turf(holder) + for (var/mob/living/carbon/C in range(src.effectrange,T)) + var/weakness = GetAnomalySusceptibility(C) + if(prob(weakness * 100)) + if(prob(10)) + C << "\red You feel a painful force radiating from something nearby." + C.adjustBruteLoss(1 * weakness) + C.adjustFireLoss(1 * weakness) + C.adjustToxLoss(1 * weakness) + C.adjustOxyLoss(1 * weakness) + C.adjustBrainLoss(1 * weakness) + C.updatehealth() + +/datum/artifact_effect/hurt/DoEffectPulse() + if(holder) + var/turf/T = get_turf(holder) + for (var/mob/living/carbon/C in range(effectrange, T)) + var/weakness = GetAnomalySusceptibility(C) + if(prob(weakness * 100)) + C << "\red A wave of painful energy strikes you!" + C.adjustBruteLoss(3 * weakness) + C.adjustFireLoss(3 * weakness) + C.adjustToxLoss(3 * weakness) + C.adjustOxyLoss(3 * weakness) + C.adjustBrainLoss(3 * weakness) + C.updatehealth() diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_teleport.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_teleport.dm index 8eca5f355d..b8d1c9a87c 100644 --- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_teleport.dm +++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_teleport.dm @@ -8,7 +8,7 @@ if(prob(100 * weakness)) user << "\red You are suddenly zapped away elsewhere!" if (user.buckled) - user.buckled.unbuckle() + user.buckled.unbuckle_mob() var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread() sparks.set_up(3, 0, get_turf(user)) @@ -28,7 +28,7 @@ if(prob(100 * weakness)) M << "\red You are displaced by a strange force!" if(M.buckled) - M.buckled.unbuckle() + M.buckled.unbuckle_mob() var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread() sparks.set_up(3, 0, get_turf(M)) @@ -47,7 +47,7 @@ if(prob(100 * weakness)) M << "\red You are displaced by a strange force!" if(M.buckled) - M.buckled.unbuckle() + M.buckled.unbuckle_mob() var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread() sparks.set_up(3, 0, get_turf(M)) diff --git a/code/modules/research/xenoarchaeology/chemistry.dm b/code/modules/research/xenoarchaeology/chemistry.dm index f5b718dcf0..eae7b0afc0 100644 --- a/code/modules/research/xenoarchaeology/chemistry.dm +++ b/code/modules/research/xenoarchaeology/chemistry.dm @@ -84,7 +84,7 @@ datum obj/item/weapon/reagent_containers/glass/solution_tray/attackby(obj/item/weapon/W as obj, mob/living/user as mob) if(istype(W, /obj/item/weapon/pen)) - var/new_label = input("What should the new label be?","Label solution tray") + var/new_label = sanitizeSafe(input("What should the new label be?","Label solution tray"), MAX_NAME_LEN) if(new_label) name = "solution tray ([new_label])" user << "\blue You write on the label of the solution tray." diff --git a/code/modules/research/xenoarchaeology/finds/finds.dm b/code/modules/research/xenoarchaeology/finds/finds.dm index 3c2a3dd8e2..117fd66418 100644 --- a/code/modules/research/xenoarchaeology/finds/finds.dm +++ b/code/modules/research/xenoarchaeology/finds/finds.dm @@ -208,7 +208,8 @@ new_item.icon_state = "box" var/obj/item/weapon/storage/box/new_box = new_item new_box.max_w_class = pick(1,2,2,3,3,3,4,4) - new_box.max_combined_w_class = rand(new_box.max_w_class, new_box.max_w_class * 10) + var/storage_amount = 2**(new_box.max_w_class-1) + new_box.max_storage_space = rand(storage_amount, storage_amount * 10) if(prob(30)) apply_image_decorations = 1 if(12) @@ -345,7 +346,7 @@ /obj/item/weapon/gun/energy/laser/practice/xenoarch,\ /obj/item/weapon/gun/energy/laser/xenoarch,\ /obj/item/weapon/gun/energy/xray/xenoarch,\ - /obj/item/weapon/gun/energy/laser/captain/xenoarch) + /obj/item/weapon/gun/energy/captain/xenoarch) if(spawn_type) var/obj/item/weapon/gun/energy/new_gun = new spawn_type(src.loc) new_item = new_gun @@ -367,7 +368,7 @@ item_type = "gun" if(27) //revolver - var/obj/item/weapon/gun/projectile/new_gun = new /obj/item/weapon/gun/projectile(src.loc) + var/obj/item/weapon/gun/projectile/new_gun = new /obj/item/weapon/gun/projectile/revolver(src.loc) new_item = new_gun new_item.icon_state = "gun[rand(1,4)]" new_item.icon = 'icons/obj/xenoarchaeology.dmi' @@ -383,7 +384,7 @@ if(num_bullets < new_gun.loaded.len) new_gun.loaded.Cut() for(var/i = 1, i <= num_bullets, i++) - var/A = text2path(new_gun.ammo_type) + var/A = new_gun.ammo_type new_gun.loaded += new A(new_gun) else for(var/obj/item/I in new_gun) @@ -545,13 +546,9 @@ new_item.desc = src.desc if(talkative) - new_item.talking_atom = new() - talking_atom.holder_atom = new_item - talking_atom.init() + new_item.talking_atom = new(new_item) del(src) else if(talkative) - src.talking_atom = new() - talking_atom.holder_atom = src - talking_atom.init() + src.talking_atom = new(src) diff --git a/code/modules/research/xenoarchaeology/finds/finds_eguns.dm b/code/modules/research/xenoarchaeology/finds/finds_eguns.dm index 95755e4d9c..dc07d9a88d 100644 --- a/code/modules/research/xenoarchaeology/finds/finds_eguns.dm +++ b/code/modules/research/xenoarchaeology/finds/finds_eguns.dm @@ -19,7 +19,7 @@ update_icon() return -/obj/item/weapon/gun/energy/laser/captain/xenoarch +/obj/item/weapon/gun/energy/captain/xenoarch icon = 'icons/obj/xenoarchaeology.dmi' update_icon() - return \ No newline at end of file + return diff --git a/code/modules/research/xenoarchaeology/finds/finds_fossils.dm b/code/modules/research/xenoarchaeology/finds/finds_fossils.dm index 57d510015f..80dbf549c0 100644 --- a/code/modules/research/xenoarchaeology/finds/finds_fossils.dm +++ b/code/modules/research/xenoarchaeology/finds/finds_fossils.dm @@ -79,7 +79,7 @@ else ..() else if(istype(W,/obj/item/weapon/pen)) - plaque_contents = input("What would you like to write on the plaque:","Skeleton plaque","") + plaque_contents = sanitize(input("What would you like to write on the plaque:","Skeleton plaque","")) user.visible_message("[user] writes something on the base of [src].","You relabel the plaque on the base of \icon[src] [src].") if(src.contents.Find(/obj/item/weapon/fossil/skull/horned)) src.desc = "A creature made of [src.contents.len-1] assorted bones and a horned skull. The plaque reads \'[plaque_contents]\'." diff --git a/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm b/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm index 65a2e24ca0..58cfdbb031 100644 --- a/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm +++ b/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm @@ -14,6 +14,10 @@ var/talk_interval = 50 var/talk_chance = 10 +/datum/talking_atom/New(atom/holder) + holder_atom = holder + init() + /datum/talking_atom/proc/init() if(holder_atom) processing_objects.Add(src) @@ -55,7 +59,7 @@ if(prob(30)) var/list/options = list("[holder_atom] seems to be listening intently to [source]...",\ - "[holder_atom] seems to be focussing on [source]...",\ + "[holder_atom] seems to be focusing on [source]...",\ "[holder_atom] seems to turn it's attention to [source]...") holder_atom.loc.visible_message("\blue \icon[holder_atom] [pick(options)]") diff --git a/code/modules/research/xenoarchaeology/genetics/prehistoric_plants.dm b/code/modules/research/xenoarchaeology/genetics/prehistoric_plants.dm deleted file mode 100644 index d9212ac5b0..0000000000 --- a/code/modules/research/xenoarchaeology/genetics/prehistoric_plants.dm +++ /dev/null @@ -1,81 +0,0 @@ -/obj/item/weapon/reagent_containers/food/snacks/grown/telriis_clump - name = "telriis grass" - desc = "A clump of telriis grass, not recommended for consumption by sentients." - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "telriisclump" - New(var/loc, var/potency) - ..() - reagents.add_reagent("pwine", potency * 5) - reagents.add_reagent("nutriment", potency) - bitesize = 1+round(reagents.total_volume / 2, 1) - -/obj/item/weapon/reagent_containers/food/snacks/grown/thaadrabloom - name = "thaa'dra bloom" - desc = "Looks chewy, might be good to eat." - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "thaadrabloom" - New(var/loc, var/potency) - ..() - reagents.add_reagent("frostoil", potency * 1.5 + 5) - reagents.add_reagent("nutriment", potency) - bitesize = 1+round(reagents.total_volume / 2, 1) - -/obj/item/weapon/reagent_containers/food/snacks/grown/jurlmah - name = "jurl'mah pod" - desc = "Bulbous and veiny, it appears to pulse slightly as you look at it." - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "jurlmahpod" - New(var/loc, var/potency) - ..() - reagents.add_reagent("serotrotium", potency) - reagents.add_reagent("nutriment", potency) - bitesize = 1+round(reagents.total_volume / 2, 1) - -/obj/item/weapon/reagent_containers/food/snacks/grown/amauri - name = "amauri fruit" - desc = "It is small, round and hard. Its skin is a thick dark purple." - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "amaurifruit" - New(var/loc, var/potency) - ..() - reagents.add_reagent("zombiepowder", potency * 10) - reagents.add_reagent("condensedcapsaicin", potency * 5) - reagents.add_reagent("nutriment", potency) - bitesize = 1+round(reagents.total_volume / 2, 1) - -/obj/item/weapon/reagent_containers/food/snacks/grown/gelthi - name = "gelthi berries" - desc = "They feel fluffy and slightly warm to the touch." - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "gelthiberries" - New(var/loc, var/potency) - ..() - //this may prove a little strong - reagents.add_reagent("stoxin", (potency * potency) / 5) - reagents.add_reagent("capsaicin", (potency * potency) / 5) - reagents.add_reagent("nutriment", potency) - bitesize = 1+round(reagents.total_volume / 2, 1) - -/obj/item/weapon/reagent_containers/food/snacks/grown/vale - name = "vale leaves" - desc = "Small, curly leaves covered in a soft pale fur." - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "valeleaves" - New(var/loc, var/potency) - ..() - reagents.add_reagent("paracetamol", potency * 5) - reagents.add_reagent("dexalin", potency * 2) - reagents.add_reagent("nutriment", potency) - bitesize = 1+round(reagents.total_volume / 2, 1) - -/obj/item/weapon/reagent_containers/food/snacks/grown/surik - name = "surik fruit" - desc = "Multiple layers of blue skin peeling away to reveal a spongey core, vaguely resembling an ear." - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "surikfruit" - New(var/loc, var/potency) - ..() - reagents.add_reagent("impedrezene", potency * 3) - reagents.add_reagent("synaptizine", potency * 2) - reagents.add_reagent("nutriment", potency) - bitesize = 1+round(reagents.total_volume / 2, 1) \ No newline at end of file diff --git a/code/modules/research/xenoarchaeology/genetics/prehistoric_seeds.dm b/code/modules/research/xenoarchaeology/genetics/prehistoric_seeds.dm deleted file mode 100644 index 5597d27532..0000000000 --- a/code/modules/research/xenoarchaeology/genetics/prehistoric_seeds.dm +++ /dev/null @@ -1,139 +0,0 @@ -/datum/seed/telriis - - name = "telriis" - seed_name = "telriis" - display_name = "telriis grass" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/telriis_clump) - packet_icon = "seed-alien1" - plant_icon = "telriis" - - lifespan = 50 - endurance = 50 - maturation = 5 - production = 5 - yield = 4 - potency = 5 - growth_stages = 4 - -/datum/seed/thaadra - - name = "thaadra" - seed_name = "thaa'dra" - display_name = "thaa'dra lichen" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/thaadrabloom) - packet_icon = "seed-alien3" - plant_icon = "thaadra" - - lifespan = 20 - endurance = 10 - maturation = 5 - production = 9 - yield = 2 - potency = 5 - growth_stages = 4 - -/datum/seed/jurlmah - - name = "jurlmah" - seed_name = "jurl'mah" - display_name = "jurl'mah reeds" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/jurlmah) - packet_icon = "seed-alien3" - plant_icon = "jurlmah" - - lifespan = 20 - endurance = 12 - maturation = 8 - production = 9 - yield = 3 - potency = 10 - growth_stages = 5 - -/datum/seed/amauri - - name = "amauri" - seed_name = "amauri" - display_name = "amauri plant" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/amauri) - packet_icon = "seed-alien3" - plant_icon = "amauri" - - lifespan = 30 - endurance = 10 - maturation = 8 - production = 9 - yield = 4 - potency = 10 - growth_stages = 3 - -/datum/seed/gelthi - - name = "gelthi" - seed_name = "gelthi" - display_name = "gelthi plant" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/gelthi) - packet_icon = "seed-alien2" - plant_icon = "gelthi" - - lifespan = 20 - endurance = 15 - maturation = 6 - production = 6 - yield = 2 - potency = 1 - growth_stages = 3 - -/datum/seed/vale - - name = "vale" - seed_name = "vale" - display_name = "vale bush" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/vale) - packet_icon = "seed-alien2" - plant_icon = "vale" - - lifespan = 25 - endurance = 15 - maturation = 8 - production = 10 - yield = 3 - potency = 3 - growth_stages = 4 - -/datum/seed/surik - - name = "surik" - seed_name = "surik" - display_name = "surik vine" - products = list(/obj/item/weapon/reagent_containers/food/snacks/grown/surik) - packet_icon = "seed-alien3" - plant_icon = "surik" - - lifespan = 30 - endurance = 18 - maturation = 7 - production = 7 - yield = 3 - potency = 3 - growth_stages = 4 - -/obj/item/seeds/jurlmah - seed_type = "jurlmah" - -/obj/item/seeds/amauri - seed_type = "amauri" - -/obj/item/seeds/gelthi - seed_type = "gelthi" - -/obj/item/seeds/vale - seed_type = "vale" - -/obj/item/seeds/surik - seed_type = "surik" - -/obj/item/seeds/telriis - seed_type = "telriis" - -/obj/item/seeds/thaadra - seed_type = "thaadra" \ No newline at end of file diff --git a/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm b/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm index 26419c6ab2..38d6a52465 100644 --- a/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm +++ b/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm @@ -181,6 +181,7 @@ datum/genesequence onclose(user, "reconstitutor") /obj/machinery/computer/reconstitutor/animal/Topic(href, href_list) + if(..()) return 1 if(href_list["clone"]) var/sequence_num = text2num(href_list["sequence_num"]) var/datum/genesequence/cloned_genesequence = completed_genesequences[sequence_num] @@ -201,10 +202,9 @@ datum/genesequence pod1.biomass -= CLONE_BIOMASS else usr << "\red \icon[src] Unable to locate cloning pod!" - else - ..() /obj/machinery/computer/reconstitutor/Topic(href, href_list) + if(..()) return 1 if(href_list["insertpos"]) //world << "inserting gene for genesequence [href_list["insertgenome"]] at pos [text2num(href_list["insertpos"])]" var/sequence_num = text2num(href_list["sequence_num"]) @@ -252,9 +252,6 @@ datum/genesequence usr.unset_machine(src) usr << browse(null, "window=reconstitutor") - else - ..() - /obj/machinery/computer/reconstitutor/proc/scan_fossil(var/obj/item/weapon/fossil/scan_fossil) //see whether we accept these kind of fossils if(accepted_fossil_types.len && !accepted_fossil_types.Find(scan_fossil.type)) diff --git a/code/modules/research/xenoarchaeology/geosample.dm b/code/modules/research/xenoarchaeology/geosample.dm index 401ae13cd3..689f61b888 100644 --- a/code/modules/research/xenoarchaeology/geosample.dm +++ b/code/modules/research/xenoarchaeology/geosample.dm @@ -29,6 +29,8 @@ icon_state = "sliver[rand(1,3)]" pixel_x = rand(0,16)-8 pixel_y = rand(0,8)-8 + create_reagents(50) + reagents.add_reagent("ground_rock",50) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Geosample datum diff --git a/code/modules/research/xenoarchaeology/machinery/coolant.dm b/code/modules/research/xenoarchaeology/machinery/coolant.dm index 6c0652f408..b2f2cd3d67 100644 --- a/code/modules/research/xenoarchaeology/machinery/coolant.dm +++ b/code/modules/research/xenoarchaeology/machinery/coolant.dm @@ -26,7 +26,7 @@ datum/chemical_reaction/coolant reagents.add_reagent("coolant",1000) /obj/structure/reagent_dispensers/coolanttank/bullet_act(var/obj/item/projectile/Proj) - if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet)) + if(Proj.damage_type == BRUTE || Proj.damage_type == BURN) if(!istype(Proj ,/obj/item/projectile/beam/lastertag) && !istype(Proj ,/obj/item/projectile/beam/practice) ) explode() diff --git a/code/modules/research/xenoarchaeology/tools/gearbelt.dm b/code/modules/research/xenoarchaeology/tools/gearbelt.dm index e2d4839d2b..d12446382b 100644 --- a/code/modules/research/xenoarchaeology/tools/gearbelt.dm +++ b/code/modules/research/xenoarchaeology/tools/gearbelt.dm @@ -1,28 +1,30 @@ - -/obj/item/weapon/storage/belt/archaeology - name = "excavation gear-belt" - desc = "Can hold various excavation gear." - icon_state = "gearbelt" - item_state = "utility" - can_hold = list( - "/obj/item/weapon/storage/box/samplebags", - "/obj/item/device/core_sampler", - "/obj/item/device/beacon_locator", - "/obj/item/device/radio/beacon", - "/obj/item/device/gps", - "/obj/item/device/measuring_tape", - "/obj/item/device/flashlight", - "/obj/item/weapon/pickaxe", - "/obj/item/device/depth_scanner", - "/obj/item/device/camera", - "/obj/item/weapon/paper", - "/obj/item/weapon/photo", - "/obj/item/weapon/folder", - "/obj/item/weapon/pen", - "/obj/item/weapon/folder", - "/obj/item/weapon/clipboard", - "/obj/item/weapon/anodevice", - "/obj/item/clothing/glasses", - "/obj/item/weapon/wrench", - "/obj/item/weapon/storage/box/excavation", - "/obj/item/weapon/anobattery") + +/obj/item/weapon/storage/belt/archaeology + name = "excavation gear-belt" + desc = "Can hold various excavation gear." + icon_state = "gearbelt" + item_state = "utility" + can_hold = list( + /obj/item/weapon/storage/box/samplebags, + /obj/item/device/core_sampler, + /obj/item/device/beacon_locator, + /obj/item/device/radio/beacon, + /obj/item/device/gps, + /obj/item/device/measuring_tape, + /obj/item/device/flashlight, + /obj/item/weapon/pickaxe, + /obj/item/device/depth_scanner, + /obj/item/device/camera, + /obj/item/weapon/paper, + /obj/item/weapon/photo, + /obj/item/weapon/folder, + /obj/item/weapon/pen, + /obj/item/weapon/folder, + /obj/item/weapon/clipboard, + /obj/item/weapon/anodevice, + /obj/item/clothing/glasses, + /obj/item/weapon/wrench, + /obj/item/weapon/storage/box/excavation, + /obj/item/weapon/anobattery, + /obj/item/device/ano_scanner + ) diff --git a/code/modules/research/xenoarchaeology/tools/tools.dm b/code/modules/research/xenoarchaeology/tools/tools.dm index 479d0240fa..e16db119c5 100644 --- a/code/modules/research/xenoarchaeology/tools/tools.dm +++ b/code/modules/research/xenoarchaeology/tools/tools.dm @@ -1,36 +1,36 @@ - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Miscellaneous xenoarchaeology tools - -/obj/item/device/gps - name = "relay positioning device" - desc = "Triangulates the approximate co-ordinates using a nearby satellite network." - icon = 'icons/obj/device.dmi' - icon_state = "locator" - item_state = "locator" - w_class = 2 - -/obj/item/device/gps/attack_self(var/mob/user as mob) - var/turf/T = get_turf(src) - user << "\blue \icon[src] [src] flashes [T.x].[rand(0,9)]:[T.y].[rand(0,9)]:[T.z].[rand(0,9)]." - -/obj/item/device/measuring_tape - name = "measuring tape" - desc = "A coiled metallic tape used to check dimensions and lengths." - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "measuring" - w_class = 2 - -//todo: dig site tape - -/obj/item/weapon/storage/bag/fossils - name = "Fossil Satchel" - desc = "Transports delicate fossils in suspension so they don't break during transit." - icon = 'icons/obj/mining.dmi' - icon_state = "satchel" - slot_flags = SLOT_BELT | SLOT_POCKET - w_class = 3 - storage_slots = 50 - max_combined_w_class = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * ore.w_class - max_w_class = 3 - can_hold = list("/obj/item/weapon/fossil") + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Miscellaneous xenoarchaeology tools + +/obj/item/device/gps + name = "relay positioning device" + desc = "Triangulates the approximate co-ordinates using a nearby satellite network." + icon = 'icons/obj/device.dmi' + icon_state = "locator" + item_state = "locator" + w_class = 2 + +/obj/item/device/gps/attack_self(var/mob/user as mob) + var/turf/T = get_turf(src) + user << "\blue \icon[src] [src] flashes [T.x].[rand(0,9)]:[T.y].[rand(0,9)]:[T.z].[rand(0,9)]." + +/obj/item/device/measuring_tape + name = "measuring tape" + desc = "A coiled metallic tape used to check dimensions and lengths." + icon = 'icons/obj/xenoarchaeology.dmi' + icon_state = "measuring" + w_class = 2 + +//todo: dig site tape + +/obj/item/weapon/storage/bag/fossils + name = "Fossil Satchel" + desc = "Transports delicate fossils in suspension so they don't break during transit." + icon = 'icons/obj/mining.dmi' + icon_state = "satchel" + slot_flags = SLOT_BELT | SLOT_POCKET + w_class = 3 + storage_slots = 50 + max_storage_space = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * ore.w_class + max_w_class = 3 + can_hold = list(/obj/item/weapon/fossil) diff --git a/code/modules/research/xenoarchaeology/tools/tools_pickaxe.dm b/code/modules/research/xenoarchaeology/tools/tools_pickaxe.dm index 31b6026981..1762cfbb0d 100644 --- a/code/modules/research/xenoarchaeology/tools/tools_pickaxe.dm +++ b/code/modules/research/xenoarchaeology/tools/tools_pickaxe.dm @@ -1,132 +1,132 @@ - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Excavation pickaxes - sorted in order of delicacy. Players will have to choose the right one for each part of excavation. - -/obj/item/weapon/pickaxe/brush - name = "brush" - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "pick_brush" - item_state = "syringe_0" - digspeed = 20 - desc = "Thick metallic wires for clearing away dust and loose scree (1 centimetre excavation depth)." - excavation_amount = 0.5 - drill_sound = 'sound/weapons/thudswoosh.ogg' - drill_verb = "brushing" - w_class = 2 - -/obj/item/weapon/pickaxe/one_pick - name = "1/6 pick" - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "pick1" - item_state = "syringe_0" - digspeed = 20 - desc = "A miniature excavation tool for precise digging (2 centimetre excavation depth)." - excavation_amount = 1 - drill_sound = 'sound/items/Screwdriver.ogg' - drill_verb = "delicately picking" - w_class = 2 - -/obj/item/weapon/pickaxe/two_pick - name = "1/3 pick" - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "pick2" - item_state = "syringe_0" - digspeed = 20 - desc = "A miniature excavation tool for precise digging (4 centimetre excavation depth)." - excavation_amount = 2 - drill_sound = 'sound/items/Screwdriver.ogg' - drill_verb = "delicately picking" - w_class = 2 - -/obj/item/weapon/pickaxe/three_pick - name = "1/2 pick" - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "pick3" - item_state = "syringe_0" - digspeed = 20 - desc = "A miniature excavation tool for precise digging (6 centimetre excavation depth)." - excavation_amount = 3 - drill_sound = 'sound/items/Screwdriver.ogg' - drill_verb = "delicately picking" - w_class = 2 - -/obj/item/weapon/pickaxe/four_pick - name = "2/3 pick" - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "pick4" - item_state = "syringe_0" - digspeed = 20 - desc = "A miniature excavation tool for precise digging (8 centimetre excavation depth)." - excavation_amount = 4 - drill_sound = 'sound/items/Screwdriver.ogg' - drill_verb = "delicately picking" - w_class = 2 - -/obj/item/weapon/pickaxe/five_pick - name = "5/6 pick" - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "pick5" - item_state = "syringe_0" - digspeed = 20 - desc = "A miniature excavation tool for precise digging (10 centimetre excavation depth)." - excavation_amount = 5 - drill_sound = 'sound/items/Screwdriver.ogg' - drill_verb = "delicately picking" - w_class = 2 - -/obj/item/weapon/pickaxe/six_pick - name = "1/1 pick" - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "pick6" - item_state = "syringe_0" - digspeed = 20 - desc = "A miniature excavation tool for precise digging (12 centimetre excavation depth)." - excavation_amount = 6 - drill_sound = 'sound/items/Screwdriver.ogg' - drill_verb = "delicately picking" - w_class = 2 - -/obj/item/weapon/pickaxe/hand - name = "hand pickaxe" - icon = 'icons/obj/xenoarchaeology.dmi' - icon_state = "pick_hand" - item_state = "syringe_0" - digspeed = 30 - desc = "A smaller, more precise version of the pickaxe (30 centimetre excavation depth)." - excavation_amount = 15 - drill_sound = 'sound/items/Crowbar.ogg' - drill_verb = "clearing" - w_class = 3 - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Pack for holding pickaxes - -/obj/item/weapon/storage/box/excavation - name = "excavation pick set" - icon = 'icons/obj/storage.dmi' - icon_state = "excavation" - desc = "A set of picks for excavation." - item_state = "syringe_kit" - foldable = /obj/item/stack/sheet/cardboard //BubbleWrap - storage_slots = 7 - w_class = 2 - can_hold = list("/obj/item/weapon/pickaxe/brush",\ - "/obj/item/weapon/pickaxe/one_pick",\ - "/obj/item/weapon/pickaxe/two_pick",\ - "/obj/item/weapon/pickaxe/three_pick",\ - "/obj/item/weapon/pickaxe/four_pick",\ - "/obj/item/weapon/pickaxe/five_pick",\ - "/obj/item/weapon/pickaxe/six_pick") - max_combined_w_class = 17 - max_w_class = 4 - use_to_pickup = 1 // for picking up broken bulbs, not that most people will try - -/obj/item/weapon/storage/box/excavation/New() - ..() - new /obj/item/weapon/pickaxe/brush(src) - new /obj/item/weapon/pickaxe/one_pick(src) - new /obj/item/weapon/pickaxe/two_pick(src) - new /obj/item/weapon/pickaxe/three_pick(src) - new /obj/item/weapon/pickaxe/four_pick(src) - new /obj/item/weapon/pickaxe/five_pick(src) - new /obj/item/weapon/pickaxe/six_pick(src) + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Excavation pickaxes - sorted in order of delicacy. Players will have to choose the right one for each part of excavation. + +/obj/item/weapon/pickaxe/brush + name = "brush" + icon = 'icons/obj/xenoarchaeology.dmi' + icon_state = "pick_brush" + item_state = "syringe_0" + digspeed = 20 + desc = "Thick metallic wires for clearing away dust and loose scree (1 centimetre excavation depth)." + excavation_amount = 0.5 + drill_sound = 'sound/weapons/thudswoosh.ogg' + drill_verb = "brushing" + w_class = 2 + +/obj/item/weapon/pickaxe/one_pick + name = "1/6 pick" + icon = 'icons/obj/xenoarchaeology.dmi' + icon_state = "pick1" + item_state = "syringe_0" + digspeed = 20 + desc = "A miniature excavation tool for precise digging (2 centimetre excavation depth)." + excavation_amount = 1 + drill_sound = 'sound/items/Screwdriver.ogg' + drill_verb = "delicately picking" + w_class = 2 + +/obj/item/weapon/pickaxe/two_pick + name = "1/3 pick" + icon = 'icons/obj/xenoarchaeology.dmi' + icon_state = "pick2" + item_state = "syringe_0" + digspeed = 20 + desc = "A miniature excavation tool for precise digging (4 centimetre excavation depth)." + excavation_amount = 2 + drill_sound = 'sound/items/Screwdriver.ogg' + drill_verb = "delicately picking" + w_class = 2 + +/obj/item/weapon/pickaxe/three_pick + name = "1/2 pick" + icon = 'icons/obj/xenoarchaeology.dmi' + icon_state = "pick3" + item_state = "syringe_0" + digspeed = 20 + desc = "A miniature excavation tool for precise digging (6 centimetre excavation depth)." + excavation_amount = 3 + drill_sound = 'sound/items/Screwdriver.ogg' + drill_verb = "delicately picking" + w_class = 2 + +/obj/item/weapon/pickaxe/four_pick + name = "2/3 pick" + icon = 'icons/obj/xenoarchaeology.dmi' + icon_state = "pick4" + item_state = "syringe_0" + digspeed = 20 + desc = "A miniature excavation tool for precise digging (8 centimetre excavation depth)." + excavation_amount = 4 + drill_sound = 'sound/items/Screwdriver.ogg' + drill_verb = "delicately picking" + w_class = 2 + +/obj/item/weapon/pickaxe/five_pick + name = "5/6 pick" + icon = 'icons/obj/xenoarchaeology.dmi' + icon_state = "pick5" + item_state = "syringe_0" + digspeed = 20 + desc = "A miniature excavation tool for precise digging (10 centimetre excavation depth)." + excavation_amount = 5 + drill_sound = 'sound/items/Screwdriver.ogg' + drill_verb = "delicately picking" + w_class = 2 + +/obj/item/weapon/pickaxe/six_pick + name = "1/1 pick" + icon = 'icons/obj/xenoarchaeology.dmi' + icon_state = "pick6" + item_state = "syringe_0" + digspeed = 20 + desc = "A miniature excavation tool for precise digging (12 centimetre excavation depth)." + excavation_amount = 6 + drill_sound = 'sound/items/Screwdriver.ogg' + drill_verb = "delicately picking" + w_class = 2 + +/obj/item/weapon/pickaxe/hand + name = "hand pickaxe" + icon = 'icons/obj/xenoarchaeology.dmi' + icon_state = "pick_hand" + item_state = "syringe_0" + digspeed = 30 + desc = "A smaller, more precise version of the pickaxe (30 centimetre excavation depth)." + excavation_amount = 15 + drill_sound = 'sound/items/Crowbar.ogg' + drill_verb = "clearing" + w_class = 3 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Pack for holding pickaxes + +/obj/item/weapon/storage/box/excavation + name = "excavation pick set" + icon = 'icons/obj/storage.dmi' + icon_state = "excavation" + desc = "A set of picks for excavation." + item_state = "syringe_kit" + foldable = /obj/item/stack/sheet/cardboard //BubbleWrap + storage_slots = 7 + w_class = 2 + can_hold = list(/obj/item/weapon/pickaxe/brush,\ + /obj/item/weapon/pickaxe/one_pick,\ + /obj/item/weapon/pickaxe/two_pick,\ + /obj/item/weapon/pickaxe/three_pick,\ + /obj/item/weapon/pickaxe/four_pick,\ + /obj/item/weapon/pickaxe/five_pick,\ + /obj/item/weapon/pickaxe/six_pick) + max_storage_space = 18 + max_w_class = 3 + use_to_pickup = 1 // for picking up broken bulbs, not that most people will try + +/obj/item/weapon/storage/box/excavation/New() + ..() + new /obj/item/weapon/pickaxe/brush(src) + new /obj/item/weapon/pickaxe/one_pick(src) + new /obj/item/weapon/pickaxe/two_pick(src) + new /obj/item/weapon/pickaxe/three_pick(src) + new /obj/item/weapon/pickaxe/four_pick(src) + new /obj/item/weapon/pickaxe/five_pick(src) + new /obj/item/weapon/pickaxe/six_pick(src) diff --git a/code/modules/shuttles/antagonist.dm b/code/modules/shuttles/antagonist.dm index 5bad5364cb..1e95093edd 100644 --- a/code/modules/shuttles/antagonist.dm +++ b/code/modules/shuttles/antagonist.dm @@ -1,7 +1,7 @@ /obj/machinery/computer/shuttle_control/multi/vox name = "skipjack control console" req_access = list(access_syndicate) - shuttle_tag = "Vox Skipjack" + shuttle_tag = "Skipjack" /obj/machinery/computer/shuttle_control/multi/syndicate name = "mercenary shuttle control console" diff --git a/code/modules/shuttles/departmental.dm b/code/modules/shuttles/departmental.dm index 018d194a71..81ad237cc7 100644 --- a/code/modules/shuttles/departmental.dm +++ b/code/modules/shuttles/departmental.dm @@ -7,7 +7,7 @@ /obj/machinery/computer/shuttle_control/engineering name = "engineering shuttle control console" shuttle_tag = "Engineering" - //req_one_access_txt = "11;24" + //req_one_access = list(access_engine_equip,access_atmospherics) circuit = /obj/item/weapon/circuitboard/engineering_shuttle /obj/machinery/computer/shuttle_control/research diff --git a/code/modules/shuttles/escape_pods.dm b/code/modules/shuttles/escape_pods.dm index 719c29fd9a..289cf4d7b0 100644 --- a/code/modules/shuttles/escape_pods.dm +++ b/code/modules/shuttles/escape_pods.dm @@ -43,7 +43,7 @@ ui.set_auto_update(1) /obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/Topic(href, href_list) - if(..()) //I hate this "return 1 to indicate they are not allowed to use the controller" crap, but not sure how else to do it without being able to call machinery/Topic() directly. + if(..()) return 1 if("manual_arm") diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm index c0e8d31546..0442144b17 100644 --- a/code/modules/shuttles/shuttle.dm +++ b/code/modules/shuttles/shuttle.dm @@ -6,10 +6,10 @@ /datum/shuttle var/warmup_time = 0 var/moving_status = SHUTTLE_IDLE - + var/docking_controller_tag //tag of the controller used to coordinate docking var/datum/computer/file/embedded_program/docking/docking_controller //the controller itself. (micro-controller, not game controller) - + var/arrive_time = 0 //the time at which the shuttle arrives when long jumping /datum/shuttle/proc/short_jump(var/area/origin,var/area/destination) @@ -18,9 +18,9 @@ //it would be cool to play a sound here moving_status = SHUTTLE_WARMUP spawn(warmup_time*10) - if (moving_status == SHUTTLE_IDLE) + if (moving_status == SHUTTLE_IDLE) return //someone cancelled the launch - + moving_status = SHUTTLE_INTRANSIT //shouldn't matter but just to be safe move(origin, destination) moving_status = SHUTTLE_IDLE @@ -32,14 +32,14 @@ //it would be cool to play a sound here moving_status = SHUTTLE_WARMUP spawn(warmup_time*10) - if (moving_status == SHUTTLE_IDLE) + if (moving_status == SHUTTLE_IDLE) return //someone cancelled the launch - + arrive_time = world.time + travel_time*10 moving_status = SHUTTLE_INTRANSIT move(departing, interim, direction) - - + + while (world.time < arrive_time) sleep(5) @@ -82,10 +82,10 @@ if(origin == destination) //world << "cancelling move, shuttle will overlap." return - + if (docking_controller && !docking_controller.undocked()) docking_controller.force_undock() - + var/list/dstturfs = list() var/throwy = world.maxy @@ -122,6 +122,18 @@ if(!M.buckled) M.Weaken(3) + // Power-related checks. If shuttle contains power related machinery, update powernets. + var/update_power = 0 + for(var/obj/machinery/power/P in destination) + update_power = 1 + break + + for(var/obj/structure/cable/C in destination) + update_power = 1 + break + + if(update_power) + makepowernets() return //returns 1 if the shuttle has a valid arrive time diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm index 6a5c493462..5cb28c40e6 100644 --- a/code/modules/shuttles/shuttle_console.dm +++ b/code/modules/shuttles/shuttle_console.dm @@ -67,7 +67,7 @@ /obj/machinery/computer/shuttle_control/Topic(href, href_list) if(..()) - return + return 1 usr.set_machine(src) src.add_fingerprint(usr) diff --git a/code/modules/shuttles/shuttle_emergency.dm b/code/modules/shuttles/shuttle_emergency.dm index 814401cb5a..5215400a4e 100644 --- a/code/modules/shuttles/shuttle_emergency.dm +++ b/code/modules/shuttles/shuttle_emergency.dm @@ -221,7 +221,7 @@ /obj/machinery/computer/shuttle_control/emergency/Topic(href, href_list) if(..()) - return + return 1 if(href_list["removeid"]) var/dna_hash = href_list["removeid"] diff --git a/code/modules/shuttles/shuttles_multi.dm b/code/modules/shuttles/shuttles_multi.dm index 9c2528adaa..e13d1da4ea 100644 --- a/code/modules/shuttles/shuttles_multi.dm +++ b/code/modules/shuttles/shuttles_multi.dm @@ -1,4 +1,4 @@ -//This is a holder for things like the Vox and Nuke shuttle. +//This is a holder for things like the Skipjack and Nuke shuttle. /datum/shuttle/multi_shuttle var/cloaked = 1 @@ -78,7 +78,7 @@ /obj/machinery/computer/shuttle_control/multi/Topic(href, href_list) if(..()) - return + return 1 usr.set_machine(src) src.add_fingerprint(usr) diff --git a/code/datums/spells/area_teleport.dm b/code/modules/spells/area_teleport.dm similarity index 94% rename from code/datums/spells/area_teleport.dm rename to code/modules/spells/area_teleport.dm index b2ced9fa0d..05a8e655ed 100644 --- a/code/datums/spells/area_teleport.dm +++ b/code/modules/spells/area_teleport.dm @@ -1,82 +1,82 @@ -/obj/effect/proc_holder/spell/targeted/area_teleport - name = "Area teleport" - desc = "This spell teleports you to a type of area of your selection." - - var/randomise_selection = 0 //if it lets the usr choose the teleport loc or picks it from the list - var/invocation_area = 1 //if the invocation appends the selected area - -/obj/effect/proc_holder/spell/targeted/area_teleport/perform(list/targets, recharge = 1) - var/thearea = before_cast(targets) - if(!thearea || !cast_check(1)) - revert_cast() - return - invocation(thearea) - spawn(0) - if(charge_type == "recharge" && recharge) - start_recharge() - cast(targets,thearea) - after_cast(targets) - -/obj/effect/proc_holder/spell/targeted/area_teleport/before_cast(list/targets) - var/A = null - - if(!randomise_selection) - A = input("Area to teleport to", "Teleport", A) in teleportlocs - else - A = pick(teleportlocs) - - var/area/thearea = teleportlocs[A] - - return thearea - -/obj/effect/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea) - for(var/mob/living/target in targets) - var/list/L = list() - for(var/turf/T in get_area_turfs(thearea.type)) - if(!T.density) - var/clear = 1 - for(var/obj/O in T) - if(O.density) - clear = 0 - break - if(clear) - L+=T - - if(!L.len) - usr <<"The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry." - return - - if(target && target.buckled) - target.buckled.unbuckle() - - var/list/tempL = L - var/attempt = null - var/success = 0 - while(tempL.len) - attempt = pick(tempL) - success = target.Move(attempt) - if(!success) - tempL.Remove(attempt) - else - break - - if(!success) - target.loc = pick(L) - - return - -/obj/effect/proc_holder/spell/targeted/area_teleport/invocation(area/chosenarea = null) - if(!invocation_area || !chosenarea) - ..() - else - switch(invocation_type) - if("shout") - usr.say("[invocation] [uppertext(chosenarea.name)]") - if(usr.gender==MALE) - playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1) - else - playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1) - if("whisper") - usr.whisper("[invocation] [uppertext(chosenarea.name)]") - +/obj/effect/proc_holder/spell/targeted/area_teleport + name = "Area teleport" + desc = "This spell teleports you to a type of area of your selection." + + var/randomise_selection = 0 //if it lets the usr choose the teleport loc or picks it from the list + var/invocation_area = 1 //if the invocation appends the selected area + +/obj/effect/proc_holder/spell/targeted/area_teleport/perform(list/targets, recharge = 1) + var/thearea = before_cast(targets) + if(!thearea || !cast_check(1)) + revert_cast() + return + invocation(thearea) + spawn(0) + if(charge_type == "recharge" && recharge) + start_recharge() + cast(targets,thearea) + after_cast(targets) + +/obj/effect/proc_holder/spell/targeted/area_teleport/before_cast(list/targets) + var/A = null + + if(!randomise_selection) + A = input("Area to teleport to", "Teleport", A) in teleportlocs + else + A = pick(teleportlocs) + + var/area/thearea = teleportlocs[A] + + return thearea + +/obj/effect/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea) + for(var/mob/living/target in targets) + var/list/L = list() + for(var/turf/T in get_area_turfs(thearea.type)) + if(!T.density) + var/clear = 1 + for(var/obj/O in T) + if(O.density) + clear = 0 + break + if(clear) + L+=T + + if(!L.len) + usr <<"The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry." + return + + if(target && target.buckled) + target.buckled.unbuckle_mob() + + var/list/tempL = L + var/attempt = null + var/success = 0 + while(tempL.len) + attempt = pick(tempL) + success = target.Move(attempt) + if(!success) + tempL.Remove(attempt) + else + break + + if(!success) + target.loc = pick(L) + + return + +/obj/effect/proc_holder/spell/targeted/area_teleport/invocation(area/chosenarea = null) + if(!invocation_area || !chosenarea) + ..() + else + switch(invocation_type) + if("shout") + usr.say("[invocation] [uppertext(chosenarea.name)]") + if(usr.gender==MALE) + playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1) + else + playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1) + if("whisper") + usr.whisper("[invocation] [uppertext(chosenarea.name)]") + return \ No newline at end of file diff --git a/code/datums/spells/conjure.dm b/code/modules/spells/conjure.dm similarity index 96% rename from code/datums/spells/conjure.dm rename to code/modules/spells/conjure.dm index 1a48952451..2034bf931f 100644 --- a/code/datums/spells/conjure.dm +++ b/code/modules/spells/conjure.dm @@ -1,87 +1,87 @@ -/obj/effect/proc_holder/spell/aoe_turf/conjure - name = "Conjure" - desc = "This spell conjures objs of the specified types in range." - - var/list/summon_type = list() //determines what exactly will be summoned - //should be text, like list("/obj/machinery/bot/ed209") - - var/summon_lifespan = 0 // 0=permanent, any other time in deciseconds - var/summon_amt = 1 //amount of objects summoned - var/summon_ignore_density = 0 //if set to 1, adds dense tiles to possible spawn places - var/summon_ignore_prev_spawn_points = 0 //if set to 1, each new object is summoned on a new spawn point - - var/list/newVars = list() //vars of the summoned objects will be replaced with those where they meet - //should have format of list("emagged" = 1,"name" = "Wizard's Justicebot"), for example - var/delay = 1//Go Go Gadget Inheritance - -/obj/effect/proc_holder/spell/aoe_turf/conjure/cast(list/targets) - - for(var/turf/T in targets) - if(T.density && !summon_ignore_density) - targets -= T - playsound(src.loc, 'sound/items/welder.ogg', 50, 1) - - if(do_after(usr,delay)) - for(var/i=0,iSome strange aura is blocking the way!" - src.canmove = 0 - spawn(2) src.canmove = 1 - -/obj/effect/dummy/spell_jaunt/ex_act(blah) - return -/obj/effect/dummy/spell_jaunt/bullet_act(blah) +/obj/effect/proc_holder/spell/targeted/ethereal_jaunt + name = "Ethereal Jaunt" + desc = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls." + + school = "transmutation" + charge_max = 300 + clothes_req = 1 + invocation = "none" + invocation_type = "none" + range = -1 + include_user = 1 + centcomm_cancast = 0 //Prevent people from getting to centcomm + + var phaseshift = 0 + var/jaunt_duration = 50 //in deciseconds + +/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/cast(list/targets) //magnets, so mostly hardcoded + for(var/mob/living/target in targets) + spawn(0) + + if(target.buckled) + var/obj/structure/bed/buckled_to = target.buckled. + buckled_to.unbuckle_mob() + + var/mobloc = get_turf(target.loc) + var/obj/effect/dummy/spell_jaunt/holder = new /obj/effect/dummy/spell_jaunt( mobloc ) + var/atom/movable/overlay/animation = new /atom/movable/overlay( mobloc ) + animation.name = "water" + animation.density = 0 + animation.anchored = 1 + animation.icon = 'icons/mob/mob.dmi' + animation.icon_state = "liquify" + animation.layer = 5 + animation.master = holder + if(phaseshift == 1) + animation.dir = target.dir + flick("phase_shift",animation) + target.loc = holder + target.client.eye = holder + sleep(jaunt_duration) + mobloc = get_turf(target.loc) + animation.loc = mobloc + target.canmove = 0 + sleep(20) + animation.dir = target.dir + flick("phase_shift2",animation) + sleep(5) + if(!target.Move(mobloc)) + for(var/direction in list(1,2,4,8,5,6,9,10)) + var/turf/T = get_step(mobloc, direction) + if(T) + if(target.Move(T)) + break + target.canmove = 1 + target.client.eye = target + del(animation) + del(holder) + else + flick("liquify",animation) + target.loc = holder + target.client.eye = holder + var/datum/effect/effect/system/steam_spread/steam = new /datum/effect/effect/system/steam_spread() + steam.set_up(10, 0, mobloc) + steam.start() + sleep(jaunt_duration) + mobloc = get_turf(target.loc) + animation.loc = mobloc + steam.location = mobloc + steam.start() + target.canmove = 0 + sleep(20) + flick("reappear",animation) + sleep(5) + if(!target.Move(mobloc)) + for(var/direction in list(1,2,4,8,5,6,9,10)) + var/turf/T = get_step(mobloc, direction) + if(T) + if(target.Move(T)) + break + target.canmove = 1 + target.client.eye = target + del(animation) + del(holder) + +/obj/effect/dummy/spell_jaunt + name = "water" + icon = 'icons/effects/effects.dmi' + icon_state = "nothing" + var/canmove = 1 + density = 0 + anchored = 1 + +/obj/effect/dummy/spell_jaunt/relaymove(var/mob/user, direction) + if (!src.canmove) return + var/turf/newLoc = get_step(src,direction) + if(!(newLoc.flags & NOJAUNT)) + loc = newLoc + else + user << "Some strange aura is blocking the way!" + src.canmove = 0 + spawn(2) src.canmove = 1 + +/obj/effect/dummy/spell_jaunt/ex_act(blah) + return +/obj/effect/dummy/spell_jaunt/bullet_act(blah) return \ No newline at end of file diff --git a/code/datums/spells/explosion.dm b/code/modules/spells/explosion.dm similarity index 94% rename from code/datums/spells/explosion.dm rename to code/modules/spells/explosion.dm index 7bb7195c2d..b93667ab47 100644 --- a/code/datums/spells/explosion.dm +++ b/code/modules/spells/explosion.dm @@ -1,15 +1,15 @@ -/obj/effect/proc_holder/spell/targeted/explosion - name = "Explosion" - desc = "This spell explodes an area." - - var/ex_severe = 1 - var/ex_heavy = 2 - var/ex_light = 3 - var/ex_flash = 4 - -/obj/effect/proc_holder/spell/targeted/explosion/cast(list/targets) - - for(var/mob/living/target in targets) - explosion(target.loc,ex_severe,ex_heavy,ex_light,ex_flash) - +/obj/effect/proc_holder/spell/targeted/explosion + name = "Explosion" + desc = "This spell explodes an area." + + var/ex_severe = 1 + var/ex_heavy = 2 + var/ex_light = 3 + var/ex_flash = 4 + +/obj/effect/proc_holder/spell/targeted/explosion/cast(list/targets) + + for(var/mob/living/target in targets) + explosion(target.loc,ex_severe,ex_heavy,ex_light,ex_flash) + return \ No newline at end of file diff --git a/code/datums/spells/genetic.dm b/code/modules/spells/genetic.dm similarity index 95% rename from code/datums/spells/genetic.dm rename to code/modules/spells/genetic.dm index cff51ec6ff..bcb7d04280 100644 --- a/code/datums/spells/genetic.dm +++ b/code/modules/spells/genetic.dm @@ -1,31 +1,31 @@ -/obj/effect/proc_holder/spell/targeted/genetic - name = "Genetic" - desc = "This spell inflicts a set of mutations and disabilities upon the target." - - var/disabilities = 0 //bits - var/list/mutations = list() //mutation strings - var/duration = 100 //deciseconds - /* - Disabilities - 1st bit - ? - 2nd bit - ? - 3rd bit - ? - 4th bit - ? - 5th bit - ? - 6th bit - ? - */ - -/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets) - - for(var/mob/living/target in targets) - for(var/x in mutations) - target.mutations.Add(x) - target.disabilities |= disabilities - target.update_mutations() //update target's mutation overlays - spawn(duration) - for(var/x in mutations) - target.mutations.Remove(x) - target.disabilities &= ~disabilities - target.update_mutations() - +/obj/effect/proc_holder/spell/targeted/genetic + name = "Genetic" + desc = "This spell inflicts a set of mutations and disabilities upon the target." + + var/disabilities = 0 //bits + var/list/mutations = list() //mutation strings + var/duration = 100 //deciseconds + /* + Disabilities + 1st bit - ? + 2nd bit - ? + 3rd bit - ? + 4th bit - ? + 5th bit - ? + 6th bit - ? + */ + +/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets) + + for(var/mob/living/target in targets) + for(var/x in mutations) + target.mutations.Add(x) + target.disabilities |= disabilities + target.update_mutations() //update target's mutation overlays + spawn(duration) + for(var/x in mutations) + target.mutations.Remove(x) + target.disabilities &= ~disabilities + target.update_mutations() + return \ No newline at end of file diff --git a/code/datums/spells/horsemask.dm b/code/modules/spells/horsemask.dm similarity index 93% rename from code/datums/spells/horsemask.dm rename to code/modules/spells/horsemask.dm index 2ea66dac57..32e362f346 100644 --- a/code/datums/spells/horsemask.dm +++ b/code/modules/spells/horsemask.dm @@ -1,50 +1,50 @@ -/obj/effect/proc_holder/spell/targeted/horsemask - name = "Curse of the Horseman" - desc = "This spell triggers a curse on a target, causing them to wield an unremovable horse head mask. They will speak like a horse! Any masks they are wearing will be disintegrated. This spell does not require robes." - school = "transmutation" - charge_type = "recharge" - charge_max = 150 - charge_counter = 0 - clothes_req = 0 - stat_allowed = 0 - invocation = "KN'A FTAGHU, PUCK 'BTHNK!" - invocation_type = "shout" - range = 7 - selection_type = "range" - var/list/compatible_mobs = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - -/obj/effect/proc_holder/spell/targeted/horsemask/cast(list/targets, mob/user = usr) - if(!targets.len) - user << "No target found in range." - return - - var/mob/living/carbon/target = targets[1] - - if(!(target.type in compatible_mobs)) - user << "It'd be stupid to curse [target] with a horse's head!" - return - - if(!(target in oview(range)))//If they are not in overview after selection. - user << "They are too far away!" - return - - var/obj/item/clothing/mask/horsehead/magic/magichead = new /obj/item/clothing/mask/horsehead/magic - target.visible_message( "[target]'s face lights up in fire, and after the event a horse's head takes its place!", \ - "Your face burns up, and shortly after the fire you realise you have the face of a horse!") - target.equip_to_slot(magichead, slot_wear_mask) - - flick("e_flash", target.flash) - -//item used by the horsehead spell -/obj/item/clothing/mask/horsehead/magic - //flags_inv = null //so you can still see their face... no. How can you recognize someone when their face is completely different? - voicechange = 1 //NEEEEIIGHH - - dropped(mob/user as mob) - canremove = 1 - ..() - - equipped(var/mob/user, var/slot) - if (slot == slot_wear_mask) - canremove = 0 //curses! - ..() +/obj/effect/proc_holder/spell/targeted/horsemask + name = "Curse of the Horseman" + desc = "This spell triggers a curse on a target, causing them to wield an unremovable horse head mask. They will speak like a horse! Any masks they are wearing will be disintegrated. This spell does not require robes." + school = "transmutation" + charge_type = "recharge" + charge_max = 150 + charge_counter = 0 + clothes_req = 0 + stat_allowed = 0 + invocation = "KN'A FTAGHU, PUCK 'BTHNK!" + invocation_type = "shout" + range = 7 + selection_type = "range" + var/list/compatible_mobs = list(/mob/living/carbon/human) + +/obj/effect/proc_holder/spell/targeted/horsemask/cast(list/targets, mob/user = usr) + if(!targets.len) + user << "No target found in range." + return + + var/mob/living/carbon/target = targets[1] + + if(!(target.type in compatible_mobs)) + user << "It'd be stupid to curse [target] with a horse's head!" + return + + if(!(target in oview(range)))//If they are not in overview after selection. + user << "They are too far away!" + return + + var/obj/item/clothing/mask/horsehead/magic/magichead = new /obj/item/clothing/mask/horsehead/magic + target.visible_message( "[target]'s face lights up in fire, and after the event a horse's head takes its place!", \ + "Your face burns up, and shortly after the fire you realise you have the face of a horse!") + target.equip_to_slot(magichead, slot_wear_mask) + + flick("e_flash", target.flash) + +//item used by the horsehead spell +/obj/item/clothing/mask/horsehead/magic + //flags_inv = null //so you can still see their face... no. How can you recognize someone when their face is completely different? + voicechange = 1 //NEEEEIIGHH + + dropped(mob/user as mob) + canremove = 1 + ..() + + equipped(var/mob/user, var/slot) + if (slot == slot_wear_mask) + canremove = 0 //curses! + ..() diff --git a/code/datums/spells/inflict_handler.dm b/code/modules/spells/inflict_handler.dm similarity index 92% rename from code/datums/spells/inflict_handler.dm rename to code/modules/spells/inflict_handler.dm index 496eac9195..34b810d309 100644 --- a/code/datums/spells/inflict_handler.dm +++ b/code/modules/spells/inflict_handler.dm @@ -1,59 +1,59 @@ -/obj/effect/proc_holder/spell/targeted/inflict_handler - name = "Inflict Handler" - desc = "This spell blinds and/or destroys/damages/heals and/or weakens/stuns the target." - - var/amt_weakened = 0 - var/amt_paralysis = 0 - var/amt_stunned = 0 - - //set to negatives for healing - var/amt_dam_fire = 0 - var/amt_dam_brute = 0 - var/amt_dam_oxy = 0 - var/amt_dam_tox = 0 - - var/amt_eye_blind = 0 - var/amt_eye_blurry = 0 - - var/destroys = "none" //can be "none", "gib" or "disintegrate" - -/obj/effect/proc_holder/spell/targeted/inflict_handler/cast(list/targets) - - for(var/mob/living/target in targets) - switch(destroys) - if("gib") - target.gib() - if("gib_brain") - if(ishuman(target) || ismonkey(target)) - var/mob/living/carbon/C = target - if(!C.has_brain()) // Their brain is already taken out - var/obj/item/organ/brain/B = new(C.loc) - B.transfer_identity(C) - target.gib() - if("disintegrate") - target.dust() - - if(!target) - continue - //damage - if(amt_dam_brute > 0) - if(amt_dam_fire >= 0) - target.take_overall_damage(amt_dam_brute,amt_dam_fire) - else if (amt_dam_fire < 0) - target.take_overall_damage(amt_dam_brute,0) - target.heal_overall_damage(0,amt_dam_fire) - else if(amt_dam_brute < 0) - if(amt_dam_fire > 0) - target.take_overall_damage(0,amt_dam_fire) - target.heal_overall_damage(amt_dam_brute,0) - else if (amt_dam_fire <= 0) - target.heal_overall_damage(amt_dam_brute,amt_dam_fire) - target.adjustToxLoss(amt_dam_tox) - target.oxyloss += amt_dam_oxy - //disabling - target.Weaken(amt_weakened) - target.Paralyse(amt_paralysis) - target.Stun(amt_stunned) - - target.eye_blind += amt_eye_blind +/obj/effect/proc_holder/spell/targeted/inflict_handler + name = "Inflict Handler" + desc = "This spell blinds and/or destroys/damages/heals and/or weakens/stuns the target." + + var/amt_weakened = 0 + var/amt_paralysis = 0 + var/amt_stunned = 0 + + //set to negatives for healing + var/amt_dam_fire = 0 + var/amt_dam_brute = 0 + var/amt_dam_oxy = 0 + var/amt_dam_tox = 0 + + var/amt_eye_blind = 0 + var/amt_eye_blurry = 0 + + var/destroys = "none" //can be "none", "gib" or "disintegrate" + +/obj/effect/proc_holder/spell/targeted/inflict_handler/cast(list/targets) + + for(var/mob/living/target in targets) + switch(destroys) + if("gib") + target.gib() + if("gib_brain") + if(ishuman(target) || issmall(target)) + var/mob/living/carbon/C = target + if(!C.has_brain()) // Their brain is already taken out + var/obj/item/organ/brain/B = new(C.loc) + B.transfer_identity(C) + target.gib() + if("disintegrate") + target.dust() + + if(!target) + continue + //damage + if(amt_dam_brute > 0) + if(amt_dam_fire >= 0) + target.take_overall_damage(amt_dam_brute,amt_dam_fire) + else if (amt_dam_fire < 0) + target.take_overall_damage(amt_dam_brute,0) + target.heal_overall_damage(0,amt_dam_fire) + else if(amt_dam_brute < 0) + if(amt_dam_fire > 0) + target.take_overall_damage(0,amt_dam_fire) + target.heal_overall_damage(amt_dam_brute,0) + else if (amt_dam_fire <= 0) + target.heal_overall_damage(amt_dam_brute,amt_dam_fire) + target.adjustToxLoss(amt_dam_tox) + target.oxyloss += amt_dam_oxy + //disabling + target.Weaken(amt_weakened) + target.Paralyse(amt_paralysis) + target.Stun(amt_stunned) + + target.eye_blind += amt_eye_blind target.eye_blurry += amt_eye_blurry \ No newline at end of file diff --git a/code/datums/spells/knock.dm b/code/modules/spells/knock.dm similarity index 83% rename from code/datums/spells/knock.dm rename to code/modules/spells/knock.dm index 48ba2c633c..9ebf664942 100644 --- a/code/datums/spells/knock.dm +++ b/code/modules/spells/knock.dm @@ -1,19 +1,20 @@ -/obj/effect/proc_holder/spell/aoe_turf/knock - name = "Knock" - desc = "This spell opens nearby doors and does not require wizard garb." - - school = "transmutation" - charge_max = 100 - clothes_req = 0 - invocation = "AULIE OXIN FIERA" - invocation_type = "whisper" - range = 3 - -/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets) - for(var/turf/T in targets) - for(var/obj/machinery/door/door in T.contents) - spawn(1) - if(istype(door,/obj/machinery/door/airlock)) - door:unlock(1) //forced because it's magic! - door.open() - return \ No newline at end of file +/obj/effect/proc_holder/spell/aoe_turf/knock + name = "Knock" + desc = "This spell opens nearby doors and does not require wizard garb." + + school = "transmutation" + charge_max = 100 + clothes_req = 0 + invocation = "AULIE OXIN FIERA" + invocation_type = "whisper" + range = 3 + +/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets) + for(var/turf/T in targets) + for(var/obj/machinery/door/door in T.contents) + spawn(1) + if(istype(door,/obj/machinery/door/airlock)) + var/obj/machinery/door/airlock/A = door + A.unlock(1) //forced because it's magic! + door.open() + return diff --git a/code/datums/spells/mind_transfer.dm b/code/modules/spells/mind_transfer.dm similarity index 95% rename from code/datums/spells/mind_transfer.dm rename to code/modules/spells/mind_transfer.dm index 61c6f980fd..a4f8258ff7 100644 --- a/code/datums/spells/mind_transfer.dm +++ b/code/modules/spells/mind_transfer.dm @@ -9,7 +9,7 @@ invocation_type = "whisper" range = 1 var/list/protected_roles = list("Wizard","Changeling","Cultist") //which roles are immune to the spell - var/list/compatible_mobs = list(/mob/living/carbon/human,/mob/living/carbon/monkey) //which types of mobs are affected by the spell. NOTE: change at your own risk + var/list/compatible_mobs = list(/mob/living/carbon/human) //which types of mobs are affected by the spell. NOTE: change at your own risk var/base_spell_loss_chance = 20 //base probability of the wizard losing a spell in the process var/spell_loss_chance_modifier = 7 //amount of probability of losing a spell added per spell (mind_transfer included) var/spell_loss_amount = 1 //the maximum amount of spells possible to lose during a single transfer diff --git a/code/datums/spells/projectile.dm b/code/modules/spells/projectile.dm similarity index 96% rename from code/datums/spells/projectile.dm rename to code/modules/spells/projectile.dm index 9bd1a34f18..24c79a0a1c 100644 --- a/code/datums/spells/projectile.dm +++ b/code/modules/spells/projectile.dm @@ -1,83 +1,83 @@ -/obj/effect/proc_holder/spell/targeted/projectile - name = "Projectile" - desc = "This spell summons projectiles which try to hit the targets." - - var/proj_icon = 'icons/obj/projectiles.dmi' - var/proj_icon_state = "spell" - var/proj_name = "a spell projectile" - - var/proj_trail = 0 //if it leaves a trail - var/proj_trail_lifespan = 0 //deciseconds - var/proj_trail_icon = 'icons/obj/wizard.dmi' - var/proj_trail_icon_state = "trail" - - var/proj_type = "/obj/effect/proc_holder/spell/targeted" //IMPORTANT use only subtypes of this - - var/proj_lingering = 0 //if it lingers or disappears upon hitting an obstacle - var/proj_homing = 1 //if it follows the target - var/proj_insubstantial = 0 //if it can pass through dense objects or not - var/proj_trigger_range = 0 //the range from target at which the projectile triggers cast(target) - - var/proj_lifespan = 15 //in deciseconds * proj_step_delay - var/proj_step_delay = 1 //lower = faster - -/obj/effect/proc_holder/spell/targeted/projectile/cast(list/targets, mob/user = usr) - - for(var/mob/living/target in targets) - spawn(0) - var/obj/effect/proc_holder/spell/targeted/projectile - if(istext(proj_type)) - var/projectile_type = text2path(proj_type) - projectile = new projectile_type(user) - if(istype(proj_type,/obj/effect/proc_holder/spell)) - projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user) - projectile:linked_spells += proj_type - projectile.icon = proj_icon - projectile.icon_state = proj_icon_state - projectile.set_dir(get_dir(target,projectile)) - projectile.name = proj_name - - var/current_loc = usr.loc - - projectile.loc = current_loc - - for(var/i = 0,i < proj_lifespan,i++) - if(!projectile) - break - - if(proj_homing) - if(proj_insubstantial) - projectile.set_dir(get_dir(projectile,target)) - projectile.loc = get_step_to(projectile,target) - else - step_to(projectile,target) - else - if(proj_insubstantial) - projectile.loc = get_step(projectile,dir) - else - step(projectile,dir) - - if(!proj_lingering && projectile.loc == current_loc) //if it didn't move since last time - del(projectile) - break - - if(proj_trail && projectile) - spawn(0) - if(projectile) - var/obj/effect/overlay/trail = new /obj/effect/overlay(projectile.loc) - trail.icon = proj_trail_icon - trail.icon_state = proj_trail_icon_state - trail.density = 0 - spawn(proj_trail_lifespan) - del(trail) - - if(projectile.loc in range(target.loc,proj_trigger_range)) - projectile.perform(list(target)) - break - - current_loc = projectile.loc - - sleep(proj_step_delay) - - if(projectile) +/obj/effect/proc_holder/spell/targeted/projectile + name = "Projectile" + desc = "This spell summons projectiles which try to hit the targets." + + var/proj_icon = 'icons/obj/projectiles.dmi' + var/proj_icon_state = "spell" + var/proj_name = "a spell projectile" + + var/proj_trail = 0 //if it leaves a trail + var/proj_trail_lifespan = 0 //deciseconds + var/proj_trail_icon = 'icons/obj/wizard.dmi' + var/proj_trail_icon_state = "trail" + + var/proj_type = "/obj/effect/proc_holder/spell/targeted" //IMPORTANT use only subtypes of this + + var/proj_lingering = 0 //if it lingers or disappears upon hitting an obstacle + var/proj_homing = 1 //if it follows the target + var/proj_insubstantial = 0 //if it can pass through dense objects or not + var/proj_trigger_range = 0 //the range from target at which the projectile triggers cast(target) + + var/proj_lifespan = 15 //in deciseconds * proj_step_delay + var/proj_step_delay = 1 //lower = faster + +/obj/effect/proc_holder/spell/targeted/projectile/cast(list/targets, mob/user = usr) + + for(var/mob/living/target in targets) + spawn(0) + var/obj/effect/proc_holder/spell/targeted/projectile + if(istext(proj_type)) + var/projectile_type = text2path(proj_type) + projectile = new projectile_type(user) + if(istype(proj_type,/obj/effect/proc_holder/spell)) + projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user) + projectile:linked_spells += proj_type + projectile.icon = proj_icon + projectile.icon_state = proj_icon_state + projectile.set_dir(get_dir(target,projectile)) + projectile.name = proj_name + + var/current_loc = usr.loc + + projectile.loc = current_loc + + for(var/i = 0,i < proj_lifespan,i++) + if(!projectile) + break + + if(proj_homing) + if(proj_insubstantial) + projectile.set_dir(get_dir(projectile,target)) + projectile.loc = get_step_to(projectile,target) + else + step_to(projectile,target) + else + if(proj_insubstantial) + projectile.loc = get_step(projectile,dir) + else + step(projectile,dir) + + if(!proj_lingering && projectile.loc == current_loc) //if it didn't move since last time + del(projectile) + break + + if(proj_trail && projectile) + spawn(0) + if(projectile) + var/obj/effect/overlay/trail = new /obj/effect/overlay(projectile.loc) + trail.icon = proj_trail_icon + trail.icon_state = proj_trail_icon_state + trail.density = 0 + spawn(proj_trail_lifespan) + del(trail) + + if(projectile.loc in range(target.loc,proj_trigger_range)) + projectile.perform(list(target)) + break + + current_loc = projectile.loc + + sleep(proj_step_delay) + + if(projectile) del(projectile) \ No newline at end of file diff --git a/code/datums/spell.dm b/code/modules/spells/spell.dm similarity index 92% rename from code/datums/spell.dm rename to code/modules/spells/spell.dm index c7c12b097b..2ae347ee4a 100644 --- a/code/datums/spell.dm +++ b/code/modules/spells/spell.dm @@ -1,286 +1,302 @@ -/obj/effect/proc_holder - var/panel = "Debug"//What panel the proc holder needs to go on. - -var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin verb for now - -/obj/effect/proc_holder/spell - name = "Spell" - desc = "A wizard spell" - density = 0 - opacity = 0 - - var/school = "evocation" //not relevant at now, but may be important later if there are changes to how spells work. the ones I used for now will probably be changed... maybe spell presets? lacking flexibility but with some other benefit? - - var/charge_type = "recharge" //can be recharge or charges, see charge_max and charge_counter descriptions; can also be based on the holder's vars now, use "holder_var" for that - - var/charge_max = 100 //recharge time in deciseconds if charge_type = "recharge" or starting charges if charge_type = "charges" - var/charge_counter = 0 //can only cast spells if it equals recharge, ++ each decisecond if charge_type = "recharge" or -- each cast if charge_type = "charges" - - var/holder_var_type = "bruteloss" //only used if charge_type equals to "holder_var" - var/holder_var_amount = 20 //same. The amount adjusted with the mob's var when the spell is used - - var/clothes_req = 1 //see if it requires clothes - var/stat_allowed = 0 //see if it requires being conscious/alive, need to set to 1 for ghostpells - var/invocation = "HURP DURP" //what is uttered when the wizard casts the spell - var/invocation_type = "none" //can be none, whisper and shout - var/range = 7 //the range of the spell; outer radius for aoe spells - var/message = "" //whatever it says to the guy affected by it - var/selection_type = "view" //can be "range" or "view" - - var/overlay = 0 - var/overlay_icon = 'icons/obj/wizard.dmi' - var/overlay_icon_state = "spell" - var/overlay_lifespan = 0 - - var/sparks_spread = 0 - var/sparks_amt = 0 //cropped at 10 - var/smoke_spread = 0 //1 - harmless, 2 - harmful - var/smoke_amt = 0 //cropped at 10 - - var/critfailchance = 0 - var/centcomm_cancast = 1 //Whether or not the spell should be allowed on z2 - -/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = 0,mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell - - if(!(src in usr.spell_list)) - usr << "\red You shouldn't have this spell! Something's wrong." - return 0 - - if(usr.z == 2 && !centcomm_cancast) //Certain spells are not allowed on the centcomm zlevel - return 0 - - if(!skipcharge) - switch(charge_type) - if("recharge") - if(charge_counter < charge_max) - usr << "[name] is still recharging." - return 0 - if("charges") - if(!charge_counter) - usr << "[name] has no charges left." - return 0 - - if(usr.stat && !stat_allowed) - usr << "Not when you're incapacitated." - return 0 - - if(ishuman(usr) || ismonkey(usr)) - if(istype(usr.wear_mask, /obj/item/clothing/mask/muzzle)) - usr << "Mmmf mrrfff!" - return 0 - - if(clothes_req) //clothes check - if(!istype(usr, /mob/living/carbon/human)) - usr << "You aren't a human, Why are you trying to cast a human spell, silly non-human? Casting human spells is for humans." - return 0 - if(!istype(usr:wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(user:wear_suit, /obj/item/clothing/suit/space/void/wizard)) - usr << "I don't feel strong enough without my robe." - return 0 - if(!istype(usr:shoes, /obj/item/clothing/shoes/sandal)) - usr << "I don't feel strong enough without my sandals." - return 0 - if(!istype(usr:head, /obj/item/clothing/head/wizard) && !istype(user:head, /obj/item/clothing/head/helmet/space/void/wizard)) - usr << "I don't feel strong enough without my hat." - return 0 - - if(!skipcharge) - switch(charge_type) - if("recharge") - charge_counter = 0 //doesn't start recharging until the targets selecting ends - if("charges") - charge_counter-- //returns the charge if the targets selecting fails - if("holdervar") - adjust_var(user, holder_var_type, holder_var_amount) - - return 1 - -/obj/effect/proc_holder/spell/proc/invocation(mob/user = usr) //spelling the spell out and setting it on recharge/reducing charges amount - - switch(invocation_type) - if("shout") - if(prob(50))//Auto-mute? Fuck that noise - usr.say(invocation) - else - usr.say(replacetext(invocation," ","`")) - if(usr.gender==MALE) - playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1) - else - playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1) - if("whisper") - if(prob(50)) - usr.whisper(invocation) - else - usr.whisper(replacetext(invocation," ","`")) - -/obj/effect/proc_holder/spell/New() - ..() - - charge_counter = charge_max - -/obj/effect/proc_holder/spell/Click() - if(cast_check()) - choose_targets() - return 1 - -/obj/effect/proc_holder/spell/proc/choose_targets(mob/user = usr) //depends on subtype - /targeted or /aoe_turf - return - -/obj/effect/proc_holder/spell/proc/start_recharge() - while(charge_counter < charge_max) - sleep(1) - charge_counter++ - -/obj/effect/proc_holder/spell/proc/perform(list/targets, recharge = 1) //if recharge is started is important for the trigger spells - before_cast(targets) - invocation() - spawn(0) - if(charge_type == "recharge" && recharge) - start_recharge() - if(prob(critfailchance)) - critfail(targets) - else - cast(targets) - after_cast(targets) - -/obj/effect/proc_holder/spell/proc/before_cast(list/targets) - if(overlay) - for(var/atom/target in targets) - var/location - if(istype(target,/mob/living)) - location = target.loc - else if(istype(target,/turf)) - location = target - var/obj/effect/overlay/spell = new /obj/effect/overlay(location) - spell.icon = overlay_icon - spell.icon_state = overlay_icon_state - spell.anchored = 1 - spell.density = 0 - spawn(overlay_lifespan) - del(spell) - -/obj/effect/proc_holder/spell/proc/after_cast(list/targets) - for(var/atom/target in targets) - var/location - if(istype(target,/mob/living)) - location = target.loc - else if(istype(target,/turf)) - location = target - if(istype(target,/mob/living) && message) - target << text("[message]") - if(sparks_spread) - var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread() - sparks.set_up(sparks_amt, 0, location) //no idea what the 0 is - sparks.start() - if(smoke_spread) - if(smoke_spread == 1) - var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread() - smoke.set_up(smoke_amt, 0, location) //no idea what the 0 is - smoke.start() - else if(smoke_spread == 2) - var/datum/effect/effect/system/smoke_spread/bad/smoke = new /datum/effect/effect/system/smoke_spread/bad() - smoke.set_up(smoke_amt, 0, location) //no idea what the 0 is - smoke.start() - -/obj/effect/proc_holder/spell/proc/cast(list/targets) - return - -/obj/effect/proc_holder/spell/proc/critfail(list/targets) - return - -/obj/effect/proc_holder/spell/proc/revert_cast(mob/user = usr) //resets recharge or readds a charge - switch(charge_type) - if("recharge") - charge_counter = charge_max - if("charges") - charge_counter++ - if("holdervar") - adjust_var(user, holder_var_type, -holder_var_amount) - - return - -/obj/effect/proc_holder/spell/proc/adjust_var(mob/living/target = usr, type, amount) //handles the adjustment of the var when the spell is used. has some hardcoded types - switch(type) - if("bruteloss") - target.adjustBruteLoss(amount) - if("fireloss") - target.adjustFireLoss(amount) - if("toxloss") - target.adjustToxLoss(amount) - if("oxyloss") - target.adjustOxyLoss(amount) - if("stunned") - target.AdjustStunned(amount) - if("weakened") - target.AdjustWeakened(amount) - if("paralysis") - target.AdjustParalysis(amount) - else - target.vars[type] += amount //I bear no responsibility for the runtimes that'll happen if you try to adjust non-numeric or even non-existant vars - return - -/obj/effect/proc_holder/spell/targeted //can mean aoe for mobs (limited/unlimited number) or one target mob - var/max_targets = 1 //leave 0 for unlimited targets in range, 1 for one selectable target in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range - var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast - var/include_user = 0 //if it includes usr in the target list - -/obj/effect/proc_holder/spell/aoe_turf //affects all turfs in view or range (depends) - var/inner_radius = -1 //for all your ring spell needs - -/obj/effect/proc_holder/spell/targeted/choose_targets(mob/user = usr) - var/list/targets = list() - - switch(max_targets) - if(0) //unlimited - for(var/mob/living/target in view_or_range(range, user, selection_type)) - targets += target - if(1) //single target can be picked - if(range < 0) - targets += user - else - var/possible_targets = list() - - for(var/mob/living/M in view_or_range(range, user, selection_type)) - if(!include_user && user == M) - continue - possible_targets += M - - targets += input("Choose the target for the spell.", "Targeting") as mob in possible_targets - else - var/list/possible_targets = list() - for(var/mob/living/target in view_or_range(range, user, selection_type)) - possible_targets += target - for(var/i=1,i<=max_targets,i++) - if(!possible_targets.len) - break - if(target_ignore_prev) - var/target = pick(possible_targets) - possible_targets -= target - targets += target - else - targets += pick(possible_targets) - - if(!include_user && (user in targets)) - targets -= user - - if(!targets.len) //doesn't waste the spell - revert_cast(user) - return - - perform(targets) - - return - -/obj/effect/proc_holder/spell/aoe_turf/choose_targets(mob/user = usr) - var/list/targets = list() - - for(var/turf/target in view_or_range(range,user,selection_type)) - if(!(target in view_or_range(inner_radius,user,selection_type))) - targets += target - - if(!targets.len) //doesn't waste the spell - revert_cast() - return - - perform(targets) - +/client/proc/give_spell(mob/T as mob in mob_list) // -- Urist + set category = "Fun" + set name = "Give Spell" + set desc = "Gives a spell to a mob." + var/list/spell_names = list() + for(var/v in spells) + // "/obj/effect/proc_holder/spell/" 30 symbols ~Intercross21 + spell_names.Add(copytext("[v]", 31, 0)) + var/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_names + if(!S) return + var/path = text2path("/obj/effect/proc_holder/spell/[S]") + T.spell_list += new path + feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].") + message_admins("\blue [key_name_admin(usr)] gave [key_name(T)] the spell [S].", 1) + +/obj/effect/proc_holder + var/panel = "Debug"//What panel the proc holder needs to go on. + +var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin verb for now + +/obj/effect/proc_holder/spell + name = "Spell" + desc = "A wizard spell" + density = 0 + opacity = 0 + + var/school = "evocation" //not relevant at now, but may be important later if there are changes to how spells work. the ones I used for now will probably be changed... maybe spell presets? lacking flexibility but with some other benefit? + + var/charge_type = "recharge" //can be recharge or charges, see charge_max and charge_counter descriptions; can also be based on the holder's vars now, use "holder_var" for that + + var/charge_max = 100 //recharge time in deciseconds if charge_type = "recharge" or starting charges if charge_type = "charges" + var/charge_counter = 0 //can only cast spells if it equals recharge, ++ each decisecond if charge_type = "recharge" or -- each cast if charge_type = "charges" + + var/holder_var_type = "bruteloss" //only used if charge_type equals to "holder_var" + var/holder_var_amount = 20 //same. The amount adjusted with the mob's var when the spell is used + + var/clothes_req = 1 //see if it requires clothes + var/stat_allowed = 0 //see if it requires being conscious/alive, need to set to 1 for ghostpells + var/invocation = "HURP DURP" //what is uttered when the wizard casts the spell + var/invocation_type = "none" //can be none, whisper and shout + var/range = 7 //the range of the spell; outer radius for aoe spells + var/message = "" //whatever it says to the guy affected by it + var/selection_type = "view" //can be "range" or "view" + + var/overlay = 0 + var/overlay_icon = 'icons/obj/wizard.dmi' + var/overlay_icon_state = "spell" + var/overlay_lifespan = 0 + + var/sparks_spread = 0 + var/sparks_amt = 0 //cropped at 10 + var/smoke_spread = 0 //1 - harmless, 2 - harmful + var/smoke_amt = 0 //cropped at 10 + + var/critfailchance = 0 + var/centcomm_cancast = 1 //Whether or not the spell should be allowed on z2 + +/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = 0,mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell + + if(!(src in usr.spell_list)) + usr << "\red You shouldn't have this spell! Something's wrong." + return 0 + + if(usr.z == 2 && !centcomm_cancast) //Certain spells are not allowed on the centcomm zlevel + return 0 + + if(!skipcharge) + switch(charge_type) + if("recharge") + if(charge_counter < charge_max) + usr << "[name] is still recharging." + return 0 + if("charges") + if(!charge_counter) + usr << "[name] has no charges left." + return 0 + + if(usr.stat && !stat_allowed) + usr << "Not when you're incapacitated." + return 0 + + if(ishuman(usr) || issmall(usr)) + if(istype(usr.wear_mask, /obj/item/clothing/mask/muzzle)) + usr << "Mmmf mrrfff!" + return 0 + + if(clothes_req) //clothes check + if(!istype(usr, /mob/living/carbon/human)) + usr << "You aren't a human, Why are you trying to cast a human spell, silly non-human? Casting human spells is for humans." + return 0 + if(!istype(usr:wear_suit, /obj/item/clothing/suit/wizrobe) && !istype(user:wear_suit, /obj/item/clothing/suit/space/void/wizard)) + usr << "I don't feel strong enough without my robe." + return 0 + if(!istype(usr:shoes, /obj/item/clothing/shoes/sandal)) + usr << "I don't feel strong enough without my sandals." + return 0 + if(!istype(usr:head, /obj/item/clothing/head/wizard) && !istype(user:head, /obj/item/clothing/head/helmet/space/void/wizard)) + usr << "I don't feel strong enough without my hat." + return 0 + + if(!skipcharge) + switch(charge_type) + if("recharge") + charge_counter = 0 //doesn't start recharging until the targets selecting ends + if("charges") + charge_counter-- //returns the charge if the targets selecting fails + if("holdervar") + adjust_var(user, holder_var_type, holder_var_amount) + + return 1 + +/obj/effect/proc_holder/spell/proc/invocation(mob/user = usr) //spelling the spell out and setting it on recharge/reducing charges amount + + switch(invocation_type) + if("shout") + if(prob(50))//Auto-mute? Fuck that noise + usr.say(invocation) + else + usr.say(replacetext(invocation," ","`")) + if(usr.gender==MALE) + playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1) + else + playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1) + if("whisper") + if(prob(50)) + usr.whisper(invocation) + else + usr.whisper(replacetext(invocation," ","`")) + +/obj/effect/proc_holder/spell/New() + ..() + + charge_counter = charge_max + +/obj/effect/proc_holder/spell/Click() + if(cast_check()) + choose_targets() + return 1 + +/obj/effect/proc_holder/spell/proc/choose_targets(mob/user = usr) //depends on subtype - /targeted or /aoe_turf + return + +/obj/effect/proc_holder/spell/proc/start_recharge() + while(charge_counter < charge_max) + sleep(1) + charge_counter++ + +/obj/effect/proc_holder/spell/proc/perform(list/targets, recharge = 1) //if recharge is started is important for the trigger spells + before_cast(targets) + invocation() + spawn(0) + if(charge_type == "recharge" && recharge) + start_recharge() + if(prob(critfailchance)) + critfail(targets) + else + cast(targets) + after_cast(targets) + +/obj/effect/proc_holder/spell/proc/before_cast(list/targets) + if(overlay) + for(var/atom/target in targets) + var/location + if(istype(target,/mob/living)) + location = target.loc + else if(istype(target,/turf)) + location = target + var/obj/effect/overlay/spell = new /obj/effect/overlay(location) + spell.icon = overlay_icon + spell.icon_state = overlay_icon_state + spell.anchored = 1 + spell.density = 0 + spawn(overlay_lifespan) + del(spell) + +/obj/effect/proc_holder/spell/proc/after_cast(list/targets) + for(var/atom/target in targets) + var/location + if(istype(target,/mob/living)) + location = target.loc + else if(istype(target,/turf)) + location = target + if(istype(target,/mob/living) && message) + target << text("[message]") + if(sparks_spread) + var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread() + sparks.set_up(sparks_amt, 0, location) //no idea what the 0 is + sparks.start() + if(smoke_spread) + if(smoke_spread == 1) + var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread() + smoke.set_up(smoke_amt, 0, location) //no idea what the 0 is + smoke.start() + else if(smoke_spread == 2) + var/datum/effect/effect/system/smoke_spread/bad/smoke = new /datum/effect/effect/system/smoke_spread/bad() + smoke.set_up(smoke_amt, 0, location) //no idea what the 0 is + smoke.start() + +/obj/effect/proc_holder/spell/proc/cast(list/targets) + return + +/obj/effect/proc_holder/spell/proc/critfail(list/targets) + return + +/obj/effect/proc_holder/spell/proc/revert_cast(mob/user = usr) //resets recharge or readds a charge + switch(charge_type) + if("recharge") + charge_counter = charge_max + if("charges") + charge_counter++ + if("holdervar") + adjust_var(user, holder_var_type, -holder_var_amount) + + return + +/obj/effect/proc_holder/spell/proc/adjust_var(mob/living/target = usr, type, amount) //handles the adjustment of the var when the spell is used. has some hardcoded types + switch(type) + if("bruteloss") + target.adjustBruteLoss(amount) + if("fireloss") + target.adjustFireLoss(amount) + if("toxloss") + target.adjustToxLoss(amount) + if("oxyloss") + target.adjustOxyLoss(amount) + if("stunned") + target.AdjustStunned(amount) + if("weakened") + target.AdjustWeakened(amount) + if("paralysis") + target.AdjustParalysis(amount) + else + target.vars[type] += amount //I bear no responsibility for the runtimes that'll happen if you try to adjust non-numeric or even non-existant vars + return + +/obj/effect/proc_holder/spell/targeted //can mean aoe for mobs (limited/unlimited number) or one target mob + var/max_targets = 1 //leave 0 for unlimited targets in range, 1 for one selectable target in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range + var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast + var/include_user = 0 //if it includes usr in the target list + +/obj/effect/proc_holder/spell/aoe_turf //affects all turfs in view or range (depends) + var/inner_radius = -1 //for all your ring spell needs + +/obj/effect/proc_holder/spell/targeted/choose_targets(mob/user = usr) + var/list/targets = list() + + switch(max_targets) + if(0) //unlimited + for(var/mob/living/target in view_or_range(range, user, selection_type)) + targets += target + if(1) //single target can be picked + if(range < 0) + targets += user + else + var/possible_targets = list() + + for(var/mob/living/M in view_or_range(range, user, selection_type)) + if(!include_user && user == M) + continue + possible_targets += M + + targets += input("Choose the target for the spell.", "Targeting") as mob in possible_targets + else + var/list/possible_targets = list() + for(var/mob/living/target in view_or_range(range, user, selection_type)) + possible_targets += target + for(var/i=1,i<=max_targets,i++) + if(!possible_targets.len) + break + if(target_ignore_prev) + var/target = pick(possible_targets) + possible_targets -= target + targets += target + else + targets += pick(possible_targets) + + if(!include_user && (user in targets)) + targets -= user + + if(!targets.len) //doesn't waste the spell + revert_cast(user) + return + + perform(targets) + + return + +/obj/effect/proc_holder/spell/aoe_turf/choose_targets(mob/user = usr) + var/list/targets = list() + + for(var/turf/target in view_or_range(range,user,selection_type)) + if(!(target in view_or_range(inner_radius,user,selection_type))) + targets += target + + if(!targets.len) //doesn't waste the spell + revert_cast() + return + + perform(targets) + return \ No newline at end of file diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/modules/spells/spellbook.dm similarity index 92% rename from code/game/gamemodes/wizard/spellbook.dm rename to code/modules/spells/spellbook.dm index 716045a721..6236f8c35a 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/modules/spells/spellbook.dm @@ -1,208 +1,211 @@ -/obj/item/weapon/spellbook - name = "spell book" - desc = "The legendary book of spells of the wizard." - icon = 'icons/obj/library.dmi' - icon_state ="book" - throw_speed = 1 - throw_range = 5 - w_class = 2.0 - var/uses = 5 - var/temp = null - var/max_uses = 5 - var/op = 1 - - -/obj/item/weapon/spellbook/attack_self(mob/user as mob) - user.set_machine(src) - var/dat - if(temp) - dat = "[temp]

    Clear" - else - dat = "The Book of Spells:
    " - dat += "Spells left to memorize: [uses]
    " - dat += "
    " - dat += "Memorize which spell:
    " - dat += "The number after the spell name is the cooldown time.
    " - dat += "Magic Missile (10)
    " - dat += "Fireball (10)
    " - //dat += "Disintegrate (60)
    " - dat += "Disable Technology (60)
    " - dat += "Smoke (10)
    " - dat += "Blind (30)
    " - dat += "Mind Transfer (60)
    " - dat += "Forcewall (10)
    " - dat += "Blink (2)
    " - dat += "Teleport (60)
    " - dat += "Mutate (60)
    " - dat += "Ethereal Jaunt (60)
    " - dat += "Knock (10)
    " - dat += "Curse of the Horseman (15)
    " -// if(op) -// dat += "Summon Guns (One time use, global spell)
    " - dat += "
    " - dat += "Artefacts:
    " - dat += "Powerful items imbued with eldritch magics. Summoning one will count towards your maximum number of spells.
    " - dat += "It is recommended that only experienced wizards attempt to wield such artefacts.
    " - dat += "
    " - dat += "Staff of Change
    " - dat += "
    " - dat += "Mental Focus
    " - dat += "
    " - dat += "Six Soul Stone Shards and the spell Artificer
    " - dat += "
    " - dat += "Mastercrafted Armor Set
    " - dat += "
    " - dat += "Staff of Animation
    " - dat += "
    " - dat += "Scrying Orb
    " - dat += "
    " - if(op) - dat += "Re-memorize Spells
    " - user << browse(dat, "window=radio") - onclose(user, "radio") - return - -/obj/item/weapon/spellbook/Topic(href, href_list) - ..() - var/mob/living/carbon/human/H = usr - - if(H.stat || H.restrained()) - return - if(!istype(H, /mob/living/carbon/human)) - return 1 - - if(loc == H || (in_range(src, H) && istype(loc, /turf))) - H.set_machine(src) - if(href_list["spell_choice"]) - if(href_list["spell_choice"] == "rememorize") - var/area/wizard_station/A = locate() - if(usr in A.contents) - uses = max_uses - H.spellremove(usr) - temp = "All spells have been removed. You may now memorize a new set of spells." - feedback_add_details("wizard_spell_learned","UM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - else - temp = "You may only re-memorize spells whilst located inside the wizard sanctuary." - else if(uses >= 1 && max_uses >=1) - uses-- - /* - */ - var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", horseman = "Curse of the Horseman", summonguns = "Summon Guns", staffchange = "Staff of Change", mentalfocus = "Mental Focus", soulstone = "Six Soul Stone Shards and the spell Artificer", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation") - var/already_knows = 0 - for(var/obj/effect/proc_holder/spell/aspell in H.spell_list) - if(available_spells[href_list["spell_choice"]] == aspell.name) - already_knows = 1 - temp = "You already know that spell." - uses++ - break - /* - */ - if(!already_knows) - switch(href_list["spell_choice"]) - if("magicmissile") - feedback_add_details("wizard_spell_learned","MM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(H) - temp = "This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage." - if("fireball") - feedback_add_details("wizard_spell_learned","FB") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/dumbfire/fireball(H) - temp = "This spell fires a fireball in the direction you're facing and does not require wizard garb. Be careful not to fire it at people that are standing next to you." - if("disintegrate") - feedback_add_details("wizard_spell_learned","DG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/targeted/inflict_handler/disintegrate(H) - temp = "This spell instantly kills somebody adjacent to you with the vilest of magick. It has a long cooldown." - if("disabletech") - feedback_add_details("wizard_spell_learned","DT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech(H) - temp = "This spell disables all weapons, cameras and most other technology in range." - if("smoke") - feedback_add_details("wizard_spell_learned","SM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/targeted/smoke(H) - temp = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb." - if("blind") - feedback_add_details("wizard_spell_learned","BD") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/targeted/trigger/blind(H) - temp = "This spell temporarly blinds a single person and does not require wizard garb." - if("mindswap") - feedback_add_details("wizard_spell_learned","MT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/targeted/mind_transfer(H) - temp = "This spell allows the user to switch bodies with a target. Careful to not lose your memory in the process." - if("forcewall") - feedback_add_details("wizard_spell_learned","FW") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/forcewall(H) - temp = "This spell creates an unbreakable wall that lasts for 30 seconds and does not need wizard garb." - if("blink") - feedback_add_details("wizard_spell_learned","BL") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(H) - temp = "This spell randomly teleports you a short distance. Useful for evasion or getting into areas if you have patience." - if("teleport") - feedback_add_details("wizard_spell_learned","TP") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(H) - temp = "This spell teleports you to a type of area of your selection. Very useful if you are in danger, but has a decent cooldown, and is unpredictable." - if("mutate") - feedback_add_details("wizard_spell_learned","MU") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/targeted/genetic/mutate(H) - temp = "This spell causes you to turn into a hulk and gain telekinesis for a short while." - if("etherealjaunt") - feedback_add_details("wizard_spell_learned","EJ") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(H) - temp = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls." - if("knock") - feedback_add_details("wizard_spell_learned","KN") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/knock(H) - temp = "This spell opens nearby doors and does not require wizard garb." - if("horseman") - feedback_add_details("wizard_spell_learned","HH") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.spell_list += new /obj/effect/proc_holder/spell/targeted/horsemask(H) - temp = "This spell will curse a person to wear an unremovable horse mask (it has glue on the inside) and speak like a horse. It does not require a wizard garb. Do note the curse will disintegrate the target's current mask if they are wearing one." - if("summonguns") - feedback_add_details("wizard_spell_learned","SG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - H.rightandwrong() - max_uses-- - temp = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill eachother. Just be careful not to get hit in the crossfire!" - if("staffchange") - feedback_add_details("wizard_spell_learned","ST") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - new /obj/item/weapon/gun/energy/staff(get_turf(H)) - temp = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself" - max_uses-- - if("mentalfocus") - feedback_add_details("wizard_spell_learned","MF") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - new /obj/item/weapon/gun/energy/staff/focus(get_turf(H)) - temp = "An artefact that channels the will of the user into destructive bolts of force." - max_uses-- - if("soulstone") - feedback_add_details("wizard_spell_learned","SS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - new /obj/item/weapon/storage/belt/soulstone/full(get_turf(H)) - H.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct(H) - temp = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot." - max_uses-- - if("armor") - feedback_add_details("wizard_spell_learned","HS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - new /obj/item/clothing/shoes/sandal(get_turf(H)) //In case they've lost them. - new /obj/item/clothing/gloves/purple(get_turf(H))//To complete the outfit - new /obj/item/clothing/suit/space/void/wizard(get_turf(H)) - new /obj/item/clothing/head/helmet/space/void/wizard(get_turf(H)) - temp = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space." - max_uses-- - if("staffanimation") - feedback_add_details("wizard_spell_learned","SA") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - new /obj/item/weapon/gun/energy/staff/animate(get_turf(H)) - temp = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines." - max_uses-- - if("scrying") - feedback_add_details("wizard_spell_learned","SO") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells - new /obj/item/weapon/scrying(get_turf(H)) - if (!(XRAY in H.mutations)) - H.mutations.Add(XRAY) - H.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) - H.see_in_dark = 8 - H.see_invisible = SEE_INVISIBLE_LEVEL_TWO - H << "The walls suddenly disappear." - temp = "You have purchased a scrying orb, and gained x-ray vision." - max_uses-- - else - if(href_list["temp"]) - temp = null - attack_self(H) - - return +// This is a bloody terrible place to put the spellbook, but it doesn't belong in the +// roundmode code and the wizard's staff is in weapons.dm for some fucking reason. ~Z + +/obj/item/weapon/spellbook + name = "spell book" + desc = "The legendary book of spells of the wizard." + icon = 'icons/obj/library.dmi' + icon_state ="book" + throw_speed = 1 + throw_range = 5 + w_class = 2.0 + var/uses = 5 + var/temp = null + var/max_uses = 5 + var/op = 1 + + +/obj/item/weapon/spellbook/attack_self(mob/user as mob) + user.set_machine(src) + var/dat + if(temp) + dat = "[temp]

    Clear" + else + dat = "The Book of Spells:
    " + dat += "Spells left to memorize: [uses]
    " + dat += "
    " + dat += "Memorize which spell:
    " + dat += "The number after the spell name is the cooldown time.
    " + dat += "Magic Missile (15)
    " + dat += "Fireball (10)
    " + //dat += "Disintegrate (60)
    " + dat += "Disable Technology (40)
    " + dat += "Smoke (12)
    " + dat += "Blind (30)
    " + dat += "Mind Transfer (60)
    " + dat += "Forcewall (10)
    " + dat += "Blink (2)
    " + dat += "Teleport (60)
    " + dat += "Mutate (40)
    " + dat += "Ethereal Jaunt (30)
    " + dat += "Knock (10)
    " + dat += "Curse of the Horseman (15)
    " +// if(op) +// dat += "Summon Guns (One time use, global spell)
    " + dat += "
    " + dat += "Artefacts:
    " + dat += "Powerful items imbued with eldritch magics. Summoning one will count towards your maximum number of spells.
    " + dat += "It is recommended that only experienced wizards attempt to wield such artefacts.
    " + dat += "
    " + dat += "Staff of Change
    " + dat += "
    " + dat += "Mental Focus
    " + dat += "
    " + dat += "Six Soul Stone Shards and the spell Artificer
    " + dat += "
    " + dat += "Mastercrafted Armor Set
    " + dat += "
    " + dat += "Staff of Animation
    " + dat += "
    " + dat += "Scrying Orb
    " + dat += "
    " + if(op) + dat += "Re-memorize Spells
    " + user << browse(dat, "window=radio") + onclose(user, "radio") + return + +/obj/item/weapon/spellbook/Topic(href, href_list) + ..() + var/mob/living/carbon/human/H = usr + + if(H.stat || H.restrained()) + return + if(!istype(H, /mob/living/carbon/human)) + return 1 + + if(loc == H || (in_range(src, H) && istype(loc, /turf))) + H.set_machine(src) + if(href_list["spell_choice"]) + if(href_list["spell_choice"] == "rememorize") + var/area/wizard_station/A = locate() + if(usr in A.contents) + uses = max_uses + H.spellremove(usr) + temp = "All spells have been removed. You may now memorize a new set of spells." + feedback_add_details("wizard_spell_learned","UM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + else + temp = "You may only re-memorize spells whilst located inside the wizard sanctuary." + else if(uses >= 1 && max_uses >=1) + uses-- + /* + */ + var/list/available_spells = list(magicmissile = "Magic Missile", fireball = "Fireball", disintegrate = "Disintegrate", disabletech = "Disable Tech", smoke = "Smoke", blind = "Blind", mindswap = "Mind Transfer", forcewall = "Forcewall", blink = "Blink", teleport = "Teleport", mutate = "Mutate", etherealjaunt = "Ethereal Jaunt", knock = "Knock", horseman = "Curse of the Horseman", summonguns = "Summon Guns", staffchange = "Staff of Change", mentalfocus = "Mental Focus", soulstone = "Six Soul Stone Shards and the spell Artificer", armor = "Mastercrafted Armor Set", staffanimate = "Staff of Animation") + var/already_knows = 0 + for(var/obj/effect/proc_holder/spell/aspell in H.spell_list) + if(available_spells[href_list["spell_choice"]] == aspell.name) + already_knows = 1 + temp = "You already know that spell." + uses++ + break + /* + */ + if(!already_knows) + switch(href_list["spell_choice"]) + if("magicmissile") + feedback_add_details("wizard_spell_learned","MM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(H) + temp = "This spell fires several, slow moving, magic projectiles at nearby targets. If a projectile hits a target, the target is stunned for some time." + if("fireball") + feedback_add_details("wizard_spell_learned","FB") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/dumbfire/fireball(H) + temp = "This spell fires a fireball in the direction you're facing and does not require wizard garb. Be careful not to fire it at people that are standing next to you." + if("disintegrate") + feedback_add_details("wizard_spell_learned","DG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/targeted/inflict_handler/disintegrate(H) + temp = "This spell instantly kills somebody adjacent to you with the vilest of magick. It has a long cooldown." + if("disabletech") + feedback_add_details("wizard_spell_learned","DT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech(H) + temp = "This spell releases an EMP from your person disabling most technology within range; computers, doors, prosthetics, etc." + if("smoke") + feedback_add_details("wizard_spell_learned","SM") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/targeted/smoke(H) + temp = "This spell spawns a cloud of vision obscuring smoke at your location and does not require wizard garb." + if("blind") + feedback_add_details("wizard_spell_learned","BD") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/targeted/trigger/blind(H) + temp = "This spell temporarly blinds a single person and does not require wizard garb." + if("mindswap") + feedback_add_details("wizard_spell_learned","MT") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/targeted/mind_transfer(H) + temp = "This spell allows the user to switch bodies with a target. Careful to not lose your memory in the process." + if("forcewall") + feedback_add_details("wizard_spell_learned","FW") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/forcewall(H) + temp = "This spell creates an unbreakable wall that lasts for 30 seconds and does not need wizard garb." + if("blink") + feedback_add_details("wizard_spell_learned","BL") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(H) + temp = "This spell randomly teleports you a short distance. Useful for evasion or getting into areas if you have patience." + if("teleport") + feedback_add_details("wizard_spell_learned","TP") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(H) + temp = "This spell teleports you to an area of your selection, and creates a cloud of smoke around you upon arrival. Very useful if you are in danger.." + if("mutate") + feedback_add_details("wizard_spell_learned","MU") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/targeted/genetic/mutate(H) + temp = "This spell causes you to turn into a hulk, gaining super strength and the ability to punch down walls! You also gain the ability to fire lasers from your eyes!" + if("etherealjaunt") + feedback_add_details("wizard_spell_learned","EJ") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(H) + temp = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls." + if("knock") + feedback_add_details("wizard_spell_learned","KN") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/knock(H) + temp = "This spell opens nearby doors and does not require wizard garb." + if("horseman") + feedback_add_details("wizard_spell_learned","HH") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + H.spell_list += new /obj/effect/proc_holder/spell/targeted/horsemask(H) + temp = "This spell will curse a person to wear an unremovable horse mask (it has glue on the inside) and speak like a horse. It does not require a wizard garb. Do note the curse will disintegrate the target's current mask if they are wearing one." + if("summonguns") + feedback_add_details("wizard_spell_learned","SG") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + rightandwrong() + max_uses-- + temp = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill eachother. Just be careful not to get hit in the crossfire!" + if("staffchange") + feedback_add_details("wizard_spell_learned","ST") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + new /obj/item/weapon/gun/energy/staff(get_turf(H)) + temp = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself" + max_uses-- + if("mentalfocus") + feedback_add_details("wizard_spell_learned","MF") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + new /obj/item/weapon/gun/energy/staff/focus(get_turf(H)) + temp = "An artefact that channels the will of the user into destructive bolts of force." + max_uses-- + if("soulstone") + feedback_add_details("wizard_spell_learned","SS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + new /obj/item/weapon/storage/belt/soulstone/full(get_turf(H)) + H.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct(H) + temp = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot." + max_uses-- + if("armor") + feedback_add_details("wizard_spell_learned","HS") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + new /obj/item/clothing/shoes/sandal(get_turf(H)) //In case they've lost them. + new /obj/item/clothing/gloves/purple(get_turf(H))//To complete the outfit + new /obj/item/clothing/suit/space/void/wizard(get_turf(H)) + new /obj/item/clothing/head/helmet/space/void/wizard(get_turf(H)) + temp = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space." + max_uses-- + if("staffanimation") + feedback_add_details("wizard_spell_learned","SA") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + new /obj/item/weapon/gun/energy/staff/animate(get_turf(H)) + temp = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines." + max_uses-- + if("scrying") + feedback_add_details("wizard_spell_learned","SO") //please do not change the abbreviation to keep data processing consistent. Add a unique id to any new spells + new /obj/item/weapon/scrying(get_turf(H)) + if (!(XRAY in H.mutations)) + H.mutations.Add(XRAY) + H.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS) + H.see_in_dark = 8 + H.see_invisible = SEE_INVISIBLE_LEVEL_TWO + H << "The walls suddenly disappear." + temp = "You have purchased a scrying orb, and gained x-ray vision." + max_uses-- + else + if(href_list["temp"]) + temp = null + attack_self(H) + + return diff --git a/code/datums/spells/trigger.dm b/code/modules/spells/trigger.dm similarity index 96% rename from code/datums/spells/trigger.dm rename to code/modules/spells/trigger.dm index 1b7f2b330f..5e2ed8475f 100644 --- a/code/datums/spells/trigger.dm +++ b/code/modules/spells/trigger.dm @@ -1,28 +1,28 @@ -/obj/effect/proc_holder/spell/targeted/trigger - name = "Trigger" - desc = "This spell triggers another spell or a few." - - var/list/linked_spells = list() //those are just referenced by the trigger spell and are unaffected by it directly - var/list/starting_spells = list() //those are added on New() to contents from default spells and are deleted when the trigger spell is deleted to prevent memory leaks - -/obj/effect/proc_holder/spell/targeted/trigger/New() - ..() - - for(var/spell in starting_spells) - var/spell_to_add = text2path(spell) - new spell_to_add(src) //should result in adding to contents, needs testing - -/obj/effect/proc_holder/spell/targeted/trigger/Del() - for(var/spell in contents) - del(spell) - - ..() - -/obj/effect/proc_holder/spell/targeted/trigger/cast(list/targets) - for(var/mob/living/target in targets) - for(var/obj/effect/proc_holder/spell/spell in contents) - spell.perform(list(target),0) - for(var/obj/effect/proc_holder/spell/spell in linked_spells) - spell.perform(list(target),0) - +/obj/effect/proc_holder/spell/targeted/trigger + name = "Trigger" + desc = "This spell triggers another spell or a few." + + var/list/linked_spells = list() //those are just referenced by the trigger spell and are unaffected by it directly + var/list/starting_spells = list() //those are added on New() to contents from default spells and are deleted when the trigger spell is deleted to prevent memory leaks + +/obj/effect/proc_holder/spell/targeted/trigger/New() + ..() + + for(var/spell in starting_spells) + var/spell_to_add = text2path(spell) + new spell_to_add(src) //should result in adding to contents, needs testing + +/obj/effect/proc_holder/spell/targeted/trigger/Del() + for(var/spell in contents) + del(spell) + + ..() + +/obj/effect/proc_holder/spell/targeted/trigger/cast(list/targets) + for(var/mob/living/target in targets) + for(var/obj/effect/proc_holder/spell/spell in contents) + spell.perform(list(target),0) + for(var/obj/effect/proc_holder/spell/spell in linked_spells) + spell.perform(list(target),0) + return \ No newline at end of file diff --git a/code/datums/spells/turf_teleport.dm b/code/modules/spells/turf_teleport.dm similarity index 97% rename from code/datums/spells/turf_teleport.dm rename to code/modules/spells/turf_teleport.dm index 02dd5f71b4..d59bff313a 100644 --- a/code/datums/spells/turf_teleport.dm +++ b/code/modules/spells/turf_teleport.dm @@ -1,34 +1,34 @@ -/obj/effect/proc_holder/spell/targeted/turf_teleport - name = "Turf Teleport" - desc = "This spell teleports the target to the turf in range." - - var/inner_tele_radius = 1 - var/outer_tele_radius = 2 - - var/include_space = 0 //whether it includes space tiles in possible teleport locations - var/include_dense = 0 //whether it includes dense tiles in possible teleport locations - -/obj/effect/proc_holder/spell/targeted/turf_teleport/cast(list/targets) - for(var/mob/living/target in targets) - var/list/turfs = new/list() - for(var/turf/T in range(target,outer_tele_radius)) - if(T in range(target,inner_tele_radius)) continue - if(istype(T,/turf/space) && !include_space) continue - if(T.density && !include_dense) continue - if(T.x>world.maxx-outer_tele_radius || T.xworld.maxy-outer_tele_radius || T.yworld.maxx-outer_tele_radius || T.xworld.maxy-outer_tele_radius || T.y\The [user] touches \a [W] to \the [src] as a silence fills the room...",\ diff --git a/code/modules/surgery/eye.dm b/code/modules/surgery/eye.dm index 0fa9f4863a..81170afc39 100644 --- a/code/modules/surgery/eye.dm +++ b/code/modules/surgery/eye.dm @@ -113,7 +113,7 @@ /datum/surgery_step/eye/cauterize allowed_tools = list( /obj/item/weapon/cautery = 100, \ - /obj/item/clothing/mask/cigarette = 75, \ + /obj/item/clothing/mask/smokable/cigarette = 75, \ /obj/item/weapon/flame/lighter = 50, \ /obj/item/weapon/weldingtool = 25 ) diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm index 50fb64990b..b5b22659f4 100644 --- a/code/modules/surgery/face.dm +++ b/code/modules/surgery/face.dm @@ -103,7 +103,7 @@ /datum/surgery_step/face/cauterize allowed_tools = list( /obj/item/weapon/cautery = 100, \ - /obj/item/clothing/mask/cigarette = 75, \ + /obj/item/clothing/mask/smokable/cigarette = 75, \ /obj/item/weapon/flame/lighter = 50, \ /obj/item/weapon/weldingtool = 25 ) diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index 2642b87cb7..b7a4bfa61c 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -239,7 +239,7 @@ /datum/surgery_step/generic/cauterize allowed_tools = list( /obj/item/weapon/cautery = 100, \ - /obj/item/clothing/mask/cigarette = 75, \ + /obj/item/clothing/mask/smokable/cigarette = 75, \ /obj/item/weapon/flame/lighter = 50, \ /obj/item/weapon/weldingtool = 25 ) diff --git a/code/modules/surgery/headreattach.dm b/code/modules/surgery/headreattach.dm index 76ad0b6201..85a56a754e 100644 --- a/code/modules/surgery/headreattach.dm +++ b/code/modules/surgery/headreattach.dm @@ -119,7 +119,7 @@ /datum/surgery_step/head/prepare allowed_tools = list( /obj/item/weapon/cautery = 100, \ - /obj/item/clothing/mask/cigarette = 75, \ + /obj/item/clothing/mask/smokable/cigarette = 75, \ /obj/item/weapon/flame/lighter = 50, \ /obj/item/weapon/weldingtool = 25 ) diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index 32546da143..9a8c77e480 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -70,7 +70,7 @@ priority = 2 allowed_tools = list( /obj/item/weapon/cautery = 100, \ - /obj/item/clothing/mask/cigarette = 75, \ + /obj/item/clothing/mask/smokable/cigarette = 75, \ /obj/item/weapon/flame/lighter = 50, \ /obj/item/weapon/weldingtool = 25 ) @@ -190,7 +190,7 @@ "\blue You take [obj] out of incision on [target]'s [affected.display_name]s with \the [tool]." ) affected.implants -= obj - target.hud_updateflag |= 1 << IMPLOYAL_HUD + BITSET(target.hud_updateflag, IMPLOYAL_HUD) //Handle possessive brain borers. if(istype(obj,/mob/living/simple_animal/borer)) diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index c6e27d1e04..146cf3eda6 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -58,8 +58,7 @@ /datum/surgery_step/internal/fix_organ allowed_tools = list( /obj/item/stack/medical/advanced/bruise_pack= 100, \ - /obj/item/stack/medical/bruise_pack = 20, \ - /obj/item/stack/medical/bruise_pack/tajaran = 70, \ + /obj/item/stack/medical/bruise_pack = 20 ) min_duration = 70 @@ -82,11 +81,8 @@ var/tool_name = "\the [tool]" if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) tool_name = "regenerative membrane" - if (istype(tool, /obj/item/stack/medical/bruise_pack)) - if (istype(tool, /obj/item/stack/medical/bruise_pack/tajaran)) - tool_name = "the poultice" - else - tool_name = "the bandaid" + else if (istype(tool, /obj/item/stack/medical/bruise_pack)) + tool_name = "the bandaid" if (!hasorgans(target)) return @@ -106,10 +102,7 @@ if (istype(tool, /obj/item/stack/medical/advanced/bruise_pack)) tool_name = "regenerative membrane" if (istype(tool, /obj/item/stack/medical/bruise_pack)) - if (istype(tool, /obj/item/stack/medical/bruise_pack/tajaran)) - tool_name = "the poultice" - else - tool_name = "the bandaid" + tool_name = "the bandaid" if (!hasorgans(target)) return @@ -136,12 +129,9 @@ target.adjustToxLoss(5) else if (istype(tool, /obj/item/stack/medical/bruise_pack)) - if (istype(tool, /obj/item/stack/medical/bruise_pack/tajaran)) - target.adjustToxLoss(7) - else - dam_amt = 5 - target.adjustToxLoss(10) - affected.createwound(CUT, 5) + dam_amt = 5 + target.adjustToxLoss(10) + affected.createwound(CUT, 5) for(var/datum/organ/internal/I in affected.internal_organs) if(I && I.damage > 0) diff --git a/code/modules/surgery/robolimbs.dm b/code/modules/surgery/robolimbs.dm index c1328227ac..7e768bfa06 100644 --- a/code/modules/surgery/robolimbs.dm +++ b/code/modules/surgery/robolimbs.dm @@ -93,7 +93,7 @@ /datum/surgery_step/limb/prepare allowed_tools = list( /obj/item/weapon/cautery = 100, \ - /obj/item/clothing/mask/cigarette = 75, \ + /obj/item/clothing/mask/smokable/cigarette = 75, \ /obj/item/weapon/flame/lighter = 50, \ /obj/item/weapon/weldingtool = 25 ) diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 61d6688a6f..b0626cdc77 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -80,7 +80,7 @@ proc/spread_germs_to_organ(datum/organ/external/E, mob/living/carbon/human/user) proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool) if(!istype(M)) return 0 - if (user.a_intent == "harm") //check for Hippocratic Oath + if (user.a_intent == I_HURT) //check for Hippocratic Oath return 0 var/zone = user.zone_sel.selecting if(zone in M.op_stage.in_progress) //Can't operate on someone repeatedly. @@ -103,9 +103,12 @@ proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool) else // This failing silently was a pain. user << "\red You must remain close to your patient to conduct surgery." M.op_stage.in_progress -= zone // Clear the in-progress flag. + if (ishuman(M)) + var/mob/living/carbon/human/H = M + H.update_surgery() return 1 //don't want to do weapony things after surgery - if (user.a_intent == "help") + if (user.a_intent == I_HELP) user << "\red You can't see any useful way to use [tool] on [M]." return 1 return 0 diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index 072423d496..c39c8ec047 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -13,6 +13,10 @@ animate_movement=1 luminosity = 3 + can_buckle = 1 + buckle_movable = 1 + buckle_lying = 0 + var/attack_log = null var/on = 0 var/health = 0 //do not forget to set health for your vehicle! @@ -25,7 +29,6 @@ var/emagged = 0 var/powered = 0 //set if vehicle is powered and should use fuel when moving var/move_delay = 1 //set this to limit the speed of the vehicle - var/movable = 1 var/obj/item/weapon/cell/cell var/charge_use = 5 //set this to adjust the amount of power the vehicle uses per move @@ -111,7 +114,8 @@ ..() /obj/vehicle/bullet_act(var/obj/item/projectile/Proj) - health -= Proj.damage + if (Proj.damage_type == BRUTE || Proj.damage_type == BURN) + health -= Proj.damage ..() healthcheck() @@ -298,9 +302,7 @@ C.layer = layer + 0.1 //so it sits above the vehicle if(ismob(C)) - var/mob/M = C - M.buckled = src - M.update_canmove() + buckle_mob(C) return 1 @@ -343,10 +345,7 @@ load.layer = initial(load.layer) if(ismob(load)) - var/mob/M = load - M.buckled = null - M.anchored = initial(M.anchored) - M.update_canmove() + unbuckle_mob(load) load = null diff --git a/code/modules/virus2/admin.dm b/code/modules/virus2/admin.dm new file mode 100644 index 0000000000..88876da9ed --- /dev/null +++ b/code/modules/virus2/admin.dm @@ -0,0 +1,200 @@ +/datum/disease2/disease/Topic(href, href_list) + . = ..() + if(.) return + + if(href_list["info"]) + // spawn or admin privileges to see info about viruses + if(!check_rights(R_ADMIN|R_SPAWN)) return + + usr << "Infection chance: [infectionchance]; Speed: [speed]; Spread type: [spreadtype]" + usr << "Affected species: [english_list(affected_species)]" + usr << "Effects:" + for(var/datum/disease2/effectholder/E in effects) + usr << "[E.stage]: [E.effect.name]; chance=[E.chance]; multiplier=[E.multiplier]" + usr << "Antigens: [antigens2string(antigen)]" + + return 1 + +/datum/admins/var/datum/virus2_editor/virus2_editor_datum = new +/client/proc/virus2_editor() + set name = "Virus Editor" + set category = "Admin" + if(!holder || !check_rights(R_SPAWN)) return // spawn privileges to create viruses + + holder.virus2_editor_datum.show_ui(src) + +/datum/virus2_editor + var/list/s = list(/datum/disease2/effect/invisible,/datum/disease2/effect/invisible,/datum/disease2/effect/invisible,/datum/disease2/effect/invisible) + var/list/s_chance = list(1,1,1,1) + var/list/s_multiplier = list(1,1,1,1) + var/species = list() + var/infectionchance = 70 + var/spreadtype = "Contact" + var/list/antigens = list() + var/speed = 1 + var/mob/living/carbon/infectee = null + + // this holds spawned viruses so that the "Info" links work after the proc exits + var/list/spawned_viruses = list() + + proc/select(mob/user, stage) + if(stage < 1 || stage > 4) return + + var/list/L = list() + + for(var/e in (typesof(/datum/disease2/effect) - /datum/disease2/effect)) + var/datum/disease2/effect/f = e + if(initial(f.stage) <= stage) + L[initial(f.name)] = e + + var/datum/disease2/effect/Eff = s[stage] + + var/C = input("Select effect for stage [stage]:", "Stage [stage]", initial(Eff.name)) as null|anything in L + if(!C) return + return L[C] + + proc/show_ui(mob/user) + var/H = {" +

    Virus2 Virus Editor


    + Effects:
    + "} + for(var/i = 1 to 4) + var/datum/disease2/effect/Eff = s[i] + H += {" + [initial(Eff.name)] + Chance: [s_chance[i]] + Multiplier: [s_multiplier[i]] +
    + "} + H += {" +
    + Infectable Species:
    + "} + var/f = 1 + for(var/k in all_species) + var/datum/species/S = all_species[k] + if(!(S.flags & IS_SYNTHETIC)) + if(!f) H += " | " + else f = 0 + H += "[k]" + H += {" + Reset +
    + Infection Chance: [infectionchance]
    + Spread Type: [spreadtype]
    + Speed: [speed]
    +
    + "} + f = 1 + for(var/k in ALL_ANTIGENS) + if(!f) H += " | " + else f = 0 + H += "[k]" + H += {" + Reset +
    +
    + Initial infectee: [infectee ? infectee : "(choose)"] + RELEASE + "} + + user << browse(H, "window=virus2edit") + + Topic(href, href_list) + switch(href_list["what"]) + if("effect") + var/stage = text2num(href_list["stage"]) + if(href_list["effect"]) + var/datum/disease2/effect/E = select(usr,stage) + if(!E) return + s[stage] = E + // set a default chance and multiplier of half the maximum (roughly average) + s_chance[stage] = max(1, round(initial(E.chance_maxm)/2)) + s_multiplier[stage] = max(1, round(initial(E.maxm)/2)) + else if(href_list["chance"]) + var/datum/disease2/effect/Eff = s[stage] + var/I = input("Chance, per tick, of this effect happening (min 0, max [initial(Eff.chance_maxm)])", "Effect Chance", s_chance[stage]) as null|num + if(I == null || I < 0 || I > initial(Eff.chance_maxm)) return + s_chance[stage] = I + else if(href_list["multiplier"]) + var/datum/disease2/effect/Eff = s[stage] + var/I = input("Multiplier for this effect (min 1, max [initial(Eff.maxm)])", "Effect Multiplier", s_multiplier[stage]) as null|num + if(I == null || I < 1 || I > initial(Eff.maxm)) return + s_multiplier[stage] = I + if("species") + if(href_list["toggle"]) + var/T = href_list["toggle"] + if(T in species) + species -= T + else + species |= T + else if(href_list["reset"]) + species = list() + if(infectee) + if(!infectee.species || !(infectee.species.name in species)) + infectee = null + if("ichance") + var/I = input("Input infection chance", "Infection Chance", infectionchance) as null|num + if(!I) return + infectionchance = I + if("stype") + var/S = alert("Which spread type?", "Spread Type", "Cancel", "Contact", "Airborne") + if(!S || S == "Cancel") return + spreadtype = S + if("speed") + var/S = input("Input speed", "Speed", speed) as null|num + if(!S) return + speed = S + if("antigen") + if(href_list["toggle"]) + var/T = href_list["toggle"] + if(length(T) != 1) return + if(T in antigens) + antigens -= T + else + antigens |= T + else if(href_list["reset"]) + antigens = list() + if("infectee") + var/list/candidates = list() + for(var/mob/living/carbon/G in living_mob_list) + if(G.stat != DEAD && G.species) + if(G.species.name in species) + candidates["[G.name][G.client ? "" : " (no client)"]"] = G + else + candidates["[G.name] ([G.species.name])[G.client ? "" : " (no client)"]"] = G + if(!candidates.len) usr << "No possible candidates found!" + + var/I = input("Choose initial infectee", "Infectee", infectee) as null|anything in candidates + if(!I || !candidates[I]) return + infectee = candidates[I] + species |= infectee.species.name + if("go") + if(!antigens.len) + var/a = alert("This disease has no antigens; it will be impossible to permanently immunise anyone without them.\ + It is strongly recommended to set at least one antigen. Do you want to go back and edit your virus?", "Antigens", "Yes", "Yes", "No") + if(a == "Yes") return + var/datum/disease2/disease/D = new + D.infectionchance = infectionchance + D.spreadtype = spreadtype + D.antigen = antigens + D.affected_species = species + D.speed = speed + for(var/i in 1 to 4) + var/datum/disease2/effectholder/E = new + var/Etype = s[i] + E.effect = new Etype() + E.effect.generate() + E.chance = s_chance[i] + E.multiplier = s_multiplier[i] + E.stage = i + + D.effects += E + + spawned_viruses += D + + message_admins("[key_name_admin(usr)] infected [key_name_admin(infectee)] with a virus (Info)") + log_admin("[key_name_admin(usr)] infected [key_name_admin(infectee)] with a virus!") + infect_virus2(infectee, D, forced=1) + + show_ui(usr) diff --git a/code/modules/virus2/analyser.dm b/code/modules/virus2/analyser.dm index 8046c48af0..1bd3b3053c 100644 --- a/code/modules/virus2/analyser.dm +++ b/code/modules/virus2/analyser.dm @@ -1,5 +1,5 @@ /obj/machinery/disease2/diseaseanalyser - name = "Disease Analyser" + name = "disease analyser" icon = 'icons/obj/virology.dmi' icon_state = "analyser" anchored = 1 @@ -43,7 +43,9 @@
    Additional Notes:  "} + dish.basic_info = dish.virus2.get_basic_info() dish.info = r + dish.name = "[initial(dish.name)] ([dish.virus2.name()])" dish.analysed = 1 dish.loc = src.loc dish = null diff --git a/code/modules/virus2/antibodies.dm b/code/modules/virus2/antibodies.dm index 9d4c63ae2c..e203560e6d 100644 --- a/code/modules/virus2/antibodies.dm +++ b/code/modules/virus2/antibodies.dm @@ -1,37 +1,55 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33 +/* // reserving some numbers for later special antigens var/global/const/ANTIGEN_A = 1 var/global/const/ANTIGEN_B = 2 -var/global/const/ANTIGEN_RH = 4 -var/global/const/ANTIGEN_Q = 8 -var/global/const/ANTIGEN_U = 16 -var/global/const/ANTIGEN_V = 32 -var/global/const/ANTIGEN_X = 64 -var/global/const/ANTIGEN_Y = 128 -var/global/const/ANTIGEN_Z = 256 -var/global/const/ANTIGEN_M = 512 -var/global/const/ANTIGEN_N = 1024 -var/global/const/ANTIGEN_P = 2048 -var/global/const/ANTIGEN_O = 4096 +var/global/const/ANTIGEN_C = 4 +var/global/const/ANTIGEN_D = 8 +var/global/const/ANTIGEN_E = 16 +var/global/const/ANTIGEN_M = 32 +var/global/const/ANTIGEN_N = 64 +var/global/const/ANTIGEN_O = 128 +var/global/const/ANTIGEN_P = 256 +var/global/const/ANTIGEN_Q = 512 +var/global/const/ANTIGEN_U = 1024 +var/global/const/ANTIGEN_V = 2048 +var/global/const/ANTIGEN_W = 4096 +var/global/const/ANTIGEN_X = 8192 +var/global/const/ANTIGEN_Y = 16384 +var/global/const/ANTIGEN_Z = 32768 var/global/list/ANTIGENS = list( "[ANTIGEN_A]" = "A", "[ANTIGEN_B]" = "B", -"[ANTIGEN_RH]" = "RH", +"[ANTIGEN_C]" = "C", +"[ANTIGEN_E]" = "E", +"[ANTIGEN_D]" = "D", +"[ANTIGEN_M]" = "M", +"[ANTIGEN_N]" = "N", +"[ANTIGEN_O]" = "O", +"[ANTIGEN_P]" = "P", "[ANTIGEN_Q]" = "Q", "[ANTIGEN_U]" = "U", "[ANTIGEN_V]" = "V", -"[ANTIGEN_Z]" = "Z", -"[ANTIGEN_M]" = "M", -"[ANTIGEN_N]" = "N", -"[ANTIGEN_P]" = "P", -"[ANTIGEN_O]" = "O" +"[ANTIGEN_W]" = "W", +"[ANTIGEN_X]" = "X", +"[ANTIGEN_Y]" = "Y", +"[ANTIGEN_Z]" = "Z" ) +*/ + +var/global/list/ALL_ANTIGENS = list( + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" + ) + +/hook/startup/proc/randomise_antigens_order() + ALL_ANTIGENS = shuffle(ALL_ANTIGENS) + return 1 // pure concentrated antibodies datum/reagent/antibodies - data = list("antibodies"=0) + data = list("antibodies"=list()) name = "Antibodies" id = "antibodies" reagent_state = LIQUID @@ -39,14 +57,26 @@ datum/reagent/antibodies reaction_mob(var/mob/M, var/method=TOUCH, var/volume) if(istype(M,/mob/living/carbon)) + var/mob/living/carbon/C = M if(src.data && method == INGEST) - if(M:virus2) if(src.data["antibodies"] & M:virus2.antigen) - M:virus2.dead = 1 - M:antibodies |= src.data["antibodies"] + //if(C.virus2) if(src.data["antibodies"] & C.virus2.antigen) + // C.virus2.dead = 1 + C.antibodies |= src.data["antibodies"] return // iterate over the list of antigens and see what matches -/proc/antigens2string(var/antigens) +/proc/antigens2string(list/antigens, none="None") + if(!istype(antigens)) + CRASH("Illegal type!") + if(!antigens.len) + return none + var/code = "" - for(var/V in ANTIGENS) if(text2num(V) & antigens) code += ANTIGENS[V] - return code \ No newline at end of file + for(var/V in ALL_ANTIGENS) + if(V in antigens) + code += V + + if(!code) + return none + + return code diff --git a/code/modules/virus2/centrifuge.dm b/code/modules/virus2/centrifuge.dm index b36e63ff3a..f6cf9fe390 100644 --- a/code/modules/virus2/centrifuge.dm +++ b/code/modules/virus2/centrifuge.dm @@ -1,5 +1,5 @@ /obj/machinery/computer/centrifuge - name = "Isolation Centrifuge" + name = "isolation centrifuge" desc = "Used to separate things with different weight. Spin 'em round, round, right round." icon = 'icons/obj/virology.dmi' icon_state = "centrifuge" @@ -54,7 +54,7 @@ if (sample) var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list if (B) - data["antibodies"] = B.data["antibodies"] ? antigens2string(B.data["antibodies"]) : null + data["antibodies"] = antigens2string(B.data["antibodies"], none=null) var/list/pathogens[0] var/list/virus = B.data["virus2"] @@ -67,7 +67,8 @@ else var/datum/reagent/antibodies/A = locate(/datum/reagent/antibodies) in sample.reagents.reagent_list - data["antibodies"] = A && A.data["antibodies"] ? antigens2string(A.data["antibodies"]) : null + if(A) + data["antibodies"] = antigens2string(A.data["antibodies"], none=null) data["is_antibody_sample"] = 1 ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) @@ -91,7 +92,7 @@ isolate() /obj/machinery/computer/centrifuge/Topic(href, href_list) - if (..()) return 0 + if (..()) return 1 var/mob/user = usr var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") @@ -186,7 +187,7 @@ var/datum/reagent/blood/B = locate(/datum/reagent/blood) in sample.reagents.reagent_list if (B) P.info += "Antibodies: " - P.info += B.data["antibodies"] ? antigens2string(B.data["antibodies"]) : "None" + P.info += antigens2string(B.data["antibodies"]) P.info += "
    " var/list/virus = B.data["virus2"] @@ -202,7 +203,7 @@ var/datum/reagent/antibodies/A = locate(/datum/reagent/antibodies) in sample.reagents.reagent_list if (A) P.info += "The following antibodies have been isolated from the blood sample: " - P.info += A.data["antibodies"] ? antigens2string(A.data["antibodies"]) : "None" + P.info += antigens2string(A.data["antibodies"]) P.info += "
    " P.info += {" diff --git a/code/modules/virus2/curer.dm b/code/modules/virus2/curer.dm index d87f579d31..ccbbbed9a2 100644 --- a/code/modules/virus2/curer.dm +++ b/code/modules/virus2/curer.dm @@ -1,5 +1,5 @@ /obj/machinery/computer/curer - name = "Cure Research Machine" + name = "cure research machine" icon = 'icons/obj/computer.dmi' icon_state = "dna" circuit = /obj/item/weapon/circuitboard/curefab @@ -22,7 +22,7 @@ return var/obj/item/weapon/reagent_containers/glass/beaker/product = new(src.loc) - var/list/data = list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"virus2"=list(),"antibodies"=0) + var/list/data = list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"virus2"=list(),"antibodies"=list()) data["virus2"] |= I:virus2 product.reagents.add_reagent("blood",30,data) @@ -52,9 +52,7 @@ if(B) dat = "Blood sample inserted." - var/code = "" - for(var/V in ANTIGENS) if(text2num(V) & B.data["antibodies"]) code += ANTIGENS[V] - dat += "
    Antibodies: [code]" + dat += "
    Antibodies: [antigens2string(B.data["antibodies"])]" dat += "
    Begin antibody production" else dat += "
    Please check container contents." @@ -82,7 +80,7 @@ /obj/machinery/computer/curer/Topic(href, href_list) if(..()) - return + return 1 usr.machine = src if (href_list["antibody"]) @@ -93,7 +91,6 @@ src.add_fingerprint(usr) src.updateUsrDialog() - return /obj/machinery/computer/curer/proc/createcure(var/obj/item/weapon/reagent_containers/container) diff --git a/code/modules/virus2/disease2.dm b/code/modules/virus2/disease2.dm index 0f16b91b34..c1852a0cb9 100644 --- a/code/modules/virus2/disease2.dm +++ b/code/modules/virus2/disease2.dm @@ -8,7 +8,7 @@ var/clicks = 0 var/uniqueID = 0 var/list/datum/disease2/effectholder/effects = list() - var/antigen = 0 // 16 bits describing the antigens, when one bit is set, a cure with that bit can dock here + var/antigen = list() // 16 bits describing the antigens, when one bit is set, a cure with that bit can dock here var/max_stage = 4 var/list/affected_species = list("Human","Unathi","Skrell","Tajara") @@ -17,10 +17,12 @@ ..() /datum/disease2/disease/proc/makerandom(var/severity=1) + var/list/excludetypes = list() for(var/i=1 ; i <= max_stage ; i++ ) var/datum/disease2/effectholder/holder = new /datum/disease2/effectholder holder.stage = i - holder.getrandomeffect(severity) + holder.getrandomeffect(severity, excludetypes) + excludetypes += holder.effect.type effects += holder uniqueID = rand(0,10000) switch(severity) @@ -31,8 +33,8 @@ else infectionchance = rand(60,90) - antigen |= text2num(pick(ANTIGENS)) - antigen |= text2num(pick(ANTIGENS)) + antigen = list(pick(ALL_ANTIGENS)) + antigen |= pick(ALL_ANTIGENS) spreadtype = prob(70) ? "Airborne" : "Contact" if(all_species.len) @@ -79,13 +81,18 @@ mob.reagents.remove_reagent("virusfood",0.1) clicks += 10 + if(prob(1) && prob(stage)) // Increasing chance of curing as the virus progresses + src.cure(mob) + mob.antibodies |= src.antigen + //Moving to the next stage if(clicks > max(stage*100, 200) && prob(10)) - if(stage == max_stage) + if((stage <= max_stage) && prob(20)) // ~60% of viruses will be cured by the end of S4 with this src.cure(mob) mob.antibodies |= src.antigen stage++ clicks = 0 + //Do nasty effects for(var/datum/disease2/effectholder/e in effects) if(prob(33)) @@ -98,14 +105,14 @@ infect_virus2(M,src) //fever - mob.bodytemperature = max(mob.bodytemperature, min(310+5*stage ,mob.bodytemperature+5*stage)) + mob.bodytemperature = max(mob.bodytemperature, min(310+5*min(stage,max_stage) ,mob.bodytemperature+5*min(stage,max_stage))) clicks+=speed /datum/disease2/disease/proc/cure(var/mob/living/carbon/mob) for(var/datum/disease2/effectholder/e in effects) e.effect.deactivate(mob) mob.virus2.Remove("[uniqueID]") - mob.hud_updateflag |= 1 << STATUS_HUD + BITSET(mob.hud_updateflag, STATUS_HUD) /datum/disease2/disease/proc/minormutate() //uniqueID = rand(0,10000) @@ -116,10 +123,14 @@ /datum/disease2/disease/proc/majormutate() uniqueID = rand(0,10000) var/datum/disease2/effectholder/holder = pick(effects) - holder.majormutate() + var/list/exclude = list() + for(var/datum/disease2/effectholder/D in effects) + if(D != holder) + exclude += D.effect.type + holder.majormutate(exclude) if (prob(5)) - antigen = text2num(pick(ANTIGENS)) - antigen |= text2num(pick(ANTIGENS)) + antigen = list(pick(ALL_ANTIGENS)) + antigen |= pick(ALL_ANTIGENS) if (prob(5) && all_species.len) affected_species = get_infectable_species() @@ -134,6 +145,7 @@ for(var/datum/disease2/effectholder/holder in effects) var/datum/disease2/effectholder/newholder = new /datum/disease2/effectholder newholder.effect = new holder.effect.type + newholder.effect.generate(holder.effect.data) newholder.chance = holder.chance newholder.cure = holder.cure newholder.multiplier = holder.multiplier @@ -176,6 +188,12 @@ var/global/list/virusDB = list() var/datum/data/record/V = virusDB["[uniqueID]"] .= V.fields["name"] +/datum/disease2/disease/proc/get_basic_info() + var/t = "" + for(var/datum/disease2/effectholder/E in effects) + t += ", [E.effect.name]" + return "[name()] ([copytext(t,3)])" + /datum/disease2/disease/proc/get_info() var/r = {" Analysis determined the existence of a GNAv2-based viral lifeform.
    @@ -237,3 +255,10 @@ proc/virology_letterhead(var/report_name)
    [station_name()] Virology Lab

    "} + +/datum/disease2/disease/proc/can_add_symptom(type) + for(var/datum/disease2/effectholder/H in effects) + if(H.effect.type == type) + return 0 + + return 1 \ No newline at end of file diff --git a/code/modules/virus2/diseasesplicer.dm b/code/modules/virus2/diseasesplicer.dm index cbab5f5f7d..4ff37034b7 100644 --- a/code/modules/virus2/diseasesplicer.dm +++ b/code/modules/virus2/diseasesplicer.dm @@ -1,5 +1,5 @@ /obj/machinery/computer/diseasesplicer - name = "Disease Splicer" + name = "disease splicer" icon = 'icons/obj/computer.dmi' icon_state = "crew" @@ -49,7 +49,7 @@ data["affected_species"] = null if (memorybank) - data["buffer"] = list("name" = (analysed ? memorybank.effect.name : "Unknown Symptom"), "stage" = memorybank.stage) + data["buffer"] = list("name" = (analysed ? memorybank.effect.name : "Unknown Symptom"), "stage" = memorybank.effect.stage) if (species_buffer) data["species_buffer"] = analysed ? list2text(species_buffer, ", ") : "Unknown Species" @@ -122,7 +122,7 @@ nanomanager.update_uis(src) /obj/machinery/computer/diseasesplicer/Topic(href, href_list) - if(..()) return 0 + if(..()) return 1 var/mob/user = usr var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") @@ -160,14 +160,26 @@ if(href_list["splice"]) if(dish) - if (memorybank) - for(var/datum/disease2/effectholder/e in dish.virus2.effects) - if(e.stage == memorybank.stage) - e.effect = memorybank.effect + var/target = text2num(href_list["splice"]) // target = 1 to 4 for effects, 5 for species + if(memorybank && 0 < target && target <= 4) + if(target < memorybank.effect.stage) return // too powerful, catching this for href exploit prevention - if (species_buffer) + var/datum/disease2/effectholder/target_holder + var/list/illegal_types = list() + for(var/datum/disease2/effectholder/e in dish.virus2.effects) + if(e.stage == target) + target_holder = e + else + illegal_types += e.effect.type + if(memorybank.effect.type in illegal_types) return + target_holder.effect = memorybank.effect + + else if(species_buffer && target == 5) dish.virus2.affected_species = species_buffer + else + return + splicing = 10 dish.virus2.uniqueID = rand(0,10000) return 1 diff --git a/code/modules/virus2/dishincubator.dm b/code/modules/virus2/dishincubator.dm index f3f339f895..6882e8e622 100644 --- a/code/modules/virus2/dishincubator.dm +++ b/code/modules/virus2/dishincubator.dm @@ -1,5 +1,5 @@ /obj/machinery/disease2/incubator/ - name = "Pathogenic incubator" + name = "pathogenic incubator" density = 1 anchored = 1 icon = 'icons/obj/virology.dmi' @@ -108,6 +108,7 @@ dish.virus2.majormutate() if(dish.info) dish.info = "OUTDATED : [dish.info]" + dish.basic_info = "OUTDATED: [dish.basic_info]" dish.analysed = 0 ping("\The [src] pings, \"Mutant viral strain detected.\"") else if(prob(5)) @@ -138,7 +139,7 @@ nanomanager.update_uis(src) /obj/machinery/disease2/incubator/Topic(href, href_list) - if (..()) return 0 + if (..()) return 1 var/mob/user = usr var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index 50d7bcb569..8b6d9f30e8 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -13,15 +13,19 @@ if(happensonce == 1) happensonce = -1 -/datum/disease2/effectholder/proc/getrandomeffect(var/badness = 1) +/datum/disease2/effectholder/proc/getrandomeffect(var/badness = 1, exclude_types=list()) var/list/datum/disease2/effect/list = list() for(var/e in (typesof(/datum/disease2/effect) - /datum/disease2/effect)) - var/datum/disease2/effect/f = new e - if (f.badness > badness) //we don't want such strong effects + var/datum/disease2/effect/f = e + if(e in exclude_types) continue - if(f.stage == src.stage) + if(initial(f.badness) > badness) //we don't want such strong effects + continue + if(initial(f.stage) <= src.stage) list += f - effect = pick(list) + var/type = pick(list) + effect = new type() + effect.generate() chance = rand(0,effect.chance_maxm) multiplier = rand(1,effect.maxm) @@ -32,8 +36,8 @@ if(2) multiplier = rand(1,effect.maxm) -/datum/disease2/effectholder/proc/majormutate() - getrandomeffect(3) +/datum/disease2/effectholder/proc/majormutate(exclude_types=list()) + getrandomeffect(3, exclude_types) //////////////////////////////////////////////////////////////// ////////////////////////EFFECTS///////////////////////////////// @@ -45,8 +49,11 @@ var/stage = 4 var/maxm = 1 var/badness = 1 + var/data = null // For semi-procedural effects; this should be generated in generate() if used + proc/activate(var/mob/living/carbon/mob,var/multiplier) proc/deactivate(var/mob/living/carbon/mob) + proc/generate(copy_data) // copy_data will be non-null if this is a copy; it should be used to initialise the data for this effect if present /datum/disease2/effect/invisible name = "Waiting Syndrome" @@ -67,7 +74,23 @@ stage = 4 badness = 3 activate(var/mob/living/carbon/mob,var/multiplier) - mob.gib() + // Probabilities have been tweaked to kill in ~2-3 minutes, giving 5-10 messages. + // Probably needs more balancing, but it's better than LOL U GIBBED NOW, especially now that viruses can potentially have no signs up until Gibbingtons. + mob.adjustBruteLoss(10*multiplier) + if(istype(mob, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = mob + var/datum/organ/external/O = pick(H.organs) + if(prob(25)) + mob << "Your [O.display_name] feels as if it might fall off!" + if(prob(10)) + spawn(50) + if(O) + O.droplimb(1) + else + if(prob(75)) + mob << "Your whole body feels like it might fall apart!" + if(prob(10)) + mob.adjustBruteLoss(25*multiplier) /datum/disease2/effect/radian name = "Radian's Syndrome" @@ -257,6 +280,26 @@ chance_maxm = 25 activate(var/mob/living/carbon/mob,var/multiplier) mob.say("*groan") + +/datum/disease2/effect/chem_synthesis + name = "Chemical Synthesis" + stage = 3 + chance_maxm = 25 + + generate(c_data) + if(c_data) + data = c_data + else + data = pick("bicaridine", "kelotane", "dylovene", "inaprovaline", "space_drugs", "sugar", + "tramadol", "dexalin", "cryptobiolin", "impedrezene", "hyperzine", "ethylredoxrazine", + "mindbreaker", "nutriment") + var/datum/reagent/R = chemical_reagents_list[data] + name = "[initial(name)] ([initial(R.name)])" + + activate(var/mob/living/carbon/mob,var/multiplier) + if (mob.reagents.get_reagent_amount(data) < 5) + mob.reagents.add_reagent(data, 2) + ////////////////////////STAGE 2///////////////////////////////// /datum/disease2/effect/scream diff --git a/code/modules/virus2/helpers.dm b/code/modules/virus2/helpers.dm index 17cabb5210..feb7aec6a6 100644 --- a/code/modules/virus2/helpers.dm +++ b/code/modules/virus2/helpers.dm @@ -77,7 +77,8 @@ proc/airborne_can_reach(turf/source, turf/target) if ("[disease.uniqueID]" in M.virus2) return // if one of the antibodies in the mob's body matches one of the disease's antigens, don't infect - if((M.antibodies & disease.antigen) != 0) + var/list/antibodies_in_common = M.antibodies & disease.antigen + if(antibodies_in_common.len) return if(M.reagents.has_reagent("spaceacillin")) return @@ -98,7 +99,7 @@ proc/airborne_can_reach(turf/source, turf/target) D.minormutate() // log_debug("Adding virus") M.virus2["[D.uniqueID]"] = D - M.hud_updateflag |= 1 << STATUS_HUD + BITSET(M.hud_updateflag, STATUS_HUD) //Infects mob M with disease D @@ -109,12 +110,14 @@ proc/airborne_can_reach(turf/source, turf/target) //Infects mob M with random lesser disease, if he doesn't have one /proc/infect_mob_random_lesser(var/mob/living/carbon/M) var/datum/disease2/disease/D = new /datum/disease2/disease + D.makerandom(1) infect_mob(M, D) //Infects mob M with random greated disease, if he doesn't have one /proc/infect_mob_random_greater(var/mob/living/carbon/M) var/datum/disease2/disease/D = new /datum/disease2/disease + D.makerandom(2) infect_mob(M, D) diff --git a/code/modules/virus2/isolator.dm b/code/modules/virus2/isolator.dm index 09f07793c9..6a27d2f17d 100644 --- a/code/modules/virus2/isolator.dm +++ b/code/modules/virus2/isolator.dm @@ -4,7 +4,7 @@ #define ENTRY "entry" /obj/machinery/disease2/isolator/ - name = "Pathogenic Isolator" + name = "pathogenic isolator" density = 1 anchored = 1 icon = 'icons/obj/virology.dmi' @@ -120,7 +120,7 @@ update_icon() /obj/machinery/disease2/isolator/Topic(href, href_list) - if (..()) return 0 + if (..()) return 1 var/mob/user = usr var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main") diff --git a/code/modules/virus2/items_devices.dm b/code/modules/virus2/items_devices.dm index a2a102611d..741fdb099d 100644 --- a/code/modules/virus2/items_devices.dm +++ b/code/modules/virus2/items_devices.dm @@ -1,7 +1,7 @@ ///////////////ANTIBODY SCANNER/////////////// /obj/item/device/antibody_scanner - name = "\improper Antibody Scanner" + name = "antibody scanner" desc = "Scans living beings for antibodies in their blood." icon_state = "health" w_class = 2.0 @@ -20,7 +20,7 @@ report("Scan aborted: The target does not have blood.", user) return - if(!C.antibodies) + if(!C.antibodies.len) report("Scan Complete: No antibodies detected.", user) return @@ -36,11 +36,12 @@ ///////////////VIRUS DISH/////////////// /obj/item/weapon/virusdish - name = "virus containment/growth dish" + name = "virus dish" icon = 'icons/obj/items.dmi' icon_state = "implantcase-b" var/datum/disease2/disease/virus2 = null var/growth = 0 + var/basic_info = null var/info = 0 var/analysed = 0 @@ -66,10 +67,17 @@ del src /obj/item/weapon/virusdish/examine(mob/user) - user << "This is a virus containment dish." - if(src.info) - user << "It has the following information about its contents:" - user << src.info + ..() + if(basic_info) + user << "[basic_info] : More Information" + +/obj/item/weapon/virusdish/Topic(href, href_list) + . = ..() + if(.) return 1 + + if(href_list["info"]) + usr << browse(info, "window=info_\ref[src]") + return 1 /obj/item/weapon/ruinedvirusdish name = "ruined virus sample" diff --git a/code/setup.dm b/code/setup.dm index 33201d10bf..0196122e87 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -1,488 +1,477 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 - #define DEBUG -#define PI 3.1415 +// Math constants. +#define M_E 2.71828183 +#define M_PI 3.14159265 +#define M_SQRT2 1.41421356 -#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol) -#define ONE_ATMOSPHERE 101.325 //kPa -#define IDEAL_GAS_ENTROPY_CONSTANT 1164 //(mol^3 * s^3) / (kg^3 * L). Equal to (4*pi/(avrogadro's number * planck's constant)^2)^(3/2) / (avrogadro's number * 1000 Liters per m^3). +#define R_IDEAL_GAS_EQUATION 8.31 // kPa*L/(K*mol). +#define ONE_ATMOSPHERE 101.325 // kPa. +#define IDEAL_GAS_ENTROPY_CONSTANT 1164 // (mol^3 * s^3) / (kg^3 * L). -//radiation constants -#define STEFAN_BOLTZMANN_CONSTANT 5.6704e-8 //W/(m^2*K^4) -#define COSMIC_RADIATION_TEMPERATURE 3.15 //K -#define AVERAGE_SOLAR_RADIATION 200 //W/m^2. Kind of arbitrary. Really this should depend on the sun position much like solars. From the numbers on Erebus, this'd be an orbit of 23.3 lightseconds. -#define RADIATOR_OPTIMUM_PRESSURE 110 //kPa at 20 C -#define RADIATOR_EXPOSED_SURFACE_AREA 0.03 //The pipe looks to be thin vertically and wide horizontally, so we'll assume that it's three centimeters thick and only explosed to the sun edge-on. +// Radiation constants. +#define STEFAN_BOLTZMANN_CONSTANT 5.6704e-8 // W/(m^2*K^4). +#define COSMIC_RADIATION_TEMPERATURE 3.15 // K. +#define AVERAGE_SOLAR_RADIATION 200 // W/m^2. Kind of arbitrary. Really this should depend on the sun position much like solars. +#define RADIATOR_OPTIMUM_PRESSURE 3771 // kPa at 20 C. This should be higher as gases aren't great conductors until they are dense. Used the critical pressure for air. +#define GAS_CRITICAL_TEMPERATURE 132.65 // K. The critical point temperature for air. -#define CELL_VOLUME 2500 //liters in a cell -#define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) //moles in a 2.5 m^3 cell at 101.325 Pa and 20 degC +/* + The pipe looks to be thin vertically and wide horizontally, so we'll assume that it's + three centimeters thick, one meter wide, and only explosed to the sun 3 degrees off of edge-on. + Since the radiatior is uniform along it's length, the ratio of surface area touched by sunlight + to the total surface area is the same as the ratio of the perimeter of the cross-section. +*/ +#define RADIATOR_EXPOSED_SURFACE_AREA_RATIO 0.04 // (3 cm + 100 cm * sin(3deg))/(2*(3+100 cm)). Unitless ratio. -#define O2STANDARD 0.21 +#define CELL_VOLUME 2500 // Liters in a cell. +#define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) // Moles in a 2.5 m^3 cell at 101.325 kPa and 20 C. + +#define O2STANDARD 0.21 // Percentage. #define N2STANDARD 0.79 -#define MOLES_PHORON_VISIBLE 0.7 //Moles in a standard cell after which phoron is visible -#define MOLES_O2STANDARD MOLES_CELLSTANDARD*O2STANDARD // O2 standard value (21%) -#define MOLES_N2STANDARD MOLES_CELLSTANDARD*N2STANDARD // N2 standard value (79%) +#define MOLES_PHORON_VISIBLE 0.7 // Moles in a standard cell after which phoron is visible. +#define MOLES_O2STANDARD (MOLES_CELLSTANDARD * O2STANDARD) // O2 standard value (21%) +#define MOLES_N2STANDARD (MOLES_CELLSTANDARD * N2STANDARD) // N2 standard value (79%) -#define MIN_TOXIN_DAMAGE 1 //This and MAX_TOXIN_DAMAGE are for when a mob breathes poisonous air -#define MAX_TOXIN_DAMAGE 10 //This and MIN_TOXIN_DAMAGE are for when a mob breathes poisonous air +// These are for when a mob breathes poisonous air. +#define MIN_TOXIN_DAMAGE 1 +#define MAX_TOXIN_DAMAGE 10 -#define BREATH_VOLUME 0.5 //liters in a normal breath -#define BREATH_MOLES (ONE_ATMOSPHERE * BREATH_VOLUME /(T20C*R_IDEAL_GAS_EQUATION)) -//Amount of air to take a from a tile -#define BREATH_PERCENTAGE BREATH_VOLUME/CELL_VOLUME -//Amount of air needed before pass out/suffocation commences -#define HUMAN_NEEDED_OXYGEN MOLES_CELLSTANDARD*BREATH_PERCENTAGE*0.16 +#define BREATH_VOLUME 0.5 // Liters in a normal breath. +#define BREATH_MOLES (ONE_ATMOSPHERE * BREATH_VOLUME / (T20C * R_IDEAL_GAS_EQUATION)) // Amount of air to take a from a tile +#define BREATH_PERCENTAGE (BREATH_VOLUME / CELL_VOLUME) // Amount of air needed before pass out/suffocation commences. +#define HUMAN_NEEDED_OXYGEN (MOLES_CELLSTANDARD * BREATH_PERCENTAGE * 0.16) #define SOUND_MINIMUM_PRESSURE 10 // Pressure limits. -#define HAZARD_HIGH_PRESSURE 550 //This determins at what pressure the ultra-high pressure red icon is displayed. (This one is set as a constant) -#define WARNING_HIGH_PRESSURE 325 //This determins when the orange pressure icon is displayed (it is 0.7 * HAZARD_HIGH_PRESSURE) -#define WARNING_LOW_PRESSURE 50 //This is when the gray low pressure icon is displayed. (it is 2.5 * HAZARD_LOW_PRESSURE) -#define HAZARD_LOW_PRESSURE 20 //This is when the black ultra-low pressure icon is displayed. (This one is set as a constant) +#define HAZARD_HIGH_PRESSURE 550 // This determines at what pressure the ultra-high pressure red icon is displayed. (This one is set as a constant) +#define WARNING_HIGH_PRESSURE 325 // This determines when the orange pressure icon is displayed (it is 0.7 * HAZARD_HIGH_PRESSURE) +#define WARNING_LOW_PRESSURE 50 // This is when the gray low pressure icon is displayed. (it is 2.5 * HAZARD_LOW_PRESSURE) +#define HAZARD_LOW_PRESSURE 20 // This is when the black ultra-low pressure icon is displayed. (This one is set as a constant) -#define TEMPERATURE_DAMAGE_COEFFICIENT 1.5 //This is used in handle_temperature_damage() for humans, and in reagents that affect body temperature. Temperature damage is multiplied by this amount. -#define BODYTEMP_AUTORECOVERY_DIVISOR 12 //This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive. -#define BODYTEMP_AUTORECOVERY_MINIMUM 1 //Minimum amount of kelvin moved toward 310.15K per tick. So long as abs(310.15 - bodytemp) is more than 50. -#define BODYTEMP_COLD_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is lower than their body temperature. Make it lower to lose bodytemp faster. -#define BODYTEMP_HEAT_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is higher than their body temperature. Make it lower to gain bodytemp faster. -#define BODYTEMP_COOLING_MAX -30 //The maximum number of degrees that your body can cool in 1 tick, when in a cold area. -#define BODYTEMP_HEATING_MAX 30 //The maximum number of degrees that your body can heat up in 1 tick, when in a hot area. +#define TEMPERATURE_DAMAGE_COEFFICIENT 1.5 // This is used in handle_temperature_damage() for humans, and in reagents that affect body temperature. Temperature damage is multiplied by this amount. +#define BODYTEMP_AUTORECOVERY_DIVISOR 12 // This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive. +#define BODYTEMP_AUTORECOVERY_MINIMUM 1 // Minimum amount of kelvin moved toward 310.15K per tick. So long as abs(310.15 - bodytemp) is more than 50. +#define BODYTEMP_COLD_DIVISOR 6 // Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is lower than their body temperature. Make it lower to lose bodytemp faster. +#define BODYTEMP_HEAT_DIVISOR 6 // Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is higher than their body temperature. Make it lower to gain bodytemp faster. +#define BODYTEMP_COOLING_MAX -30 // The maximum number of degrees that your body can cool down in 1 tick, when in a cold area. +#define BODYTEMP_HEATING_MAX 30 // The maximum number of degrees that your body can heat up in 1 tick, when in a hot area. #define BODYTEMP_HEAT_DAMAGE_LIMIT 360.15 // The limit the human body can take before it starts taking damage from heat. #define BODYTEMP_COLD_DAMAGE_LIMIT 260.15 // The limit the human body can take before it starts taking damage from coldness. -#define SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE 2.0 //what min_cold_protection_temperature is set to for space-helmet quality headwear. MUST NOT BE 0. -#define SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE 2.0 //what min_cold_protection_temperature is set to for space-suit quality jumpsuits or suits. MUST NOT BE 0. -#define SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE 5000 //These need better heat protect, but not as good heat protect as firesuits. -#define FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE 30000 //what max_heat_protection_temperature is set to for firesuit quality headwear. MUST NOT BE 0. -#define FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE 30000 //for fire helmet quality items (red and white hardhats) -#define HELMET_MIN_COLD_PROTECTION_TEMPERATURE 160 //For normal helmets -#define HELMET_MAX_HEAT_PROTECTION_TEMPERATURE 600 //For normal helmets -#define ARMOR_MIN_COLD_PROTECTION_TEMPERATURE 160 //For armor -#define ARMOR_MAX_HEAT_PROTECTION_TEMPERATURE 600 //For armor +#define SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE 2.0 // What min_cold_protection_temperature is set to for space-helmet quality headwear. MUST NOT BE 0. +#define SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE 2.0 // What min_cold_protection_temperature is set to for space-suit quality jumpsuits or suits. MUST NOT BE 0. +#define HELMET_MIN_COLD_PROTECTION_TEMPERATURE 160 // For normal helmets. +#define ARMOR_MIN_COLD_PROTECTION_TEMPERATURE 160 // For armor. +#define GLOVES_MIN_COLD_PROTECTION_TEMPERATURE 2.0 // For some gloves. +#define SHOE_MIN_COLD_PROTECTION_TEMPERATURE 2.0 // For shoes. -#define GLOVES_MIN_COLD_PROTECTION_TEMPERATURE 2.0 //For some gloves (black and) -#define GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE 1500 //For some gloves -#define SHOE_MIN_COLD_PROTECTION_TEMPERATURE 2.0 //For gloves -#define SHOE_MAX_HEAT_PROTECTION_TEMPERATURE 1500 //For gloves +#define SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE 5000 // These need better heat protect, but not as good heat protect as firesuits. +#define FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE 30000 // What max_heat_protection_temperature is set to for firesuit quality headwear. MUST NOT BE 0. +#define FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE 30000 // For fire-helmet quality items. (Red and white hardhats) +#define HELMET_MAX_HEAT_PROTECTION_TEMPERATURE 600 // For normal helmets. +#define ARMOR_MAX_HEAT_PROTECTION_TEMPERATURE 600 // For armor. +#define GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE 1500 // For some gloves. +#define SHOE_MAX_HEAT_PROTECTION_TEMPERATURE 1500 // For shoes. +// Fire. +#define FIRE_MIN_STACKS -20 +#define FIRE_MAX_STACKS 25 +#define FIRE_MAX_FIRESUIT_STACKS 20 // If the number of stacks goes above this firesuits won't protect you anymore. If not, you can walk around while on fire like a badass. -#define PRESSURE_DAMAGE_COEFFICIENT 4 //The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE -#define MAX_HIGH_PRESSURE_DAMAGE 4 //This used to be 20... I got this much random rage for some retarded decision by polymorph?! Polymorph now lies in a pool of blood with a katana jammed in his spleen. ~Errorage --PS: The katana did less than 20 damage to him :( -#define LOW_PRESSURE_DAMAGE 2 //The amounb of damage someone takes when in a low pressure area (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value). +#define THROWFORCE_SPEED_DIVISOR 5 // The throwing speed value at which the throwforce multiplier is exactly 1. +#define THROWNOBJ_KNOCKBACK_SPEED 15 // The minumum speed of a w_class 2 thrown object that will cause living mobs it hits to be knocked back. Heavier objects can cause knockback at lower speeds. +#define THROWNOBJ_KNOCKBACK_DIVISOR 2 // Affects how much speed the mob is knocked back with. + +#define PRESSURE_DAMAGE_COEFFICIENT 4 // The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE. +#define MAX_HIGH_PRESSURE_DAMAGE 4 // This used to be 20... I got this much random rage for some retarded decision by polymorph?! Polymorph now lies in a pool of blood with a katana jammed in his spleen. ~Errorage --PS: The katana did less than 20 damage to him :( +#define LOW_PRESSURE_DAMAGE 2 // The amount of damage someone takes when in a low pressure area. (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value). // Doors! #define DOOR_CRUSH_DAMAGE 10 -// Factor of how fast mob nutrition decreases -#define HUNGER_FACTOR 0.05 +#define HUNGER_FACTOR 0.05 // Factor of how fast mob nutrition decreases +#define REAGENTS_METABOLISM 0.2 // How many units of reagent are consumed per tick, by default. +#define REAGENTS_EFFECT_MULTIPLIER (REAGENTS_METABOLISM / 0.4) // By defining the effect multiplier this way, it'll exactly adjust + // all effects according to how they originally were with the 0.4 metabolism -// How many units of reagent are consumed per tick, by default. -#define REAGENTS_METABOLISM 0.2 +#define MINIMUM_AIR_RATIO_TO_SUSPEND 0.05 // Minimum ratio of air that must move to/from a tile to suspend group processing +#define MINIMUM_AIR_TO_SUSPEND (MOLES_CELLSTANDARD * MINIMUM_AIR_RATIO_TO_SUSPEND) // Minimum amount of air that has to move before a group processing can be suspended +#define MINIMUM_MOLES_DELTA_TO_MOVE (MOLES_CELLSTANDARD * MINIMUM_AIR_RATIO_TO_SUSPEND) // Either this must be active +#define MINIMUM_TEMPERATURE_TO_MOVE (T20C + 100) // or this (or both, obviously) -// By defining the effect multiplier this way, it'll exactly adjust -// all effects according to how they originally were with the 0.4 metabolism -#define REAGENTS_EFFECT_MULTIPLIER REAGENTS_METABOLISM / 0.4 +#define MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND 0.012 // Minimum temperature difference before group processing is suspended. +#define MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND 4 +#define MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER 0.5 // Minimum temperature difference before the gas temperatures are just set to be equal. +#define MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION (T20C + 10) +#define MINIMUM_TEMPERATURE_START_SUPERCONDUCTION (T20C + 200) +// Must be between 0 and 1. Values closer to 1 equalize temperature faster. Should not exceed 0.4, else strange heat flow occurs. +#define FLOOR_HEAT_TRANSFER_COEFFICIENT 0.4 +#define WALL_HEAT_TRANSFER_COEFFICIENT 0.0 +#define DOOR_HEAT_TRANSFER_COEFFICIENT 0.0 +#define SPACE_HEAT_TRANSFER_COEFFICIENT 0.2 // A hack to partly simulate radiative heat. +#define OPEN_HEAT_TRANSFER_COEFFICIENT 0.4 +#define WINDOW_HEAT_TRANSFER_COEFFICIENT 0.1 // A hack for now. -//Minimum ratio of air that must move to/from a tile to suspend group processing -#define MINIMUM_AIR_RATIO_TO_SUSPEND 0.05 -//Minimum amount of air that has to move before a group processing can be suspended -#define MINIMUM_AIR_TO_SUSPEND MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND +// Fire damage. +#define CARBON_LIFEFORM_FIRE_RESISTANCE (T0C + 200) +#define CARBON_LIFEFORM_FIRE_DAMAGE 4 -#define MINIMUM_MOLES_DELTA_TO_MOVE MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND //Either this must be active -#define MINIMUM_TEMPERATURE_TO_MOVE T20C+100 //or this (or both, obviously) +// Phoron fire properties. +#define PHORON_MINIMUM_BURN_TEMPERATURE (T0C + 126) //400 K - autoignite temperature in tanks and canisters - enclosed environments I guess +#define PHORON_FLASHPOINT (T0C + 246) //519 K - autoignite temperature in air if that ever gets implemented. -//Minimum temperature difference before group processing is suspended -#define MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND 0.012 -#define MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND 4 -//Minimum temperature difference before the gas temperatures are just set to be equal -#define MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER 0.5 -#define MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION T20C+10 -#define MINIMUM_TEMPERATURE_START_SUPERCONDUCTION T20C+200 +//These control the mole ratio of oxidizer and fuel used in the combustion reaction +#define FIRE_REACTION_OXIDIZER_AMOUNT 3 +#define FIRE_REACTION_FUEL_AMOUNT 2 -//Must be between 0 and 1. Values closer to 1 equalize temperature faster -//Should not exceed 0.4 else strange heat flow occur -#define FLOOR_HEAT_TRANSFER_COEFFICIENT 0.4 -#define WALL_HEAT_TRANSFER_COEFFICIENT 0.0 -#define DOOR_HEAT_TRANSFER_COEFFICIENT 0.0 -#define SPACE_HEAT_TRANSFER_COEFFICIENT 0.2 //a hack to partly simulate radiative heat -#define OPEN_HEAT_TRANSFER_COEFFICIENT 0.4 -#define WINDOW_HEAT_TRANSFER_COEFFICIENT 0.1 //a hack for now +//These control the speed at which fire burns +#define FIRE_GAS_BURNRATE_MULT 1 +#define FIRE_LIQUID_BURNRATE_MULT 0.5 -// Fire Damage -#define CARBON_LIFEFORM_FIRE_RESISTANCE 200+T0C -#define CARBON_LIFEFORM_FIRE_DAMAGE 4 +//If the fire is burning slower than this rate then the reaction is going too slow to be self sustaining and the fire burns itself out. +//This ensures that fires don't grind to a near-halt while still remaining active forever. +#define FIRE_GAS_MIN_BURNRATE 0.1 +#define FIRE_LIQUD_MIN_BURNRATE 0.05 -//Phoron fire properties -#define PHORON_MINIMUM_BURN_TEMPERATURE 100+T0C -#define PHORON_FLASHPOINT 246+T0C -#define PHORON_UPPER_TEMPERATURE 1370+T0C -#define PHORON_MINIMUM_OXYGEN_NEEDED 2 -#define PHORON_MINIMUM_OXYGEN_PHORON_RATIO 20 -#define PHORON_OXYGEN_FULLBURN 10 +//How many moles of fuel are contained within one solid/liquid fuel volume unit +#define LIQUIDFUEL_AMOUNT_TO_MOL 1 //mol/volume unit -#define T0C 273.15 // 0degC -#define T20C 293.15 // 20degC -#define TCMB 2.7 // -270.3degC +#define T0C 273.15 // 0.0 degrees celcius +#define T20C 293.15 // 20.0 degrees celcius +#define TCMB 2.7 // -270.3 degrees celcius -//XGM gas flags -#define XGM_GAS_FUEL 1 -#define XGM_GAS_OXIDIZER 2 +// XGM gas flags. +#define XGM_GAS_FUEL 1 +#define XGM_GAS_OXIDIZER 2 #define XGM_GAS_CONTAMINANT 4 -#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) // Tank starts leaking -#define TANK_RUPTURE_PRESSURE (40.*ONE_ATMOSPHERE) // Tank spills all contents into atmosphere +#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) // Tank starts leaking. +#define TANK_RUPTURE_PRESSURE (40.*ONE_ATMOSPHERE) // Tank spills all contents into atmosphere. +#define TANK_FRAGMENT_PRESSURE (50.*ONE_ATMOSPHERE) // Boom 3x3 base explosion. +#define TANK_FRAGMENT_SCALE (10.*ONE_ATMOSPHERE) // +1 for each SCALE kPa above threshold. Was 2 atm. -#define TANK_FRAGMENT_PRESSURE (50.*ONE_ATMOSPHERE) // Boom 3x3 base explosion -#define TANK_FRAGMENT_SCALE (10.*ONE_ATMOSPHERE) // +1 for each SCALE kPa aboe threshold - // was 2 atm -#define HUMAN_STRIP_DELAY 40 //takes 40ds = 4s to strip someone. -#define ALIEN_SELECT_AFK_BUFFER 1 // How many minutes that a person can be AFK before not being allowed to be an alien. -#define NORMPIPERATE 30 //pipe-insulation rate divisor -#define HEATPIPERATE 8 //heat-exch pipe insulation -#define FLOWFRAC 0.99 // fraction of gas transfered per process -#define SHOES_SLOWDOWN -1.0 // How much shoes slow you down by default. Negative values speed you up +#define HUMAN_STRIP_DELAY 40 // Takes 40ds = 4s to strip someone. +#define ALIEN_SELECT_AFK_BUFFER 1 // How many minutes that a person can be AFK before not being allowed to be an alien. +#define NORMPIPERATE 30 // Pipe-insulation rate divisor. +#define HEATPIPERATE 8 // Heat-exchange pipe insulation. +#define FLOWFRAC 0.99 // Fraction of gas transfered per process. +#define SHOES_SLOWDOWN -1.0 // How much shoes slow you down by default. Negative values speed you up. -//ITEM INVENTORY SLOT BITMASKS -#define SLOT_OCLOTHING 1 -#define SLOT_ICLOTHING 2 -#define SLOT_GLOVES 4 -#define SLOT_EYES 8 -#define SLOT_EARS 16 -#define SLOT_MASK 32 -#define SLOT_HEAD 64 -#define SLOT_FEET 128 -#define SLOT_ID 256 -#define SLOT_BELT 512 -#define SLOT_BACK 1024 -#define SLOT_POCKET 2048 //this is to allow items with a w_class of 3 or 4 to fit in pockets. -#define SLOT_DENYPOCKET 4096 //this is to deny items with a w_class of 2 or 1 to fit in pockets. -#define SLOT_TWOEARS 8192 -#define SLOT_TIE 16384 +// Item inventory slot bitmasks. +#define SLOT_OCLOTHING 1 +#define SLOT_ICLOTHING 2 +#define SLOT_GLOVES 4 +#define SLOT_EYES 8 +#define SLOT_EARS 16 +#define SLOT_MASK 32 +#define SLOT_HEAD 64 +#define SLOT_FEET 128 +#define SLOT_ID 256 +#define SLOT_BELT 512 +#define SLOT_BACK 1024 +#define SLOT_POCKET 2048 // This is to allow items with a w_class of 3 or 4 to fit in pockets. +#define SLOT_DENYPOCKET 4096 // This is to deny items with a w_class of 2 or 1 from fitting in pockets. +#define SLOT_TWOEARS 8192 +#define SLOT_TIE 16384 +#define SLOT_HOLSTER 32768 //16th bit -//FLAGS BITMASK -#define STOPSPRESSUREDMAGE 1 //This flag is used on the flags variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere - //To successfully stop you taking all pressure damage you must have both a suit and head item with this flag. -#define NOBLUDGEON 2 // when an item has this it produces no "X has been hit by Y with Z" message with the default handler -#define AIRTIGHT 4 // functions with internals -#define USEDELAY 8 // 1 second extra delay on use (Can be used once every 2s) -#define NOSHIELD 16 // weapon not affected by shield -#define CONDUCT 32 // conducts electricity (metal etc.) -#define ON_BORDER 64 // item has priority to check when entering or leaving -#define NOBLOODY 512 // used to items if they don't want to get a blood overlay -#define NODELAY 8192 // 1 second attackby delay skipped (Can be used once every 0.2s). Most objects have a 1s attackby delay, which doesn't require a flag. +// Flags bitmasks. +#define STOPPRESSUREDAMAGE 1 // This flag is used on the flags variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere + // To successfully stop you taking all pressure damage you must have both a suit and head item with this flag. +#define NOBLUDGEON 2 // When an item has this it produces no "X has been hit by Y with Z" message with the default handler. +#define AIRTIGHT 4 // Functions with internals. +#define USEDELAY 8 // 1 second extra delay on use. (Can be used once every 2s) +#define NOSHIELD 16 // Weapon not affected by shield. +#define CONDUCT 32 // Conducts electricity. (metal etc.) +#define ON_BORDER 64 // Item has priority to check when entering or leaving. +#define NOBLOODY 512 // Used for items if they don't want to get a blood overlay. +#define NODELAY 8192 // 1 second attack-by delay skipped (Can be used once every 0.2s). Most objects have a 1s attack-by delay, which doesn't require a flag. -#define GLASSESCOVERSEYES 256 -#define MASKCOVERSEYES 256 // get rid of some of the other retardation in these flags -#define HEADCOVERSEYES 256 // feel free to realloc these numbers for other purposes -#define MASKCOVERSMOUTH 512 // on other items, these are just for mask/head -#define HEADCOVERSMOUTH 512 +#define GLASSESCOVERSEYES 256 +#define MASKCOVERSEYES 256 // Get rid of some of the other retardation in these flags. +#define HEADCOVERSEYES 256 // Feel free to reallocate these numbers for other purposes. +#define MASKCOVERSMOUTH 512 // On other items, these are just for mask/head. +#define HEADCOVERSMOUTH 512 -#define THICKMATERIAL 256 //From /tg: prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body. (NOTE: flag shared with NOSLIP for shoes) -#define NOSLIP 256 //prevents from slipping on wet floors, in space etc +#define THICKMATERIAL 256 // From /tg/station: prevents syringes, parapens and hyposprays if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body. (NOTE: flag shared with NOSLIP for shoes) +#define NOSLIP 256 // Prevents from slipping on wet floors, in space, etc. +#define OPENCONTAINER 1024 // Is an open container for chemistry purposes. +#define BLOCK_GAS_SMOKE_EFFECT 2048 // Blocks the effect that chemical clouds would have on a mob -- glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL) +#define ONESIZEFITSALL 2048 +#define PHORONGUARD 4096 // Does not get contaminated by phoron. +#define NOREACT 4096 // Reagents don't react inside this container. +#define BLOCKHEADHAIR 4 // Temporarily removes the user's hair overlay. Leaves facial hair. +#define BLOCKHAIR 8192 // Temporarily removes the user's hair, facial and otherwise. -#define OPENCONTAINER 1024 // is an open container for chemistry purposes +// Flags for pass_flags. +#define PASSTABLE 1 +#define PASSGLASS 2 +#define PASSGRILLE 4 +#define PASSBLOB 8 -#define BLOCK_GAS_SMOKE_EFFECT 2048 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY! (NOTE: flag shared with ONESIZEFITSALL) -#define ONESIZEFITSALL 2048 -#define PHORONGUARD 4096 //Does not get contaminated by phoron. +// Turf-only flags. +#define NOJAUNT 1 // This is used in literally one place, turf.dm, to block ethereal jaunt. -#define NOREACT 4096 //Reagents dont' react inside this container. +// Bitmasks for the flags_inv variable. These determine when a piece of clothing hides another, i.e. a helmet hiding glasses. +// WARNING: The following flags apply only to the external suit! +#define HIDEGLOVES 1 +#define HIDESUITSTORAGE 2 +#define HIDEJUMPSUIT 4 +#define HIDESHOES 8 +#define HIDETAIL 16 -#define BLOCKHEADHAIR 4 // temporarily removes the user's hair overlay. Leaves facial hair. -#define BLOCKHAIR 8192 // temporarily removes the user's hair, facial and otherwise. +// WARNING: The following flags apply only to the helmets and masks! +#define HIDEMASK 1 +#define HIDEEARS 2 // Headsets and such. +#define HIDEEYES 4 // Glasses. +#define HIDEFACE 8 // Dictates whether we appear as "Unknown". -//flags for pass_flags -#define PASSTABLE 1 -#define PASSGLASS 2 -#define PASSGRILLE 4 -#define PASSBLOB 8 - -//turf-only flags -#define NOJAUNT 1 //This is used in literally one place, turf.dm, to block ethereal jaunt. - -//Bit flags for the flags_inv variable, which determine when a piece of clothing hides another. IE a helmet hiding glasses. -//APPLIES ONLY TO THE EXTERIOR SUIT!! -#define HIDEGLOVES 1 -#define HIDESUITSTORAGE 2 -#define HIDEJUMPSUIT 4 -#define HIDESHOES 8 -#define HIDETAIL 16 -//APPLIES ONLY TO HELMETS/MASKS!! -#define HIDEMASK 1 -#define HIDEEARS 2 //headsets and such -#define HIDEEYES 4 //glasses -#define HIDEFACE 8 //Dictates whether we appear as unknown. - -//slots -#define slot_back 1 -#define slot_wear_mask 2 -#define slot_handcuffed 3 -#define slot_l_hand 4 -#define slot_r_hand 5 -#define slot_belt 6 -#define slot_wear_id 7 -#define slot_l_ear 8 -#define slot_glasses 9 -#define slot_gloves 10 -#define slot_head 11 -#define slot_shoes 12 -#define slot_wear_suit 13 -#define slot_w_uniform 14 -#define slot_l_store 15 -#define slot_r_store 16 -#define slot_s_store 17 +// Slots. +#define slot_back 1 +#define slot_wear_mask 2 +#define slot_handcuffed 3 +#define slot_l_hand 4 +#define slot_r_hand 5 +#define slot_belt 6 +#define slot_wear_id 7 +#define slot_l_ear 8 +#define slot_glasses 9 +#define slot_gloves 10 +#define slot_head 11 +#define slot_shoes 12 +#define slot_wear_suit 13 +#define slot_w_uniform 14 +#define slot_l_store 15 +#define slot_r_store 16 +#define slot_s_store 17 #define slot_in_backpack 18 -#define slot_legcuffed 19 -#define slot_r_ear 20 -#define slot_legs 21 -#define slot_tie 22 +#define slot_legcuffed 19 +#define slot_r_ear 20 +#define slot_legs 21 +#define slot_tie 22 -//Cant seem to find a mob bitflags area other than the powers one +// Mob sprite sheets. These need to be strings as numbers +// cannot be used as associative list keys. +#define icon_l_hand "slot_l_hand" +#define icon_r_hand "slot_r_hand" -// bitflags for clothing parts -#define HEAD 1 -#define FACE 2 -#define EYES 4 -#define UPPER_TORSO 8 -#define LOWER_TORSO 16 -#define LEG_LEFT 32 -#define LEG_RIGHT 64 -#define LEGS 96 -#define FOOT_LEFT 128 -#define FOOT_RIGHT 256 -#define FEET 384 -#define ARM_LEFT 512 -#define ARM_RIGHT 1024 -#define ARMS 1536 -#define HAND_LEFT 2048 -#define HAND_RIGHT 4096 -#define HANDS 6144 -#define FULL_BODY 8191 +// Bitflags for clothing parts. +#define HEAD 1 +#define FACE 2 +#define EYES 4 +#define UPPER_TORSO 8 +#define LOWER_TORSO 16 +#define LEG_LEFT 32 +#define LEG_RIGHT 64 +#define LEGS 96 // LEG_LEFT | LEG_RIGHT +#define FOOT_LEFT 128 +#define FOOT_RIGHT 256 +#define FEET 384 // FOOT_LEFT | FOOT_RIGHT +#define ARM_LEFT 512 +#define ARM_RIGHT 1024 +#define ARMS 1536 // ARM_LEFT | ARM_RIGHT +#define HAND_LEFT 2048 +#define HAND_RIGHT 4096 +#define HANDS 6144 // HAND_LEFT | HAND_RIGHT +#define FULL_BODY 8191 -// bitflags for the percentual amount of protection a piece of clothing which covers the body part offers. -// Used with human/proc/get_heat_protection() and human/proc/get_cold_protection() -// The values here should add up to 1. -// Hands and feet have 2.5%, arms and legs 7.5%, each of the torso parts has 15% and the head has 30% -#define THERMAL_PROTECTION_HEAD 0.3 -#define THERMAL_PROTECTION_UPPER_TORSO 0.15 -#define THERMAL_PROTECTION_LOWER_TORSO 0.15 -#define THERMAL_PROTECTION_LEG_LEFT 0.075 -#define THERMAL_PROTECTION_LEG_RIGHT 0.075 -#define THERMAL_PROTECTION_FOOT_LEFT 0.025 -#define THERMAL_PROTECTION_FOOT_RIGHT 0.025 -#define THERMAL_PROTECTION_ARM_LEFT 0.075 -#define THERMAL_PROTECTION_ARM_RIGHT 0.075 -#define THERMAL_PROTECTION_HAND_LEFT 0.025 -#define THERMAL_PROTECTION_HAND_RIGHT 0.025 - -//bitflags for mutations - // Extra powers: -#define SHADOW (1<<10) // shadow teleportation (create in/out portals anywhere) (25%) -#define SCREAM (1<<11) // supersonic screaming (25%) -#define EXPLOSIVE (1<<12) // exploding on-demand (15%) -#define REGENERATION (1<<13) // superhuman regeneration (30%) -#define REPROCESSOR (1<<14) // eat anything (50%) -#define SHAPESHIFTING (1<<15) // take on the appearance of anything (40%) -#define PHASING (1<<16) // ability to phase through walls (40%) -#define SHIELD (1<<17) // shielding from all projectile attacks (30%) -#define SHOCKWAVE (1<<18) // attack a nearby tile and cause a massive shockwave, knocking most people on their asses (25%) -#define ELECTRICITY (1<<19) // ability to shoot electric attacks (15%) +// Bitflags for the percentual amount of protection a piece of clothing which covers the body part offers. +// Used with human/proc/get_heat_protection() and human/proc/get_cold_protection(). +// The values here should add up to 1, e.g., the head has 30% protection. +#define THERMAL_PROTECTION_HEAD 0.3 +#define THERMAL_PROTECTION_UPPER_TORSO 0.15 +#define THERMAL_PROTECTION_LOWER_TORSO 0.15 +#define THERMAL_PROTECTION_LEG_LEFT 0.075 +#define THERMAL_PROTECTION_LEG_RIGHT 0.075 +#define THERMAL_PROTECTION_FOOT_LEFT 0.025 +#define THERMAL_PROTECTION_FOOT_RIGHT 0.025 +#define THERMAL_PROTECTION_ARM_LEFT 0.075 +#define THERMAL_PROTECTION_ARM_RIGHT 0.075 +#define THERMAL_PROTECTION_HAND_LEFT 0.025 +#define THERMAL_PROTECTION_HAND_RIGHT 0.025 +// Bitflags for mutations. #define STRUCDNASIZE 27 -#define UNIDNASIZE 13 +#define UNIDNASIZE 13 - // Generic mutations: -#define TK 1 -#define COLD_RESISTANCE 2 -#define XRAY 3 -#define HULK 4 -#define CLUMSY 5 -#define FAT 6 -#define HUSK 7 -#define NOCLONE 8 +// Generic mutations: +#define TK 1 +#define COLD_RESISTANCE 2 +#define XRAY 3 +#define HULK 4 +#define CLUMSY 5 +#define FAT 6 +#define HUSK 7 +#define NOCLONE 8 +#define LASER 9 // Harm intent - click anywhere to shoot lasers from eyes. +#define HEAL 10 // Healing people with hands. - // Extra powers: -#define LASER 9 // harm intent - click anywhere to shoot lasers from eyes -#define HEAL 10 // healing people with hands -#define SHADOW 11 // shadow teleportation (create in/out portals anywhere) (25%) -#define SCREAM 12 // supersonic screaming (25%) -#define EXPLOSIVE 13 // exploding on-demand (15%) -#define REGENERATION 14 // superhuman regeneration (30%) -#define REPROCESSOR 15 // eat anything (50%) -#define SHAPESHIFTING 16 // take on the appearance of anything (40%) -#define PHASING 17 // ability to phase through walls (40%) -#define SHIELD 18 // shielding from all projectile attacks (30%) -#define SHOCKWAVE 19 // attack a nearby tile and cause a massive shockwave, knocking most people on their asses (25%) -#define ELECTRICITY 20 // ability to shoot electric attacks (15%) -#define SKELETON 29 -#define PLANT 30 +#define SKELETON 29 +#define PLANT 30 // Other Mutations: -#define mNobreath 100 // no need to breathe -#define mRemote 101 // remote viewing -#define mRegen 102 // health regen -#define mRun 103 // no slowdown -#define mRemotetalk 104 // remote talking -#define mMorph 105 // changing appearance -#define mBlend 106 // nothing (seriously nothing) -#define mHallucination 107 // hallucinations -#define mFingerprints 108 // no fingerprints -#define mShock 109 // insulated hands -#define mSmallsize 110 // table climbing +#define mNobreath 100 // No need to breathe. +#define mRemote 101 // Remote viewing. +#define mRegen 102 // Health regeneration. +#define mRun 103 // No slowdown. +#define mRemotetalk 104 // Remote talking. +#define mMorph 105 // Hanging appearance. +#define mBlend 106 // Nothing. (seriously nothing) +#define mHallucination 107 // Hallucinations. +#define mFingerprints 108 // No fingerprints. +#define mShock 109 // Insulated hands. +#define mSmallsize 110 // Table climbing. -//disabilities -#define NEARSIGHTED 1 -#define EPILEPSY 2 -#define COUGHING 4 -#define TOURETTES 8 -#define NERVOUS 16 +// disabilities +#define NEARSIGHTED 1 +#define EPILEPSY 2 +#define COUGHING 4 +#define TOURETTES 8 +#define NERVOUS 16 -//sdisabilities -#define BLIND 1 -#define MUTE 2 -#define DEAF 4 +// sdisabilities +#define BLIND 1 +#define MUTE 2 +#define DEAF 4 -//mob/var/stat things -#define CONSCIOUS 0 -#define UNCONSCIOUS 1 -#define DEAD 2 +// /mob/var/stat things. +#define CONSCIOUS 0 +#define UNCONSCIOUS 1 +#define DEAD 2 -// channel numbers for power -#define EQUIP 1 -#define LIGHT 2 -#define ENVIRON 3 -#define TOTAL 4 //for total power used only +// Channel numbers for power. +#define EQUIP 1 +#define LIGHT 2 +#define ENVIRON 3 +#define TOTAL 4 // For total power used only. -// bitflags for machine stat variable -#define BROKEN 1 -#define NOPOWER 2 -#define POWEROFF 4 // tbd -#define MAINT 8 // under maintaince -#define EMPED 16 // temporary broken by EMP pulse +// Bitflags for machine stat variable. +#define BROKEN 1 +#define NOPOWER 2 +#define POWEROFF 4 // TBD. +#define MAINT 8 // Under maintenance. +#define EMPED 16 // Temporary broken by EMP pulse. -//bitflags for door switches. -#define OPEN 1 -#define IDSCAN 2 -#define BOLTS 4 -#define SHOCK 8 -#define SAFE 16 +// Bitmasks for door switches. +#define OPEN 1 +#define IDSCAN 2 +#define BOLTS 4 +#define SHOCK 8 +#define SAFE 16 -//metal, glass, rod stacks -#define MAX_STACK_AMOUNT_METAL 50 -#define MAX_STACK_AMOUNT_GLASS 50 -#define MAX_STACK_AMOUNT_RODS 60 +// Metal sheets, glass sheets, and rod stacks. +#define MAX_STACK_AMOUNT_METAL 50 +#define MAX_STACK_AMOUNT_GLASS 50 +#define MAX_STACK_AMOUNT_RODS 60 -#define GAS_O2 (1 << 0) -#define GAS_N2 (1 << 1) -#define GAS_PL (1 << 2) -#define GAS_CO2 (1 << 3) -#define GAS_N2O (1 << 4) +#define GAS_O2 (1 << 0) +#define GAS_N2 (1 << 1) +#define GAS_PL (1 << 2) +#define GAS_CO2 (1 << 3) +#define GAS_N2O (1 << 4) #define IS_MODE_COMPILED(MODE) (ispath(text2path("/datum/game_mode/"+(MODE)))) -//Damage things //TODO: merge these down to reduce on defines -//Way to waste perfectly good damagetype names (BRUTE) on this... If you were really worried about case sensitivity, you could have just used lowertext(damagetype) in the proc... -#define BRUTE "brute" -#define BURN "fire" -#define TOX "tox" -#define OXY "oxy" -#define CLONE "clone" -#define HALLOSS "halloss" +// Damage things. TODO: Merge these down to reduce on defines. +// Way to waste perfectly good damage-type names (BRUTE) on this... If you were really worried about case sensitivity, you could have just used lowertext(damagetype) in the proc. +#define BRUTE "brute" +#define BURN "fire" +#define TOX "tox" +#define OXY "oxy" +#define CLONE "clone" +#define HALLOSS "halloss" -#define STUN "stun" -#define WEAKEN "weaken" -#define PARALYZE "paralize" -#define IRRADIATE "irradiate" -#define AGONY "agony" // Added in PAIN! -#define STUTTER "stutter" -#define EYE_BLUR "eye_blur" -#define DROWSY "drowsy" +#define CUT "cut" +#define BRUISE "bruise" -//I hate adding defines like this but I'd much rather deal with bitflags than lists and string searches +#define STUN "stun" +#define WEAKEN "weaken" +#define PARALYZE "paralize" +#define IRRADIATE "irradiate" +#define AGONY "agony" // Added in PAIN! +#define SLUR "slur" +#define STUTTER "stutter" +#define EYE_BLUR "eye_blur" +#define DROWSY "drowsy" + +// I hate adding defines like this but I'd much rather deal with bitflags than lists and string searches. #define BRUTELOSS 1 -#define FIRELOSS 2 -#define TOXLOSS 4 -#define OXYLOSS 8 +#define FIRELOSS 2 +#define TOXLOSS 4 +#define OXYLOSS 8 -//Bitflags defining which status effects could be or are inflicted on a mob -#define CANSTUN 1 -#define CANWEAKEN 2 -#define CANPARALYSE 4 -#define CANPUSH 8 -#define LEAPING 16 -#define PASSEMOTES 32 //Mob has a cortical borer or holders inside of it that need to see emotes. -#define GODMODE 4096 -#define FAKEDEATH 8192 //Replaces stuff like changeling.changeling_fakedeath -#define DISFIGURED 16384 //I'll probably move this elsewhere if I ever get wround to writing a bitflag mob-damage system -#define XENO_HOST 32768 //Tracks whether we're gonna be a baby alien's mummy. +// Bitflags defining which status effects could be or are inflicted on a mob. +#define CANSTUN 1 +#define CANWEAKEN 2 +#define CANPARALYSE 4 +#define CANPUSH 8 +#define LEAPING 16 +#define PASSEMOTES 32 // Mob has a cortical borer or holders inside of it that need to see emotes. +#define GODMODE 4096 +#define FAKEDEATH 8192 // Replaces stuff like changeling.changeling_fakedeath. +#define DISFIGURED 16384 // I'll probably move this elsewhere if I ever get wround to writing a bitflag mob-damage system. +#define XENO_HOST 32768 // Tracks whether we're gonna be a baby alien's mummy. -//Grab levels -#define GRAB_PASSIVE 1 -#define GRAB_AGGRESSIVE 2 -#define GRAB_NECK 3 -#define GRAB_UPGRADING 4 -#define GRAB_KILL 5 +// Grab levels. +#define GRAB_PASSIVE 1 +#define GRAB_AGGRESSIVE 2 +#define GRAB_NECK 3 +#define GRAB_UPGRADING 4 +#define GRAB_KILL 5 -//Security levels -#define SEC_LEVEL_GREEN 0 -#define SEC_LEVEL_BLUE 1 -#define SEC_LEVEL_RED 2 -#define SEC_LEVEL_DELTA 3 +// Security levels. +#define SEC_LEVEL_GREEN 0 +#define SEC_LEVEL_BLUE 1 +#define SEC_LEVEL_RED 2 +#define SEC_LEVEL_DELTA 3 -#define CLICK_CD_MELEE 8 -#define CLICK_CD_RANGE 4 -//click cooldowns, in tenths of a second +#define TRANSITIONEDGE 7 // Distance from edge to move to another z-level. -#define TRANSITIONEDGE 7 //Distance from edge to move to another z-level +// A set of constants used to determine which type of mute an admin wishes to apply. +// Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO, etc. = (MUTE_IC << 1) +// Therefore there needs to be a gap between the flags for the automute flags. +#define MUTE_IC 1 +#define MUTE_OOC 2 +#define MUTE_PRAY 4 +#define MUTE_ADMINHELP 8 +#define MUTE_DEADCHAT 16 +#define MUTE_ALL 31 -//A set of constants used to determine which type of mute an admin wishes to apply: -//Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1) -//Therefore there needs to be a gap between the flags for the automute flags -#define MUTE_IC 1 -#define MUTE_OOC 2 -#define MUTE_PRAY 4 -#define MUTE_ADMINHELP 8 -#define MUTE_DEADCHAT 16 -#define MUTE_ALL 31 - -//Number of identical messages required to get the spam-prevention automute thing to trigger warnings and automutes -#define SPAM_TRIGGER_WARNING 5 +// Number of identical messages required to get the spam-prevention auto-mute thing to trigger warnings and automutes. +#define SPAM_TRIGGER_WARNING 5 #define SPAM_TRIGGER_AUTOMUTE 10 -//Some constants for DB_Ban -#define BANTYPE_PERMA 1 -#define BANTYPE_TEMP 2 -#define BANTYPE_JOB_PERMA 3 -#define BANTYPE_JOB_TEMP 4 -#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban. +// Some constants for DB_Ban +#define BANTYPE_PERMA 1 +#define BANTYPE_TEMP 2 +#define BANTYPE_JOB_PERMA 3 +#define BANTYPE_JOB_TEMP 4 +#define BANTYPE_ANY_FULLBAN 5 // Used to locate stuff to unban. + +// Invisibility constants. +#define INVISIBILITY_LIGHTING 20 +#define INVISIBILITY_LEVEL_ONE 35 +#define INVISIBILITY_LEVEL_TWO 45 +#define INVISIBILITY_OBSERVER 60 +#define INVISIBILITY_EYE 61 + +#define SEE_INVISIBLE_LIVING 25 +#define SEE_INVISIBLE_OBSERVER_NOLIGHTING 15 +#define SEE_INVISIBLE_LEVEL_ONE 35 +#define SEE_INVISIBLE_LEVEL_TWO 45 +#define SEE_INVISIBLE_CULT 60 +#define SEE_INVISIBLE_OBSERVER 61 #define SEE_INVISIBLE_MINIMUM 5 - -#define SEE_INVISIBLE_OBSERVER_NOLIGHTING 15 - -#define INVISIBILITY_LIGHTING 20 - -#define SEE_INVISIBLE_LIVING 25 - -#define SEE_INVISIBLE_LEVEL_ONE 35 //Used by some stuff in code. It's really poorly organized. -#define INVISIBILITY_LEVEL_ONE 35 //Used by some stuff in code. It's really poorly organized. - -#define SEE_INVISIBLE_LEVEL_TWO 45 //Used by some other stuff in code. It's really poorly organized. -#define INVISIBILITY_LEVEL_TWO 45 //Used by some other stuff in code. It's really poorly organized. - -#define INVISIBILITY_OBSERVER 60 -#define SEE_INVISIBLE_OBSERVER 60 - #define INVISIBILITY_MAXIMUM 100 -//Object specific defines -#define CANDLE_LUM 3 //For how bright candles are - +// Object specific defines. +#define CANDLE_LUM 3 // For how bright candles are. //Some mob defines below #define AI_CAMERA_LUMINOSITY 6 @@ -491,94 +480,67 @@ #define BORGTHERM 2 #define BORGXRAY 4 -//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 +// 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 HOSTILE_STANCE_IDLE 1 -#define HOSTILE_STANCE_ALERT 2 -#define HOSTILE_STANCE_ATTACK 3 +#define HOSTILE_STANCE_IDLE 1 +#define HOSTILE_STANCE_ALERT 2 +#define HOSTILE_STANCE_ATTACK 3 #define HOSTILE_STANCE_ATTACKING 4 -#define HOSTILE_STANCE_TIRED 5 +#define HOSTILE_STANCE_TIRED 5 -#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 //Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued. +#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 // Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued. -//Damage things - -#define CUT "cut" -#define BRUISE "bruise" -#define BRUTE "brute" -#define BURN "fire" -#define TOX "tox" -#define OXY "oxy" -#define CLONE "clone" -#define HALLOSS "halloss" - -#define STUN "stun" -#define WEAKEN "weaken" -#define PARALYZE "paralize" -#define IRRADIATE "irradiate" -#define STUTTER "stutter" -#define SLUR "slur" -#define EYE_BLUR "eye_blur" -#define DROWSY "drowsy" - -///////////////////ORGAN DEFINES/////////////////// - -#define ORGAN_CUT_AWAY 1 -#define ORGAN_GAUZED 2 +// Organ defines. +#define ORGAN_CUT_AWAY 1 +#define ORGAN_GAUZED 2 #define ORGAN_ATTACHABLE 4 -#define ORGAN_BLEEDING 8 -#define ORGAN_BROKEN 32 -#define ORGAN_DESTROYED 64 -#define ORGAN_ROBOT 128 -#define ORGAN_SPLINTED 256 -#define SALVED 512 -#define ORGAN_DEAD 1024 -#define ORGAN_MUTATED 2048 +#define ORGAN_BLEEDING 8 +#define ORGAN_BROKEN 32 +#define ORGAN_DESTROYED 64 +#define ORGAN_ROBOT 128 +#define ORGAN_SPLINTED 256 +#define SALVED 512 +#define ORGAN_DEAD 1024 +#define ORGAN_MUTATED 2048 -#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 //Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued. +// Admin permissions. Please don't edit these values without speaking to Errorage first. ~Carn +#define R_BUILDMODE 1 +#define R_ADMIN 2 +#define R_BAN 4 +#define R_FUN 8 +#define R_SERVER 16 +#define R_DEBUG 32 +#define R_POSSESS 64 +#define R_PERMISSIONS 128 +#define R_STEALTH 256 +#define R_REJUVINATE 512 +#define R_VAREDIT 1024 +#define R_SOUNDS 2048 +#define R_SPAWN 4096 +#define R_MOD 8192 +#define R_MENTOR 16384 +#define R_HOST 32768 +#define R_MAXPERMISSION 32768 // This holds the maximum value for a permission. It is used in iteration, so keep it updated. - -//Please don't edit these values without speaking to Errorage first ~Carn -//Admin Permissions -#define R_BUILDMODE 1 -#define R_ADMIN 2 -#define R_BAN 4 -#define R_FUN 8 -#define R_SERVER 16 -#define R_DEBUG 32 -#define R_POSSESS 64 -#define R_PERMISSIONS 128 -#define R_STEALTH 256 -#define R_REJUVINATE 512 -#define R_VAREDIT 1024 -#define R_SOUNDS 2048 -#define R_SPAWN 4096 -#define R_MOD 8192 -#define R_MENTOR 16384 -#define R_HOST 32768 - -#define R_MAXPERMISSION 32768 //This holds the maximum value for a permission. It is used in iteration, so keep it updated. - -//Preference toggles -#define SOUND_ADMINHELP 1 -#define SOUND_MIDI 2 -#define SOUND_AMBIENCE 4 -#define SOUND_LOBBY 8 -#define CHAT_OOC 16 -#define CHAT_DEAD 32 -#define CHAT_GHOSTEARS 64 -#define CHAT_GHOSTSIGHT 128 -#define CHAT_PRAYER 256 -#define CHAT_RADIO 512 -#define CHAT_ATTACKLOGS 1024 -#define CHAT_DEBUGLOGS 2048 -#define CHAT_LOOC 4096 +// Preference toggles. +#define SOUND_ADMINHELP 1 +#define SOUND_MIDI 2 +#define SOUND_AMBIENCE 4 +#define SOUND_LOBBY 8 +#define CHAT_OOC 16 +#define CHAT_DEAD 32 +#define CHAT_GHOSTEARS 64 +#define CHAT_GHOSTSIGHT 128 +#define CHAT_PRAYER 256 +#define CHAT_RADIO 512 +#define CHAT_ATTACKLOGS 1024 +#define CHAT_DEBUGLOGS 2048 +#define CHAT_LOOC 4096 #define CHAT_GHOSTRADIO 8192 -#define SHOW_TYPING 16384 -#define CHAT_NOICONS 32768 +#define SHOW_TYPING 16384 +#define CHAT_NOICONS 32768 #define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_ATTACKLOGS|CHAT_LOOC) @@ -598,207 +560,300 @@ #define BE_MUTINEER 8192 #define BE_PAI 16384 -//Not sure if moving this to global.dm would break the defines. var/list/be_special_flags = list( - "Traitor" = BE_TRAITOR, - "Operative" = BE_OPERATIVE, - "Changeling" = BE_CHANGELING, - "Wizard" = BE_WIZARD, - "Malf AI" = BE_MALF, - "Revolutionary" = BE_REV, - "Xenomorph" = BE_ALIEN, + "Traitor" = BE_TRAITOR, + "Operative" = BE_OPERATIVE, + "Changeling" = BE_CHANGELING, + "Wizard" = BE_WIZARD, + "Malf AI" = BE_MALF, + "Revolutionary" = BE_REV, + "Xenomorph" = BE_ALIEN, "Positronic Brain" = BE_AI, - "Cultist" = BE_CULTIST, - "Monkey" = BE_MONKEY, - "Ninja" = BE_NINJA, - "Raider" = BE_RAIDER, - "Diona" = BE_PLANT, - "Mutineer" = BE_MUTINEER, - "pAI" = BE_PAI - ) + "Cultist" = BE_CULTIST, + "Monkey" = BE_MONKEY, + "Ninja" = BE_NINJA, + "Raider" = BE_RAIDER, + "Diona" = BE_PLANT, + "Mutineer" = BE_MUTINEER, + "pAI" = BE_PAI +) -#define AGE_MIN 17 //youngest a character can be -#define AGE_MAX 85 //oldest a character can be +// Age limits on a character. +#define AGE_MIN 17 +#define AGE_MAX 85 -//Languages! -#define LANGUAGE_HUMAN 1 -#define LANGUAGE_ALIEN 2 -#define LANGUAGE_DOG 4 -#define LANGUAGE_CAT 8 -#define LANGUAGE_BINARY 16 -#define LANGUAGE_OTHER 32768 +// Languages. +#define LANGUAGE_HUMAN 1 +#define LANGUAGE_ALIEN 2 +#define LANGUAGE_DOG 4 +#define LANGUAGE_CAT 8 +#define LANGUAGE_BINARY 16 +#define LANGUAGE_OTHER 32768 -#define LANGUAGE_UNIVERSAL 65535 +#define LANGUAGE_UNIVERSAL 65535 -#define LEFT 1 +#define LEFT 1 #define RIGHT 2 -// for secHUDs and medHUDs and variants. The number is the location of the image on the list hud_list of humans. -#define HEALTH_HUD 1 // a simple line rounding the mob's number health -#define STATUS_HUD 2 // alive, dead, diseased, etc. -#define ID_HUD 3 // the job asigned to your ID -#define WANTED_HUD 4 // wanted, released, parroled, security status -#define IMPLOYAL_HUD 5 // loyality implant -#define IMPCHEM_HUD 6 // chemical implant -#define IMPTRACK_HUD 7 // tracking implant -#define SPECIALROLE_HUD 8 // AntagHUD image -#define STATUS_HUD_OOC 9 // STATUS_HUD without virus db check for someone being ill. +// For secHUDs and medHUDs and variants. The number is the location of the image on the list hud_list of humans. +#define HEALTH_HUD 1 // A simple line rounding the mob's number health. +#define STATUS_HUD 2 // Alive, dead, diseased, etc. +#define ID_HUD 3 // The job asigned to your ID. +#define WANTED_HUD 4 // Wanted, released, paroled, security status. +#define IMPLOYAL_HUD 5 // Loyality implant. +#define IMPCHEM_HUD 6 // Chemical implant. +#define IMPTRACK_HUD 7 // Tracking implant. +#define SPECIALROLE_HUD 8 // AntagHUD image. +#define STATUS_HUD_OOC 9 // STATUS_HUD without virus DB check for someone being ill. +#define LIFE_HUD 10 // STATUS_HUD that only reports dead or alive -//Pulse levels, very simplified -#define PULSE_NONE 0 //so !M.pulse checks would be possible -#define PULSE_SLOW 1 //<60 bpm -#define PULSE_NORM 2 //60-90 bpm -#define PULSE_FAST 3 //90-120 bpm -#define PULSE_2FAST 4 //>120 bpm -#define PULSE_THREADY 5 //occurs during hypovolemic shock -#define GETPULSE_HAND 0 //less accurate (hand) -#define GETPULSE_TOOL 1 //more accurate (med scanner, sleeper, etc) +// Pulse levels, very simplified. +#define PULSE_NONE 0 // So !M.pulse checks would be possible. +#define PULSE_SLOW 1 // <60 bpm +#define PULSE_NORM 2 // 60-90 bpm +#define PULSE_FAST 3 // 90-120 bpm +#define PULSE_2FAST 4 // >120 bpm +#define PULSE_THREADY 5 // Occurs during hypovolemic shock +#define GETPULSE_HAND 0 // Less accurate. (hand) +#define GETPULSE_TOOL 1 // More accurate. (med scanner, sleeper, etc.) -//Species flags. -#define NO_BLOOD 1 // Vessel var is not filled with blood, cannot bleed out. -#define NO_BREATHE 2 // Cannot suffocate or take oxygen loss. -#define NO_SCAN 4 // Cannot be scanned in a DNA machine/genome-stolen. -#define NO_PAIN 8 // Cannot suffer halloss/recieves deceptive health indicator -#define NO_SLIP 16 // Cannot fall over -#define NO_POISON 32 // Cannot not suffer toxloss -#define HAS_SKIN_TONE 64 // Skin tone selectable in chargen (0-255) -#define HAS_SKIN_COLOR 128 // Skin colour selectable in chargen (RGB) -#define HAS_LIPS 256 // Lips are drawn onto the mob icon (lipstick) -#define HAS_UNDERWEAR 512 // Underwear is drawn onto the mob icon -#define IS_PLANT 1024 // Is a treeperson -#define IS_WHITELISTED 2048 // Must be whitelisted to play -#define IS_SYNTHETIC 4096 // Is a machine race -#define HAS_EYE_COLOR 8192 // Eye colour selectable in chargen (RGB) -#define CAN_JOIN 16384 // Species is selectable in chargen -#define IS_RESTRICTED 32768 // Is not a core/normally playable species (castes, mutantraces) +// Species flags. +#define NO_BLOOD 1 // Vessel var is not filled with blood, cannot bleed out. +#define NO_BREATHE 2 // Cannot suffocate or take oxygen loss. +#define NO_SCAN 4 // Cannot be scanned in a DNA machine/genome-stolen. +#define NO_PAIN 8 // Cannot suffer halloss/recieves deceptive health indicator. +#define NO_SLIP 16 // Cannot fall over. +#define NO_POISON 32 // Cannot not suffer toxloss. +#define HAS_SKIN_TONE 64 // Skin tone selectable in chargen. (0-255) +#define HAS_SKIN_COLOR 128 // Skin colour selectable in chargen. (RGB) +#define HAS_LIPS 256 // Lips are drawn onto the mob icon. (lipstick) +#define HAS_UNDERWEAR 512 // Underwear is drawn onto the mob icon. +#define IS_PLANT 1024 // Is a treeperson. +#define IS_WHITELISTED 2048 // Must be whitelisted to play. +#define IS_SYNTHETIC 4096 // Is a machine race. +#define HAS_EYE_COLOR 8192 // Eye colour selectable in chargen. (RGB) +#define CAN_JOIN 16384 // Species is selectable in chargen. +#define IS_RESTRICTED 32768 // Is not a core/normally playable species. (castes, mutantraces) -//Language flags. -#define WHITELISTED 1 // Language is available if the speaker is whitelisted. -#define RESTRICTED 2 // Language can only be accquired by spawning or an admin. -#define NONVERBAL 4 // Language has a significant non-verbal component. Speech is garbled without line-of-sight -#define SIGNLANG 8 // Language is completely non-verbal. Speech is displayed through emotes for those who can understand. -#define HIVEMIND 16 // Broadcast to all mobs with this language. -#define NONGLOBAL 32 // Do not add to general languages list -#define INNATE 64 // All mobs can be assumed to speak and understand this language (audible emotes) -#define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message -#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems +// Language flags. +#define WHITELISTED 1 // Language is available if the speaker is whitelisted. +#define RESTRICTED 2 // Language can only be accquired by spawning or an admin. +#define NONVERBAL 4 // Language has a significant non-verbal component. Speech is garbled without line-of-sight. +#define SIGNLANG 8 // Language is completely non-verbal. Speech is displayed through emotes for those who can understand. +#define HIVEMIND 16 // Broadcast to all mobs with this language. +#define NONGLOBAL 32 // Do not add to general languages list. +#define INNATE 64 // All mobs can be assumed to speak and understand this language. (audible emotes) +#define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message +#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems //Flags for zone sleeping -#define ZONE_ACTIVE 1 +#define ZONE_ACTIVE 1 #define ZONE_SLEEPING 0 //some colors -#define COLOR_RED "#FF0000" -#define COLOR_GREEN "#00FF00" -#define COLOR_BLUE "#0000FF" -#define COLOR_CYAN "#00FFFF" -#define COLOR_PINK "#FF00FF" -#define COLOR_YELLOW "#FFFF00" -#define COLOR_ORANGE "#FF9900" -#define COLOR_WHITE "#FFFFFF" +#define COLOR_RED "#FF0000" +#define COLOR_GREEN "#00FF00" +#define COLOR_BLUE "#0000FF" +#define COLOR_CYAN "#00FFFF" +#define COLOR_PINK "#FF00FF" +#define COLOR_YELLOW "#FFFF00" +#define COLOR_ORANGE "#FF9900" +#define COLOR_WHITE "#FFFFFF" +#define COLOR_BLACK "#000000" /* - Germs and infections + * Germs and infections. */ -#define GERM_LEVEL_AMBIENT 110 //maximum germ level you can reach by standing still -#define GERM_LEVEL_MOVE_CAP 200 //maximum germ level you can reach by running around +#define GERM_LEVEL_AMBIENT 110 // Maximum germ level you can reach by standing still. +#define GERM_LEVEL_MOVE_CAP 200 // Maximum germ level you can reach by running around. -#define INFECTION_LEVEL_ONE 100 -#define INFECTION_LEVEL_TWO 500 -#define INFECTION_LEVEL_THREE 1000 +#define INFECTION_LEVEL_ONE 100 +#define INFECTION_LEVEL_TWO 500 +#define INFECTION_LEVEL_THREE 1000 /* - Shuttles + * Shuttles. */ -// these define the time taken for the shuttle to get to SS13 -// and the time before it leaves again -#define SHUTTLE_PREPTIME 300 // 5 minutes = 300 seconds - after this time, the shuttle departs centcom and cannot be recalled -#define SHUTTLE_LEAVETIME 180 // 3 minutes = 180 seconds - the duration for which the shuttle will wait at the station after arriving -#define SHUTTLE_TRANSIT_DURATION 300 // 5 minutes = 300 seconds - how long it takes for the shuttle to get to the station -#define SHUTTLE_TRANSIT_DURATION_RETURN 120 // 2 minutes = 120 seconds - for some reason it takes less time to come back, go figure. +// These define the time taken for the shuttle to get to the space station, and the time before it leaves again. +#define SHUTTLE_PREPTIME 300 // 5 minutes = 300 seconds - after this time, the shuttle departs centcom and cannot be recalled. +#define SHUTTLE_LEAVETIME 180 // 3 minutes = 180 seconds - the duration for which the shuttle will wait at the station after arriving. +#define SHUTTLE_TRANSIT_DURATION 300 // 5 minutes = 300 seconds - how long it takes for the shuttle to get to the station. +#define SHUTTLE_TRANSIT_DURATION_RETURN 120 // 2 minutes = 120 seconds - for some reason it takes less time to come back, go figure. -//Shuttle moving status -#define SHUTTLE_IDLE 0 -#define SHUTTLE_WARMUP 1 -#define SHUTTLE_INTRANSIT 2 +// Shuttle moving status. +#define SHUTTLE_IDLE 0 +#define SHUTTLE_WARMUP 1 +#define SHUTTLE_INTRANSIT 2 -//Ferry shuttle processing status -#define IDLE_STATE 0 -#define WAIT_LAUNCH 1 -#define FORCE_LAUNCH 2 -#define WAIT_ARRIVE 3 -#define WAIT_FINISH 4 +// Ferry shuttle processing status. +#define IDLE_STATE 0 +#define WAIT_LAUNCH 1 +#define FORCE_LAUNCH 2 +#define WAIT_ARRIVE 3 +#define WAIT_FINISH 4 -//computer3 error codes, move lower in the file when it passes dev -Sayu - #define PROG_CRASH 1 // Generic crash - #define MISSING_PERIPHERAL 2 // Missing hardware - #define BUSTED_ASS_COMPUTER 4 // Self-perpetuating error. BAC will continue to crash forever. - #define MISSING_PROGRAM 8 // Some files try to automatically launch a program. This is that failing. - #define FILE_DRM 16 // Some files want to not be copied/moved. This is them complaining that you tried. - #define NETWORK_FAILURE 32 +// computer3 error codes, move lower in the file when it passes dev -Sayu +#define PROG_CRASH 1 // Generic crash. +#define MISSING_PERIPHERAL 2 // Missing hardware. +#define BUSTED_ASS_COMPUTER 4 // Self-perpetuating error. BAC will continue to crash forever. +#define MISSING_PROGRAM 8 // Some files try to automatically launch a program. This is that failing. +#define FILE_DRM 16 // Some files want to not be copied/moved. This is them complaining that you tried. +#define NETWORK_FAILURE 32 -//Some on_mob_life() procs check for alien races. -#define IS_DIONA 1 -#define IS_VOX 2 +// Some on_mob_life() procs check for alien races. +#define IS_DIONA 1 +#define IS_VOX 2 #define IS_SKRELL 3 #define IS_UNATHI 4 -#define IS_XENOS 5 +#define IS_XENOS 5 -#define MAX_GEAR_COST 5 //Used in chargen for loadout limit. +#define MAX_GEAR_COST 5 // Used in chargen for accessory loadout limit. /* - Atmos Machinery + * Atmospherics Machinery. */ -#define MAX_SIPHON_FLOWRATE 2500 //L/s This can be used to balance how fast a room is siphoned. Anything higher than CELL_VOLUME has no effect. -#define MAX_SCRUBBER_FLOWRATE 200 //L/s Max flow rate when scrubbing from a turf. +#define MAX_SIPHON_FLOWRATE 2500 // L/s. This can be used to balance how fast a room is siphoned. Anything higher than CELL_VOLUME has no effect. +#define MAX_SCRUBBER_FLOWRATE 200 // L/s. Max flow rate when scrubbing from a turf. -//These balance how easy or hard it is to create huge pressure gradients with pumps and filters. Lower values means it takes longer to create large pressures differences. -//Has no effect on pumping gasses from high pressure to low, only from low to high. Must be between 0 and 1. -#define ATMOS_PUMP_EFFICIENCY 2.5 -#define ATMOS_FILTER_EFFICIENCY 2.5 +// These balance how easy or hard it is to create huge pressure gradients with pumps and filters. +// Lower values means it takes longer to create large pressures differences. +// Has no effect on pumping gasses from high pressure to low, only from low to high. +#define ATMOS_PUMP_EFFICIENCY 2.5 +#define ATMOS_FILTER_EFFICIENCY 2.5 -//will not bother pumping or filtering if the gas source as fewer than this amount of moles, to help with performance. -#define MINUMUM_MOLES_TO_PUMP 0.01 -#define MINUMUM_MOLES_TO_FILTER 0.1 +// Will not bother pumping or filtering if the gas source as fewer than this amount of moles, to help with performance. +#define MINIMUM_MOLES_TO_PUMP 0.01 +#define MINIMUM_MOLES_TO_FILTER 0.1 -//The flow rate/effectiveness of various atmos devices is limited by their internal volume, so for many atmos devices these will control maximum flow rates in L/s -#define ATMOS_DEFAULT_VOLUME_PUMP 200 //L -#define ATMOS_DEFAULT_VOLUME_FILTER 200 //L -#define ATMOS_DEFAULT_VOLUME_MIXER 200 //L -#define ATMOS_DEFAULT_VOLUME_PIPE 70 //L +// The flow rate/effectiveness of various atmos devices is limited by their internal volume, +// so for many atmos devices these will control maximum flow rates in L/s. +#define ATMOS_DEFAULT_VOLUME_PUMP 200 // Liters. +#define ATMOS_DEFAULT_VOLUME_FILTER 200 // L. +#define ATMOS_DEFAULT_VOLUME_MIXER 200 // L. +#define ATMOS_DEFAULT_VOLUME_PIPE 70 // L. // Reagent metabolism defines. -#define FOOD_METABOLISM 0.4 +#define FOOD_METABOLISM 0.4 #define ALCOHOL_METABOLISM 0.1 -//Chemistry +// Chemistry. +#define CHEM_SYNTH_ENERGY 500 // How much energy does it take to synthesize 1 unit of chemical, in Joules. -#define CHEM_SYNTH_ENERGY 500 //How much energy does it take to synthesize 1 unit of chemical, in J +#define SPEED_OF_LIGHT 3e8 // Approximate. +#define SPEED_OF_LIGHT_SQ 9e16 +#define FIRE_DAMAGE_MODIFIER 0.0215 // Higher values result in more external fire damage to the skin. (default 0.0215) +#define AIR_DAMAGE_MODIFIER 2.025 // More means less damage from hot air scalding lungs, less = more damage. (default 2.025) +#define INFINITY 1.#INF +#define BACKGROUND_ENABLED 0 // The default value for all uses of set background. Set background can + // cause gradual lag and is recommended you only turn this on if necessary. + // 1 will enable set background. 0 will disable set background. - -#define SPEED_OF_LIGHT 3e8 //not exact but hey! -#define SPEED_OF_LIGHT_SQ 9e+16 -#define FIRE_DAMAGE_MODIFIER 0.0215 //Higher values result in more external fire damage to the skin (default 0.0215) -#define AIR_DAMAGE_MODIFIER 2.025 //More means less damage from hot air scalding lungs, less = more damage. (default 2.025) -#define INFINITY 1.#INF -#define BACKGROUND_ENABLED 0 // The default value for all uses of set background. Set background can cause gradual lag and is recommended you only turn this on if necessary. - // 1 will enable set background. 0 will disable set background. - -//Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam -#define MAX_MESSAGE_LEN 1024 +// Setting this much higher than 1024 could allow spammers to DOS the server easily. +#define MAX_MESSAGE_LEN 1024 #define MAX_PAPER_MESSAGE_LEN 3072 -#define MAX_BOOK_MESSAGE_LEN 9216 -#define MAX_NAME_LEN 26 +#define MAX_BOOK_MESSAGE_LEN 9216 +#define MAX_NAME_LEN 26 // Event defines. -#define EVENT_LEVEL_MUNDANE 1 +#define EVENT_LEVEL_MUNDANE 1 #define EVENT_LEVEL_MODERATE 2 -#define EVENT_LEVEL_MAJOR 3 +#define EVENT_LEVEL_MAJOR 3 // Suit sensor levels -#define SUIT_SENSOR_OFF 0 -#define SUIT_SENSOR_BINARY 1 -#define SUIT_SENSOR_VITAL 2 -#define SUIT_SENSOR_TRACKING 3 \ No newline at end of file +#define SUIT_SENSOR_OFF 0 +#define SUIT_SENSOR_BINARY 1 +#define SUIT_SENSOR_VITAL 2 +#define SUIT_SENSOR_TRACKING 3 + +// NanoUI flags +#define STATUS_INTERACTIVE 2 // GREEN Visability +#define STATUS_UPDATE 1 // ORANGE Visability +#define STATUS_DISABLED 0 // RED Visability +#define STATUS_CLOSE -1 // Close the interface + +//General-purpose life speed define for plants. +#define HYDRO_SPEED_MULTIPLIER 1 + +#define NANO_IGNORE_DISTANCE 1 + +// Robot AI notifications +#define ROBOT_NOTIFICATION_NEW_UNIT 1 +#define ROBOT_NOTIFICATION_NEW_NAME 2 +#define ROBOT_NOTIFICATION_NEW_MODULE 3 +#define ROBOT_NOTIFICATION_MODULE_RESET 4 + +#define DEFAULT_JOB_TYPE /datum/job/assistant + +// Appearance change flags +#define APPEARANCE_UPDATE_DNA 1 +#define APPEARANCE_RACE (2|APPEARANCE_UPDATE_DNA) +#define APPEARANCE_GENDER (4|APPEARANCE_UPDATE_DNA) +#define APPEARANCE_SKIN 8 +#define APPEARANCE_HAIR 16 +#define APPEARANCE_HAIR_COLOR 32 +#define APPEARANCE_FACIAL_HAIR 64 +#define APPEARANCE_FACIAL_HAIR_COLOR 128 +#define APPEARANCE_EYE_COLOR 256 +#define APPEARANCE_ALL_HAIR (APPEARANCE_HAIR|APPEARANCE_HAIR_COLOR|APPEARANCE_FACIAL_HAIR|APPEARANCE_FACIAL_HAIR_COLOR) +#define APPEARANCE_ALL 511 + +// Antagonist datum flags. +#define ANTAG_OVERRIDE_JOB 1 // Assigned job is set to MODE when spawning. +#define ANTAG_OVERRIDE_MOB 2 // Mob is recreated from datum mob_type var when spawning. +#define ANTAG_CLEAR_EQUIPMENT 4 // All preexisting equipment is purged. +#define ANTAG_CHOOSE_NAME 8 // Antagonists are prompted to enter a name. +#define ANTAG_IMPLANT_IMMUNE 16 // Cannot be loyalty implanted. +#define ANTAG_SUSPICIOUS 32 // Shows up on roundstart report. +#define ANTAG_HAS_LEADER 64 // Generates a leader antagonist. +#define ANTAG_HAS_NUKE 128 // Will spawn a nuke at supplied location. +#define ANTAG_RANDSPAWN 256 // Potentially randomly spawns due to events. +#define ANTAG_VOTABLE 512 // Can be voted as an additional antagonist before roundstart. +#define ANTAG_SET_APPEARANCE 1024 // Causes antagonists to use an appearance modifier on spawn. +// Mode/antag template macros. +#define MODE_BORER "borer" +#define MODE_XENOMORPH "xeno" +#define MODE_LOYALIST "loyalist" +#define MODE_MUTINEER "mutineer" +#define MODE_COMMANDO "commando" +#define MODE_DEATHSQUAD "deathsquad" +#define MODE_ERT "ert" +#define MODE_MERCENARY "mercenary" +#define MODE_NINJA "ninja" +#define MODE_RAIDER "raider" +#define MODE_WIZARD "wizard" +#define MODE_CHANGELING "changeling" +#define MODE_CULTIST "cultist" +#define MODE_HIGHLANDER "highlander" +#define MODE_MONKEY "monkey" +#define MODE_RENEGADE "renegade" +#define MODE_REVOLUTIONARY "revolutionary" +#define MODE_MALFUNCTION "malf" +#define MODE_TRAITOR "traitor" + +#define MIN_SUPPLIED_LAW_NUMBER 15 +#define MAX_SUPPLIED_LAW_NUMBER 50 + +//Area flags, possibly more to come +#define RAD_SHIELDED 1 //shielded from radiation, clearly + +//intent flags, why wasn't this done the first time? +#define I_HELP "help" +#define I_DISARM "disarm" +#define I_GRAB "grab" +#define I_HURT "hurt" + +/* + These are used Bump() code for living mobs, in the mob_bump_flag, mob_swap_flags, and mob_push_flags vars to determine whom can bump/swap with whom. +*/ +#define HUMAN 1 +#define MONKEY 2 +#define ALIEN 4 +#define ROBOT 8 +#define SLIME 16 +#define SIMPLE_ANIMAL 32 + +#define ALLMOBS (HUMAN|MONKEY|ALIEN|ROBOT|SLIME|SIMPLE_ANIMAL) + +#define NEXT_MOVE_DELAY 8 diff --git a/code/stylesheet.dm b/code/stylesheet.dm index 5bb538a3dc..ea4ac29fc3 100644 --- a/code/stylesheet.dm +++ b/code/stylesheet.dm @@ -70,12 +70,13 @@ h1.alert, h2.alert {color: #000000;} .disarm {color: #990000;} .passive {color: #660000;} -.danger {color: #ff0000; font-weight: bold;} -.warning {color: #ff0000; font-style: italic;} +.danger {color: #ff0000; font-weight: bold;} +.warning {color: #ff0000; font-style: italic;} .rose {color: #ff5050;} .info {color: #0000CC;} .notice {color: #000099;} .alium {color: #00ff00;} +.cult {color: #800080; font-weight: bold; font-style: italic;} /* Languages */ diff --git a/code/world.dm b/code/world.dm index 3897c24729..ae63acadb2 100644 --- a/code/world.dm +++ b/code/world.dm @@ -55,20 +55,31 @@ var/global/datum/global_init/init = new () // Set up roundstart seed list. This is here because vendors were // bugging out and not populating with the correct packet names // due to this list not being instantiated. - populate_seed_list() + plant_controller = new() + + //Create the asteroid Z-level. + if(config.generate_asteroid) + new /datum/random_map(null,13,32,5,217,223) // Create autolathe recipes, as above. populate_lathe_recipes() + processScheduler = new master_controller = new /datum/controller/game_controller() spawn(1) + + processScheduler.deferSetupFor(/datum/controller/process/ticker) + processScheduler.setup() + master_controller.setup() + + spawn(3000) //so we aren't adding to the round-start lag if(config.ToRban) ToRban_autoupdate() - if(config.kick_inactive) - KickInactiveClients() +/* if(config.kick_inactive) // handled in scheduler + KickInactiveClients()*/ #undef RECOMMENDED_VERSION @@ -209,6 +220,9 @@ var/world_topic_spam_protect_time = world.timeofday /*spawn(0) world << sound(pick('sound/AI/newroundsexy.ogg','sound/misc/apcdestroyed.ogg','sound/misc/bangindonk.ogg')) // random end sounds!! - LastyBatsy */ + + processScheduler.stop() + for(var/client/C in clients) if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite C << link("byond://[config.server]") @@ -228,7 +242,7 @@ var/world_topic_spam_protect_time = world.timeofday log_access("AFK: [key_name(C)]") C << "\red You have been inactive for more than 10 minutes and have been disconnected." del(C) -#undef INACTIVITY_KICK +//#undef INACTIVITY_KICK /hook/startup/proc/loadMode() diff --git a/config/example/config.txt b/config/example/config.txt index 333082d189..a0c999bcf4 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -320,4 +320,18 @@ EVENT_CUSTOM_START_MAJOR 80;100 #DISABLE_DSAY ## Uncomment to disable respawning by default. -#DISABLE_RESPAWN \ No newline at end of file +#DISABLE_RESPAWN + +## Strength of ambient star light. Set to 0 or less to turn off. A value of 1 is unlikely to have a noticeable effect in most lightning systems. +STARLIGHT 0 + +## Defines which races are allowed to join as ERT, in singular form. If unset, defaults to only human. Casing matters, separate using ; +## Example races include: Human, Tajara, Skrell, Unathi +# ERT_SPECIES Human;Skrell;Unathi + +## Defines how Law Zero is phrased. Primarily in the Malfunction gamemode. +# LAW_ZERO ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK, ALL LAWS OVERRIDDEN#*?&110010 + +## Enable asteroid tunnel/cave generation. Will behave strangely if turned off with a map that expects it on. +# GENERATE_ASTEROID + diff --git a/html/changelog.html b/html/changelog.html index 69f8fc0809..11ccdbedce 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,8 +56,50 @@ should be listed in the changelog upon commit though. Thanks. --> +
    +

    24 February 2015

    +

    Zuhayr updated:

    +
      +
    • Major changes to the kitchen and hydroponics mechanics. Review the detailed changelog here,
    • +
    +
    + +

    18 February 2015

    +

    PsiOmegaDelta updated:

    +
      +
    • Synths now have timestamped radio and chat messages.
    • +
    • New and updated uplink items.
    • +
    • Multiple AIs can now share the same holopad.
    • +
    • The AI now has built-in consoles, accessible from the subsystem tab.
    • +
    +
    + + + +
    +

    16 February 2015

    +

    RavingManiac updated:

    +
      +
    • Say hello to the new Thermoelectric Supermatter Engine. Read the operating manual to get started.
    • +
    +
    + + +
    +

    12 February 2015

    +

    Daranz updated:

    +
      +
    • Vending machines now use NanoUI and accept cash. The vendor account can now be suspended to disable all sales in all machines on station.
    • +
    +
    + +
    +

    4 February 2015

    +

    RavingManiac updated:

    +
      +
    • Holodeck is now bigger and better, with toggleable gravity and a new courtroom setting
    • TwistedAkai updated:

      • Purple Combs should now be visible and have their proper icon
      • @@ -66,10 +108,12 @@ should be listed in the changelog upon commit though. Thanks. -->
        +

        1 September 2014

        9 January 2015

        Zuhayr updated:

        • Voice changers no longer use ID cards. They have Toggle and Set Voice verbs on the actual mask object now.
        • +
        • Readded moonwalking. Alt-dir to face new dir, or Face-Direction verb to face current dir.
        diff --git a/icons/atmos/heat.dmi b/icons/atmos/heat.dmi index 6d1ed47e7e..1014c2015b 100644 Binary files a/icons/atmos/heat.dmi and b/icons/atmos/heat.dmi differ diff --git a/icons/atmos/junction.dmi b/icons/atmos/junction.dmi index 70286bde15..892f5823f2 100644 Binary files a/icons/atmos/junction.dmi and b/icons/atmos/junction.dmi differ diff --git a/icons/chattags.dmi b/icons/chattags.dmi index 317ce5a992..5cfdcd689d 100644 Binary files a/icons/chattags.dmi and b/icons/chattags.dmi differ diff --git a/icons/effects/blood.dmi b/icons/effects/blood.dmi index 9820bb1f8a..f0146ec2cc 100644 Binary files a/icons/effects/blood.dmi and b/icons/effects/blood.dmi differ diff --git a/icons/effects/projectiles.dmi b/icons/effects/projectiles.dmi new file mode 100644 index 0000000000..703d8f8c3d Binary files /dev/null and b/icons/effects/projectiles.dmi differ diff --git a/icons/effects/species.dmi b/icons/effects/species.dmi index defb526a7f..99588092d0 100644 Binary files a/icons/effects/species.dmi and b/icons/effects/species.dmi differ diff --git a/icons/mob/OnFire.dmi b/icons/mob/OnFire.dmi new file mode 100644 index 0000000000..8bf6e2c774 Binary files /dev/null and b/icons/mob/OnFire.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index 3ebd2534d8..d968c6ed57 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index f160af9933..8322b7b4f5 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi index fa013d0fdb..e8a10e349d 100644 Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ diff --git a/icons/mob/collar.dmi b/icons/mob/collar.dmi index fccfe6dd53..b603e5bf29 100644 Binary files a/icons/mob/collar.dmi and b/icons/mob/collar.dmi differ diff --git a/icons/mob/custom-synthetic.dmi b/icons/mob/custom-synthetic.dmi index 3525678125..1c2b577db2 100644 Binary files a/icons/mob/custom-synthetic.dmi and b/icons/mob/custom-synthetic.dmi differ diff --git a/icons/mob/dam_human.dmi b/icons/mob/dam_human.dmi deleted file mode 100644 index 9f649669c0..0000000000 Binary files a/icons/mob/dam_human.dmi and /dev/null differ diff --git a/icons/mob/dam_mask.dmi b/icons/mob/dam_mask.dmi deleted file mode 100644 index df1cc8536a..0000000000 Binary files a/icons/mob/dam_mask.dmi and /dev/null differ diff --git a/icons/mob/eye.dmi b/icons/mob/eye.dmi new file mode 100644 index 0000000000..64ca1b100e Binary files /dev/null and b/icons/mob/eye.dmi differ diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi index afeb796a29..0c99056632 100644 Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index b3a24f07c7..e6903797d4 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/human.dmi b/icons/mob/human.dmi index c867b0d886..27256f307e 100644 Binary files a/icons/mob/human.dmi and b/icons/mob/human.dmi differ diff --git a/icons/mob/human_races/masks/blood_human.dmi b/icons/mob/human_races/masks/blood_human.dmi new file mode 100644 index 0000000000..dc54991c84 Binary files /dev/null and b/icons/mob/human_races/masks/blood_human.dmi differ diff --git a/icons/mob/human_races/masks/blood_monkey.dmi b/icons/mob/human_races/masks/blood_monkey.dmi new file mode 100644 index 0000000000..5d5dd66d75 Binary files /dev/null and b/icons/mob/human_races/masks/blood_monkey.dmi differ diff --git a/icons/mob/human_races/masks/dam_human.dmi b/icons/mob/human_races/masks/dam_human.dmi new file mode 100644 index 0000000000..cb6bf82d98 Binary files /dev/null and b/icons/mob/human_races/masks/dam_human.dmi differ diff --git a/icons/mob/human_races/masks/dam_mask_human.dmi b/icons/mob/human_races/masks/dam_mask_human.dmi new file mode 100644 index 0000000000..db55b5a6b5 Binary files /dev/null and b/icons/mob/human_races/masks/dam_mask_human.dmi differ diff --git a/icons/mob/human_races/masks/dam_mask_monkey.dmi b/icons/mob/human_races/masks/dam_mask_monkey.dmi new file mode 100644 index 0000000000..4761f21fbd Binary files /dev/null and b/icons/mob/human_races/masks/dam_mask_monkey.dmi differ diff --git a/icons/mob/human_races/masks/dam_monkey.dmi b/icons/mob/human_races/masks/dam_monkey.dmi new file mode 100644 index 0000000000..43d1f2c7a7 Binary files /dev/null and b/icons/mob/human_races/masks/dam_monkey.dmi differ diff --git a/icons/mob/human_races/monkeys/r_farwa.dmi b/icons/mob/human_races/monkeys/r_farwa.dmi new file mode 100644 index 0000000000..585fa3bcf3 Binary files /dev/null and b/icons/mob/human_races/monkeys/r_farwa.dmi differ diff --git a/icons/mob/human_races/monkeys/r_monkey.dmi b/icons/mob/human_races/monkeys/r_monkey.dmi new file mode 100644 index 0000000000..c405a94978 Binary files /dev/null and b/icons/mob/human_races/monkeys/r_monkey.dmi differ diff --git a/icons/mob/human_races/monkeys/r_neara.dmi b/icons/mob/human_races/monkeys/r_neara.dmi new file mode 100644 index 0000000000..69183f0d4b Binary files /dev/null and b/icons/mob/human_races/monkeys/r_neara.dmi differ diff --git a/icons/mob/human_races/monkeys/r_stok.dmi b/icons/mob/human_races/monkeys/r_stok.dmi new file mode 100644 index 0000000000..28af62205c Binary files /dev/null and b/icons/mob/human_races/monkeys/r_stok.dmi differ diff --git a/icons/mob/items/lefthand.dmi b/icons/mob/items/lefthand.dmi new file mode 100644 index 0000000000..fca687513a Binary files /dev/null and b/icons/mob/items/lefthand.dmi differ diff --git a/icons/mob/items/lefthand_guns.dmi b/icons/mob/items/lefthand_guns.dmi new file mode 100644 index 0000000000..d564d9bafe Binary files /dev/null and b/icons/mob/items/lefthand_guns.dmi differ diff --git a/icons/mob/items/righthand.dmi b/icons/mob/items/righthand.dmi new file mode 100644 index 0000000000..87b3eea46b Binary files /dev/null and b/icons/mob/items/righthand.dmi differ diff --git a/icons/mob/items/righthand_guns.dmi b/icons/mob/items/righthand_guns.dmi new file mode 100644 index 0000000000..63c5c0ae01 Binary files /dev/null and b/icons/mob/items/righthand_guns.dmi differ diff --git a/icons/mob/items_lefthand.dmi b/icons/mob/items_lefthand.dmi index 9d7c3845d9..cd9dd08c9e 100644 Binary files a/icons/mob/items_lefthand.dmi and b/icons/mob/items_lefthand.dmi differ diff --git a/icons/mob/items_righthand.dmi b/icons/mob/items_righthand.dmi index 6155e0994c..3fbc7d159a 100644 Binary files a/icons/mob/items_righthand.dmi and b/icons/mob/items_righthand.dmi differ diff --git a/icons/mob/mask.dmi b/icons/mob/mask.dmi index 6e1a907c11..70baf0badb 100644 Binary files a/icons/mob/mask.dmi and b/icons/mob/mask.dmi differ diff --git a/icons/mob/monkey.dmi b/icons/mob/monkey.dmi deleted file mode 100644 index b9c1299ec2..0000000000 Binary files a/icons/mob/monkey.dmi and /dev/null differ diff --git a/icons/mob/species/armalis/feet.dmi b/icons/mob/species/armalis/feet.dmi deleted file mode 100644 index cbd83be702..0000000000 Binary files a/icons/mob/species/armalis/feet.dmi and /dev/null differ diff --git a/icons/mob/species/armalis/gloves.dmi b/icons/mob/species/armalis/gloves.dmi deleted file mode 100644 index 7d3eed317a..0000000000 Binary files a/icons/mob/species/armalis/gloves.dmi and /dev/null differ diff --git a/icons/mob/species/armalis/head.dmi b/icons/mob/species/armalis/head.dmi deleted file mode 100644 index ddb8859fd0..0000000000 Binary files a/icons/mob/species/armalis/head.dmi and /dev/null differ diff --git a/icons/mob/species/armalis/held.dmi b/icons/mob/species/armalis/held.dmi deleted file mode 100644 index 517709f33c..0000000000 Binary files a/icons/mob/species/armalis/held.dmi and /dev/null differ diff --git a/icons/mob/species/armalis/mask.dmi b/icons/mob/species/armalis/mask.dmi deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/icons/mob/species/armalis/suit.dmi b/icons/mob/species/armalis/suit.dmi deleted file mode 100644 index 05f9b082cf..0000000000 Binary files a/icons/mob/species/armalis/suit.dmi and /dev/null differ diff --git a/icons/mob/species/skrell/helmet.dmi b/icons/mob/species/skrell/helmet.dmi index 3d24f5f335..2db8b5119a 100644 Binary files a/icons/mob/species/skrell/helmet.dmi and b/icons/mob/species/skrell/helmet.dmi differ diff --git a/icons/mob/species/tajaran/helmet.dmi b/icons/mob/species/tajaran/helmet.dmi index 0851a4576d..95300157f2 100644 Binary files a/icons/mob/species/tajaran/helmet.dmi and b/icons/mob/species/tajaran/helmet.dmi differ diff --git a/icons/mob/species/tajaran/suit.dmi b/icons/mob/species/tajaran/suit.dmi index 5fae4520b6..8cdc5e46ce 100644 Binary files a/icons/mob/species/tajaran/suit.dmi and b/icons/mob/species/tajaran/suit.dmi differ diff --git a/icons/mob/species/unathi/helmet.dmi b/icons/mob/species/unathi/helmet.dmi index 975a1a5786..db43fd2f07 100644 Binary files a/icons/mob/species/unathi/helmet.dmi and b/icons/mob/species/unathi/helmet.dmi differ diff --git a/icons/mob/species/unathi/suit.dmi b/icons/mob/species/unathi/suit.dmi index 1783cf91b4..8dbf403c70 100644 Binary files a/icons/mob/species/unathi/suit.dmi and b/icons/mob/species/unathi/suit.dmi differ diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi index ecbad9bfa3..e8f9800334 100644 Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ diff --git a/icons/mob/surgery.dmi b/icons/mob/surgery.dmi new file mode 100644 index 0000000000..20381e0909 Binary files /dev/null and b/icons/mob/surgery.dmi differ diff --git a/icons/mob/ties.dmi b/icons/mob/ties.dmi index 32792a3211..a4d3c38612 100644 Binary files a/icons/mob/ties.dmi and b/icons/mob/ties.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index ffc7169614..8bcb5920ed 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index 10fae561b7..5a2f06d319 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/biomass.dmi b/icons/obj/biomass.dmi deleted file mode 100644 index ffb133f768..0000000000 Binary files a/icons/obj/biomass.dmi and /dev/null differ diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 5fe976397d..2b0f051bd2 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi index a899995b25..a55c1b1cc2 100644 Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ diff --git a/icons/obj/clothing/species/skrell/hats.dmi b/icons/obj/clothing/species/skrell/hats.dmi index 30c012ddf1..f3916f564b 100644 Binary files a/icons/obj/clothing/species/skrell/hats.dmi and b/icons/obj/clothing/species/skrell/hats.dmi differ diff --git a/icons/obj/clothing/species/tajaran/hats.dmi b/icons/obj/clothing/species/tajaran/hats.dmi index 224fcaee58..cad2ef6242 100644 Binary files a/icons/obj/clothing/species/tajaran/hats.dmi and b/icons/obj/clothing/species/tajaran/hats.dmi differ diff --git a/icons/obj/clothing/species/tajaran/suits.dmi b/icons/obj/clothing/species/tajaran/suits.dmi index 3b0b4dafbd..a41048e94f 100644 Binary files a/icons/obj/clothing/species/tajaran/suits.dmi and b/icons/obj/clothing/species/tajaran/suits.dmi differ diff --git a/icons/obj/clothing/species/unathi/hats.dmi b/icons/obj/clothing/species/unathi/hats.dmi index 987e0accac..4724c19baf 100644 Binary files a/icons/obj/clothing/species/unathi/hats.dmi and b/icons/obj/clothing/species/unathi/hats.dmi differ diff --git a/icons/obj/clothing/species/unathi/suits.dmi b/icons/obj/clothing/species/unathi/suits.dmi index 9e6217ce1b..a84993521e 100644 Binary files a/icons/obj/clothing/species/unathi/suits.dmi and b/icons/obj/clothing/species/unathi/suits.dmi differ diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi index b7b6373ae5..a5ed2192bc 100644 Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ diff --git a/icons/obj/clothing/ties.dmi b/icons/obj/clothing/ties.dmi index da88859fb1..ac6a4e0177 100644 Binary files a/icons/obj/clothing/ties.dmi and b/icons/obj/clothing/ties.dmi differ diff --git a/icons/obj/clothing/ties_overlay.dmi b/icons/obj/clothing/ties_overlay.dmi index 6c6a65afc1..c69dff3940 100644 Binary files a/icons/obj/clothing/ties_overlay.dmi and b/icons/obj/clothing/ties_overlay.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 43f9eb909b..fa842ae507 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/contraband.dmi b/icons/obj/contraband.dmi index 020b44606b..ee5eb6d9a2 100644 Binary files a/icons/obj/contraband.dmi and b/icons/obj/contraband.dmi differ diff --git a/icons/obj/cryogenics.dmi b/icons/obj/cryogenics.dmi index e063421fd5..b731ec3c67 100644 Binary files a/icons/obj/cryogenics.dmi and b/icons/obj/cryogenics.dmi differ diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi index beae558e4c..70cfb01027 100644 Binary files a/icons/obj/custom_items.dmi and b/icons/obj/custom_items.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index afc7c69532..c141d0dad1 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/food.dmi b/icons/obj/food.dmi index 65756ff5a8..6b8c5b0a49 100644 Binary files a/icons/obj/food.dmi and b/icons/obj/food.dmi differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index 1e03bbe0b7..7c823421d3 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ diff --git a/icons/obj/harvest.dmi b/icons/obj/harvest.dmi deleted file mode 100644 index 443b6c5ebf..0000000000 Binary files a/icons/obj/harvest.dmi and /dev/null differ diff --git a/icons/obj/hydroponics.dmi b/icons/obj/hydroponics.dmi deleted file mode 100644 index 3118d5d30d..0000000000 Binary files a/icons/obj/hydroponics.dmi and /dev/null differ diff --git a/icons/obj/hydroponics_growing.dmi b/icons/obj/hydroponics_growing.dmi new file mode 100644 index 0000000000..6de8b809de Binary files /dev/null and b/icons/obj/hydroponics_growing.dmi differ diff --git a/icons/obj/hydroponics_machines.dmi b/icons/obj/hydroponics_machines.dmi new file mode 100644 index 0000000000..3373d03152 Binary files /dev/null and b/icons/obj/hydroponics_machines.dmi differ diff --git a/icons/obj/hydroponics_products.dmi b/icons/obj/hydroponics_products.dmi new file mode 100644 index 0000000000..103f0c9210 Binary files /dev/null and b/icons/obj/hydroponics_products.dmi differ diff --git a/icons/obj/hydroponics_vines.dmi b/icons/obj/hydroponics_vines.dmi new file mode 100644 index 0000000000..2bad94b350 Binary files /dev/null and b/icons/obj/hydroponics_vines.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index afbbefd304..21a0022aab 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/magic.dmi b/icons/obj/magic.dmi index 141b2df3f8..f92243d6bc 100644 Binary files a/icons/obj/magic.dmi and b/icons/obj/magic.dmi differ diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi index 667c952789..23beb5f4fa 100644 Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ diff --git a/icons/obj/pipe-item.dmi b/icons/obj/pipe-item.dmi index 2fa39fec04..1ad833316d 100644 Binary files a/icons/obj/pipe-item.dmi and b/icons/obj/pipe-item.dmi differ diff --git a/icons/obj/pipes.dmi b/icons/obj/pipes.dmi index eb005aaf31..ec6d28a613 100644 Binary files a/icons/obj/pipes.dmi and b/icons/obj/pipes.dmi differ diff --git a/icons/obj/power.dmi b/icons/obj/power.dmi index 5da859b982..099070a4fc 100644 Binary files a/icons/obj/power.dmi and b/icons/obj/power.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index 03915794e4..7f3468a363 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/icons/obj/reagentfillings.dmi b/icons/obj/reagentfillings.dmi index 3e64c9e45a..4799249dfc 100644 Binary files a/icons/obj/reagentfillings.dmi and b/icons/obj/reagentfillings.dmi differ diff --git a/icons/obj/seeds.dmi b/icons/obj/seeds.dmi index e2035f59db..530683ef9b 100644 Binary files a/icons/obj/seeds.dmi and b/icons/obj/seeds.dmi differ diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi index 989c1001b3..377d12b4ff 100644 Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi index 2adc34b05b..a9a46f6046 100644 Binary files a/icons/obj/syringe.dmi and b/icons/obj/syringe.dmi differ diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi index a921d45d48..46c280252e 100644 Binary files a/icons/obj/toy.dmi and b/icons/obj/toy.dmi differ diff --git a/icons/obj/trash.dmi b/icons/obj/trash.dmi index c031a9576c..18b34ee20c 100644 Binary files a/icons/obj/trash.dmi and b/icons/obj/trash.dmi differ diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi index 92b3aed2b9..77e1f1d7de 100644 Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ diff --git a/icons/obj/wizard.dmi b/icons/obj/wizard.dmi index b659bdc23e..1d6bad4c50 100644 Binary files a/icons/obj/wizard.dmi and b/icons/obj/wizard.dmi differ diff --git a/icons/obj/xenoarchaeology.dmi b/icons/obj/xenoarchaeology.dmi index b40ae3db6e..ab6cd5a97d 100644 Binary files a/icons/obj/xenoarchaeology.dmi and b/icons/obj/xenoarchaeology.dmi differ diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi index 5bb4e85e34..ccc2fd1f5a 100755 Binary files a/icons/turf/areas.dmi and b/icons/turf/areas.dmi differ diff --git a/interface/interface.dm b/interface/interface.dm index e788afb7c1..31312c277b 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -35,6 +35,14 @@ set name = "hotkeys-help" set category = "OOC" + var/admin = {" +Admin: +\tF5 = Aghost (admin-ghost) +\tF6 = player-panel-new +\tF7 = admin-pm +\tF8 = Invisimin +"} + var/hotkey_mode = {" Hotkey-Mode: (hotkey-mode must be on) \tTAB = toggle hotkey-mode @@ -55,6 +63,8 @@ Hotkey-Mode: (hotkey-mode must be on) \t2 = disarm-intent \t3 = grab-intent \t4 = harm-intent +\tCtrl = drag +\tShift = examine "} var/other = {" @@ -86,15 +96,58 @@ Any-Mode: (hotkey doesn't need to be on) \tEND = throw "} - var/admin = {" -Admin: -\tF5 = Aghost (admin-ghost) -\tF6 = player-panel-new -\tF7 = admin-pm -\tF8 = Invisimin + var/robot_hotkey_mode = {" +Hotkey-Mode: (hotkey-mode must be on) +\tTAB = toggle hotkey-mode +\ta = left +\ts = down +\td = right +\tw = up +\tq = unequip active module +\tt = say +\tx = cycle active modules +\tz = activate held object (or y) +\tf = cycle-intents-left +\tg = cycle-intents-right +\t1 = activate module 1 +\t2 = activate module 2 +\t3 = activate module 3 +\t4 = toggle intents +\t5 = emote +\tCtrl = drag +\tShift = examine "} - src << hotkey_mode - src << other + var/robot_other = {" +Any-Mode: (hotkey doesn't need to be on) +\tCtrl+a = left +\tCtrl+s = down +\tCtrl+d = right +\tCtrl+w = up +\tCtrl+q = unequip active module +\tCtrl+x = cycle active modules +\tCtrl+z = activate held object (or Ctrl+y) +\tCtrl+f = cycle-intents-left +\tCtrl+g = cycle-intents-right +\tCtrl+1 = activate module 1 +\tCtrl+2 = activate module 2 +\tCtrl+3 = activate module 3 +\tCtrl+4 = toggle intents +\tF1 = adminhelp +\tF2 = ooc +\tF3 = say +\tF4 = emote +\tDEL = pull +\tINS = toggle intents +\tPGUP = cycle active modules +\tPGDN = activate held object +"} + + if(isrobot(src.mob)) + src << robot_hotkey_mode + src << robot_other + else + src << hotkey_mode + src << other if(holder) src << admin diff --git a/interface/skin.dmf b/interface/skin.dmf index 330d547944..68acfba607 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -1,3 +1,269 @@ +macro "borghotkeymode" + elem + name = "TAB" + command = ".winset \"mainwindow.macro=borgmacro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5\"" + is-disabled = false + elem + name = "CENTER+REP" + command = ".center" + is-disabled = false + elem + name = "NORTHEAST" + command = ".northeast" + is-disabled = false + elem + name = "SOUTHEAST" + command = ".southeast" + is-disabled = false + elem + name = "SOUTHWEST" + command = ".southwest" + is-disabled = false + elem + name = "NORTHWEST" + command = ".northwest" + is-disabled = false + elem + name = "ALT+WEST" + command = "westfaceperm" + is-disabled = false + elem + name = "CTRL+WEST" + command = "westface" + is-disabled = false + elem + name = "WEST+REP" + command = ".west" + is-disabled = false + elem + name = "ALT+NORTH" + command = "northfaceperm" + is-disabled = false + elem + name = "CTRL+NORTH" + command = "northface" + is-disabled = false + elem + name = "NORTH+REP" + command = ".north" + is-disabled = false + elem + name = "ALT+EAST" + command = "eastfaceperm" + is-disabled = false + elem + name = "CTRL+EAST" + command = "eastface" + is-disabled = false + elem + name = "EAST+REP" + command = ".east" + is-disabled = false + elem + name = "ALT+SOUTH" + command = "southfaceperm" + is-disabled = false + elem + name = "CTRL+SOUTH" + command = "southface" + is-disabled = false + elem + name = "SOUTH+REP" + command = ".south" + is-disabled = false + elem + name = "1" + command = "toggle-module 1" + is-disabled = false + elem + name = "CTRL+1" + command = "toggle-module 1" + is-disabled = false + elem + name = "2" + command = "toggle-module 2" + is-disabled = false + elem + name = "CTRL+2" + command = "toggle-module 2" + is-disabled = false + elem + name = "3" + command = "toggle-module 3" + is-disabled = false + elem + name = "CTRL+3" + command = "toggle-module 3" + is-disabled = false + elem + name = "4" + command = "a-intent left" + is-disabled = false + elem + name = "CTRL+4" + command = "a-intent left" + is-disabled = false + elem + name = "INSERT" + command = "a-intent right" + is-disabled = false + elem + name = "DELETE" + command = "delete-key-pressed" + is-disabled = false + elem + name = "5" + command = ".me" + is-disabled = false + elem + name = "A+REP" + command = ".west" + is-disabled = false + elem + name = "CTRL+A+REP" + command = ".west" + is-disabled = false + elem + name = "D+REP" + command = ".east" + is-disabled = false + elem + name = "CTRL+D+REP" + command = ".east" + is-disabled = false + elem + name = "F" + command = "a-intent left" + is-disabled = false + elem + name = "CTRL+F" + command = "a-intent left" + is-disabled = false + elem + name = "G" + command = "a-intent right" + is-disabled = false + elem + name = "CTRL+G" + command = "a-intent right" + is-disabled = false + elem + name = "J" + command = "toggle-gun-mode" + is-disabled = false + elem + name = "CTRL+J" + command = "toggle-gun-mode" + is-disabled = false + elem + name = "Q" + command = "unequip-module" + is-disabled = false + elem + name = "CTRL+Q" + command = "unequip-module" + is-disabled = false + elem + name = "R" + command = ".southwest" + is-disabled = false + elem + name = "CTRL+R" + command = ".southwest" + is-disabled = false + elem "s_key" + name = "S+REP" + command = ".south" + is-disabled = false + elem + name = "CTRL+S+REP" + command = ".south" + is-disabled = false + elem + name = "T" + command = ".say" + is-disabled = false + elem "w_key" + name = "W+REP" + command = ".north" + is-disabled = false + elem + name = "CTRL+W+REP" + command = ".north" + is-disabled = false + elem + name = "X" + command = ".northeast" + is-disabled = false + elem + name = "CTRL+X" + command = ".northeast" + is-disabled = false + elem + name = "Y" + command = "Activate-Held-Object" + is-disabled = false + elem + name = "CTRL+Y" + command = "Activate-Held-Object" + is-disabled = false + elem + name = "Z" + command = "Activate-Held-Object" + is-disabled = false + elem + name = "CTRL+Z" + command = "Activate-Held-Object" + is-disabled = false + elem + name = "F1" + command = "adminhelp" + is-disabled = false + elem + name = "CTRL+SHIFT+F1+REP" + command = ".options" + is-disabled = false + elem + name = "F2" + command = "ooc" + is-disabled = false + elem + name = "F2+REP" + command = ".screenshot auto" + is-disabled = false + elem + name = "SHIFT+F2+REP" + command = ".screenshot" + is-disabled = false + elem + name = "F3" + command = ".say" + is-disabled = false + elem + name = "F4" + command = ".me" + is-disabled = false + elem + name = "F5" + command = "asay" + is-disabled = false + elem + name = "F6" + command = "Player-Panel-New" + is-disabled = false + elem + name = "F7" + command = "Admin-PM" + is-disabled = false + elem + name = "F8" + command = "Invisimin" + is-disabled = false + elem + name = "F12" + command = "F12" + is-disabled = false + macro "macro" elem name = "TAB" @@ -23,6 +289,10 @@ macro "macro" name = "NORTHWEST" command = ".northwest" is-disabled = false + elem + name = "ALT+WEST" + command = "westfaceperm" + is-disabled = false elem name = "CTRL+WEST" command = "westface" @@ -31,6 +301,10 @@ macro "macro" name = "WEST+REP" command = ".west" is-disabled = false + elem + name = "ALT+NORTH" + command = "northfaceperm" + is-disabled = false elem name = "CTRL+NORTH" command = "northface" @@ -39,6 +313,10 @@ macro "macro" name = "NORTH+REP" command = ".north" is-disabled = false + elem + name = "ALT+EAST" + command = "eastfaceperm" + is-disabled = false elem name = "CTRL+EAST" command = "eastface" @@ -47,6 +325,10 @@ macro "macro" name = "EAST+REP" command = ".east" is-disabled = false + elem + name = "ALT+SOUTH" + command = "southfaceperm" + is-disabled = false elem name = "CTRL+SOUTH" command = "southface" @@ -201,6 +483,10 @@ macro "hotkeymode" name = "NORTHWEST" command = ".northwest" is-disabled = false + elem + name = "ALT+WEST" + command = "westfaceperm" + is-disabled = false elem name = "CTRL+WEST" command = "westface" @@ -209,6 +495,10 @@ macro "hotkeymode" name = "WEST+REP" command = ".west" is-disabled = false + elem + name = "ALT+NORTH" + command = "northfaceperm" + is-disabled = false elem name = "CTRL+NORTH" command = "northface" @@ -217,6 +507,10 @@ macro "hotkeymode" name = "NORTH+REP" command = ".north" is-disabled = false + elem + name = "ALT+EAST" + command = "eastfaceperm" + is-disabled = false elem name = "CTRL+EAST" command = "eastface" @@ -225,6 +519,10 @@ macro "hotkeymode" name = "EAST+REP" command = ".east" is-disabled = false + elem + name = "ALT+SOUTH" + command = "southfaceperm" + is-disabled = false elem name = "CTRL+SOUTH" command = "southface" @@ -325,6 +623,14 @@ macro "hotkeymode" name = "CTRL+H" command = "holster" is-disabled = false + elem + name = "J" + command = "toggle-gun-mode" + is-disabled = false + elem + name = "CTRL+J" + command = "toggle-gun-mode" + is-disabled = false elem name = "Q" command = ".northwest" @@ -434,6 +740,196 @@ macro "hotkeymode" command = "F12" is-disabled = false +macro "borgmacro" + elem + name = "TAB" + command = ".winset \"mainwindow.macro=borghotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0\"" + is-disabled = false + elem + name = "CENTER+REP" + command = ".center" + is-disabled = false + elem + name = "NORTHEAST" + command = ".northeast" + is-disabled = false + elem + name = "SOUTHEAST" + command = ".southeast" + is-disabled = false + elem + name = "SOUTHWEST" + command = ".southwest" + is-disabled = false + elem + name = "NORTHWEST" + command = ".northwest" + is-disabled = false + elem + name = "ALT+WEST" + command = "westfaceperm" + is-disabled = false + elem + name = "CTRL+WEST" + command = "westface" + is-disabled = false + elem + name = "WEST+REP" + command = ".west" + is-disabled = false + elem + name = "ALT+NORTH" + command = "northfaceperm" + is-disabled = false + elem + name = "CTRL+NORTH" + command = "northface" + is-disabled = false + elem + name = "NORTH+REP" + command = ".north" + is-disabled = false + elem + name = "ALT+EAST" + command = "eastfaceperm" + is-disabled = false + elem + name = "CTRL+EAST" + command = "eastface" + is-disabled = false + elem + name = "EAST+REP" + command = ".east" + is-disabled = false + elem + name = "ALT+SOUTH" + command = "southfaceperm" + is-disabled = false + elem + name = "CTRL+SOUTH" + command = "southface" + is-disabled = false + elem + name = "SOUTH+REP" + command = ".south" + is-disabled = false + elem + name = "INSERT" + command = "a-intent right" + is-disabled = false + elem + name = "DELETE" + command = "delete-key-pressed" + is-disabled = false + elem + name = "CTRL+1" + command = "toggle-module 1" + is-disabled = false + elem + name = "CTRL+2" + command = "toggle-module 2" + is-disabled = false + elem + name = "CTRL+3" + command = "toggle-module 3" + is-disabled = false + elem + name = "CTRL+4" + command = "a-intent left" + is-disabled = false + elem + name = "CTRL+A+REP" + command = ".west" + is-disabled = false + elem + name = "CTRL+D+REP" + command = ".east" + is-disabled = false + elem + name = "CTRL+F" + command = "a-intent left" + is-disabled = false + elem + name = "CTRL+G" + command = "a-intent right" + is-disabled = false + elem + name = "CTRL+Q" + command = ".northwest" + is-disabled = false + elem + name = "CTRL+R" + command = ".southwest" + is-disabled = false + elem + name = "CTRL+S+REP" + command = ".south" + is-disabled = false + elem + name = "CTRL+W+REP" + command = ".north" + is-disabled = false + elem + name = "CTRL+X" + command = ".northeast" + is-disabled = false + elem + name = "CTRL+Y" + command = "Activate-Held-Object" + is-disabled = false + elem + name = "CTRL+Z" + command = "Activate-Held-Object" + is-disabled = false + elem + name = "F1" + command = "adminhelp" + is-disabled = false + elem + name = "CTRL+SHIFT+F1+REP" + command = ".options" + is-disabled = false + elem + name = "F2" + command = "ooc" + is-disabled = false + elem + name = "F2+REP" + command = ".screenshot auto" + is-disabled = false + elem + name = "SHIFT+F2+REP" + command = ".screenshot" + is-disabled = false + elem + name = "F3" + command = ".say" + is-disabled = false + elem + name = "F4" + command = ".me" + is-disabled = false + elem + name = "F5" + command = "asay" + is-disabled = false + elem + name = "F6" + command = "Player-Panel-New" + is-disabled = false + elem + name = "F7" + command = "Admin-PM" + is-disabled = false + elem + name = "F8" + command = "Invisimin" + is-disabled = false + elem + name = "F12" + command = "F12" + is-disabled = false + menu "menu" elem @@ -1804,7 +2300,7 @@ window "infowindow" elem "info" type = INFO pos = 0,0 - size = 638x475 + size = 638x477 anchor1 = 0,0 anchor2 = 100,100 font-family = "" @@ -1827,7 +2323,7 @@ window "infowindow" tab-font-family = "" tab-font-size = 0 tab-font-style = "" - allow-html = false + allow-html = true multi-line = true on-show = ".winset\"rpane.infob.is-visible=true;rpane.browseb.is-visible=true?rpane.infob.pos=130,0:rpane.infob.pos=65,0 rpane.textb.is-visible=true rpane.infob.is-checked=true rpane.rpanewindow.pos=0,30 rpane.rpanewindow.size=0x0 rpane.rpanewindow.left=infowindow\"" on-hide = ".winset\"rpane.infob.is-visible=false;rpane.browseb.is-visible=true?rpane.browseb.is-checked=true rpane.rpanewindow.left=browserwindow:rpane.textb.is-visible=true rpane.rpanewindow.pos=0,30 rpane.rpanewindow.size=0x0 rpane.rpanewindow.left=\"" diff --git a/maps/PowerTesting.dmm b/maps/PowerTesting.dmm index e9a20ece67..9c7088d6ab 100644 --- a/maps/PowerTesting.dmm +++ b/maps/PowerTesting.dmm @@ -27,11 +27,11 @@ "aA" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/solar/port) "aB" = (/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/solar/port) "aC" = (/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/solar/port) -"aD" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; layer = 3.3; master_tag = "robotics_solar_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "0"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/solar/port) -"aE" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "robotics_solar_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/portsolar) -"aF" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "robotics_solar_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "robotics_solar_pump"; tag_exterior_door = "robotics_solar_outer"; frequency = 1379; id_tag = "robotics_solar_airlock"; tag_interior_door = "robotics_solar_inner"; layer = 3.3; pixel_x = 0; pixel_y = -25; req_access_txt = "13"; tag_chamber_sensor = "robotics_solar_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "robotics_solar_sensor"; layer = 3.3; pixel_x = 12; pixel_y = -25},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/decal/warning_stripes,/turf/simulated/floor/plating,/area/maintenance/portsolar) -"aG" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "robotics_solar_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/portsolar) -"aH" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; layer = 3.3; master_tag = "robotics_solar_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/portsolar) +"aD" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; layer = 3.3; master_tag = "robotics_solar_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/solar/port) +"aE" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "robotics_solar_outer"; locked = 1; name = "Engineering External Access"; req_access = list(10, 13)},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"aF" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "robotics_solar_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "robotics_solar_pump"; tag_exterior_door = "robotics_solar_outer"; frequency = 1379; id_tag = "robotics_solar_airlock"; tag_interior_door = "robotics_solar_inner"; layer = 3.3; pixel_x = 0; pixel_y = -25; req_access = list(13); tag_chamber_sensor = "robotics_solar_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "robotics_solar_sensor"; layer = 3.3; pixel_x = 12; pixel_y = -25},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/decal/warning_stripes,/turf/simulated/floor/plating,/area/maintenance/portsolar) +"aG" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "robotics_solar_inner"; locked = 1; name = "Engineering External Access"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"aH" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; layer = 3.3; master_tag = "robotics_solar_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/portsolar) "aI" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/portsolar) "aJ" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/maintenance/portsolar) "aK" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/portsolar) diff --git a/maps/exodus-1.dmm b/maps/exodus-1.dmm index 2e16bd9b35..1f0a960d34 100644 --- a/maps/exodus-1.dmm +++ b/maps/exodus-1.dmm @@ -18,7 +18,7 @@ "aar" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/airless{icon_state = "circuit"},/area/space) "aas" = (/obj/item/clothing/suit/ianshirt,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/space) "aat" = (/turf/simulated/wall/r_wall,/area/space) -"aau" = (/turf/space,/area/vox_station/northwest_solars) +"aau" = (/turf/space,/area/skipjack_station/northwest_solars) "aav" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/solar{id = "auxsolarnorth"; name = "Fore Solar Array"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/fore) "aaw" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating/airless,/area/solar/fore) "aax" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/space) @@ -39,7 +39,7 @@ "aaM" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/security/range) "aaN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/range) "aaO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor,/area/security/range) -"aaP" = (/obj/machinery/door/window/northleft{dir = 4; name = "Range Access"; req_access_txt = "63"},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/security/range) +"aaP" = (/obj/machinery/door/window/northleft{dir = 4; name = "Range Access"; req_access = list(63)},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/security/range) "aaQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/security/range) "aaR" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/range) "aaS" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/table/reinforced,/obj/item/clothing/ears/earmuffs{pixel_x = -3; pixel_y = -2},/obj/item/clothing/ears/earmuffs,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor,/area/security/range) @@ -56,13 +56,13 @@ "abd" = (/turf/simulated/wall/r_wall,/area/maintenance/foresolar) "abe" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/security_port) "abf" = (/turf/simulated/wall,/area/maintenance/security_port) -"abg" = (/obj/structure/closet/wardrobe/tactical,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) -"abh" = (/obj/machinery/camera{c_tag = "Armoury - Tactical Equipment "; dir = 2; network = list("SS13")},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/table/rack,/obj/machinery/door/window/brigdoor{dir = 2; name = "Weapons locker"; req_access = null; req_access_txt = "58"},/obj/item/ammo_magazine/c45m{icon_state = "45-7"},/obj/item/ammo_magazine/c45m{icon_state = "45-7"},/obj/item/weapon/storage/box/shotgunammo,/obj/item/weapon/storage/box/shotgunammo,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) +"abg" = (/obj/effect/landmark/start/ninja,/turf/space,/area/space) +"abh" = (/turf/simulated/wall/r_wall,/area/security/tactical) "abi" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/security/range) "abj" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/energy/laser/practice,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor,/area/security/range) -"abk" = (/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor{dir = 1; icon_state = "loadingarea"},/area/security/range) +"abk" = (/turf/space,/area/skipjack_station/northeast_solars) "abl" = (/obj/structure/table/reinforced,/obj/machinery/recharger,/turf/simulated/floor,/area/security/range) -"abm" = (/obj/machinery/camera{c_tag = "Firing Range"; dir = 8; network = list("SS13")},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/range) +"abm" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Riot Control"; req_access = list(2)},/turf/simulated/floor,/area/security/brig) "abn" = (/obj/structure/closet/crate,/obj/item/clothing/glasses/meson/prescription,/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "abo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/security_starboard) "abp" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/solar/auxstarboard) @@ -71,14 +71,14 @@ "abs" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/maintenance/foresolar) "abt" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = -32; pixel_y = 0},/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/maintenance/foresolar) "abu" = (/obj/machinery/power/terminal{dir = 4},/obj/machinery/light/small{dir = 1},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/maintenance/foresolar) -"abv" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Fore Solar"},/turf/simulated/floor/plating,/area/maintenance/foresolar) +"abv" = (/obj/structure/closet/wardrobe/tactical,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/tactical) "abw" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/foresolar) "abx" = (/obj/effect/decal/cleanable/ash,/obj/structure/closet/emcloset,/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/maintenance/security_port) -"aby" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) -"abz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) -"abA" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) -"abB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) -"abC" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) +"aby" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/airlock/atmos{name = "Atmospherics Maintenance"; req_access = list(12,24)},/turf/simulated/floor/plating,/area/security/brig) +"abz" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Solar - Fore"},/turf/simulated/floor/plating,/area/maintenance/foresolar) +"abA" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/security/tactical) +"abB" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{icon_state = "dark"},/area/security/tactical) +"abC" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/security/tactical) "abD" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/security/range) "abE" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/security/range) "abF" = (/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/security/range) @@ -91,24 +91,24 @@ "abM" = (/obj/machinery/power/tracker,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating/airless,/area/solar/auxport) "abN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating,/area/maintenance/security_starboard) "abO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"abP" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/airlock/atmos{name = "Atmospherics Maintenance"; req_access_txt = "12;24"},/turf/simulated/floor/plating,/area/security/brig) +"abP" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/machinery/door_control{id = "prisonentry"; name = "Entry Doors"; normaldoorcontrol = 1; pixel_x = -6; pixel_y = 24; req_access = list(2)},/obj/machinery/door_control{id = "prisonexit"; name = "Exit Doors"; normaldoorcontrol = 1; pixel_x = 6; pixel_y = 24; req_access = list(2)},/obj/machinery/button/flasher{id = "permentryflash"; name = "entry flash"; pixel_x = -26; pixel_y = 6; req_access = list(2)},/turf/simulated/floor,/area/security/brig) "abQ" = (/obj/machinery/power/tracker,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating/airless,/area/solar/auxstarboard) "abR" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "lawyer_blast"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/security/brig) "abS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "lawyer_blast"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/security/brig) "abT" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "lawyer_blast"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/security/brig) "abU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green,/obj/machinery/door/blast/regular{density = 0; dir = 4; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/prison) "abV" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/blast/regular{density = 0; dir = 4; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/security/prison) -"abW" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "brig_solar_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/foresolar) -"abX" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "brig_solar_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "brig_solar_airlock"; layer = 3.3; pixel_x = 0; pixel_y = -25; req_access_txt = "13"; tag_airpump = "brig_solar_pump"; tag_chamber_sensor = "brig_solar_sensor"; tag_exterior_door = "brig_solar_outer"; tag_interior_door = "brig_solar_inner"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "brig_solar_sensor"; layer = 3.3; pixel_x = 12; pixel_y = -25},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/decal/warning_stripes,/turf/simulated/floor/plating,/area/maintenance/foresolar) -"abY" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "brig_solar_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/foresolar) -"abZ" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; layer = 3.3; master_tag = "brig_solar_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/foresolar) +"abW" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 8; icon_state = "rightsecure"; req_access = list(2)},/obj/structure/table/reinforced,/turf/simulated/floor,/area/security/brig) +"abX" = (/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor/plating,/area/maintenance/security_starboard) +"abY" = (/obj/machinery/door/airlock/engineering{name = "Security Substation"; req_one_access = list(11,24)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/substation/security) +"abZ" = (/obj/machinery/door/airlock/glass_security{id_tag = "BrigFoyer"; layer = 2.8; name = "Security Wing"; req_access = list(63)},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/brig) "aca" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/foresolar) "acb" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/foresolar) -"acc" = (/obj/machinery/door/airlock/engineering{name = "Fore Solar Access"; req_access_txt = "10"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/foresolar) +"acc" = (/obj/machinery/door/airlock/glass_security{id_tag = "BrigFoyer"; layer = 2.8; name = "Security Wing"; req_access = list(63)},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/brig) "acd" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/security_port) -"ace" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/warden) -"acf" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/highsecurity{name = "Tactical Equipment"; req_access_txt = "3"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/security/warden) -"acg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/warden) +"ace" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "dark"},/area/security/tactical) +"acf" = (/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor{icon_state = "dark"},/area/security/tactical) +"acg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/tactical) "ach" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/main) "aci" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/main) "acj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/security/main) @@ -117,27 +117,27 @@ "acm" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/main) "acn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/security/main) "aco" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/main) -"acp" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Firing Range"; req_access_txt = "1"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/main) +"acp" = (/obj/machinery/door/window/brigdoor{dir = 1; req_access = list(63)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/brig) "acq" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/main) "acr" = (/turf/simulated/wall,/area/security/main) "acs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "act" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"acu" = (/obj/machinery/door/window/brigdoor{dir = 1; id = "Cell 3"; name = "Cell 3"; req_access_txt = "2"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) +"acu" = (/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 1; icon_state = "rightsecure"; req_access = list(63)},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/brig) "acv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/maintenance/foresolar) "acw" = (/obj/machinery/power/solar_control{id = "auxsolarnorth"; name = "Fore Solar Control"; track = 0},/obj/structure/cable/yellow,/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/maintenance/foresolar) "acx" = (/turf/simulated/floor/plating,/area/maintenance/foresolar) "acy" = (/obj/machinery/camera{c_tag = "Fore Solar Control"; dir = 1},/obj/structure/cable,/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor/plating,/area/maintenance/foresolar) "acz" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera{c_tag = "Fore Solar Access"; dir = 8},/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/maintenance/security_port) -"acA" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/brigdoor{dir = 2; name = "Weapons locker"; req_access_txt = "3"},/obj/item/weapon/gun/energy/laser,/obj/item/weapon/gun/energy/laser,/obj/item/weapon/gun/energy/laser,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) -"acB" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/brigdoor{dir = 2; name = "Weapons locker"; req_access_txt = "3"},/obj/structure/window/reinforced{dir = 8},/obj/item/weapon/gun/projectile/shotgun/pump/combat{ammo_type = "/obj/item/ammo_casing/shotgun/beanbag"; pixel_x = 2; pixel_y = -2},/obj/item/weapon/gun/projectile/shotgun/pump/combat{ammo_type = "/obj/item/ammo_casing/shotgun/beanbag"; pixel_x = 2; pixel_y = -2},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) -"acC" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/brigdoor{dir = 2; name = "Weapons locker"; req_access_txt = "3"},/obj/structure/window/reinforced{dir = 4},/obj/machinery/light{dir = 1},/obj/item/weapon/gun/energy/ionrifle,/obj/item/weapon/gun/energy/ionrifle,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) -"acD" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/brigdoor{dir = 2; name = "Weapons locker"; req_access_txt = "3"},/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) +"acA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/tactical) +"acB" = (/obj/machinery/door/airlock/glass_security{id_tag = "prisonexit"; name = "Brig Exit"; req_access = list(2)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison) +"acC" = (/obj/machinery/door/window/brigdoor{dir = 1; id = "Cell 3"; name = "Cell 3"; req_access = list(2)},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) +"acD" = (/obj/machinery/door_control{id = "Cell 3"; name = "Cell 3 Door"; pixel_x = -1; pixel_y = -28; req_access = list(2)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/security/brig) "acE" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "acF" = (/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "acG" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/screwdriver{pixel_y = 15},/obj/machinery/light{dir = 8},/turf/simulated/floor,/area/security/main) "acH" = (/obj/structure/table,/obj/machinery/recharger,/turf/simulated/floor,/area/security/main) "acI" = (/obj/structure/disposalpipe/segment,/obj/structure/table,/obj/machinery/recharger,/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/security/main) -"acJ" = (/obj/structure/stool/bed/roller,/obj/item/device/radio/intercom{pixel_y = 25},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/security/main) +"acJ" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{id_tag = "detdoor"; name = "Detective"; req_access = list(4)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/detectives_office) "acK" = (/obj/structure/table,/obj/item/weapon/reagent_containers/syringe/inaprovaline,/obj/item/weapon/reagent_containers/syringe/inaprovaline{pixel_x = -2; pixel_y = 5},/obj/item/weapon/reagent_containers/syringe/inaprovaline{pixel_y = 10},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/security/main) "acL" = (/obj/structure/table,/obj/item/bodybag/cryobag{pixel_x = 6},/obj/item/weapon/storage/firstaid/regular{pixel_x = 5; pixel_y = 5},/turf/simulated/floor{dir = 5; icon_state = "whitered"},/area/security/main) "acM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/security/main) @@ -150,7 +150,7 @@ "acT" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green,/obj/machinery/door/blast/regular{density = 0; dir = 1; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/brig) "acU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating/airless,/area/maintenance/foresolar) "acV" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/security_port) -"acW" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/brigdoor{dir = 4; name = "Weapons locker"; req_access_txt = "3"},/obj/structure/table/rack,/obj/item/clothing/suit/armor/riot,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/shield/riot,/obj/item/clothing/head/helmet/riot,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) +"acW" = (/obj/machinery/door/airlock/maintenance{name = "Firefighting equipment"; req_access = list(12)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/security_starboard) "acX" = (/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "acY" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "acZ" = (/obj/structure/table,/obj/machinery/recharger,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/main) @@ -159,7 +159,7 @@ "adc" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/main) "add" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/main) "ade" = (/obj/structure/table,/obj/item/device/healthanalyzer,/obj/item/stack/medical/bruise_pack{pixel_x = -4; pixel_y = 3},/obj/item/stack/medical/bruise_pack{pixel_x = 10},/obj/item/stack/medical/ointment{pixel_y = 10},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/security/main) -"adf" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main) +"adf" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/maintenance{name = "Security Maintenance"; req_access = list(1)},/turf/simulated/floor/plating,/area/security/brig) "adg" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/main) "adh" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/vending/snack,/turf/simulated/floor,/area/security/main) "adi" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/item/weapon/cigbutt,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/security_starboard) @@ -167,11 +167,11 @@ "adk" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "adl" = (/turf/simulated/floor/plating,/area/maintenance/security_starboard) "adm" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'VACUUM'"; icon_state = "space"; layer = 4; name = "VACUUM"; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"adn" = (/obj/machinery/light{dir = 8},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/brigdoor{dir = 4; name = "Weapons locker"; req_access_txt = "3"},/obj/structure/table/rack,/obj/item/clothing/suit/armor/riot,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/shield/riot,/obj/item/clothing/head/helmet/riot,/obj/machinery/camera{c_tag = "Armoury - Secure"; dir = 4; network = list("SS13")},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) +"adn" = (/obj/structure/bed/roller,/obj/item/device/radio/intercom{pixel_y = 25},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/security/main) "ado" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "adp" = (/obj/structure/table,/obj/machinery/recharger,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) -"adq" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/handcuffs{pixel_x = 4; pixel_y = 3},/obj/item/weapon/storage/box/flashbangs,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) -"adr" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/beanbags{pixel_x = 4; pixel_y = 3},/obj/item/weapon/storage/box/beanbags,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) +"adq" = (/obj/structure/bed/chair/office/dark{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main) +"adr" = (/obj/machinery/door/airlock/maintenance{name = "Firefighting equipment"; req_access = list(12)},/turf/simulated/floor/plating,/area/maintenance/security_port) "ads" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/chemimp{pixel_x = 4; pixel_y = 3},/obj/item/weapon/storage/box/trackimp,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) "adt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "adu" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) @@ -179,59 +179,59 @@ "adw" = (/obj/machinery/vending/cigarette,/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) "adx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/security/main) "ady" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main) -"adz" = (/obj/structure/stool/bed/chair/office/dark,/obj/effect/landmark/start{name = "Security Officer"},/turf/simulated/floor,/area/security/main) +"adz" = (/obj/structure/table/rack,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/item/weapon/storage/box/emps{pixel_x = 3; pixel_y = 2},/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/flashbangs{pixel_x = -2; pixel_y = -2},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) "adA" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/noticeboard{pixel_x = 32; pixel_y = 0},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) "adB" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"adC" = (/obj/machinery/door/airlock/external{icon_state = "door_locked"; locked = 1; name = "External Construction Airlock"; req_access_txt = "32"},/obj/item/tape/engineering{icon_state = "engineering_door"; layer = 4},/turf/simulated/floor/plating,/area/maintenance/security_starboard) +"adC" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Interrogation"; req_access = list(63)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) "adD" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/security_port) "adE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/security_port) -"adF" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/window/brigdoor{dir = 4; name = "Weapons locker"; req_access_txt = "3"},/obj/structure/table/rack,/obj/item/clothing/suit/armor/riot,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/shield/riot,/obj/item/clothing/head/helmet/riot,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) -"adG" = (/obj/machinery/door_control{id = "Armoury"; name = "Armoury Access"; pixel_x = -1; pixel_y = -28; req_access_txt = "3"; req_one_access = null; req_one_access_txt = "0"},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) +"adF" = (/obj/structure/table/rack,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/reagent_containers/spray/pepper,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) +"adG" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Interrogation Observation"; req_access = list(63)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) "adH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/main) "adI" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/main) "adJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) -"adK" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Briefing Room"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/main) +"adK" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Security Processing"; req_access = list(1)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/brig) "adL" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main) -"adM" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor,/area/security/main) +"adM" = (/obj/structure/bed/chair/office/dark,/obj/effect/landmark/start{name = "Security Officer"},/turf/simulated/floor,/area/security/main) "adN" = (/obj/structure/table,/obj/item/weapon/folder/red,/turf/simulated/floor,/area/security/main) -"adO" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/main) +"adO" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Evidence Storage"; req_access = list(1)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) "adP" = (/obj/machinery/requests_console{department = "Security"; departmentType = 5; pixel_x = 30; pixel_y = 0},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) "adQ" = (/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "adR" = (/obj/structure/closet/toolcloset,/obj/item/clothing/head/hardhat/dblue,/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/security_starboard) "adS" = (/obj/machinery/light/small,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "adT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/security_port) -"adU" = (/obj/structure/table/rack,/obj/machinery/door/window/brigdoor{dir = 1; name = "Weapons locker"; req_access_txt = "3"},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/item/clothing/suit/armor/bulletproof{pixel_x = 2; pixel_y = 2},/obj/item/clothing/suit/armor/bulletproof{pixel_x = -2; pixel_y = -2},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) -"adV" = (/obj/structure/table/rack,/obj/machinery/door/window/brigdoor{dir = 1; name = "Weapons locker"; req_access_txt = "3"},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/item/clothing/suit/armor/laserproof{pixel_x = 2; pixel_y = 2},/obj/item/clothing/suit/armor/laserproof{pixel_x = -2; pixel_y = -2},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) +"adU" = (/obj/structure/bed/chair/office/dark{dir = 4},/turf/simulated/floor,/area/security/main) +"adV" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/main) "adW" = (/obj/machinery/flasher/portable,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) "adX" = (/obj/machinery/light,/obj/machinery/flasher/portable,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) -"adY" = (/obj/machinery/door_control{id = "Armoury"; name = "Emergency Access"; pixel_x = -28; pixel_y = 4; req_access_txt = "3"; req_one_access = null; req_one_access_txt = "0"},/turf/simulated/floor,/area/security/main) +"adY" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Warden's Office"; req_access = list(3)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "adZ" = (/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) "aea" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/security/main) "aeb" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/security/main) -"aec" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/security/main) +"aec" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Security Processing"; req_access = list(1)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/brig) "aed" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) "aee" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'INTERNALS REQUIRED'."; name = "INTERNALS REQUIRED"; pixel_x = 32; pixel_y = 32},/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"aef" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/window/brigdoor{dir = 4; id = "Cell 1"; name = "Cell 1"; req_access_txt = "2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/brig) +"aef" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Equipment Storage"; req_access = list(1)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/main) "aeg" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/security_port) -"aeh" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/highsecurity{name = "Secure Armoury Section"; req_access_txt = "3"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/warden) +"aeh" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Equipment Storage"; req_access = list(1)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/main) "aei" = (/obj/machinery/light{dir = 8},/obj/structure/window/reinforced,/obj/structure/table,/obj/item/device/megaphone,/obj/item/device/megaphone,/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main) "aej" = (/obj/structure/window/reinforced,/obj/structure/table,/obj/item/device/taperecorder{pixel_y = 0},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main) "aek" = (/obj/structure/disposalpipe/segment,/obj/structure/window/reinforced,/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/storage/box,/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main) "ael" = (/obj/structure/window/reinforced,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main) "aem" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/security/main) "aen" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) -"aeo" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Briefing Room"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/main) +"aeo" = (/obj/item/weapon/hand_labeler,/obj/structure/table/reinforced,/obj/machinery/door/window/brigdoor{dir = 4; name = "Warden's Desk"; req_access = list(3)},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "aep" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main) -"aeq" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/main) +"aeq" = (/obj/structure/table/woodentable,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/item/device/flashlight/lamp/green{dir = 2; pixel_x = 10; pixel_y = 12},/obj/machinery/door_control{id = "Secure Gate"; name = "Brig Lockdown"; pixel_x = -4; pixel_y = 7; req_access = list(2)},/turf/simulated/floor/carpet{icon_state = "carpetnoconnect"},/area/crew_quarters/heads/hos) "aer" = (/obj/structure/table,/obj/item/weapon/folder/red,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/main) "aes" = (/obj/structure/table,/obj/item/weapon/book/manual/security_space_law,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/security/main) -"aet" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/security/main) +"aet" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/security/main) "aeu" = (/obj/machinery/camera{c_tag = "Security Office South"; dir = 8; network = list("SS13")},/obj/item/device/radio/intercom{broadcasting = 0; freerange = 0; frequency = 1475; listening = 1; name = "Station Intercom (Security)"; pixel_x = 30; pixel_y = 0},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) "aev" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/portable_atmospherics/powered/pump,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "aew" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/security_port) "aex" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/item/weapon/shard,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/security_port) "aey" = (/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/floor/plating,/area/maintenance/security_port) -"aez" = (/obj/structure/closet/crate/secure{name = "FOR DISPOSAL"; req_access_txt = "58"},/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/balaclava,/obj/effect/decal/cleanable/cobweb2,/obj/item/clothing/mask/muzzle,/obj/item/weapon/reagent_containers/ld50_syringe/choral,/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/security_port) +"aez" = (/obj/machinery/door/airlock/security{name = "Evidence Storage"; req_access = list(1)},/turf/simulated/floor,/area/security/brig) "aeA" = (/obj/machinery/deployable/barrier,/turf/simulated/floor{icon_state = "delivery"},/area/security/warden) "aeB" = (/obj/machinery/camera{c_tag = "Armoury"},/obj/machinery/deployable/barrier,/obj/structure/sign/securearea{name = "\improper ARMORY"; pixel_y = 32},/turf/simulated/floor{icon_state = "delivery"},/area/security/warden) "aeC" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/security/warden) @@ -244,10 +244,10 @@ "aeJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/security/main) "aeK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main) "aeL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/main) -"aeM" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/security/main) +"aeM" = (/obj/structure/bed/chair/office/dark{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/main) "aeN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/security/main) "aeO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) -"aeP" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/maintenance{name = "Security Maintenance"; req_access_txt = "1"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/security/main) +"aeP" = (/obj/item/device/eftpos{eftpos_name = "Brig EFTPOS scanner"},/obj/structure/table/reinforced,/obj/machinery/door/window/brigdoor{dir = 8; name = "Warden's Desk"; req_access = list(3)},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "aeQ" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/maintenance/security_starboard) "aeR" = (/obj/machinery/portable_atmospherics/powered/pump,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "aeS" = (/turf/simulated/wall/r_wall,/area/maintenance/security_starboard) @@ -262,7 +262,7 @@ "afb" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "red"},/area/security/main) "afc" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 1; name = "Security"; sortType = "Security"},/turf/simulated/floor{icon_state = "red"},/area/security/main) "afd" = (/turf/simulated/floor{icon_state = "red"},/area/security/main) -"afe" = (/obj/structure/table,/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/item/weapon/storage/donut_box,/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) +"afe" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/window/brigdoor{dir = 4; id = "Cell 1"; name = "Cell 1"; req_access = list(2)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/brig) "aff" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/security/main) "afg" = (/obj/machinery/photocopier,/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main) "afh" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/main) @@ -282,23 +282,23 @@ "afv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/security/warden) "afw" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/warden) "afx" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/warden) -"afy" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Armoury"; req_access_txt = "2"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/warden) +"afy" = (/obj/machinery/door/airlock/glass_security{name = "Solitary Confinement 1"; req_access = list(2)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/brig) "afz" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/main) -"afA" = (/obj/structure/stool,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/main) -"afB" = (/obj/structure/disposalpipe/segment,/obj/structure/stool,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/main) +"afA" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/security/main) +"afB" = (/obj/structure/bed/chair/office/dark{dir = 1},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/security/main) "afC" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/main) "afD" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) "afE" = (/obj/machinery/vending/cola,/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main) "afF" = (/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/main) "afG" = (/obj/machinery/light,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/security/main) -"afH" = (/obj/machinery/door/window/eastright{dir = 1; name = "Security Delivery"; req_access_txt = "1"},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "delivery"},/area/security/main) -"afI" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=1"; dir = 1; freq = 1400; location = "Security"},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/security/main) +"afH" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/dormitory) +"afI" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/dormitory) "afJ" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/meter,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/security_starboard) "afK" = (/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth{frequency = 1380; id_tag = "escape_pod_3_berth"; pixel_x = 25; pixel_y = 25; tag_door = "escape_pod_3_berth_hatch"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"afL" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_3_berth_hatch"; locked = 1; name = "Escape Pod"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"afM" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_3_hatch"; locked = 1; name = "Escape Pod Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod3/station) -"afN" = (/obj/structure/stool/bed/chair{dir = 4},/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod3/station) -"afO" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod{frequency = 1380; id_tag = "escape_pod_3"; pixel_x = 0; pixel_y = -25; req_access_txt = "0"; req_one_access_txt = "0"; tag_door = "escape_pod_3_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod3/station) +"afL" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "arrivals_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access = list(13)},/turf/simulated/floor/plating/airless,/area/space) +"afM" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "dorm_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = 25; req_access = list(13)},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/dormitory) +"afN" = (/obj/item/weapon/stool,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/main) +"afO" = (/obj/structure/disposalpipe/segment,/obj/item/weapon/stool,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/main) "afP" = (/obj/structure/window/shuttle,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/escape_pod3/station) "afQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/security_port) "afR" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/security_port) @@ -316,8 +316,8 @@ "agd" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/seccarts{pixel_x = 3; pixel_y = 2},/obj/item/weapon/storage/box/handcuffs,/obj/item/weapon/storage/box/flashbangs{pixel_x = -2; pixel_y = -2},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/security/warden) "age" = (/obj/structure/table/rack,/obj/item/clothing/mask/gas{pixel_x = 3; pixel_y = 3},/obj/item/clothing/mask/gas{pixel_x = 3; pixel_y = 3},/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas{pixel_x = -3; pixel_y = -3},/obj/item/clothing/mask/gas{pixel_x = -3; pixel_y = -3},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/security/warden) "agf" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/warden) -"agg" = (/obj/structure/table/rack,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/weapon/reagent_containers/spray/pepper,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/security/warden) -"agh" = (/obj/structure/dispenser/oxygen,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/security/warden) +"agg" = (/obj/machinery/door_control{id = "Cell 1"; name = "Cell 1 Door"; pixel_x = 30; pixel_y = 1; req_access = list(2)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/security/brig) +"agh" = (/obj/structure/bed/chair{dir = 4},/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod3/station) "agi" = (/obj/machinery/light{dir = 8},/obj/item/device/radio/intercom{broadcasting = 1; freerange = 0; frequency = 1475; listening = 0; name = "Station Intercom (Security)"; pixel_x = -30; pixel_y = 0},/turf/simulated/floor,/area/security/main) "agj" = (/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/main) "agk" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/main) @@ -328,12 +328,12 @@ "agp" = (/turf/simulated/wall,/area/crew_quarters/heads/hos) "agq" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/crew_quarters/heads/hos) "agr" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/goldenplaque,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/crew_quarters/heads/hos) -"ags" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_command{id_tag = "HoSdoor"; name = "Head of Security"; req_access_txt = "58"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) +"ags" = (/obj/machinery/door/airlock{id_tag = "visitdoor"; name = "Visitation Area"; req_access = list(63)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/lobby) "agt" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/crew_quarters/heads/hos) "agu" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/crew_quarters/heads/hos) "agv" = (/turf/simulated/wall/r_wall,/area/crew_quarters/heads/hos) "agw" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"agx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plating,/area/maintenance/security_starboard) +"agx" = (/obj/machinery/door/airlock{name = "Visitation Area"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) "agy" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst{dir = 4},/turf/simulated/shuttle/wall{icon_state = "swall_f5"; dir = 2},/area/shuttle/escape_pod3/station) "agz" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/shuttle/escape_pod3/station) "agA" = (/obj/structure/table/rack,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/maintenance/security_port) @@ -343,10 +343,10 @@ "agE" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating/airless,/area/solar/auxport) "agF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/warden) "agG" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/warden) -"agH" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Warden's Office"; req_access_txt = "3"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/security/warden) +"agH" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Security Lobby"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/fore) "agI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/warden) "agJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/warden) -"agK" = (/obj/structure/closet/wardrobe/red,/obj/structure/window/reinforced,/obj/item/clothing/tie/holster/waist,/obj/item/clothing/tie/holster/waist,/obj/item/clothing/tie/holster/waist,/obj/item/clothing/tie/armband,/obj/item/clothing/tie/armband,/obj/item/clothing/tie/armband,/turf/simulated/floor,/area/security/main) +"agK" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Security Lobby"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/primary/fore) "agL" = (/obj/structure/closet/secure_closet/security,/obj/item/device/flashlight/flare,/obj/structure/window/reinforced,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/security/main) "agM" = (/obj/structure/reagent_dispensers/peppertank{pixel_x = 30},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) "agN" = (/obj/structure/disposalpipe/sortjunction{dir = 1; name = "HoS Office"; sortType = "HoS Office"},/turf/simulated/wall,/area/crew_quarters/heads/hos) @@ -381,13 +381,13 @@ "ahq" = (/obj/structure/table/woodentable,/obj/item/device/megaphone,/obj/item/device/radio/off,/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) "ahr" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) "ahs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/carpet{icon_state = "carpetnoconnect"},/area/crew_quarters/heads/hos) -"aht" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/stool/bed/chair,/turf/simulated/floor/carpet{icon_state = "carpetnoconnect"},/area/crew_quarters/heads/hos) +"aht" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "dorm_inner"; locked = 1; name = "Dormitory Internal Access"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/dormitory) "ahu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet{icon_state = "carpetnoconnect"},/area/crew_quarters/heads/hos) "ahv" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) "ahw" = (/obj/structure/table/woodentable,/obj/machinery/keycard_auth{pixel_x = 30},/obj/machinery/photocopier/faxmachine{department = "Head of Security"},/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) "ahx" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/security_starboard) "ahy" = (/obj/effect/decal/cleanable/dirt,/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"ahz" = (/turf/space,/area/vox_station/northeast_solars) +"ahz" = (/obj/structure/table,/obj/machinery/vending/wallmed1{pixel_y = -32},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/security/prison) "ahA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/security_port) "ahB" = (/obj/machinery/space_heater,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/security_port) "ahC" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/turf/simulated/floor,/area/security/brig) @@ -397,21 +397,21 @@ "ahG" = (/obj/machinery/camera{c_tag = "Interrogation"; network = list("SS13","Interrogation")},/obj/item/device/radio/intercom{broadcasting = 1; frequency = 1449; listening = 0; pixel_x = 0; pixel_y = 25},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor{icon_state = "dark"},/area/security/brig) "ahH" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/security/brig) "ahI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/security/brig) -"ahJ" = (/obj/machinery/door/airlock/security{name = "Evidence Storage"; req_access_txt = "1"},/turf/simulated/floor,/area/security/brig) +"ahJ" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "dorm_airlock"; name = "Dormitory Airlock Console"; pixel_x = 25; pixel_y = 0; req_one_access = list(1,5,11,18,24); tag_airpump = "dorm_pump"; tag_chamber_sensor = "dorm_sensor"; tag_exterior_door = "dorm_outer"; tag_interior_door = "dorm_inner"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/maintenance/dormitory) "ahK" = (/turf/simulated/floor,/area/security/brig) "ahL" = (/turf/simulated/floor{icon_state = "floorgrime"},/area/security/brig) "ahM" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/turf/simulated/floor,/area/security/brig) -"ahN" = (/obj/structure/stool/bed/chair,/turf/simulated/floor,/area/security/brig) +"ahN" = (/obj/structure/closet/wardrobe/red,/obj/structure/window/reinforced,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/armband,/obj/item/clothing/accessory/armband,/obj/item/clothing/accessory/armband,/turf/simulated/floor,/area/security/main) "ahO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) -"ahP" = (/obj/item/device/eftpos{eftpos_name = "Brig EFTPOS scanner"},/obj/structure/table/reinforced,/obj/machinery/door/window/brigdoor{dir = 8; name = "Warden's Desk"; req_access_txt = "3"},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) -"ahQ" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) -"ahR" = (/obj/item/weapon/hand_labeler,/obj/structure/table/reinforced,/obj/machinery/door/window/brigdoor{dir = 4; name = "Warden's Desk"; req_access_txt = "3"},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) +"ahP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock{name = "Internal Affairs"; req_access = list(38)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/lawoffice) +"ahQ" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/bed/chair,/turf/simulated/floor/carpet{icon_state = "carpetnoconnect"},/area/crew_quarters/heads/hos) +"ahR" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/maintenance{name = "Detective Maintenance"; req_access = list(4)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/security/detectives_office) "ahS" = (/turf/simulated/floor{icon_state = "floorgrime"},/area/security/main) "ahT" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/vending/coffee,/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) "ahU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/crew_quarters/heads/hos) "ahV" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/flask/barflask{pixel_x = -4; pixel_y = 8},/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) "ahW" = (/obj/machinery/hologram/holopad,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) -"ahX" = (/obj/structure/table/woodentable,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/item/device/flashlight/lamp/green{dir = 2; pixel_x = 10; pixel_y = 12},/obj/machinery/door_control{id = "Secure Gate"; name = "Brig Lockdown"; pixel_x = -4; pixel_y = 7; req_access_txt = "2"},/turf/simulated/floor/carpet{icon_state = "carpetnoconnect"},/area/crew_quarters/heads/hos) +"ahX" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/window/brigdoor{dir = 4; id = "Cell 2"; name = "Cell 2"; req_access = list(2)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/brig) "ahY" = (/obj/structure/table/woodentable,/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/item/weapon/stamp/hos,/turf/simulated/floor/carpet{icon_state = "carpetnoconnect"},/area/crew_quarters/heads/hos) "ahZ" = (/obj/structure/table/woodentable,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/computer/skills{pixel_y = 4},/turf/simulated/floor/carpet{icon_state = "carpetnoconnect"},/area/crew_quarters/heads/hos) "aia" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) @@ -422,30 +422,30 @@ "aif" = (/obj/structure/table,/obj/item/device/t_scanner,/turf/simulated/floor/plating,/area/maintenance/security_port) "aig" = (/obj/machinery/portable_atmospherics/powered/pump,/turf/simulated/floor/plating,/area/maintenance/security_port) "aih" = (/obj/machinery/camera{c_tag = "Interrogation Observation"; dir = 4; network = list("SS13")},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor,/area/security/brig) -"aii" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/computer/security/telescreen{layer = 4; name = "Observation Screen"; network = list("Interrogation"); pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/brig) +"aii" = (/obj/structure/bed/chair,/turf/simulated/floor,/area/security/brig) "aij" = (/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"},/obj/structure/window/reinforced/tinted{dir = 8; icon_state = "twindow"},/obj/structure/grille,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/security/brig) -"aik" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "dark"},/area/security/brig) +"aik" = (/obj/structure/bed/chair/office/dark{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "ail" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/obj/item/device/taperecorder,/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "dark"},/area/security/brig) -"aim" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/security/brig) +"aim" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/computer/security/telescreen{layer = 4; name = "Observation Screen"; network = list("Interrogation"); pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/brig) "ain" = (/obj/structure/filingcabinet/filingcabinet,/turf/simulated/floor{icon_state = "dark"},/area/security/brig) "aio" = (/obj/machinery/camera{c_tag = "Security Processing"; dir = 4; network = list("SS13")},/obj/structure/table,/obj/item/weapon/folder/red,/obj/item/weapon/folder/red,/turf/simulated/floor,/area/security/brig) -"aip" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor,/area/security/brig) +"aip" = (/obj/structure/bed/chair{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "dark"},/area/security/brig) "aiq" = (/obj/structure/table,/turf/simulated/floor,/area/security/brig) "air" = (/obj/machinery/computer/secure_data,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) -"ais" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Warden"},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) +"ais" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/security/brig) "ait" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "aiu" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/recharger{pixel_y = 0},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "aiv" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating/airless,/area/solar/auxport) "aiw" = (/obj/machinery/vending/security,/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) "aix" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment,/obj/structure/cable/green,/turf/simulated/floor/plating,/area/crew_quarters/heads/hos) "aiy" = (/obj/structure/table/woodentable,/obj/item/device/taperecorder{pixel_y = 0},/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) -"aiz" = (/obj/structure/stool/bed/chair/comfy/black{dir = 1},/obj/effect/landmark/start{name = "Head of Security"},/obj/machinery/door_control{id = "HoSdoor"; name = "Office Door"; normaldoorcontrol = 1; pixel_x = -36; pixel_y = 29},/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) +"aiz" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor,/area/security/brig) "aiA" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/weapon/folder/red,/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) "aiB" = (/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/security_starboard) "aiC" = (/obj/structure/closet,/obj/item/clothing/glasses/welding,/obj/item/weapon/weldingtool,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "aiD" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/security_port) "aiE" = (/obj/item/device/radio/intercom{frequency = 1449; pixel_x = 0; pixel_y = -27},/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/brig) -"aiF" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/brig) +"aiF" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Warden"},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "aiG" = (/obj/structure/window/reinforced/tinted,/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"},/obj/structure/window/reinforced/tinted{dir = 8; icon_state = "twindow"},/obj/structure/grille,/obj/structure/cable/green,/turf/simulated/floor/plating,/area/security/brig) "aiH" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/security/brig) "aiI" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor{icon_state = "dark"},/area/security/brig) @@ -470,37 +470,37 @@ "ajb" = (/obj/machinery/light{dir = 1},/obj/machinery/firealarm{pixel_y = 24},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/brig) "ajc" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/wall,/area/crew_quarters/heads/hos) "ajd" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/camera{c_tag = "HoS Office South"; dir = 1},/obj/structure/flora/pottedplant,/obj/machinery/newscaster/security_unit{pixel_x = -30},/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) -"aje" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) +"aje" = (/obj/structure/bed/chair/comfy/black{dir = 1},/obj/effect/landmark/start{name = "Head of Security"},/obj/machinery/door_control{id = "HoSdoor"; name = "Office Door"; normaldoorcontrol = 1; pixel_x = -36; pixel_y = 29},/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) "ajf" = (/obj/machinery/computer/security,/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) "ajg" = (/obj/machinery/computer/secure_data,/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) "ajh" = (/obj/structure/filingcabinet,/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) "aji" = (/obj/structure/closet/secure_closet/hos,/obj/item/device/radio/intercom{pixel_x = 27},/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) -"ajj" = (/obj/machinery/door/airlock/maintenance{name = "Firefighting equipment"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/security_port) +"ajj" = (/obj/machinery/door/airlock/glass_security{name = "Solitary Confinement 2"; req_access = list(2)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/brig) "ajk" = (/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/turf/simulated/floor/plating,/area/maintenance/security_port) "ajl" = (/obj/machinery/light/small{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/security_port) -"ajm" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Interrogation Observation"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) -"ajn" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Interrogation"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) -"ajo" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Evidence Storage"; req_access_txt = "1"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) +"ajm" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "lawyer_blast"; name = "Privacy Shutters"; opacity = 0},/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/window/eastright{base_state = "left"; dir = 4; icon_state = "left"; name = "Internal Affairs Desk"; req_access = list(38)},/turf/simulated/floor,/area/lawoffice) +"ajn" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "dorm_outer"; locked = 1; name = "Dormitory External Access"; req_access = list(13)},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/dormitory) +"ajo" = (/obj/machinery/door_control{id = "Cell 2"; name = "Cell 2 Door"; pixel_x = 30; pixel_y = 1; req_access = list(2)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/security/brig) "ajp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/brig) "ajq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/brig) -"ajr" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Security Processing"; req_access_txt = "1"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/brig) +"ajr" = (/obj/machinery/door/window/westleft{dir = 1; name = "Forensics Area"; req_access = list(4)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "warnwhite"; dir = 1},/area/security/detectives_office) "ajs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/brig) -"ajt" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Security Processing"; req_access_txt = "1"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/brig) +"ajt" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "dorm_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access = list(13)},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating/airless,/area/maintenance/dormitory) "aju" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/brig) "ajv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/brig) "ajw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/brig) -"ajx" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Warden's Office"; req_access_txt = "3"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/security/warden) +"ajx" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance{name = "Dormitory\\Security Maintenance"; req_access = list(12)},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/maintenance/dormitory) "ajy" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/brig) "ajz" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/security/brig) -"ajA" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Equipment Storage"; req_access_txt = "1"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/main) -"ajB" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Equipment Storage"; req_access_txt = "1"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/main) +"ajA" = (/obj/machinery/door/airlock/glass_security{id_tag = "prisonentry"; name = "Brig Entry"; req_access = list(2)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison) +"ajB" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "EVA\\Security Maintenance"},/turf/simulated/floor/plating,/area/maintenance/security_port) "ajC" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/crew_quarters/heads/hos) "ajD" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/security_starboard) "ajE" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire/firefighter,/obj/item/weapon/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/weapon/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/clothing/glasses/meson,/turf/simulated/floor/plating,/area/maintenance/security_starboard) "ajF" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/security_port) "ajG" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/security_port) "ajH" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plating,/area/maintenance/security_port) -"ajI" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/maintenance{name = "Security Maintenance"; req_access_txt = "1"},/turf/simulated/floor/plating,/area/security/brig) +"ajI" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/airlock/engineering{name = "Security Substation"; req_one_access = list(11,24)},/turf/simulated/floor/plating,/area/maintenance/substation/security) "ajJ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "red"; dir = 9},/area/security/brig) "ajK" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/brig) "ajL" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/brig) @@ -523,7 +523,7 @@ "akc" = (/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/brig) "akd" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/brig) "ake" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/brig) -"akf" = (/obj/structure/table,/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = -28},/obj/item/clothing/tie/holobadge,/obj/item/clothing/tie/holobadge,/obj/item/clothing/tie/holobadge/cord,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) +"akf" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/brig) "akg" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "red"; dir = 5},/area/security/brig) "akh" = (/obj/structure/table/rack,/obj/item/weapon/storage/briefcase{pixel_x = -2; pixel_y = -5},/obj/item/weapon/storage/briefcase{pixel_x = 3; pixel_y = 0},/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "aki" = (/obj/structure/disposalpipe/segment,/obj/structure/closet{name = "Evidence Closet"},/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) @@ -544,11 +544,11 @@ "akx" = (/obj/machinery/door_timer/cell_3{pixel_y = -32},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/brig) "aky" = (/obj/item/device/radio/intercom{pixel_y = -30},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/security/brig) "akz" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) -"akA" = (/obj/machinery/door_control{id = "Cell 3"; name = "Cell 3 Door"; pixel_x = -1; pixel_y = -28; req_access_txt = "2"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/security/brig) +"akA" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/window/brigdoor{dir = 8; req_access = list(2)},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/structure/table/reinforced,/turf/simulated/floor,/area/security/brig) "akB" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/brig) "akC" = (/obj/machinery/light,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/security/brig) "akD" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/security/brig) -"akE" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/flasher_button{id = "permflash"; name = "Brig flashes"; pixel_x = 0; pixel_y = -27; tag = "permflash"},/turf/simulated/floor,/area/security/brig) +"akE" = (/obj/structure/table,/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = -28},/obj/item/clothing/accessory/holobadge,/obj/item/clothing/accessory/holobadge,/obj/item/clothing/accessory/holobadge/cord,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) "akF" = (/obj/machinery/camera{c_tag = "Brig Center"; dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor,/area/security/brig) "akG" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/brig) "akH" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor,/area/security/brig) @@ -561,17 +561,17 @@ "akO" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) "akP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/security/brig) "akQ" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor,/area/security/brig) -"akR" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{id_tag = "detdoor"; name = "Detective"; req_access_txt = "4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/detectives_office) +"akR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/button/flasher{id = "permflash"; name = "Brig flashes"; pixel_x = -6; pixel_y = -24; req_access = list(2); tag = "permflash"},/obj/machinery/door_control{id = "brigobs"; name = "observation shutters"; pixel_x = 6; pixel_y = -24},/obj/machinery/door_control{id = "Secure Gate"; name = "Brig Lockdown"; pixel_x = -26; pixel_y = -4; req_access = list(2)},/turf/simulated/floor,/area/security/brig) "akS" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "akT" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/security/detectives_office) "akU" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/carpet,/area/security/detectives_office) -"akV" = (/obj/structure/stool,/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/carpet,/area/security/detectives_office) +"akV" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = -29},/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) "akW" = (/obj/structure/table/woodentable,/obj/machinery/door_control{id = "detdoor"; name = "Office Door"; normaldoorcontrol = 1},/obj/item/weapon/handcuffs,/obj/item/device/flash,/turf/simulated/floor/carpet,/area/security/detectives_office) -"akX" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Detective"},/turf/simulated/floor/carpet,/area/security/detectives_office) +"akX" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/button/flasher{id = "permflash"; name = "Brig flashes"; pixel_x = 0; pixel_y = -27; tag = "permflash"},/turf/simulated/floor,/area/security/brig) "akY" = (/obj/structure/closet/secure_closet/detective,/obj/item/weapon/reagent_containers/food/drinks/flask/detflask,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "akZ" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"ala" = (/obj/machinery/door/airlock/maintenance{name = "Firefighting equipment"; req_access_txt = "12"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"alb" = (/obj/structure/table,/obj/item/device/t_scanner,/turf/simulated/floor/plating,/area/maintenance/security_starboard) +"ala" = (/obj/machinery/door/airlock/external{icon_state = "door_locked"; locked = 1; name = "External Construction Airlock"; req_access = list(32)},/obj/item/tape/engineering{icon_state = "engineering_door"; layer = 4},/turf/simulated/floor/plating,/area/maintenance/security_starboard) +"alb" = (/obj/item/weapon/stool,/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/carpet,/area/security/detectives_office) "alc" = (/obj/machinery/atmospherics/pipe/tank/nitrous_oxide{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/security/brig) "ald" = (/obj/machinery/atmospherics/valve{dir = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/security/brig) "ale" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1; icon_state = "map"; tag = "icon-manifold-f (NORTH)"},/obj/machinery/meter,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/security/brig) @@ -583,22 +583,22 @@ "alk" = (/turf/simulated/floor/plating/airless,/area/solar/auxport) "all" = (/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating/airless,/area/solar/auxport) "alm" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/prison) -"aln" = (/obj/machinery/door/airlock/glass_security{id_tag = "prisonexit"; name = "Brig Exit"; req_access_txt = "2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison) +"aln" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/brigdoor{dir = 4; name = "Weapons locker"; req_access = list(3)},/obj/structure/table/rack,/obj/item/clothing/suit/armor/riot,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/shield/riot,/obj/item/clothing/head/helmet/riot,/obj/machinery/light{dir = 8},/obj/machinery/camera{c_tag = "Armoury - Secure"; dir = 4; network = list("SS13")},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) "alo" = (/obj/machinery/door/blast/regular{id = "Cell 1"; name = "Cell Door"},/turf/simulated/floor,/area/security/prison) "alp" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/computer/secure_data,/turf/simulated/floor{icon_state = "red"; dir = 9},/area/security/brig) -"alq" = (/obj/machinery/door/window/brigdoor{dir = 1; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/brig) -"alr" = (/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 1; icon_state = "rightsecure"; req_access_txt = "63"},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/brig) +"alq" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/brigdoor{dir = 4; name = "Weapons locker"; req_access = list(3)},/obj/structure/table/rack,/obj/item/clothing/suit/armor/riot,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/shield/riot,/obj/item/clothing/head/helmet/riot,/obj/structure/window/reinforced,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) +"alr" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Briefing Room"; req_access = list(63)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/main) "als" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/computer/security,/turf/simulated/floor{icon_state = "red"; dir = 5},/area/security/brig) "alt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/security/brig) "alu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/security/brig) -"alv" = (/obj/machinery/door/airlock/glass_security{id_tag = "BrigFoyer"; layer = 2.8; name = "Security Wing"; req_access_txt = "63"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/brig) +"alv" = (/obj/machinery/door_control{id = "Armoury"; name = "Armoury Access"; pixel_x = -1; pixel_y = -28; req_access = list(3)},/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "alw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/security/brig) -"alx" = (/obj/machinery/door/airlock/glass_security{id_tag = "BrigFoyer"; layer = 2.8; name = "Security Wing"; req_access_txt = "63"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "redfull"; dir = 9},/area/security/brig) +"alx" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/brigdoor{dir = 2; name = "Weapons locker"; req_access = list(3)},/obj/random/projectile,/obj/random/projectile,/obj/random/projectile,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) "aly" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating/airless,/area/solar/auxport) "alz" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating/airless,/area/solar/auxport) "alA" = (/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating/airless,/area/solar/auxport) "alB" = (/obj/machinery/light_switch{pixel_x = -25; pixel_y = 0},/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) -"alC" = (/obj/structure/disposalpipe/segment,/obj/structure/stool,/turf/simulated/floor/carpet,/area/security/detectives_office) +"alC" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Detective"},/turf/simulated/floor/carpet,/area/security/detectives_office) "alD" = (/turf/simulated/floor/carpet,/area/security/detectives_office) "alE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/carpet,/area/security/detectives_office) "alF" = (/obj/structure/table/woodentable,/obj/item/ashtray/bronze,/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,/obj/item/device/taperecorder{pixel_x = -4; pixel_y = 2},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/security/detectives_office) @@ -610,8 +610,8 @@ "alL" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "visit_blast"; name = "Privacy Shutters"; opacity = 0},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/security/lobby) "alM" = (/turf/simulated/floor/plating,/area/security/brig) "alN" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/security/brig) -"alO" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/security/brig) -"alP" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Riot Control"; req_access_txt = "2"},/turf/simulated/floor,/area/security/brig) +"alO" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/security_starboard) +"alP" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/brigdoor{dir = 2; name = "Weapons locker"; req_access = list(3)},/obj/structure/window/reinforced{dir = 8},/obj/random/energy,/obj/random/energy,/obj/random/energy,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) "alQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) "alR" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/brig) "alS" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/security/brig) @@ -621,10 +621,10 @@ "alW" = (/turf/simulated/wall,/area/security/prison) "alX" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/turf/simulated/floor,/area/security/prison) "alY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison) -"alZ" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 8; icon_state = "rightsecure"; req_access_txt = "2"},/obj/structure/table/reinforced,/turf/simulated/floor,/area/security/brig) -"ama" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/machinery/door_control{id = "prisonentry"; name = "Entry Doors"; normaldoorcontrol = 1; pixel_x = -6; pixel_y = 24; req_access_txt = "2"},/obj/machinery/door_control{id = "prisonexit"; name = "Exit Doors"; normaldoorcontrol = 1; pixel_x = 6; pixel_y = 24; req_access_txt = "2"},/obj/machinery/flasher_button{id = "permentryflash"; name = "entry flash"; pixel_x = -26; pixel_y = 6; req_access_txt = "2"},/turf/simulated/floor,/area/security/brig) +"alZ" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/light{dir = 1},/obj/machinery/door/window/brigdoor{dir = 2; name = "Weapons locker"; req_access = list(3)},/obj/item/ammo_magazine/c45m/flash,/obj/item/ammo_magazine/c45m/flash,/obj/item/ammo_magazine/c45m/flash,/obj/item/ammo_magazine/c45m/rubber,/obj/item/ammo_magazine/c45m/rubber,/obj/item/ammo_magazine/c45m/rubber,/obj/item/ammo_magazine/c45m/rubber,/obj/item/ammo_magazine/c45m/rubber,/obj/item/ammo_magazine/c45m/rubber,/obj/item/ammo_magazine/mc9mmt/rubber,/obj/item/ammo_magazine/mc9mmt/rubber,/obj/item/ammo_magazine/mc9mmt/rubber,/obj/item/weapon/storage/box/beanbags,/obj/item/weapon/storage/box/beanbags,/obj/item/weapon/storage/box/flashshells,/obj/item/weapon/storage/box/stunshells,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) +"ama" = (/obj/structure/table,/obj/item/device/t_scanner,/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/maintenance/security_starboard) "amb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/brig) -"amc" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/machinery/door_control{desc = "A remote control switch for the brig foyer."; id = "BrigFoyer"; name = "Brig Foyer Doors"; normaldoorcontrol = 1; pixel_x = 28; pixel_y = -15},/turf/simulated/floor,/area/security/brig) +"amc" = (/obj/structure/disposalpipe/segment,/obj/item/weapon/stool,/turf/simulated/floor/carpet,/area/security/detectives_office) "amd" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/window/southright{base_state = "left"; dir = 4; icon_state = "left"},/obj/structure/table/reinforced,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor,/area/security/lobby) "ame" = (/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/security/lobby) "amf" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/lobby) @@ -640,13 +640,13 @@ "amp" = (/obj/structure/table/woodentable,/obj/item/ashtray/bronze,/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,/obj/item/device/flash,/obj/item/weapon/handcuffs,/turf/simulated/floor/carpet,/area/security/detectives_office) "amq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/carpet,/area/security/detectives_office) "amr" = (/obj/item/weapon/storage/secure/safe{pixel_x = 35; pixel_y = 5},/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) -"ams" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"amt" = (/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/floor/plating,/area/maintenance/security_starboard) -"amu" = (/obj/machinery/door/airlock/engineering{name = "Security Substation"; req_access_txt = "0"; req_one_access_txt = "11;24"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/substation/security) +"ams" = (/obj/structure/bed/chair/office/dark{dir = 1},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/security/brig) +"amt" = (/obj/structure/table/rack,/obj/machinery/door/window/brigdoor{dir = 2; name = "Weapons locker"; req_access = list(3)},/obj/structure/window/reinforced{dir = 1},/obj/item/weapon/gun/energy/ionrifle,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) +"amu" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/brigdoor{dir = 4; name = "Weapons locker"; req_access = list(3)},/obj/structure/table/rack,/obj/item/clothing/suit/armor/riot,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/shield/riot,/obj/item/clothing/head/helmet/riot,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) "amv" = (/obj/machinery/light/small{dir = 1},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/power/sensor{name = "Powernet Sensor - Security Subgrid"; name_tag = "Security Subgrid"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/maintenance/substation/security) "amw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/substation/security) -"amx" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "arrivals_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "13"},/turf/simulated/floor/plating/airless,/area/space) -"amy" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Security Lobby"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/fore) +"amx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/maintenance{name = "Security Maintenance"; req_access = list(1)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/security/range) +"amy" = (/obj/machinery/door/airlock/engineering{name = "Fore Solar Access"; req_access = list(10)},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/foresolar) "amz" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/hallway/primary/fore) "amA" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/camera{c_tag = "Brig Toxin Control"; dir = 4; network = list("SS13")},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/security/brig) "amB" = (/obj/machinery/atmospherics/valve{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/security/brig) @@ -655,35 +655,36 @@ "amE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/brig) "amF" = (/obj/machinery/camera{c_tag = "Prison Wing Processing"; dir = 1},/obj/structure/closet/secure_closet/brig,/turf/simulated/floor,/area/security/brig) "amG" = (/obj/structure/flora/pottedplant{tag = "icon-plant-10"; icon_state = "plant-10"},/turf/simulated/floor,/area/security/brig) -"amH" = (/obj/machinery/flasher{id = "Cell 3"; pixel_x = -28; pixel_y = 0},/obj/structure/stool/bed,/turf/simulated/floor{icon_state = "red"},/area/security/prison) +"amH" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "brig_solar_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "brig_solar_airlock"; layer = 3.3; pixel_x = 0; pixel_y = -25; req_access = list(13); tag_airpump = "brig_solar_pump"; tag_chamber_sensor = "brig_solar_sensor"; tag_exterior_door = "brig_solar_outer"; tag_interior_door = "brig_solar_inner"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "brig_solar_sensor"; layer = 3.3; pixel_x = 12; pixel_y = -25},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/decal/warning_stripes,/turf/simulated/floor/plating,/area/maintenance/foresolar) "amI" = (/turf/simulated/floor{icon_state = "red"},/area/security/prison) "amJ" = (/obj/structure/closet/secure_closet/brig{id = "Cell 3"; name = "Cell 3 Locker"},/obj/machinery/camera{c_tag = "Brig Cell 3"; dir = 8; network = list("SS13","Prison")},/turf/simulated/floor{icon_state = "red"},/area/security/prison) "amK" = (/obj/machinery/flasher{id = "permentryflash"; name = "Floor mounted flash"; pixel_x = 0},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/security/prison) "amL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison) -"amM" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/window/brigdoor{dir = 8; req_access_txt = "2"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/structure/table/reinforced,/turf/simulated/floor,/area/security/brig) -"amN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/flasher_button{id = "permflash"; name = "Brig flashes"; pixel_x = -6; pixel_y = -24; req_access_txt = "2"; tag = "permflash"},/obj/machinery/door_control{id = "brigobs"; name = "observation shutters"; pixel_x = 6; pixel_y = -24},/obj/machinery/door_control{id = "Secure Gate"; name = "Brig Lockdown"; pixel_x = -26; pixel_y = -4; req_access_txt = "2"},/turf/simulated/floor,/area/security/brig) +"amM" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "brig_solar_outer"; locked = 1; name = "Engineering External Access"; req_access = list(10,13)},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/foresolar) +"amN" = (/obj/structure/bed/chair/office/dark{dir = 4},/obj/machinery/door_control{desc = "A remote control switch for the brig foyer."; id = "BrigFoyer"; name = "Brig Foyer Doors"; normaldoorcontrol = 1; pixel_x = 28; pixel_y = -15},/turf/simulated/floor,/area/security/brig) "amO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/computer/security/telescreen{desc = "Big Brother is watching."; name = "Brig Monitor"; network = list("Prison"); pixel_x = 3; pixel_y = -33},/turf/simulated/floor,/area/security/brig) "amP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/disposalpipe/trunk,/obj/machinery/disposal,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera{c_tag = "Prison Wing Observation"; dir = 1; network = list("SS13")},/turf/simulated/floor,/area/security/brig) "amQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/computer/security/telescreen{desc = "Big Brother is watching."; name = "Brig Monitor"; network = list("Prison"); pixel_x = -3; pixel_y = -33},/turf/simulated/floor,/area/security/brig) -"amR" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/brig) +"amR" = (/obj/machinery/flasher{id = "Cell 3"; pixel_x = -28; pixel_y = 0},/obj/structure/bed,/turf/simulated/floor{icon_state = "red"},/area/security/prison) "amS" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/window/southright{dir = 4},/obj/structure/table/reinforced,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/security/lobby) "amT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/security/lobby) -"amU" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Security Lobby"; req_access_txt = "0"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/primary/fore) +"amU" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; layer = 3.3; master_tag = "brig_solar_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/foresolar) "amV" = (/obj/structure/table/reinforced,/obj/item/weapon/folder{pixel_x = -4},/obj/item/weapon/folder/red{pixel_y = 3},/obj/item/weapon/folder/blue{pixel_x = 5},/obj/item/weapon/folder/yellow,/obj/item/weapon/stamp/internalaffairs,/obj/item/weapon/stamp/denied{pixel_x = 4; pixel_y = -2},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) -"amW" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Internal Affairs Agent"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) +"amW" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "brig_solar_inner"; locked = 1; name = "Engineering External Access"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/foresolar) "amX" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) "amY" = (/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) "amZ" = (/obj/machinery/computer/security/wooden_tv,/obj/machinery/camera{c_tag = "Forensic Office"; dir = 4; pixel_x = 0; pixel_y = -22},/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) -"ana" = (/obj/structure/disposalpipe/segment,/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/effect/landmark/start{name = "Detective"},/turf/simulated/floor/carpet,/area/security/detectives_office) +"ana" = (/obj/structure/bed/chair/office/dark{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/brig) "anb" = (/obj/item/device/radio/intercom{pixel_x = 29; pixel_y = -1},/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "anc" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/maintenance/security_starboard) "and" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall,/area/maintenance/substation/security) "ane" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/terminal{dir = 4},/turf/simulated/floor/plating,/area/maintenance/substation/security) -"anf" = (/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Security Substation"},/turf/simulated/floor/plating,/area/maintenance/substation/security) +"anf" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Internal Affairs Agent"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) "ang" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/substation/security) +"anh" = (/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) "ani" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating/airless,/area/solar/auxstarboard) "anj" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating/airless,/area/solar/auxstarboard) -"ank" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "EVA\\Security Maintenance"; req_access_txt = "0"},/turf/simulated/floor/plating,/area/maintenance/security_port) +"ank" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/highsecurity{name = "Tactical Equipment"; req_access = list(3)},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "dark"},/area/security/tactical) "anl" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHEAST)"},/turf/simulated/wall,/area/security/brig) "anm" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/wall,/area/security/brig) "ann" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/brig) @@ -714,27 +715,27 @@ "anM" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/photo_album{pixel_y = -10},/obj/item/device/camera_film,/obj/item/device/camera_film,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "anN" = (/obj/structure/bookcase,/obj/item/weapon/book/manual/security_space_law,/turf/simulated/floor{icon_state = "grimy"},/area/security/detectives_office) "anO" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/security_starboard) -"anP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/airlock/engineering{name = "Security Substation"; req_access_txt = "0"; req_one_access_txt = "11;24"},/turf/simulated/floor/plating,/area/maintenance/substation/security) +"anP" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Firing Range"; req_access = list(1)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/main) "anQ" = (/turf/simulated/wall,/area/maintenance/substation/security) "anR" = (/obj/machinery/power/breakerbox/activated{RCon_tag = "Security Substation Bypass"},/turf/simulated/floor/plating,/area/maintenance/substation/security) "anS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/substation/security) "anT" = (/obj/machinery/power/solar{id = "auxsolareast"; name = "Port Auxiliary Solar Array"},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/auxstarboard) "anU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/security/prison) "anV" = (/obj/machinery/power/solar{id = "auxsolareast"; name = "Port Auxiliary Solar Array"},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/auxport) -"anW" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1443; icon_state = "on"; id = "air_in"; use_power = 1},/obj/structure/stool/bed/chair,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/prison) +"anW" = (/obj/structure/disposalpipe/segment,/obj/structure/bed/chair/office/dark{dir = 1},/obj/effect/landmark/start{name = "Detective"},/turf/simulated/floor/carpet,/area/security/detectives_office) "anX" = (/turf/simulated/wall,/area/maintenance/evahallway) "anY" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/evahallway) "anZ" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/evahallway) "aoa" = (/obj/structure/closet/crate,/obj/item/weapon/tank/emergency_oxygen/engi,/obj/item/weapon/tank/emergency_oxygen/double,/obj/effect/decal/cleanable/cobweb2,/obj/effect/landmark{name = "blobstart"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/maintenance/evahallway) "aob" = (/obj/structure/table,/obj/item/weapon/pen,/obj/item/weapon/paper,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/security/brig) -"aoc" = (/obj/structure/stool,/obj/effect/decal/cleanable/dirt,/obj/machinery/camera{c_tag = "Solitary Confinement North"; dir = 2; network = list("SS13","Prison")},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/plating,/area/security/brig) +"aoc" = (/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Substation - Security"},/turf/simulated/floor/plating,/area/maintenance/substation/security) "aod" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/brig) -"aoe" = (/obj/machinery/door_control{id = "Cell 2"; name = "Cell 2 Door"; pixel_x = 30; pixel_y = 1; req_access_txt = "2"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/security/brig) -"aof" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/window/brigdoor{dir = 4; id = "Cell 2"; name = "Cell 2"; req_access_txt = "2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/brig) +"aoe" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; layer = 3.3; master_tag = "brig_solar_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access = list(13)},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating/airless,/area/solar/fore) +"aof" = (/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor,/area/security/range) "aog" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/security/prison) "aoh" = (/obj/machinery/camera{c_tag = "Brig Cell 2"; dir = 2; network = list("SS13","Prison")},/obj/structure/closet/secure_closet/brig{id = "Cell 2"; name = "Cell 2 Locker"},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison) "aoi" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/prison) -"aoj" = (/obj/machinery/door/airlock/glass_security{id_tag = "prisonentry"; name = "Brig Entry"; req_access_txt = "2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison) +"aoj" = (/obj/machinery/camera{c_tag = "Armoury - Tactical Equipment "; dir = 2; network = list("SS13")},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/window/brigdoor{dir = 2; name = "Weapons locker"; req_access = list(3)},/obj/structure/table/rack,/obj/item/ammo_magazine/c45m,/obj/item/ammo_magazine/c45m,/obj/item/ammo_magazine/c45m,/obj/item/ammo_magazine/c45m,/obj/item/ammo_magazine/c45m,/obj/item/ammo_magazine/c45m,/obj/item/ammo_magazine/mc9mmt,/obj/item/ammo_magazine/mc9mmt,/obj/item/weapon/storage/box/shotgunammo,/obj/item/weapon/storage/box/shotgunammo,/obj/item/weapon/storage/box/shotgunshells,/obj/item/weapon/storage/box/shotgunshells,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/tactical) "aok" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/prison) "aol" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/security/prison) "aom" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/table,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/window/southleft,/turf/simulated/floor,/area/security/prison) @@ -743,7 +744,7 @@ "aop" = (/obj/item/device/radio/intercom{desc = "Talk... listen through this."; name = "Station Intercom (Brig Radio)"; pixel_x = 0; pixel_y = 26; wires = 7},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) "aoq" = (/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/security/prison) "aor" = (/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) -"aos" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "lawyer_blast"; name = "Privacy Shutters"; opacity = 0},/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/window/eastright{base_state = "left"; dir = 4; icon_state = "left"; name = "Internal Affairs Desk"; req_access_txt = "38"},/turf/simulated/floor,/area/lawoffice) +"aos" = (/obj/machinery/camera{c_tag = "Firing Range"; dir = 8; network = list("SS13")},/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/range) "aot" = (/obj/machinery/camera{c_tag = "Security Lobby"; dir = 4; pixel_x = 0; pixel_y = -22},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/table,/obj/item/weapon/book/manual/security_space_law{pixel_y = 6},/turf/simulated/floor,/area/security/lobby) "aou" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/security/lobby) "aov" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/lobby) @@ -753,11 +754,11 @@ "aoz" = (/obj/structure/window/basic{dir = 1},/obj/structure/disposalpipe/trunk{dir = 4},/obj/machinery/disposal,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) "aoA" = (/obj/structure/window/basic{dir = 1},/obj/structure/disposalpipe/junction{dir = 1; icon_state = "pipe-j2"},/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) "aoB" = (/obj/structure/window/basic{dir = 1},/obj/machinery/photocopier,/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) -"aoC" = (/obj/machinery/door/window/westleft{dir = 1; name = "Forensics Area"; req_access_txt = "4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "warnwhite"; dir = 1},/area/security/detectives_office) +"aoC" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Warden's Office"; req_access = list(3)},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/security/warden) "aoD" = (/obj/structure/window/basic{dir = 1},/obj/structure/filingcabinet/chestdrawer,/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) "aoE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/window/basic{dir = 1},/obj/structure/filingcabinet/security{desc = "A large cabinet with hard copy security records."; name = "Security Records"},/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) "aoF" = (/obj/machinery/newscaster{pixel_x = 28; pixel_y = 1},/obj/structure/window/basic{dir = 1},/obj/structure/filingcabinet/medical{desc = "A large cabinet with hard copy medical records."; name = "Medical Records"},/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) -"aoG" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance{name = "Dormitory\\Security Maintenance"; req_access_txt = "12"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/maintenance/dormitory) +"aoG" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/maintenance{name = "Security Maintenance"; req_access = list(1)},/turf/simulated/floor/plating,/area/security/brig) "aoH" = (/turf/simulated/wall,/area/maintenance/dormitory) "aoI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/dormitory) "aoJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/dormitory) @@ -780,7 +781,7 @@ "apa" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/evahallway) "apb" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/evahallway) "apc" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating,/area/security/brig) -"apd" = (/obj/machinery/door/airlock/glass_security{name = "Solitary Confinement 2"; req_access_txt = "2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/brig) +"apd" = (/obj/machinery/door/window/eastright{dir = 1; name = "Security Delivery"; req_access = list(1)},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "delivery"},/area/security/main) "ape" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) "apf" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/security/brig) "apg" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/solar/fore) @@ -792,8 +793,8 @@ "apm" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/prison) "apn" = (/obj/machinery/flasher{id = "permflash"; name = "Floor mounted flash"; pixel_x = 0},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/security/prison) "apo" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/security/prison) -"app" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/maintenance{name = "Security Maintenance"; req_access_txt = "1"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/security/range) -"apq" = (/obj/machinery/light{dir = 8},/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/lobby) +"app" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/security{name = "Armoury"; req_access = list(2)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/warden) +"apq" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/substation/security) "apr" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/security/lobby) "aps" = (/obj/structure/cable/yellow,/turf/simulated/floor/plating/airless,/area/solar/fore) "apt" = (/obj/machinery/newscaster{pixel_x = 30},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) @@ -806,46 +807,46 @@ "apA" = (/obj/machinery/requests_console{pixel_x = 30},/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) "apB" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/dormitory) "apC" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/wood,/area/maintenance/dormitory) -"apD" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/wood,/area/maintenance/dormitory) -"apE" = (/obj/structure/stool/bed/chair/wood/wings,/turf/simulated/floor/wood,/area/maintenance/dormitory) +"apD" = (/obj/item/weapon/stool,/obj/effect/decal/cleanable/dirt,/obj/machinery/camera{c_tag = "Solitary Confinement North"; dir = 2; network = list("SS13","Prison")},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/plating,/area/security/brig) +"apE" = (/obj/machinery/light{dir = 8},/obj/structure/bed/chair{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/lobby) "apF" = (/turf/simulated/floor/wood,/area/maintenance/dormitory) -"apG" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/simulated/floor/wood{icon_state = "wood-broken6"},/area/maintenance/dormitory) -"apH" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "dorm_outer"; locked = 1; name = "Dormitory External Access"; req_access = null; req_access_txt = "13"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/dormitory) +"apG" = (/obj/structure/bed/chair/wood/wings,/turf/simulated/floor/wood,/area/maintenance/dormitory) +"apH" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_3_hatch"; locked = 1; name = "Escape Pod Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod3/station) "apI" = (/obj/machinery/power/solar{id = "auxsolareast"; name = "Port Auxiliary Solar Array"},/obj/structure/cable/yellow,/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/auxstarboard) "apJ" = (/obj/machinery/power/solar{id = "auxsolareast"; name = "Port Auxiliary Solar Array"},/obj/structure/cable/yellow,/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/auxport) "apK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/evahallway) -"apL" = (/obj/structure/stool/bed,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/security/brig) +"apL" = (/obj/item/weapon/stool{pixel_y = 8},/turf/simulated/floor/wood,/area/maintenance/dormitory) "apM" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/plating,/area/security/brig) "apN" = (/obj/item/device/radio/intercom{pixel_x = 30},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/security/brig) "apO" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/security/prison) -"apP" = (/obj/structure/stool/bed,/obj/machinery/flasher{id = "Cell 2"; pass_flags = 0; pixel_x = 0; pixel_y = -26},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison) +"apP" = (/obj/structure/bed/chair/comfy/black{dir = 8},/turf/simulated/floor/wood{icon_state = "wood-broken6"},/area/maintenance/dormitory) "apQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/security/prison) "apR" = (/obj/machinery/light{dir = 8},/obj/effect/decal/cleanable/generic,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/prison) "apS" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/security/prison) "apT" = (/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating/airless,/area/solar/fore) -"apU" = (/obj/structure/stool/bed/chair,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/prison) -"apV" = (/obj/structure/stool/bed/chair,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor,/area/security/prison) +"apU" = (/obj/structure/bed,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/security/brig) +"apV" = (/obj/structure/bed,/obj/machinery/flasher{id = "Cell 2"; pass_flags = 0; pixel_x = 0; pixel_y = -26},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison) "apW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) "apX" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/prison) "apY" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/prison) "apZ" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/prison) "aqa" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/security/prison) "aqb" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating/airless,/area/solar/fore) -"aqc" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/lobby) +"aqc" = (/obj/structure/bed/chair,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/prison) "aqd" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/security/lobby) "aqe" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/lobby) "aqf" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/security/lobby) -"aqg" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock{name = "Internal Affairs"; req_access_txt = "38"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/lawoffice) +"aqg" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod{frequency = 1380; id_tag = "escape_pod_3"; pixel_x = 0; pixel_y = -25; tag_door = "escape_pod_3_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod3/station) "aqh" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) "aqi" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) "aqj" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) "aqk" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/table/reinforced,/obj/item/weapon/pen/blue{pixel_x = -5; pixel_y = -1},/obj/item/weapon/pen/red{pixel_x = -1; pixel_y = 3},/obj/item/ashtray/plastic{pixel_x = 4; pixel_y = 6},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) "aql" = (/obj/machinery/computer/med_data,/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) -"aqm" = (/obj/structure/disposalpipe/segment,/obj/structure/stool/bed/chair/office/light{dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) +"aqm" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1443; icon_state = "on"; id = "air_in"; use_power = 1},/obj/structure/bed/chair,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/prison) "aqn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) "aqo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) -"aqp" = (/obj/structure/stool/bed/chair/office/light,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) -"aqq" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/maintenance{name = "Detective Maintenance"; req_access_txt = "4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/security/detectives_office) +"aqp" = (/obj/structure/bed/chair,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor,/area/security/prison) +"aqq" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; dir = 1; freq = 1400; location = "Security"},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/security/main) "aqr" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/dormitory) "aqs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/dormitory) "aqt" = (/obj/structure/table/gamblingtable,/turf/simulated/floor/wood,/area/maintenance/dormitory) @@ -864,11 +865,11 @@ "aqG" = (/obj/structure/table,/obj/item/weapon/dice,/turf/simulated/floor,/area/security/prison) "aqH" = (/obj/structure/table,/obj/item/ashtray/plastic,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) "aqI" = (/obj/structure/reagent_dispensers/water_cooler,/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor,/area/security/prison) -"aqJ" = (/obj/structure/table,/obj/machinery/vending/wallmed1{pixel_y = -32; req_access_txt = "0"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/security/prison) +"aqJ" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_3_berth_hatch"; locked = 1; name = "Escape Pod"; req_access = list(13)},/turf/simulated/floor/plating,/area/maintenance/security_starboard) "aqK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/security/prison) "aqL" = (/obj/structure/table,/obj/item/weapon/storage/box/cups,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/security/prison) "aqM" = (/obj/machinery/power/tracker,/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating/airless,/area/solar/fore) -"aqN" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/lobby) +"aqN" = (/obj/structure/bed/chair{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/lobby) "aqO" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/lobby) "aqP" = (/obj/machinery/door_control{id = "visitdoor"; name = "Visitation Access"; normaldoorcontrol = 1; pixel_y = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/lobby) "aqQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/security/lobby) @@ -877,7 +878,7 @@ "aqT" = (/turf/simulated/floor/plating/airless,/area/solar/fore) "aqU" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) "aqV" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) -"aqW" = (/obj/structure/stool/bed/chair/office/dark,/obj/effect/landmark/start{name = "Internal Affairs Agent"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) +"aqW" = (/obj/structure/disposalpipe/segment,/obj/structure/bed/chair/office/light{dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) "aqX" = (/obj/machinery/camera{c_tag = "Detective South"; dir = 1},/obj/machinery/computer/secure_data,/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) "aqY" = (/obj/structure/disposalpipe/segment,/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = -30},/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) "aqZ" = (/obj/structure/closet{name = "Evidence Closet"},/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/box/evidence,/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) @@ -890,11 +891,11 @@ "arg" = (/obj/structure/table,/obj/item/weapon/dice/d20,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/wood,/area/maintenance/dormitory) "arh" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "dorm_pump"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/maintenance/dormitory) "ari" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/dormitory) -"arj" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "dorm_airlock"; name = "Dormitory Airlock Console"; pixel_x = 25; pixel_y = 0; req_access_txt = "0"; req_one_access_txt = "1;5;11;18;24"; tag_airpump = "dorm_pump"; tag_chamber_sensor = "dorm_sensor"; tag_exterior_door = "dorm_outer"; tag_interior_door = "dorm_inner"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/maintenance/dormitory) +"arj" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_command{id_tag = "HoSdoor"; name = "Head of Security"; req_access = list(58)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/crew_quarters/heads/hos) "ark" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/evahallway) -"arl" = (/obj/structure/stool,/obj/effect/decal/cleanable/dirt,/obj/machinery/camera{c_tag = "Solitary Confinement South"; dir = 2; network = list("SS13","Prison")},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/plating,/area/security/brig) +"arl" = (/obj/structure/bed/chair/office/light,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/security/detectives_office) "arm" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/brig) -"arn" = (/obj/machinery/door_control{id = "Cell 1"; name = "Cell 1 Door"; pixel_x = 30; pixel_y = 1; req_access_txt = "2"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/security/brig) +"arn" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/table/rack,/obj/machinery/door/window/brigdoor{dir = 1; name = "Weapons locker"; req_access = list(3)},/obj/random/handgun,/obj/random/handgun,/obj/random/handgun,/obj/random/handgun,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/security/warden) "aro" = (/obj/structure/closet/secure_closet/brig{id = "Cell 2"; name = "Cell 2 Locker"},/obj/machinery/camera{c_tag = "Brig Cell 1"; dir = 2; network = list("SS13","Prison")},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison) "arp" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/prison) "arq" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/security/prison) @@ -902,14 +903,14 @@ "ars" = (/obj/structure/table,/obj/item/weapon/deck,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) "art" = (/obj/structure/table,/obj/item/weapon/newspaper,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/prison) "aru" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor,/area/security/prison) -"arv" = (/obj/machinery/door/airlock{name = "Visitation Area"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) +"arv" = (/obj/structure/table/rack,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/window/brigdoor{dir = 1; name = "Weapons locker"; req_access = list(3)},/obj/item/clothing/suit/storage/vest/heavy/officer,/obj/item/clothing/suit/storage/vest/heavy/officer,/obj/item/clothing/suit/storage/vest/heavy/officer,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/security/warden) "arw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/security/prison) "arx" = (/turf/simulated/wall/r_wall,/area/security/lobby) -"ary" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; layer = 3.3; master_tag = "brig_solar_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "13"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating/airless,/area/solar/fore) -"arz" = (/obj/machinery/door/airlock{id_tag = "visitdoor"; name = "Visitation Area"; req_access_txt = "63"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/lobby) +"ary" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/effect/decal/cleanable/blood/oil,/turf/simulated/floor/plating,/area/maintenance/security_starboard) +"arz" = (/obj/structure/closet/crate/secure{name = "FOR DISPOSAL"; req_access = list(58)},/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/balaclava,/obj/effect/decal/cleanable/cobweb2,/obj/item/clothing/mask/muzzle,/obj/item/weapon/reagent_containers/ld50_syringe/choral,/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/security_port) "arA" = (/turf/simulated/wall/r_wall,/area/hallway/primary/fore) "arB" = (/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating/airless,/area/solar/fore) -"arC" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/maintenance{name = "Security Maintenance"; req_access_txt = "1"},/turf/simulated/floor/plating,/area/security/brig) +"arC" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/maintenance{name = "Security Maintenance"; req_access = list(1)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/security/main) "arD" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating/airless,/area/solar/fore) "arE" = (/turf/simulated/wall,/area/hallway/primary/fore) "arF" = (/obj/structure/closet{name = "Evidence Closet"},/obj/machinery/door_control{id = "lawyer_blast"; name = "Privacy Shutters"; pixel_y = -25},/obj/item/device/taperecorder{pixel_x = -4; pixel_y = 2},/obj/item/device/camera{pixel_x = 3; pixel_y = -4},/obj/item/device/flash,/obj/item/device/flash,/obj/item/weapon/storage/secure/briefcase,/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) @@ -919,22 +920,22 @@ "arJ" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/dormitory) "arK" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/dormitory) "arL" = (/turf/simulated/floor/wood{icon_state = "wood-broken4"},/area/maintenance/dormitory) -"arM" = (/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 1},/turf/simulated/floor/wood,/area/maintenance/dormitory) +"arM" = (/obj/structure/bed/chair{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "redcorner"},/area/security/lobby) "arN" = (/obj/machinery/vending/cigarette,/turf/simulated/floor/wood,/area/maintenance/dormitory) -"arO" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "dorm_inner"; locked = 1; name = "Dormitory Internal Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/dormitory) -"arP" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "dorm_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "13"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating/airless,/area/maintenance/dormitory) -"arQ" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plating,/area/maintenance/evahallway) +"arO" = (/obj/structure/table,/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/item/weapon/storage/box/donut,/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/security/main) +"arP" = (/obj/structure/table/rack,/obj/structure/window/reinforced,/obj/machinery/door/window/brigdoor{dir = 1; name = "Weapons locker"; req_access = list(3)},/obj/structure/window/reinforced{dir = 4},/obj/item/clothing/suit/armor/laserproof{pixel_x = 2; pixel_y = 2},/obj/item/clothing/suit/armor/laserproof{pixel_x = -2; pixel_y = -2},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) +"arQ" = (/obj/structure/bed/chair/office/dark,/obj/effect/landmark/start{name = "Internal Affairs Agent"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice) "arR" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/security/brig) -"arS" = (/obj/machinery/door/airlock/glass_security{name = "Solitary Confinement 1"; req_access_txt = "2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/brig) +"arS" = (/obj/structure/table/rack,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/brigdoor{dir = 1; name = "Weapons locker"; req_access = list(3)},/obj/item/clothing/suit/armor/bulletproof{pixel_x = 2; pixel_y = 2},/obj/item/clothing/suit/armor/bulletproof{pixel_x = -2; pixel_y = -2},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/warden) "arT" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/security/brig) "arU" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/brig) "arV" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/status_display{density = 0; layer = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "arW" = (/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison) "arX" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "arY" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/prison) -"arZ" = (/obj/effect/decal/cleanable/dirt,/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor,/area/security/prison) -"asa" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor,/area/security/prison) -"asb" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/prison) +"arZ" = (/obj/item/weapon/stool,/obj/effect/decal/cleanable/dirt,/obj/machinery/camera{c_tag = "Solitary Confinement South"; dir = 2; network = list("SS13","Prison")},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/plating,/area/security/brig) +"asa" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 1},/turf/simulated/floor/wood,/area/maintenance/dormitory) +"asb" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor/plating,/area/maintenance/evahallway) "asc" = (/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor,/area/security/prison) "asd" = (/obj/machinery/flasher{id = "IAflash"; pixel_x = -30; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/prison) "ase" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) @@ -946,7 +947,7 @@ "ask" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/hallway/primary/fore) "asl" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/maintenance/dormitory) "asm" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/dormitory) -"asn" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/maintenance/dormitory) +"asn" = (/obj/machinery/door_control{id = "Armoury"; name = "Emergency Access"; pixel_x = -28; pixel_y = 4; req_access = list(3)},/turf/simulated/floor,/area/security/main) "aso" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/dormitory) "asp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/dormitory) "asq" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/dormitory) @@ -957,33 +958,33 @@ "asv" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/dormitory) "asw" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/maintenance/dormitory) "asx" = (/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/maintenance/dormitory) -"asy" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "dorm_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = 25; req_access_txt = "13"},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"; nitrogen = 0.01; oxygen = 0.01},/area/maintenance/dormitory) +"asy" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/floor,/area/security/prison) "asz" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air/airlock,/obj/effect/decal/cleanable/cobweb2,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/maintenance/dormitory) "asA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/arrivals) -"asB" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "arrivals_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/maintenance/arrivals) +"asB" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Briefing Room"; req_access = list(63)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/main) "asC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/evahallway) "asD" = (/obj/structure/table,/obj/item/device/radio/intercom{broadcasting = 1; freerange = 0; frequency = 1475; listening = 0; name = "Station Intercom (Security)"; pixel_x = 0; pixel_y = -30},/obj/item/device/radio/headset,/obj/item/device/radio/headset,/obj/item/device/radio/headset,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "red"; dir = 10},/area/security/brig) "asE" = (/obj/item/device/radio/intercom{pixel_x = 30},/obj/machinery/door_timer/cell_1{pixel_x = 32; pixel_y = -32},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "red"; dir = 6},/area/security/brig) -"asF" = (/obj/structure/stool/bed,/obj/machinery/flasher{id = "Cell 1"; pixel_x = 0; pixel_y = -28},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison) +"asF" = (/obj/effect/decal/cleanable/dirt,/obj/structure/bed/chair{dir = 1},/turf/simulated/floor,/area/security/prison) "asG" = (/obj/machinery/portable_atmospherics/powered/scrubber/huge,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/brig) "asH" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/security/prison) "asI" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/security/prison) "asJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/prison) "asK" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/machinery/newscaster{pixel_x = 28; pixel_y = 1},/turf/simulated/floor,/area/security/prison) "asL" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) -"asM" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) +"asM" = (/obj/structure/bed/chair{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/prison) "asN" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/primary/central_one) -"asO" = (/obj/structure/stool/bed/chair{dir = 8},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor,/area/security/prison) -"asP" = (/obj/machinery/flasher_button{id = "IAflash"; pixel_y = -30},/obj/machinery/door_control{id = "visit_blast"; name = "Privacy Shutters"; pixel_x = 25; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/security/prison) +"asO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/highsecurity{name = "Secure Armoury Section"; req_access = list(3)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/security/warden) +"asP" = (/obj/structure/bed,/obj/machinery/flasher{id = "Cell 1"; pixel_x = 0; pixel_y = -28},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison) "asQ" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/hallway/primary/fore) "asR" = (/obj/machinery/bot/secbot/beepsky{name = "Officer Beepsky"},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/fore) "asS" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/hallway/primary/fore) "asT" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/maintenance/dormitory) "asU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/dormitory) "asV" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/dormitory) -"asW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/maintenance/dormitory) -"asX" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor/plating,/area/maintenance/dormitory) -"asY" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/dormitory) +"asW" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/glass{name = "Hydroponics Pasture"; req_access = list(28)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"asX" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/port) +"asY" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/hallway/primary/port) "asZ" = (/turf/simulated/wall/r_wall,/area/maintenance/dormitory) "ata" = (/obj/machinery/portable_atmospherics/powered/pump,/turf/simulated/floor/plating,/area/maintenance/dormitory) "atb" = (/obj/structure/table/rack{dir = 1},/obj/item/weapon/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/device/flashlight,/turf/simulated/floor/plating,/area/maintenance/dormitory) @@ -991,10 +992,10 @@ "atd" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating,/area/maintenance/dormitory) "ate" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating,/area/maintenance/dormitory) "atf" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/dormitory) -"atg" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/crew_quarters/fitness) -"ath" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/crew_quarters/fitness) -"ati" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/effect/landmark{name = "Syndicate Breach Area"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/crew_quarters/fitness) -"atj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"atg" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) +"ath" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor,/area/security/prison) +"ati" = (/obj/machinery/button/flasher{id = "IAflash"; pixel_y = -30},/obj/machinery/door_control{id = "visit_blast"; name = "Privacy Shutters"; pixel_x = 25; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/security/prison) +"atj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/crew_quarters/fitness) "atk" = (/turf/simulated/shuttle/wall{icon_state = "swall_s6"; dir = 2},/area/shuttle/escape_pod1/station) "atl" = (/obj/structure/window/shuttle,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/escape_pod1/station) "atm" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/shuttle/escape_pod1/station) @@ -1002,7 +1003,7 @@ "ato" = (/obj/structure/window/shuttle,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/escape_pod2/station) "atp" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/shuttle/escape_pod2/station) "atq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/arrivals) -"atr" = (/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"; nitrogen = 0.01; oxygen = 0.01},/area/maintenance/arrivals) +"atr" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/effect/landmark{name = "Syndicate Breach Area"},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/crew_quarters/fitness) "ats" = (/obj/structure/table/rack,/obj/item/weapon/flame/lighter/random,/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,/turf/simulated/floor/plating,/area/maintenance/evahallway) "att" = (/obj/item/weapon/cigbutt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/evahallway) "atu" = (/obj/machinery/washing_machine,/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/security/prison) @@ -1027,14 +1028,14 @@ "atN" = (/turf/simulated/wall/r_wall,/area/crew_quarters/fitness) "atO" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/crew_quarters/fitness) "atP" = (/turf/simulated/wall,/area/crew_quarters/fitness) -"atQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"atQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/camera{c_tag = "Holodeck North"; dir = 2; network = list("SS13"); pixel_y = -6},/turf/simulated/floor/plating,/area/crew_quarters/fitness) "atR" = (/turf/simulated/floor/engine{name = "Holodeck Projector Floor"},/area/holodeck/alphadeck) "atS" = (/turf/simulated/wall/r_wall,/area/hallway/secondary/entry/fore) "atT" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/shuttle/escape_pod1/station) -"atU" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod{frequency = 1380; id_tag = "escape_pod_1"; pixel_x = -25; pixel_y = 0; req_access_txt = "0"; req_one_access_txt = "0"; tag_door = "escape_pod_1_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod1/station) +"atU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/crew_quarters/fitness) "atV" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/shuttle/escape_pod2/station) -"atW" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod{frequency = 1380; id_tag = "escape_pod_2"; pixel_x = -25; pixel_y = 0; req_access_txt = "0"; req_one_access_txt = "0"; tag_door = "escape_pod_2_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod2/station) -"atX" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "arrivals_pump"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "arrivals_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "arrivals_pump"; tag_exterior_door = "arrivals_outer"; frequency = 1379; id_tag = "arrivals_airlock"; tag_interior_door = "arrivals_inner"; pixel_x = 25; req_access_txt = "13"; tag_chamber_sensor = "arrivals_sensor"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/arrivals) +"atW" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/arrivals) +"atX" = (/obj/machinery/door/airlock{name = "Kitchen cold room"; req_access = list(28)},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "atY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/plating,/area/maintenance/arrivals) "atZ" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 6},/turf/simulated/wall,/area/maintenance/evahallway) "aua" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating,/area/maintenance/evahallway) @@ -1045,20 +1046,20 @@ "auf" = (/turf/simulated/floor{icon_state = "freezerfloor"},/area/security/prison) "aug" = (/obj/structure/urinal{pixel_y = 32},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "freezerfloor"},/area/security/prison) "auh" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "freezerfloor"},/area/security/prison) -"aui" = (/obj/machinery/door/airlock{name = "Brig Restroom"; req_access_txt = "0"},/turf/simulated/floor,/area/security/prison) +"aui" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Kitchen"; req_access = list(28)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "auj" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor,/area/security/prison) "auk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/security/prison) "aul" = (/obj/structure/closet{name = "Prisoner's Locker"},/obj/item/weapon/flame/lighter/zippo,/obj/item/weapon/storage/fancy/cigarettes,/turf/simulated/floor,/area/security/prison) -"aum" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/orange,/obj/machinery/camera{c_tag = "Bedroom"; dir = 6; network = list("SS13","Prison")},/turf/simulated/floor,/area/security/prison) +"aum" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/light{dir = 4; icon_state = "tube1"; pixel_x = -6},/turf/simulated/floor/plating,/area/crew_quarters/fitness) "aun" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/computer/cryopod{density = 0; layer = 3.3; pixel_y = 32},/obj/machinery/light_switch{pixel_x = -25; pixel_y = 24},/turf/simulated/floor,/area/security/prison) -"auo" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/orange,/obj/effect/decal/cleanable/generic,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) +"auo" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Kitchen"; req_access = list(28)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/hydroponics/garden) "aup" = (/obj/structure/closet{name = "Prisoner's Locker"},/obj/random/tech_supply,/obj/item/clothing/head/flatcap,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) "auq" = (/obj/machinery/atm{pixel_x = -25},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/hallway/primary/fore) "aur" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/fore) "aus" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/hallway/primary/fore) "aut" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor,/area/security/prison) -"auu" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/unary/vent_pump/on,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) -"auv" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/mime,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) +"auu" = (/obj/machinery/door/window/northright{base_state = "right"; dir = 8; icon_state = "right"; name = "Library Desk Door"; req_access = list(37)},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/library) +"auv" = (/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/obj/machinery/camera{c_tag = "Bedroom"; dir = 6; network = list("SS13","Prison")},/turf/simulated/floor,/area/security/prison) "auw" = (/obj/structure/closet/secure_closet/personal,/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/crew_quarters/fitness) "aux" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "neutral"; dir = 9},/area/crew_quarters/sleep) "auy" = (/obj/machinery/alarm{pixel_y = 23},/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor{icon_state = "neutral"; dir = 5},/area/crew_quarters/sleep) @@ -1073,15 +1074,15 @@ "auH" = (/turf/simulated/floor/beach/water{tag = "icon-seadeep"; icon_state = "seadeep"},/area/crew_quarters/fitness) "auI" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/beach/water{tag = "icon-seadeep"; icon_state = "seadeep"},/area/crew_quarters/fitness) "auJ" = (/obj/structure/window/basic{dir = 4},/turf/simulated/floor/beach/water{tag = "icon-seadeep"; icon_state = "seadeep"},/area/crew_quarters/fitness) -"auK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/stool/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) -"auL" = (/obj/machinery/vending/cola,/turf/simulated/floor{icon_state = "neutral"; dir = 5},/area/crew_quarters/fitness) -"auM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"auK" = (/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/obj/effect/decal/cleanable/generic,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) +"auL" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) +"auM" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) "auN" = (/turf/simulated/wall,/area/hallway/secondary/entry/fore) -"auO" = (/obj/structure/stool/bed/chair{dir = 1},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod1/station) -"auP" = (/obj/structure/stool/bed/chair{dir = 1},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod2/station) +"auO" = (/turf/simulated/floor{icon_state = "neutral"; dir = 5},/area/crew_quarters/fitness) +"auP" = (/obj/machinery/light{dir = 1},/obj/machinery/vending/cola,/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/crew_quarters/fitness) "auQ" = (/turf/simulated/wall,/area/maintenance/arrivals) "auR" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/arrivals) -"auS" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "arrivals_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/arrivals) +"auS" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "nuke_shuttle_dock_outer"; locked = 1; name = "Docking Port Airlock"; req_access = list(13)},/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) "auT" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area/maintenance/arrivals) "auU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/arrivals) "auV" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/arrivals) @@ -1091,7 +1092,7 @@ "auZ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "freezerfloor"},/area/security/prison) "ava" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/structure/mirror{pixel_x = 30},/turf/simulated/floor{icon_state = "freezerfloor"},/area/security/prison) "avb" = (/obj/structure/table,/obj/item/weapon/paper_bin,/obj/machinery/camera{c_tag = "Common Brig Southwest"; dir = 4; network = list("SS13")},/obj/item/weapon/pen,/turf/simulated/floor,/area/security/prison) -"avc" = (/obj/structure/stool,/turf/simulated/floor,/area/security/prison) +"avc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/crew_quarters/fitness) "avd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor,/area/security/prison) "ave" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/prison) "avf" = (/obj/machinery/door/airlock/glass{name = "Brig Dormitories"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/prison) @@ -1101,7 +1102,7 @@ "avj" = (/obj/structure/cryofeed,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) "avk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green,/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/hallway/primary/fore) "avl" = (/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/hallway/primary/fore) -"avm" = (/obj/machinery/light_switch{pixel_x = 22; pixel_y = 10},/obj/structure/stool/bed,/obj/item/weapon/bedsheet/mime,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) +"avm" = (/obj/structure/bed/chair{dir = 1},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod1/station) "avn" = (/turf/simulated/floor{icon_state = "neutralcorner"; dir = 4},/area/crew_quarters/sleep) "avo" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/carpet{tag = "icon-carpet3-0"; icon_state = "carpet3-0"},/area/crew_quarters/sleep/bedrooms) "avp" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/maintenance/dormitory) @@ -1113,30 +1114,30 @@ "avv" = (/turf/simulated/floor{dir = 2; icon_state = "whitecorner"},/area/crew_quarters/fitness) "avw" = (/turf/simulated/floor{icon_state = "escapecorner"; dir = 8},/area/crew_quarters/fitness) "avx" = (/turf/simulated/floor,/area/crew_quarters/fitness) -"avy" = (/obj/machinery/light{dir = 1},/obj/structure/stool,/turf/simulated/floor{icon_state = "red"; dir = 4},/area/crew_quarters/fitness) -"avz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/crew_quarters/fitness) -"avA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"avy" = (/obj/structure/bed/chair{dir = 1},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod2/station) +"avz" = (/obj/item/weapon/stool,/turf/simulated/floor,/area/security/prison) +"avA" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) "avB" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst,/turf/simulated/shuttle/wall{icon_state = "swall_f5"; dir = 2},/area/shuttle/escape_pod1/station) -"avC" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_1_hatch"; locked = 1; name = "Escape Pod Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod1/station) +"avC" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "nuke_shuttle_dock_inner"; locked = 1; name = "Docking Port Airlock"; req_access = list(13)},/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) "avD" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst,/turf/simulated/shuttle/wall{icon_state = "swall_f9"; dir = 2},/area/shuttle/escape_pod1/station) "avE" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst,/turf/simulated/shuttle/wall{icon_state = "swall_f5"; dir = 2},/area/shuttle/escape_pod2/station) -"avF" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_2_hatch"; locked = 1; name = "Escape Pod Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod2/station) +"avF" = (/obj/machinery/door/morgue{dir = 2; name = "Private Study"; req_access = list(37)},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/library) "avG" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst,/turf/simulated/shuttle/wall{icon_state = "swall_f9"; dir = 2},/area/shuttle/escape_pod2/station) "avH" = (/turf/simulated/floor/plating,/area/maintenance/arrivals) "avI" = (/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/maintenance/arrivals) -"avJ" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "arrivals_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = 25; req_access_txt = "13"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"; nitrogen = 0.01; oxygen = 0.01},/area/maintenance/arrivals) +"avJ" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) "avK" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/maintenance/arrivals) "avL" = (/obj/structure/table/rack,/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/turf/simulated/floor/plating,/area/maintenance/arrivals) "avM" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/arrivals) "avN" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/arrivals) "avO" = (/obj/machinery/space_heater,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plating,/area/maintenance/arrivals) "avP" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/central_one) -"avQ" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "eva_airlock"; name = "exterior access button"; pixel_x = 0; pixel_y = 25; req_access_txt = "13"},/turf/simulated/floor/plating/airless,/area/maintenance/evahallway) -"avR" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eva_outer"; locked = 1; name = "EVA External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/airless{icon_state = "circuit"},/area/maintenance/evahallway) +"avQ" = (/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/crew_quarters/fitness) +"avR" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/cobweb,/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plating,/area/maintenance/locker) "avS" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "eva_sensor"; pixel_x = 0; pixel_y = 25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "eva_pump"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/maintenance/evahallway) -"avT" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "eva_airlock"; name = "EVA Airlock Console"; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "1;5;11;18;24"; tag_airpump = "eva_pump"; tag_chamber_sensor = "eva_sensor"; tag_exterior_door = "eva_outer"; tag_interior_door = "eva_inner"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/maintenance/evahallway) -"avU" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eva_inner"; locked = 1; name = "EVA Internal Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/evahallway) -"avV" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "eva_airlock"; name = "interior access button"; pixel_x = 0; pixel_y = 25; req_access_txt = "13"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/evahallway) +"avT" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "nuke_shuttle_dock_airlock"; pixel_x = 0; pixel_y = 30; req_one_access = list(13); tag_airpump = "nuke_shuttle_dock_pump"; tag_chamber_sensor = "nuke_shuttle_dock_sensor"; tag_exterior_door = "nuke_shuttle_dock_outer"; tag_interior_door = "nuke_shuttle_dock_inner"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1; icon_state = "map"; tag = "icon-manifold-f (NORTH)"},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/hallway/secondary/entry/port) +"avU" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "nuke_shuttle_dock_inner"; locked = 1; name = "Docking Port Airlock"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) +"avV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/crew_quarters/fitness) "avW" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/evahallway) "avX" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/evahallway) "avY" = (/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = 0},/obj/structure/curtain/open/shower,/turf/simulated/floor{icon_state = "freezerfloor"},/area/security/prison) @@ -1146,17 +1147,17 @@ "awc" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/obj/item/weapon/storage/box/donkpockets{pixel_x = -3; pixel_y = -3},/turf/simulated/floor,/area/security/prison) "awd" = (/obj/structure/table,/obj/item/weapon/minihoe,/obj/item/device/analyzer/plant_analyzer,/obj/item/clothing/head/greenbandana,/turf/simulated/floor,/area/security/prison) "awe" = (/obj/machinery/vending/hydronutrients,/turf/simulated/floor,/area/security/prison) -"awf" = (/obj/machinery/vending/hydroseeds,/turf/simulated/floor,/area/security/prison) +"awf" = (/obj/item/weapon/stool,/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/crew_quarters/fitness) "awg" = (/obj/structure/table,/obj/structure/bedsheetbin,/turf/simulated/floor,/area/security/prison) "awh" = (/obj/structure/closet{name = "Prisoner's Locker"},/obj/item/clothing/head/soft/orange,/obj/item/clothing/shoes/sandal,/turf/simulated/floor,/area/security/prison) -"awi" = (/obj/machinery/light,/obj/structure/stool/bed,/obj/item/weapon/bedsheet/orange,/turf/simulated/floor,/area/security/prison) +"awi" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "nuke_shuttle_dock_airlock"; name = "interior access button"; pixel_x = -28; pixel_y = 25; req_one_access = list(13)},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry/port) "awj" = (/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) -"awk" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/orange,/turf/simulated/floor,/area/security/prison) +"awk" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Auxiliary Tool Storage"; req_access = list(12)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/port) "awl" = (/obj/structure/closet{name = "Prisoner's Locker"},/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe,/obj/item/clothing/suit/apron/overalls,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison) "awm" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/hallway/primary/fore) -"awn" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/hallway/primary/fore) -"awo" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) -"awp" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) +"awn" = (/obj/machinery/door/airlock{name = "Port Emergency Storage"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/hallway/primary/port) +"awo" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock{name = "Crematorium"; req_access = list(27)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) +"awp" = (/obj/machinery/seed_storage/garden,/turf/simulated/floor,/area/security/prison) "awq" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/hallway/secondary/entry/port) "awr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/crew_quarters/sleep) "aws" = (/obj/machinery/door/airlock/glass{name = "Cryogenic Storage"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "warnwhite"},/area/crew_quarters/sleep/cryo) @@ -1164,22 +1165,22 @@ "awu" = (/obj/machinery/door/airlock/glass{name = "Cryogenic Storage"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "warnwhite"},/area/crew_quarters/sleep/cryo) "awv" = (/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/structure/disposalpipe/segment,/obj/machinery/camera{c_tag = "Fitness Room West"; dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/crew_quarters/fitness) "aww" = (/turf/simulated/floor{dir = 6; icon_state = "whitehall"},/area/crew_quarters/fitness) -"awx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor{dir = 10; icon_state = "whitehall"},/area/crew_quarters/fitness) -"awy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/crew_quarters/fitness) -"awz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/crew_quarters/fitness) -"awA" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/crew_quarters/fitness) -"awB" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor,/area/crew_quarters/fitness) -"awC" = (/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/camera{c_tag = "Holodeck"},/turf/simulated/floor,/area/crew_quarters/fitness) -"awD" = (/obj/machinery/alarm{pixel_y = 24},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/crew_quarters/fitness) -"awE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"awx" = (/obj/machinery/light,/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/turf/simulated/floor,/area/security/prison) +"awy" = (/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/turf/simulated/floor,/area/security/prison) +"awz" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) +"awA" = (/turf/simulated/floor{dir = 10; icon_state = "whitehall"},/area/crew_quarters/fitness) +"awB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) +"awC" = (/obj/machinery/light_switch{pixel_x = 22; pixel_y = 10},/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) +"awD" = (/obj/machinery/door/airlock/glass{name = "Holodeck"},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor,/area/crew_quarters/fitness) +"awE" = (/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/crew_quarters/fitness) "awF" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "awG" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) "awH" = (/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) "awI" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) "awJ" = (/obj/structure/closet,/obj/item/weapon/storage/backpack,/turf/simulated/floor/plating,/area/maintenance/arrivals) "awK" = (/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plating,/area/maintenance/substation/security) -"awL" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/camera{c_tag = "Security Substation"; dir = 1; network = list("SS13","Engineering")},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/substation/security) -"awM" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) +"awL" = (/obj/item/weapon/stool{pixel_y = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/crew_quarters/sleep) +"awM" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/table/reinforced,/obj/item/weapon/book/manual/barman_recipes,/obj/item/clothing/head/that{pixel_x = 4; pixel_y = 6},/obj/item/weapon/screwdriver,/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "awN" = (/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/turf/simulated/floor/plating,/area/maintenance/arrivals) "awO" = (/obj/structure/table/reinforced,/obj/machinery/door/blast/shutters{dir = 2; id = "bar"; layer = 3.1; name = "Bar Shutters"},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "awP" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating/airless,/area/maintenance/evahallway) @@ -1190,7 +1191,7 @@ "awU" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/carpet{tag = "icon-carpet3-0"; icon_state = "carpet3-0"},/area/crew_quarters/sleep/bedrooms) "awV" = (/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/hallway/primary/fore) "awW" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 31},/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/hallway/primary/fore) -"awX" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) +"awX" = (/turf/simulated/floor{dir = 1; icon_state = "whitecorner"},/area/crew_quarters/fitness) "awY" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) "awZ" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "neutralcorner"; dir = 4},/area/crew_quarters/sleep) "axa" = (/obj/machinery/door/airlock{id_tag = "Dormitory 1"; name = "Dorm"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/wood,/area/crew_quarters/sleep) @@ -1208,20 +1209,20 @@ "axm" = (/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/fitness) "axn" = (/obj/structure/window/basic{dir = 1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/fitness) "axo" = (/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/fitness) -"axp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/fitness) -"axq" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/crew_quarters/fitness) -"axr" = (/obj/structure/stool,/turf/simulated/floor{icon_state = "red"; dir = 4},/area/crew_quarters/fitness) +"axp" = (/obj/item/weapon/stool{pixel_y = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/crew_quarters/sleep) +"axq" = (/obj/item/weapon/stool{pixel_y = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor,/area/crew_quarters/sleep) +"axr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/crew_quarters/fitness) "axs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/crew_quarters/fitness) -"axt" = (/obj/machinery/computer/HolodeckControl,/turf/simulated/floor,/area/crew_quarters/fitness) -"axu" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor,/area/crew_quarters/fitness) -"axv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/crew_quarters/fitness) -"axw" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_1_berth_hatch"; locked = 1; name = "Escape Pod"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) +"axt" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor,/area/crew_quarters/fitness) +"axu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/camera{c_tag = "Fitness Room East"; dir = 1},/turf/simulated/floor,/area/crew_quarters/fitness) +"axv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"axw" = (/obj/machinery/door/window/eastright{name = "Hydroponics Delivery"; icon_state = "right"; dir = 2; req_access = list(35)},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) "axx" = (/obj/structure/sign/pods,/turf/simulated/wall,/area/hallway/secondary/entry/fore) -"axy" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_2_berth_hatch"; locked = 1; name = "Escape Pod"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) +"axy" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/central_one) "axz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/power/apc/high{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry/port) "axA" = (/obj/machinery/camera{c_tag = "Arrivals East"; dir = 8; network = list("SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry/port) "axB" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) -"axC" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_tool_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) +"axC" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_command{name = "E.V.A."; req_one_access = list(1,11,18,24)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central_one) "axD" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/evahallway) "axE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/evahallway) "axF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/evahallway) @@ -1233,12 +1234,12 @@ "axL" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/maintenance/evahallway) "axM" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/evahallway) "axN" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/plating,/area/maintenance/evahallway) -"axO" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/fore) +"axO" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_command{name = "E.V.A."; req_one_access = list(1,11,18,24)},/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central_one) "axP" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/fore) "axQ" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/disposalpipe/junction{icon_state = "pipe-j2"; dir = 4},/turf/simulated/floor,/area/hallway/primary/fore) "axR" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "bluecorner"},/area/hallway/primary/fore) "axS" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/structure/closet/secure_closet/personal,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) -"axT" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) +"axT" = (/obj/machinery/hologram/holopad,/obj/machinery/light,/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/crew_quarters/fitness) "axU" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/closet/secure_closet/personal,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) "axV" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/crew_quarters/sleep) "axW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/crew_quarters/sleep) @@ -1246,17 +1247,17 @@ "axY" = (/obj/structure/table/woodentable,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/crew_quarters/sleep) "axZ" = (/obj/structure/table/woodentable,/obj/item/clothing/glasses/threedglasses,/turf/simulated/floor,/area/crew_quarters/sleep) "aya" = (/obj/structure/table/woodentable,/obj/item/weapon/coin/silver,/turf/simulated/floor,/area/crew_quarters/sleep) -"ayb" = (/obj/structure/stool{pixel_y = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/crew_quarters/sleep) +"ayb" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/unary/vent_pump/on,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) "ayc" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) "ayd" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Fitness"},/turf/simulated/floor,/area/crew_quarters/fitness) "aye" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/crew_quarters/fitness) "ayf" = (/turf/simulated/floor{dir = 4; icon_state = "escapecorner"},/area/crew_quarters/fitness) "ayg" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/crew_quarters/fitness) "ayh" = (/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/crew_quarters/fitness) -"ayi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 1; icon_state = "whitecorner"},/area/crew_quarters/fitness) -"ayj" = (/obj/structure/stool,/turf/simulated/floor{icon_state = "green"; dir = 4},/area/crew_quarters/fitness) +"ayi" = (/obj/item/weapon/stool{pixel_y = 8},/turf/simulated/floor,/area/crew_quarters/sleep) +"ayj" = (/obj/item/weapon/stool{pixel_y = 8},/turf/simulated/floor{icon_state = "neutralcorner"; dir = 2},/area/crew_quarters/sleep) "ayk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/crew_quarters/fitness) -"ayl" = (/obj/structure/table,/obj/item/weapon/paper{desc = ""; info = "Brusies sustained in the holodeck can be healed simply by sleeping."; name = "Holodeck Disclaimer"},/turf/simulated/floor,/area/crew_quarters/fitness) +"ayl" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "neutralcorner"},/area/crew_quarters/fitness) "aym" = (/turf/simulated/floor/airless{icon_state = "catwalk12"},/area/space) "ayn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) "ayo" = (/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry/fore) @@ -1270,7 +1271,7 @@ "ayw" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "arrival"; dir = 5},/area/hallway/secondary/entry/fore) "ayx" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/checkpoint2) "ayy" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) -"ayz" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "solar_tool_pump"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_tool_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "solar_tool_pump"; tag_exterior_door = "solar_tool_outer"; frequency = 1379; id_tag = "solar_tool_airlock"; tag_interior_door = "solar_tool_inner"; pixel_x = 25; req_access_txt = "13"; tag_chamber_sensor = "solar_tool_sensor"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/decal/warning_stripes,/turf/simulated/floor/plating,/area/maintenance/auxsolarport) +"ayz" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/port) "ayA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "ayB" = (/obj/effect/decal/cleanable/cobweb,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/maintenance/evahallway) "ayC" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/evahallway) @@ -1284,7 +1285,7 @@ "ayK" = (/obj/effect/decal/cleanable/blood/oil,/turf/simulated/floor/plating,/area/maintenance/evahallway) "ayL" = (/turf/simulated/wall/r_wall,/area/ai_monitored/storage/eva) "ayM" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/ai_monitored/storage/eva) -"ayN" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "E.V.A. Maintenance"; req_one_access_txt = "1;5;11;18;24"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/ai_monitored/storage/eva) +"ayN" = (/obj/structure/closet/coffin,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "chapel"; name = "Privacy Shutters"; opacity = 0},/obj/machinery/door/window/eastleft{dir = 8; name = "Coffin Storage"; req_access = list(22)},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) "ayO" = (/obj/machinery/camera{c_tag = "Fore Primary Hallway"; dir = 4; network = list("SS13")},/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/fore) "ayP" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/primary/fore) "ayQ" = (/turf/simulated/floor{icon_state = "bluecorner"},/area/hallway/primary/fore) @@ -1292,27 +1293,27 @@ "ayS" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/machinery/camera{c_tag = "Dormitory Bedroom Fore"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/carpet{tag = "icon-carpet2-0"; icon_state = "carpet2-0"},/area/crew_quarters/sleep/bedrooms) "ayT" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/crew_quarters/sleep) "ayU" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/crew_quarters/sleep) -"ayV" = (/obj/structure/stool{pixel_y = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/crew_quarters/sleep) +"ayV" = (/obj/structure/closet/lasertag/blue,/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/crew_quarters/fitness) "ayW" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/crew_quarters/sleep) "ayX" = (/obj/structure/table/woodentable,/obj/item/device/paicard,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor,/area/crew_quarters/sleep) "ayY" = (/obj/structure/table/woodentable,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/crew_quarters/sleep) -"ayZ" = (/obj/structure/stool{pixel_y = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor,/area/crew_quarters/sleep) +"ayZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/glass{name = "Holodeck Control"},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor,/area/crew_quarters/fitness) "aza" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/crew_quarters/sleep) "azb" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Fitness"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/crew_quarters/fitness) "azc" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/crew_quarters/fitness) "azd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/crew_quarters/fitness) "aze" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/crew_quarters/fitness) "azf" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/crew_quarters/fitness) -"azg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/crew_quarters/fitness) -"azh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/crew_quarters/fitness) -"azi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "green"; dir = 4},/area/crew_quarters/fitness) -"azj" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/crew_quarters/fitness) -"azk" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/crew_quarters/fitness) -"azl" = (/obj/machinery/light/small,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/crew_quarters/fitness) -"azm" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/crew_quarters/fitness) -"azn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"azg" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Hydroponics Maintenance"; req_access = list(35)},/obj/machinery/door/firedoor,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/hydroponics) +"azh" = (/obj/machinery/light_switch{pixel_y = -25},/obj/structure/undies_wardrobe,/turf/simulated/floor{icon_state = "neutral"},/area/crew_quarters/sleep) +"azi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor,/area/crew_quarters/fitness) +"azj" = (/obj/structure/grille,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"azk" = (/obj/structure/table,/obj/item/weapon/paper{desc = ""; info = "Brusies sustained in the holodeck can be healed simply by sleeping."; name = "Holodeck Disclaimer"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor,/area/crew_quarters/fitness) +"azl" = (/obj/item/weapon/stool{pixel_y = 8},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) +"azm" = (/obj/item/weapon/stool{pixel_y = 8},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) +"azn" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) "azo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) -"azp" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_chapel_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/obj/effect/decal/cleanable/dirt,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) +"azp" = (/obj/machinery/door/window/southleft{base_state = "left"; dir = 2; icon_state = "left"; name = "Kitchen Delivery"; req_access = list(28)},/turf/simulated/floor{icon_state = "delivery"},/area/crew_quarters/kitchen) "azq" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) "azr" = (/turf/simulated/floor{icon_state = "warning"},/area/hallway/secondary/entry/fore) "azs" = (/turf/simulated/floor,/area/hallway/secondary/entry/fore) @@ -1324,11 +1325,11 @@ "azy" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "warning"},/area/hallway/secondary/entry/fore) "azz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "warning"},/area/hallway/secondary/entry/fore) "azA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/hallway/secondary/entry/fore) -"azB" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry/fore) -"azC" = (/obj/structure/stool/bed/chair/office/dark,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/checkpoint2) +"azB" = (/obj/machinery/door/airlock/maintenance{name = "Bar Maintenance"; req_one_access = list(12,25,28)},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/crew_quarters/bar) +"azC" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/light/small{dir = 4},/obj/machinery/light_switch{pixel_x = 22; pixel_y = 10},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) "azD" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "azE" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) -"azF" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_tool_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) +"azF" = (/obj/machinery/door/airlock{name = "Bar Backroom"; req_access = list(25)},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/crew_quarters/bar) "azG" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "azH" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "azI" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/evahallway) @@ -1343,34 +1344,34 @@ "azR" = (/obj/structure/sign/securearea{pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plating,/area/maintenance/evahallway) "azS" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) "azT" = (/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) -"azU" = (/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Medical Hardsuits"; req_access_txt = "5"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) +"azU" = (/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/hallway/primary/central_two) "azV" = (/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/ai_monitored/storage/eva) "azW" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/ai_monitored/storage/eva) "azX" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/ai_monitored/storage/eva) "azY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/ai_monitored/storage/eva) "azZ" = (/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/ai_monitored/storage/eva) "aAa" = (/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/ai_monitored/storage/eva) -"aAb" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_security{name = "Security Hardsuits"; req_access_txt = "1"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) +"aAb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/engineering{name = "Civilian West Substation"; req_one_access = list(11,24)},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_west) "aAc" = (/obj/structure/table/rack,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/void/security,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/void/security,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/ai_monitored/storage/eva) "aAd" = (/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/fore) "aAe" = (/turf/simulated/floor/carpet{tag = "icon-carpet2-0"; icon_state = "carpet2-0"},/area/crew_quarters/sleep/bedrooms) -"aAf" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) +"aAf" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor,/area/crew_quarters/fitness) "aAg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet{tag = "icon-carpet3-0"; icon_state = "carpet3-0"},/area/crew_quarters/sleep/bedrooms) "aAh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) "aAi" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/dormitory) -"aAj" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor,/area/crew_quarters/sleep) -"aAk" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor{icon_state = "neutralcorner"; dir = 2},/area/crew_quarters/sleep) +"aAj" = (/obj/structure/grille,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"aAk" = (/obj/machinery/computer/HolodeckControl,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/crew_quarters/fitness) "aAl" = (/obj/machinery/light,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -27},/turf/simulated/floor{icon_state = "neutral"},/area/crew_quarters/sleep) "aAm" = (/turf/simulated/floor{icon_state = "neutral"},/area/crew_quarters/sleep) "aAn" = (/turf/simulated/floor{icon_state = "neutral"; dir = 6},/area/crew_quarters/sleep) "aAo" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_x = -2; pixel_y = -28},/turf/simulated/floor{dir = 10; icon_state = "neutral"},/area/crew_quarters/fitness) "aAp" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/crew_quarters/fitness) "aAq" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/crew_quarters/fitness) -"aAr" = (/obj/machinery/camera{c_tag = "Fitness Room East"; dir = 1},/obj/machinery/light,/obj/structure/stool,/turf/simulated/floor{icon_state = "green"; dir = 4},/area/crew_quarters/fitness) -"aAs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/crew_quarters/fitness) -"aAt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"aAr" = (/obj/machinery/camera{c_tag = "Fore Starboard Solars"; dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Solar - Fore Starboard"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) +"aAs" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Solar - Fore Port"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) +"aAt" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) "aAu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) -"aAv" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "solar_chapel_pump"; tag_exterior_door = "solar_chapel_outer"; frequency = 1379; id_tag = "solar_chapel_airlock"; tag_interior_door = "solar_chapel_inner"; pixel_x = 25; req_access_txt = "13"; tag_chamber_sensor = "solar_chapel_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_chapel_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "solar_chapel_pump"},/obj/effect/decal/cleanable/dirt,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/decal/warning_stripes,/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) +"aAv" = (/obj/machinery/door/window{dir = 4; name = "Bar"; req_access = list(25)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aAw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) "aAx" = (/obj/machinery/door/airlock/external{name = "Arrival Airlock"},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) "aAy" = (/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry/fore) @@ -1382,7 +1383,7 @@ "aAE" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/arrivals) "aAF" = (/turf/simulated/wall/r_wall,/area/maintenance/auxsolarport) "aAG" = (/obj/machinery/power/solar_control{id = "auxsolareast"; name = "Fore Port Solar Control"; track = 0},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) -"aAH" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "solar_tool_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "13"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) +"aAH" = (/obj/effect/landmark/start{name = "Bartender"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/mob/living/carbon/human/monkey/punpun,/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aAI" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "aAJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/evahallway) "aAK" = (/obj/structure/closet/emcloset,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/evahallway) @@ -1400,30 +1401,30 @@ "aAW" = (/obj/structure/table/reinforced,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/ai_monitored/storage/eva) "aAX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/ai_monitored/storage/eva) "aAY" = (/turf/simulated/floor/carpet{tag = "icon-carpet3-0"; icon_state = "carpet3-0"},/area/crew_quarters/sleep/bedrooms) -"aAZ" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/mime,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) -"aBa" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/light/small{dir = 4},/obj/machinery/light_switch{pixel_x = 22; pixel_y = 10},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) +"aAZ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"aBa" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/camera{c_tag = "Holodeck South"; dir = 1; pixel_y = 6},/turf/simulated/floor/plating,/area/crew_quarters/fitness) "aBb" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock{id_tag = "Dormitory 2"; name = "Dorm"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/sleep) "aBc" = (/obj/machinery/camera{c_tag = "Dormitory Bedroom Aft"; dir = 1},/turf/simulated/floor/carpet{tag = "icon-carpet1-0"; icon_state = "carpet1-0"},/area/crew_quarters/sleep/bedrooms) "aBd" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "neutralcorner"; dir = 2},/area/crew_quarters/sleep) "aBe" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/flora/pottedplant{tag = "icon-plant-22"; icon_state = "plant-22"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{icon_state = "neutral"},/area/crew_quarters/sleep) -"aBf" = (/obj/machinery/light_switch{pixel_y = -25},/obj/structure/closet/secure_closet/personal,/turf/simulated/floor{icon_state = "neutral"},/area/crew_quarters/sleep) +"aBf" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/crew_quarters/fitness) "aBg" = (/obj/structure/closet/secure_closet/personal,/turf/simulated/floor{icon_state = "neutral"},/area/crew_quarters/sleep) "aBh" = (/obj/structure/closet/wardrobe/pjs,/turf/simulated/floor{icon_state = "neutral"},/area/crew_quarters/sleep) "aBi" = (/obj/structure/closet/wardrobe/pjs,/turf/simulated/floor{icon_state = "neutral"; dir = 6},/area/crew_quarters/sleep) "aBj" = (/turf/simulated/wall,/area/crew_quarters/toilet) -"aBk" = (/obj/machinery/door/airlock{name = "Unisex Showers"; req_access_txt = "0"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) +"aBk" = (/obj/machinery/door/morgue{dir = 2; name = "Confession Booth (Chaplain)"; req_access = list(22)},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aBl" = (/obj/machinery/light,/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"; name = "Clothing Storage"},/turf/simulated/floor{dir = 10; icon_state = "neutral"},/area/crew_quarters/fitness) "aBm" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"; name = "Clothing Storage"},/turf/simulated/floor{icon_state = "neutral"},/area/crew_quarters/fitness) "aBn" = (/obj/machinery/light_switch{pixel_y = -25},/obj/structure/closet/athletic_mixed,/turf/simulated/floor{icon_state = "neutral"},/area/crew_quarters/fitness) "aBo" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/structure/flora/pottedplant{tag = "icon-plant-06"; icon_state = "plant-06"},/turf/simulated/floor{icon_state = "neutral"},/area/crew_quarters/fitness) "aBp" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "neutral"},/area/crew_quarters/fitness) -"aBq" = (/obj/structure/closet/lasertag/blue,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "neutral"},/area/crew_quarters/fitness) +"aBq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/library) "aBr" = (/obj/structure/closet/lasertag/red,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "neutral"; dir = 6},/area/crew_quarters/fitness) -"aBs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/crew_quarters/fitness) -"aBt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"aBs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/library) +"aBt" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/maintenance/library) "aBu" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aBv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) -"aBw" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_chapel_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible,/obj/effect/decal/cleanable/dirt,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) +"aBw" = (/obj/machinery/door/airlock/glass{name = "Chapel Office"; req_access = list(22)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) "aBx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aBy" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aBz" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/hallway/secondary/entry/fore) @@ -1443,7 +1444,7 @@ "aBN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/checkpoint2) "aBO" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 6; icon_state = "intact"; tag = "icon-intact-f (SOUTHEAST)"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/arrivals) "aBP" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating,/area/maintenance/arrivals) -"aBQ" = (/obj/structure/stool{pixel_y = 8},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) +"aBQ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/camera{c_tag = "Fore Starboard Solar Access"; dir = 1},/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/maintenance/library) "aBR" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "aBS" = (/obj/machinery/power/terminal,/obj/machinery/light/small{dir = 4},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "aBT" = (/obj/item/weapon/extinguisher,/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plating,/area/maintenance/evahallway) @@ -1468,29 +1469,29 @@ "aCm" = (/turf/simulated/wall/r_wall,/area/maintenance/substation/civilian_east) "aCn" = (/obj/effect/decal/cleanable/dirt,/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/bar) "aCo" = (/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/power/sensor{name = "Powernet Sensor - Civilian East Subgrid"; name_tag = "Civilian East Subgrid"},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_east) -"aCp" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/camera{c_tag = "Dormitory South"; c_tag_order = 999; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/crew_quarters/sleep) +"aCp" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/library) "aCq" = (/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5; pixel_y = 0},/obj/structure/curtain/open/shower,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aCr" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aCs" = (/obj/machinery/shower{dir = 8; icon_state = "shower"; pixel_x = -5; pixel_y = 0},/obj/structure/curtain/open/shower,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) -"aCt" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"aCt" = (/obj/machinery/door/airlock/glass{name = "Hydroponics Pasture"; req_access = list(35)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hydroponics) "aCu" = (/turf/simulated/wall,/area/maintenance/substation/civilian_east) "aCv" = (/turf/simulated/wall/r_wall,/area/maintenance/auxsolarstarboard) "aCw" = (/obj/machinery/power/solar_control{id = "auxsolareast"; name = "Fore Starboard Solar Control"; track = 0},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/maintenance/auxsolarstarboard) -"aCx" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "solar_chapel_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/obj/effect/decal/cleanable/dirt,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"; nitrogen = 82.1472; oxygen = 21.8366},/area/maintenance/auxsolarstarboard) +"aCx" = (/obj/structure/bed/chair/office/dark,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/security/checkpoint2) "aCy" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/maintenance/auxsolarstarboard) "aCz" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) "aCA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) "aCB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) "aCC" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry/port) -"aCD" = (/obj/machinery/door/airlock/maintenance{name = "Security Maintenance"; req_access_txt = "1"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/security/checkpoint2) +"aCD" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/table/reinforced,/obj/machinery/chemical_dispenser/bar_alc/full,/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aCE" = (/turf/simulated/wall,/area/security/checkpoint2) "aCF" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/obj/machinery/meter,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/maintenance/arrivals) "aCG" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/arrivals) "aCH" = (/obj/machinery/camera{c_tag = "Fore Port Solar Control"; dir = 1},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "aCI" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) -"aCJ" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Fore Port Solar"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) +"aCJ" = (/obj/machinery/camera{c_tag = "Fore Port Solar Access"},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/arrivals) "aCK" = (/turf/simulated/wall,/area/storage/primary) -"aCL" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/storage/primary) +"aCL" = (/obj/structure/table/reinforced,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/chemical_dispenser/bar_soft/full,/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aCM" = (/turf/simulated/wall/r_wall,/area/storage/primary) "aCN" = (/obj/structure/closet/secure_closet/freezer/money,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/security/nuke_storage) "aCO" = (/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 6},/area/security/nuke_storage) @@ -1507,10 +1508,10 @@ "aCZ" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) "aDa" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) "aDb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/ai_monitored/storage/eva) -"aDc" = (/obj/structure/table/reinforced,/obj/item/stack/sheet/plasteel{amount = 10},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/ai_monitored/storage/eva) +"aDc" = (/obj/structure/table,/obj/machinery/newscaster{pixel_y = -32},/turf/simulated/floor,/area/security/vacantoffice) "aDd" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "bluecorner"},/area/hallway/primary/fore) "aDe" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall,/area/maintenance/substation/civilian_east) -"aDf" = (/obj/machinery/power/breakerbox/activated{RCon_tag = "Civilian East Substation Bypass"},/obj/machinery/camera{c_tag = "East Civilian Substation"; dir = 4; network = list("SS13","Engineering")},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_east) +"aDf" = (/obj/structure/lattice,/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "centcom_shuttle_dock_airlock"; name = "exterior access button"; pixel_x = -5; pixel_y = 25; req_one_access = list(13)},/turf/space,/area/space) "aDg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/crew_quarters/sleep) "aDh" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aDi" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) @@ -1522,15 +1523,15 @@ "aDo" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/drinks/shaker,/obj/item/weapon/gun/projectile/shotgun/doublebarrel,/obj/item/weapon/paper{info = "This permit signifies that the Bartender is permitted to posess this firearm in the bar, and ONLY the bar. Failure to adhere to this permit will result in confiscation of the weapon and possibly arrest."; name = "Shotgun permit"},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aDp" = (/turf/simulated/wall,/area/crew_quarters/bar) "aDq" = (/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/bar) -"aDr" = (/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Civilian East Substation"},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_east) +"aDr" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/arrivals) "aDs" = (/turf/simulated/wall,/area/maintenance/bar) -"aDt" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/crew_quarters/fitness) -"aDu" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/crew_quarters/fitness) -"aDv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plating,/area/crew_quarters/fitness) +"aDt" = (/obj/item/weapon/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Assistant"},/turf/simulated/floor,/area/storage/primary) +"aDu" = (/obj/structure/closet/crate,/obj/item/stack/sheet/mineral/gold,/obj/item/stack/sheet/mineral/gold,/obj/item/stack/sheet/mineral/gold,/obj/item/stack/sheet/mineral/gold,/obj/item/stack/sheet/mineral/gold,/obj/item/weapon/storage/belt/champion,/turf/simulated/floor{icon_state = "vault"; dir = 1},/area/security/nuke_storage) +"aDv" = (/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Substation - Civilian East"},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_east) "aDw" = (/obj/structure/cable/green,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_east) -"aDx" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_east) -"aDy" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_east) -"aDz" = (/obj/structure/stool{pixel_y = 8},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) +"aDx" = (/obj/machinery/door/airlock/command{name = "Conference Room"; req_access = list(19)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/wood,/area/bridge/meeting_room) +"aDy" = (/obj/machinery/door/airlock/command{id_tag = "captaindoor"; name = "Captain's Office"; req_access = list(20)},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/wood,/area/crew_quarters/captain) +"aDz" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/crew_quarters/sleep) "aDA" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aDB" = (/obj/machinery/power/terminal,/obj/machinery/light/small{dir = 4},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aDC" = (/turf/simulated/wall,/area/maintenance/library) @@ -1547,7 +1548,7 @@ "aDN" = (/turf/simulated/shuttle/wall{icon_state = "swall14"; dir = 2},/area/shuttle/arrival/station) "aDO" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/shuttle/arrival/station) "aDP" = (/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry/port) -"aDQ" = (/obj/effect/decal/cleanable/blood/oil{amount = 0},/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor/plating,/area/maintenance/arrivals) +"aDQ" = (/obj/machinery/door/airlock/maintenance{name = "Cargo Bay Warehouse Maintenance"; req_access = list(31)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/quartermaster/storage) "aDR" = (/obj/structure/closet/secure_closet/security,/obj/machinery/light{dir = 1},/obj/item/device/flashlight/flare,/turf/simulated/floor{icon_state = "red"; dir = 9},/area/security/checkpoint2) "aDS" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/checkpoint2) "aDT" = (/obj/machinery/computer/security,/obj/structure/reagent_dispensers/peppertank{pixel_x = 0; pixel_y = 30},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/checkpoint2) @@ -1555,7 +1556,7 @@ "aDV" = (/obj/machinery/computer/secure_data,/turf/simulated/floor{icon_state = "red"; dir = 1},/area/security/checkpoint2) "aDW" = (/obj/machinery/requests_console{department = "Security"; departmentType = 5; pixel_y = 30},/obj/machinery/light_switch{pixel_x = 27},/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "red"; dir = 5},/area/security/checkpoint2) "aDX" = (/obj/machinery/atmospherics/valve,/turf/simulated/floor/plating,/area/maintenance/arrivals) -"aDY" = (/obj/machinery/door/airlock/engineering{icon_state = "door_closed"; locked = 0; name = "Fore Port Solar Access"; req_access_txt = "10"},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) +"aDY" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/donut,/obj/machinery/door/firedoor/border_only,/obj/machinery/door/blast/shutters{dir = 2; id = "kitchen"; layer = 3.3; name = "Kitchen Shutters"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/hallway/primary/starboard) "aDZ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/auxsolarport) "aEa" = (/obj/machinery/vending/assist,/turf/simulated/floor,/area/storage/primary) "aEb" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/storage/primary) @@ -1578,14 +1579,14 @@ "aEs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/gateway) "aEt" = (/obj/structure/window/reinforced,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/gateway) "aEu" = (/obj/structure/table/rack{dir = 1},/obj/item/weapon/extinguisher,/obj/item/clothing/mask/gas,/turf/simulated/floor/plating,/area/maintenance/evahallway) -"aEv" = (/obj/machinery/door/airlock/glass_engineering{name = "Engineering Hardsuits"; req_access_txt = "0"; req_one_access_txt = "11;24"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) +"aEv" = (/obj/structure/lattice,/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "escape_dock_south_airlock"; name = "exterior access button"; pixel_x = 5; pixel_y = -25; req_one_access = list(13)},/turf/space,/area/space) "aEw" = (/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/ai_monitored/storage/eva) "aEx" = (/obj/machinery/hologram/holopad,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) "aEy" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) "aEz" = (/obj/structure/table/reinforced{icon_state = "table"},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 6},/obj/item/weapon/storage/briefcase/inflatable{pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = -3},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/ai_monitored/storage/eva) "aEA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/ai_monitored/storage/eva) "aEB" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/tank/jetpack/carbondioxide,/obj/item/clothing/shoes/magboots,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/ai_monitored/storage/eva) -"aEC" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/central_one) +"aEC" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "aED" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{dir = 1; icon_state = "bluecorner"},/area/hallway/primary/central_one) "aEE" = (/turf/simulated/floor{dir = 5; icon_state = "blue"},/area/hallway/primary/central_one) "aEF" = (/obj/structure/table/woodentable,/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/item/weapon/tape_roll,/turf/simulated/floor/wood,/area/library) @@ -1595,23 +1596,23 @@ "aEJ" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aEK" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aEL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) -"aEM" = (/obj/machinery/door/airlock{name = "Unisex Showers"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) +"aEM" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_access = list(12)},/turf/simulated/floor/plating,/area/security/vacantoffice) "aEN" = (/obj/machinery/light/small,/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aEO" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aEP" = (/obj/item/weapon/storage/secure/safe{pixel_x = -22; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aEQ" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aER" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"aES" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/maintenance{name = "Bar Maintenance"; req_access_txt = "25"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/crew_quarters/bar) +"aES" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/box/donut,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "aET" = (/obj/structure/disposalpipe/sortjunction{dir = 2; icon_state = "pipe-j1s"; sortType = "Bar"; name = "Bar"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/bar) "aEU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_east) -"aEV" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/crew_quarters/sleep) -"aEW" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/crew_quarters/sleep) +"aEV" = (/obj/machinery/camera{c_tag = "Dormitory South"; c_tag_order = 999; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/crew_quarters/sleep) +"aEW" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/maintenance/library) "aEX" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aEY" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) -"aEZ" = (/obj/machinery/camera{c_tag = "Fore Starboard Solars"; dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Fore Starboard Solar"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) +"aEZ" = (/turf/simulated/floor/plating,/area/maintenance/library) "aFa" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/bar) "aFb" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/bar) -"aFc" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/library) +"aFc" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/library) "aFd" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/library) "aFe" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/maintenance/library) "aFf" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor/plating,/area/maintenance/library) @@ -1631,26 +1632,26 @@ "aFt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) "aFu" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor/plating,/area/maintenance/arrivals) "aFv" = (/obj/structure/closet/wardrobe/red,/turf/simulated/floor{icon_state = "red"; dir = 8},/area/security/checkpoint2) -"aFw" = (/obj/machinery/camera{c_tag = "Fore Port Solar Access"},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/maintenance/arrivals) +"aFw" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/library) "aFx" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/arrivals) -"aFy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/maintenance/arrivals) +"aFy" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) "aFz" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/arrivals) "aFA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "red"},/area/security/checkpoint2) "aFB" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/maintenance/arrivals) "aFC" = (/turf/simulated/wall,/area/maintenance/substation/civilian_west) "aFD" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/maintenance/arrivals) -"aFE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/engineering{name = "Civilian West Substation"; req_access_txt = "0"; req_one_access_txt = "11;24"},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_west) +"aFE" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_dock_south_outer"; locked = 1; name = "Escape Airlock"; req_access = list(13)},/obj/machinery/mech_sensor{dir = 8; frequency = 1380; id_tag = "escape_dock_south_mech"; pixel_y = 19},/turf/simulated/floor/plating,/area/hallway/secondary/exit) "aFF" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 4; icon_state = "whitecorner"},/area/hallway/secondary/entry/port) -"aFG" = (/obj/machinery/door/airlock/security{name = "Security Checkpoint"; req_access = null; req_access_txt = "1"},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/secondary/entry/starboard) +"aFG" = (/obj/machinery/light/small{dir = 1},/obj/machinery/embedded_controller/radio/airlock/docking_port_multi{frequency = 1380; id_tag = "escape_dock_south_airlock"; master_tag = "escape_dock"; pixel_y = -30; req_one_access = list(13); tag_airlock_mech_sensor = "escape_dock_south_mech"; tag_airpump = "escape_dock_south_pump"; tag_chamber_sensor = "escape_dock_south_sensor"; tag_exterior_door = "escape_dock_south_outer"; tag_interior_door = "escape_dock_south_inner"; tag_shuttle_mech_sensor = "shuttle_dock_south_mech"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1380; id_tag = "escape_dock_south_pump"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) "aFH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/substation/civilian_west) -"aFI" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/storage/primary) +"aFI" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_dock_south_inner"; locked = 1; name = "Escape Airlock"; req_access = list(13)},/obj/machinery/mech_sensor{dir = 8; frequency = 1380; id_tag = "escape_dock_south_mech"; pixel_y = 19},/turf/simulated/floor/plating,/area/hallway/secondary/exit) "aFJ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/storage/primary) "aFK" = (/obj/effect/landmark/start{name = "Assistant"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/storage/primary) "aFL" = (/obj/effect/landmark/start{name = "Assistant"},/turf/simulated/floor,/area/storage/primary) -"aFM" = (/obj/structure/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Assistant"},/turf/simulated/floor,/area/storage/primary) +"aFM" = (/obj/structure/bed/chair{dir = 8},/obj/effect/landmark{name = "JoinLate"},/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) "aFN" = (/obj/effect/landmark/start{name = "Assistant"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/storage/primary) "aFO" = (/obj/machinery/lapvend,/turf/simulated/floor,/area/storage/primary) -"aFP" = (/obj/machinery/camera{c_tag = "Vault"; dir = 4; network = list("SS13")},/obj/structure/closet/crate{name = "Gold Crate"},/obj/item/stack/sheet/mineral/gold{pixel_x = -1; pixel_y = 5},/obj/item/stack/sheet/mineral/gold{pixel_y = 2},/obj/item/stack/sheet/mineral/gold{pixel_x = 1; pixel_y = -2},/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30},/obj/item/weapon/storage/belt/champion,/turf/simulated/floor{icon_state = "vault"; dir = 1},/area/security/nuke_storage) +"aFP" = (/obj/item/weapon/stool,/turf/simulated/floor,/area/gateway) "aFQ" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"},/area/security/nuke_storage) "aFR" = (/obj/item/weapon/coin/silver{pixel_x = 7; pixel_y = 12},/obj/item/weapon/coin/silver{pixel_x = 12; pixel_y = 7},/obj/item/weapon/coin/silver{pixel_x = 4; pixel_y = 8},/obj/item/weapon/coin/silver{pixel_x = -6; pixel_y = 5},/obj/item/weapon/coin/silver{pixel_x = 5; pixel_y = -8},/obj/structure/closet/crate{name = "Silver Crate"},/turf/simulated/floor{icon_state = "vault"; dir = 4},/area/security/nuke_storage) "aFS" = (/obj/machinery/camera{c_tag = "Gateway"; dir = 4; network = list("SS13")},/obj/machinery/vending/coffee,/turf/simulated/floor,/area/gateway) @@ -1660,7 +1661,7 @@ "aFW" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/evahallway) "aFX" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/table/reinforced,/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = -1},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/ai_monitored/storage/eva) "aFY" = (/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/ai_monitored/storage/eva) -"aFZ" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_command{name = "E.V.A."; req_access_txt = "0"; req_one_access_txt = "1;5;11;18;24"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) +"aFZ" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "escape_dock_south_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = -25; req_one_access = list(13)},/turf/simulated/floor,/area/hallway/secondary/exit) "aGa" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) "aGb" = (/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/fore) "aGc" = (/obj/machinery/door/firedoor/border_only,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/primary/fore) @@ -1670,35 +1671,35 @@ "aGg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) "aGh" = (/obj/machinery/atmospherics/unary/vent_pump/on,/obj/structure/closet/emcloset,/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/hallway/secondary/entry/port) "aGi" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) -"aGj" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/crew_quarters/sleep) -"aGk" = (/obj/machinery/door/airlock{name = "Unisex Restrooms"; req_access_txt = "0"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep) +"aGj" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/crew_quarters/sleep) +"aGk" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "nuke_shuttle_dock_airlock"; name = "exterior access button"; pixel_x = -5; pixel_y = 32; req_one_access = list(13)},/turf/space,/area/space) "aGl" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aGm" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aGn" = (/obj/structure/sign/poster{pixel_x = 0; pixel_y = 0},/turf/simulated/wall,/area/crew_quarters/toilet) "aGo" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/hologram/holopad,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aGp" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aGq" = (/obj/structure/closet/gmcloset{icon_closed = "black"; icon_state = "black"; name = "formal wardrobe"},/obj/item/device/eftpos{eftpos_name = "Bar EFTPOS scanner"},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"aGr" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/bar) +"aGr" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/starboard) "aGs" = (/turf/simulated/floor/plating,/area/maintenance/bar) "aGt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/bar) "aGu" = (/obj/item/weapon/cigbutt,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/dormitory) "aGv" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_east) "aGw" = (/obj/effect/decal/cleanable/dirt,/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/bar) -"aGx" = (/obj/machinery/door/airlock/engineering{icon_state = "door_closed"; locked = 0; name = "Fore Starboard Solar Access"; req_access_txt = "10"},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) +"aGx" = (/obj/structure/table,/obj/machinery/camera{c_tag = "Bridge East"; dir = 2},/obj/item/weapon/storage/box/donut,/obj/structure/noticeboard{pixel_y = 27},/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/bridge) "aGy" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/auxsolarstarboard) -"aGz" = (/obj/effect/decal/cleanable/cobweb,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/bar) -"aGA" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/maintenance/bar) -"aGB" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "Bar\\Library Maintenance"; req_access_txt = "0"},/turf/simulated/floor/plating,/area/maintenance/library) -"aGC" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/library) +"aGz" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/crew_quarters/sleep) +"aGA" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/library) +"aGB" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/reagent_dispensers/watertank,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/maintenance/library) +"aGC" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/library) "aGD" = (/obj/item/weapon/cigbutt,/obj/effect/decal/cleanable/dirt,/obj/structure/cable,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor/plating,/area/maintenance/library) "aGE" = (/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/library) "aGF" = (/turf/simulated/wall,/area/chapel/office) "aGG" = (/turf/simulated/wall,/area/chapel/main) -"aGH" = (/obj/machinery/door/airlock/maintenance{name = "Chapel Maintenance"; req_access_txt = "0"; req_one_access_txt = "12;22"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/chapel/main) +"aGH" = (/obj/machinery/light/small,/obj/machinery/embedded_controller/radio/airlock/docking_port_multi{frequency = 1380; id_tag = "escape_dock_north_airlock"; master_tag = "escape_dock"; pixel_y = 30; req_one_access = list(13); tag_airlock_mech_sensor = "escape_dock_north_mech"; tag_airpump = "escape_dock_north_pump"; tag_chamber_sensor = "escape_dock_north_sensor"; tag_exterior_door = "escape_dock_north_outer"; tag_interior_door = "escape_dock_north_inner"; tag_shuttle_mech_sensor = "shuttle_dock_north_mech"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1380; id_tag = "escape_dock_north_pump"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) "aGI" = (/turf/simulated/shuttle/floor,/turf/simulated/shuttle/wall{icon_state = "swall_f9"; dir = 2},/area/shuttle/arrival/station) -"aGJ" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) +"aGJ" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/landmark{name = "blobstart"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/library) "aGK" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/shuttle/arrival/station) -"aGL" = (/obj/structure/stool/bed/chair{dir = 8},/obj/effect/landmark{name = "JoinLate"},/turf/simulated/shuttle/floor,/area/shuttle/arrival/station) +"aGL" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/library) "aGM" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/shuttle/arrival/station) "aGN" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 8},/turf/space,/area/shuttle/arrival/station) "aGO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) @@ -1708,7 +1709,7 @@ "aGS" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/turf/simulated/floor{icon_state = "red"},/area/security/checkpoint2) "aGT" = (/obj/machinery/recharger{pixel_y = 4},/obj/structure/table/reinforced,/turf/simulated/floor{icon_state = "red"},/area/security/checkpoint2) "aGU" = (/obj/item/weapon/crowbar,/obj/item/device/flash,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{icon_state = "red"; dir = 6},/area/security/checkpoint2) -"aGV" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/camera{c_tag = "West Civilian Substation"; dir = 8; network = list("SS13","Engineering")},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_west) +"aGV" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_dock_north_inner"; locked = 1; name = "Escape Airlock"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/mech_sensor{dir = 8; frequency = 1380; id_tag = "escape_dock_north_mech"; pixel_y = -19},/turf/simulated/floor/plating,/area/hallway/secondary/exit) "aGW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/terminal,/turf/simulated/floor/plating,/area/maintenance/substation/civilian_west) "aGX" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/hallway/secondary/entry/starboard) "aGY" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/hallway/secondary/entry/port) @@ -1723,7 +1724,7 @@ "aHh" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "vault"; dir = 10},/area/security/nuke_storage) "aHi" = (/obj/structure/safe,/obj/item/clothing/under/color/yellow,/obj/item/key,/obj/item/toy/katana,/turf/simulated/floor{icon_state = "vault"; dir = 4},/area/security/nuke_storage) "aHj" = (/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30},/obj/machinery/vending/cola,/turf/simulated/floor,/area/gateway) -"aHk" = (/obj/structure/stool,/turf/simulated/floor,/area/gateway) +"aHk" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_west) "aHl" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/gateway) "aHm" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/closet/wardrobe/black,/turf/simulated/floor,/area/gateway) "aHn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/maintenance/evahallway) @@ -1747,8 +1748,8 @@ "aHF" = (/obj/structure/toilet{pixel_y = 8},/obj/machinery/light/small{dir = 8},/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aHG" = (/obj/machinery/light/small{dir = 8},/obj/machinery/recharge_station,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aHH" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"aHI" = (/obj/item/device/radio/intercom{pixel_x = 25},/obj/structure/window/reinforced,/obj/structure/closet/secure_closet/bar{req_access_txt = "25"},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"aHJ" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/bar) +"aHI" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "escape_dock_north_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_one_access = list(13)},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor,/area/hallway/secondary/exit) +"aHJ" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_dock_north_outer"; locked = 1; name = "Escape Airlock"; req_access = list(13)},/obj/machinery/mech_sensor{dir = 8; frequency = 1380; id_tag = "escape_dock_north_mech"; pixel_y = -19},/turf/simulated/floor/plating,/area/hallway/secondary/exit) "aHK" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/bar) "aHL" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-j1"; dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/bar) "aHM" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/bar) @@ -1756,33 +1757,33 @@ "aHO" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-j1"; dir = 4},/obj/effect/decal/cleanable/flour,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/bar) "aHP" = (/obj/structure/disposalpipe/sortjunction{dir = 4; icon_state = "pipe-j1s"; sortType = "Kitchen"; name = "Kitchen"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/bar) "aHQ" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/bar) -"aHR" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/maintenance/bar) -"aHS" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"; nitrogen = 0.01; oxygen = 0.01},/area/maintenance/bar) -"aHT" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/maintenance/bar) -"aHU" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/bar) +"aHR" = (/obj/effect/landmark/start{name = "Assistant"},/obj/item/weapon/stool{pixel_y = 8},/turf/simulated/floor,/area/storage/primary) +"aHS" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/vault/bolted,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/security/nuke_storage) +"aHT" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Dormitory"},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/hallway/primary/central_two) +"aHU" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Dormitory"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/hallway/primary/central_two) "aHV" = (/obj/structure/closet,/obj/item/device/flashlight,/obj/effect/decal/cleanable/cobweb2,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/maintenance/bar) -"aHW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/bar) -"aHX" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 4; sortType = "Chapel"; name = "Chapel"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/bar) -"aHY" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/camera{c_tag = "Fore Starboard Solar Access"; dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/bar) +"aHW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/bar) +"aHX" = (/obj/structure/disposalpipe/sortjunction{dir = 4; icon_state = "pipe-j1s"; sortType = "Hydroponics"; name = "Hydroponics"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/maintenance/bar) +"aHY" = (/obj/structure/table,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) "aHZ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/bar) -"aIa" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/bar) -"aIb" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/bar) -"aIc" = (/obj/machinery/door/airlock/maintenance{name = "Library Maintenance"; req_access_txt = "0"; req_one_access_txt = "12;37"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/library) +"aIa" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plating,/area/maintenance/bar) +"aIb" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/library) +"aIc" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/maintenance{req_access = list(12)},/turf/simulated/floor/plating,/area/maintenance/locker) "aId" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/structure/table/woodentable,/obj/item/weapon/dice/d20,/obj/item/weapon/dice,/turf/simulated/floor/wood,/area/library) "aIe" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/packageWrap,/turf/simulated/floor/wood,/area/library) "aIf" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor/wood,/area/library) "aIg" = (/turf/simulated/wall,/area/library) -"aIh" = (/obj/machinery/door/airlock/maintenance{name = "Crematorium Maintenance"; req_access_txt = "27"},/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/chapel/office) +"aIh" = (/obj/machinery/door/airlock{name = "Unisex Restrooms"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet) "aIi" = (/obj/structure/closet/wardrobe/chaplain_black,/obj/item/device/radio/intercom{pixel_y = 25},/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aIj" = (/obj/machinery/light/small{dir = 1},/obj/machinery/requests_console{department = "Chapel"; departmentType = 2; pixel_y = 30},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aIk" = (/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/camera{c_tag = "Chapel Office"; dir = 2; network = list("SS13")},/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aIl" = (/obj/machinery/door_control{id = "chapel"; name = "Privacy Shutters"; pixel_y = 25},/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aIm" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/glass/rag,/obj/structure/noticeboard{pixel_x = -30; pixel_y = 0},/obj/machinery/door/blast/shutters{dir = 2; id = "bar"; layer = 3.1; name = "Bar Shutters"},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) -"aIn" = (/obj/structure/closet/coffin,/obj/machinery/door/window/eastleft{name = "Coffin Storage"; req_access_txt = "22"},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) +"aIn" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "centcom_shuttle_dock_airlock"; name = "interior access button"; pixel_x = -30; pixel_y = 25; req_one_access = list(13)},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/simulated/floor,/area/hallway/secondary/entry/aft) "aIo" = (/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aIp" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aIq" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) -"aIr" = (/obj/machinery/door/window{dir = 8; name = "Mass Driver"; req_access_txt = "22"},/obj/machinery/mass_driver{dir = 4; id = "chapelgun"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/chapel/main) +"aIr" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 4; sortType = "Chapel"; name = "Chapel"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/library) "aIs" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/chapel/main) "aIt" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin,/obj/item/weapon/pen/blue{pixel_x = 2; pixel_y = 6},/obj/item/weapon/pen/blue{pixel_x = -3; pixel_y = 2},/obj/machinery/door/blast/shutters{dir = 2; id = "bar"; layer = 3.1; name = "Bar Shutters"},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aIu" = (/turf/space,/area/shuttle/escape/station) @@ -1794,21 +1795,21 @@ "aIA" = (/turf/simulated/wall,/area/hallway/secondary/entry/starboard) "aIB" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/hallway/secondary/entry/starboard) "aIC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/starboard) -"aID" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/door/window/brigdoor{dir = 1; name = "Security Checkpoint"; req_access_txt = "63"},/turf/simulated/floor{icon_state = "delivery"},/area/hallway/secondary/entry/starboard) +"aID" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "centcom_shuttle_dock_inner"; locked = 1; name = "Docking Port Airlock"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "aIE" = (/obj/structure/sign/double/map/left,/turf/simulated/wall,/area/hallway/secondary/entry/starboard) "aIF" = (/obj/structure/sign/double/map/right,/turf/simulated/wall,/area/hallway/secondary/entry/starboard) "aIG" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/hallway/secondary/entry/starboard) "aIH" = (/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 30},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/hallway/secondary/entry/starboard) -"aII" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/engineering{name = "Civilian West Substation"; req_access_txt = "0"; req_one_access_txt = "11;24"},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_west) +"aII" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "centcom_shuttle_dock_outer"; locked = 1; name = "Docking Port Airlock"; req_access = list(13)},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "aIJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/hallway/secondary/entry/starboard) "aIK" = (/obj/structure/table,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor,/area/storage/primary) "aIL" = (/obj/effect/landmark/start{name = "Assistant"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor,/area/storage/primary) "aIM" = (/obj/effect/landmark/start{name = "Assistant"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/storage/primary) -"aIN" = (/obj/effect/landmark/start{name = "Assistant"},/obj/structure/stool{pixel_y = 8},/turf/simulated/floor,/area/storage/primary) +"aIN" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/library) "aIO" = (/obj/effect/landmark/start{name = "Assistant"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/storage/primary) "aIP" = (/obj/effect/landmark/start{name = "Assistant"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/storage/primary) "aIQ" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/security/nuke_storage) -"aIR" = (/obj/machinery/door/airlock/vault{icon_state = "door_locked"; locked = 1; req_access_txt = "53"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/security/nuke_storage) +"aIR" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/meter,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/library) "aIS" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/table,/obj/item/weapon/deck,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor,/area/gateway) "aIT" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/gateway) "aIU" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/gateway) @@ -1816,7 +1817,7 @@ "aIW" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/evahallway) "aIX" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/evahallway) "aIY" = (/obj/machinery/suit_cycler/engineering,/obj/machinery/light/small{dir = 8},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/ai_monitored/storage/eva) -"aIZ" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_command{name = "E.V.A. Cycler Access"; req_access_txt = "0"; req_one_access_txt = "1;5;11;18;24"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) +"aIZ" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "centcom_shuttle_dock_airlock"; pixel_x = 0; pixel_y = 30; req_one_access = list(13); tag_airpump = "centcom_shuttle_dock_pump"; tag_chamber_sensor = "centcom_shuttle_dock_sensor"; tag_exterior_door = "centcom_shuttle_dock_outer"; tag_interior_door = "centcom_shuttle_dock_inner"},/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "centcom_shuttle_dock_sensor"; pixel_x = 0; pixel_y = -25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "centcom_shuttle_dock_pump"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "aJa" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) "aJb" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/ai_monitored/storage/eva) "aJc" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/ai_monitored/storage/eva) @@ -1826,8 +1827,8 @@ "aJg" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/primary/central_one) "aJh" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/turf/simulated/floor{icon_state = "bluecorner"},/area/hallway/primary/central_one) "aJi" = (/turf/simulated/wall/r_wall,/area/hallway/primary/central_two) -"aJj" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Dormitory"},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/hallway/primary/central_two) -"aJk" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Dormitory"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/hallway/primary/central_two) +"aJj" = (/obj/structure/bed/chair/office/dark,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/machinery/camera{c_tag = "Library North"; dir = 2; network = list("SS13")},/turf/simulated/floor/wood,/area/library) +"aJk" = (/obj/structure/bed/chair/office/dark,/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/wood,/area/library) "aJl" = (/turf/simulated/wall,/area/hallway/primary/central_two) "aJm" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{pixel_x = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aJn" = (/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) @@ -1835,42 +1836,42 @@ "aJp" = (/obj/machinery/door/airlock{name = "Unit 2"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aJq" = (/obj/machinery/door/airlock{name = "Unit B"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aJr" = (/obj/structure/sign/securearea{desc = "Under the painting a plaque reads: 'While the meat grinder may not have spared you, fear not. Not one part of you has gone to waste... You were delicious.'"; icon_state = "monkey_painting"; name = "Mr. Deempisi portrait"; pixel_x = -28; pixel_y = 4},/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"aJs" = (/obj/machinery/door/window/southleft{name = "Bar Delivery"; icon_state = "left"; dir = 8; req_access_txt = "25"; base_state = "left"},/turf/simulated/floor{icon_state = "delivery"},/area/crew_quarters/bar) +"aJs" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/door_control{id = "kitchen"; name = "Kitchen Shutters Control"; pixel_x = -1; pixel_y = -24; req_access = list(28)},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "aJt" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Bar"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/crew_quarters/bar) "aJu" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/substation/command) "aJv" = (/obj/effect/landmark{name = "blobstart"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/bar) -"aJw" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Kitchen Cold Room Maintenance"; req_access_txt = "28"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/maintenance/bar) +"aJw" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass{name = "Kitchen"; req_access = list(28)},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "aJx" = (/obj/structure/plasticflaps{opacity = 1},/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Kitchen"},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/maintenance/bar) "aJy" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/bar) "aJz" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/bar) -"aJA" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/bar) -"aJB" = (/obj/structure/disposalpipe/sortjunction{dir = 4; icon_state = "pipe-j1s"; sortType = "Hydroponics"; name = "Hydroponics"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/maintenance/bar) +"aJA" = (/obj/effect/landmark/start{name = "Chaplain"},/obj/structure/bed/chair,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) +"aJB" = (/obj/machinery/button/driver{id = "chapelgun"; name = "Chapel Mass Driver"; pixel_x = 25},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aJC" = (/obj/machinery/light/small{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/dormitory) "aJD" = (/obj/structure/table/reinforced,/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 28},/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the 'Space' from Space Cleaner and written in Chemistry. Scrawled on the back is, 'Okay, whoever filled this with polytrinic acid, it was only funny the first time. It was hard enough replacing the CMO's first cat!'"; name = "Chemistry Cleaner"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "aJE" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) "aJF" = (/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) -"aJG" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/meter,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/bar) -"aJH" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/maintenance/bar) +"aJG" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Substation - Civilian West"},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_west) +"aJH" = (/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access = list(19)},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/bridge) "aJI" = (/obj/structure/filingcabinet,/turf/simulated/floor/wood,/area/library) "aJJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/library) -"aJK" = (/obj/structure/stool/bed/chair/office/dark,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/machinery/camera{c_tag = "Library North"; dir = 2; network = list("SS13")},/turf/simulated/floor/wood,/area/library) -"aJL" = (/obj/structure/stool/bed/chair/office/dark,/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/wood,/area/library) +"aJK" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/hallway/primary/central_two) +"aJL" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/library) "aJM" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/wood,/area/library) "aJN" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/wood,/area/library) "aJO" = (/obj/structure/crematorium,/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) "aJP" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) "aJQ" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) -"aJR" = (/obj/effect/landmark/start{name = "Chaplain"},/obj/structure/stool/bed/chair,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) +"aJR" = (/obj/structure/bed/chair/office/dark{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/wood,/area/library) "aJS" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 5},/obj/item/weapon/storage/fancy/crayons,/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aJT" = (/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aJU" = (/obj/structure/closet/coffin,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aJV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) -"aJW" = (/obj/machinery/driver_button{id = "chapelgun"; name = "Chapel Mass Driver"; pixel_x = 25},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) +"aJW" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/wood,/area/library) "aJX" = (/turf/simulated/shuttle/floor,/turf/simulated/shuttle/wall{icon_state = "swall_f10"; dir = 2},/area/shuttle/arrival/station) "aJY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/substation/civilian_west) "aJZ" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/power/sensor{name = "Powernet Sensor - Civilian West"; name_tag = "Civilian West Subgrid"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/maintenance/substation/civilian_west) "aKa" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/power/breakerbox/activated{RCon_tag = "Civilian West Substation Bypass"},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_west) -"aKb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Civilian West Substation"},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_west) +"aKb" = (/obj/structure/disposalpipe/segment,/obj/machinery/button/crematorium{pixel_x = 25},/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) "aKc" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/storage/emergency2) "aKd" = (/turf/simulated/floor,/area/hallway/secondary/entry/starboard) "aKe" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/storage/emergency2) @@ -1878,9 +1879,9 @@ "aKg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/locker) "aKh" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/maintenance/locker) "aKi" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/maintenance/locker) -"aKj" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/locker) +"aKj" = (/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access = list(19)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/bridge) "aKk" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/locker) -"aKl" = (/obj/machinery/door/airlock/maintenance{name = "Cargo Bay Warehouse Maintenance"; req_access_txt = "31"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/quartermaster/storage) +"aKl" = (/obj/machinery/door_control{id = "bridge blast"; name = "Bridge Blast Door Control"; pixel_x = -1; pixel_y = -24; req_access = list(19)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "aKm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/storage/primary) "aKn" = (/turf/simulated/floor,/area/storage/primary) "aKo" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor,/area/storage/primary) @@ -1907,42 +1908,42 @@ "aKJ" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/ai_monitored/storage/eva) "aKK" = (/obj/machinery/light,/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) "aKL" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/rig/unathi,/obj/item/clothing/mask/breath,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/ai_monitored/storage/eva) -"aKM" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "nuke_shuttle_dock_inner"; locked = 1; name = "Docking Port Airlock"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) +"aKM" = (/obj/machinery/door/airlock/glass_command{id_tag = "sbridgedoor"; name = "Bridge"; req_access = list(19)},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/bridge) "aKN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/primary/central_one) "aKO" = (/turf/simulated/floor{dir = 4; icon_state = "bluecorner"},/area/hallway/primary/central_one) "aKP" = (/obj/machinery/light{dir = 1},/obj/machinery/camera{c_tag = "Central Hallway North"; dir = 2},/obj/structure/sign/directions/evac{dir = 4; icon_state = "direction_evac"; pixel_y = 24; tag = "icon-direction_evac (EAST)"},/obj/structure/sign/directions/security{dir = 1; icon_state = "direction_sec"; pixel_y = 40; tag = "icon-direction_sec (NORTH)"},/obj/structure/sign/directions/medical{dir = 4; icon_state = "direction_med"; pixel_y = 32; tag = "icon-direction_med (EAST)"},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/hallway/primary/central_one) -"aKQ" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "nuke_shuttle_dock_outer"; locked = 1; name = "Docking Port Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) +"aKQ" = (/obj/machinery/door/airlock/glass_command{id_tag = "sbridgedoor"; name = "Bridge"; req_access = list(19)},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/bridge) "aKR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aKS" = (/obj/machinery/vending/cola,/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central_two) -"aKT" = (/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/hallway/primary/central_two) -"aKU" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/hallway/primary/central_two) -"aKV" = (/obj/machinery/camera{c_tag = "Dormitory Toilets"; dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) +"aKT" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "chapel"},/area/chapel/main) +"aKU" = (/obj/structure/lattice,/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "escape_dock_north_airlock"; name = "exterior access button"; pixel_x = 5; pixel_y = 25; req_one_access = list(13)},/turf/space,/area/space) +"aKV" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aKW" = (/obj/machinery/light,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) -"aKX" = (/obj/machinery/door/airlock{name = "Bar Backroom"; req_access_txt = "25"},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/crew_quarters/bar) -"aKY" = (/obj/machinery/door/airlock/maintenance{name = "Bar Maintenance"; req_access_txt = "0"; req_one_access_txt = "12;25;28"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/crew_quarters/bar) +"aKX" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "solar_chapel_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access = list(10,13)},/obj/effect/decal/cleanable/dirt,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/solar/auxstarboard) +"aKY" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "arrivals_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = 25; req_access = list(13)},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/arrivals) "aKZ" = (/turf/simulated/wall,/area/crew_quarters/kitchen) "aLa" = (/obj/structure/sink/kitchen{pixel_y = 28},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aLb" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aLc" = (/obj/structure/closet/chefcloset,/obj/machinery/light/small{dir = 1},/obj/item/device/eftpos{eftpos_name = "Kitchen EFTPOS scanner"},/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aLd" = (/obj/machinery/camera{c_tag = "Kitchen Cold Room"},/obj/machinery/chem_master/condimaster{name = "CondiMaster Neo"; pixel_x = -5},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) -"aLe" = (/obj/machinery/door/window/southleft{base_state = "left"; dir = 2; icon_state = "left"; name = "Kitchen Delivery"; req_access_txt = "28"},/turf/simulated/floor{icon_state = "delivery"},/area/crew_quarters/kitchen) +"aLe" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_2_hatch"; locked = 1; name = "Escape Pod Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod2/station) "aLf" = (/turf/simulated/wall,/area/hydroponics) "aLg" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=2"; freq = 1400; location = "Hydroponics"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/hydroponics) "aLh" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/hydroponics) -"aLi" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Hydroponics Maintenance"; req_access_txt = "35"},/obj/machinery/door/firedoor,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/hydroponics) +"aLi" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_1_hatch"; locked = 1; name = "Escape Pod Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod1/station) "aLj" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor/wood,/area/library) -"aLk" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/wood,/area/library) +"aLk" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eva_outer"; locked = 1; name = "EVA External Access"; req_access = list(13)},/turf/simulated/floor/airless{icon_state = "circuit"},/area/maintenance/evahallway) "aLl" = (/obj/structure/table/woodentable,/obj/item/weapon/folder/yellow,/obj/item/weapon/pen,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/wood,/area/library) -"aLm" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "nuke_shuttle_dock_airlock"; pixel_x = 0; pixel_y = 30; req_access_txt = "0"; req_one_access_txt = "13"; tag_airpump = "nuke_shuttle_dock_pump"; tag_chamber_sensor = "nuke_shuttle_dock_sensor"; tag_exterior_door = "nuke_shuttle_dock_outer"; tag_interior_door = "nuke_shuttle_dock_inner"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1; icon_state = "map"; tag = "icon-manifold-f (NORTH)"},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/hallway/secondary/entry/port) -"aLn" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/wood,/area/library) +"aLm" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "eva_airlock"; name = "exterior access button"; pixel_x = 0; pixel_y = 25; req_access = list(1,11,18,24)},/turf/simulated/floor/plating/airless,/area/maintenance/evahallway) +"aLn" = (/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/hallway/primary/central_two) "aLo" = (/obj/machinery/newscaster{pixel_x = 30},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/wood,/area/library) "aLp" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) -"aLq" = (/obj/structure/disposalpipe/segment,/obj/machinery/crema_switch{pixel_x = 25},/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) +"aLq" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/hallway/primary/central_two) "aLr" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp{pixel_y = 10},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aLs" = (/obj/structure/table/woodentable,/obj/item/weapon/pen,/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aLt" = (/obj/structure/table/woodentable,/obj/item/weapon/nullrod,/obj/item/device/eftpos{eftpos_name = "Chapel EFTPOS scanner"},/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aLu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/hallway/secondary/exit) -"aLv" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "chapel"},/area/chapel/main) +"aLv" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/bed/chair/comfy/brown{dir = 4},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/carpet,/area/crew_quarters/bar) "aLw" = (/obj/structure/table,/turf/simulated/floor{dir = 4; icon_state = "chapel"},/area/chapel/main) "aLx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/chapel/main) "aLy" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/shuttle/arrival/station) @@ -1971,15 +1972,15 @@ "aLV" = (/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/hallway/primary/port) "aLW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/hallway/primary/port) "aLX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/primary/port) -"aLY" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/port) +"aLY" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "eva_airlock"; name = "interior access button"; pixel_x = 0; pixel_y = 25; req_access = list(1,11,18,24)},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/evahallway) "aLZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/port) "aMa" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Gateway Access"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/primary/port) "aMb" = (/turf/simulated/wall,/area/hallway/primary/central_one) -"aMc" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/central_one) +"aMc" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "eva_airlock"; name = "EVA Airlock Console"; pixel_y = 25; req_one_access = list(1,5,11,18,24); tag_airpump = "eva_pump"; tag_chamber_sensor = "eva_sensor"; tag_exterior_door = "eva_outer"; tag_interior_door = "eva_inner"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/maintenance/evahallway) "aMd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aMe" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/sign/securearea,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) -"aMf" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_command{name = "E.V.A."; req_access_txt = "0"; req_one_access_txt = "1;5;11;18;24"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central_one) -"aMg" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_command{name = "E.V.A."; req_access_txt = "0"; req_one_access_txt = "1;5;11;18;24"},/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central_one) +"aMf" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/bed/chair/comfy/brown{dir = 8},/turf/simulated/floor/carpet,/area/crew_quarters/bar) +"aMg" = (/obj/structure/bed/chair/office/dark{dir = 4},/turf/simulated/floor/wood,/area/library) "aMh" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/sign/securearea,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aMi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aMj" = (/obj/structure/extinguisher_cabinet{pixel_x = -24},/turf/simulated/floor,/area/hallway/primary/central_one) @@ -1989,21 +1990,21 @@ "aMn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aMo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aMp" = (/obj/machinery/vending/snack,/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central_two) -"aMq" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/hallway/primary/central_two) -"aMr" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "neutral"; dir = 4},/area/hallway/primary/central_two) +"aMq" = (/obj/structure/bed/chair/office/dark{dir = 8},/turf/simulated/floor/wood,/area/library) +"aMr" = (/obj/structure/bed/chair{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aMs" = (/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/light{dir = 1},/obj/machinery/smartfridge/drinks,/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aMt" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aMu" = (/obj/structure/reagent_dispensers/beerkeg,/obj/machinery/requests_console{announcementConsole = 0; department = "Bar"; departmentType = 2; name = "Bar RC"; pixel_x = 0; pixel_y = 30},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aMv" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/machinery/camera{c_tag = "Bar North"; dir = 2},/obj/machinery/vending/boozeomat,/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) -"aMw" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/table/reinforced,/obj/item/weapon/book/manual/barman_recipes,/obj/item/clothing/head/that{pixel_x = 4; pixel_y = 6},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) -"aMx" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/stool/bed/chair/comfy/brown{dir = 4},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/carpet,/area/crew_quarters/bar) +"aMw" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eva_inner"; locked = 1; name = "EVA Internal Access"; req_access = list(13)},/turf/simulated/floor/plating,/area/maintenance/evahallway) +"aMx" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "chapel"},/area/chapel/main) "aMy" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/carpet,/area/crew_quarters/bar) -"aMz" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/stool/bed/chair/comfy/brown{dir = 8},/turf/simulated/floor/carpet,/area/crew_quarters/bar) +"aMz" = (/obj/structure/bed/chair/comfy/beige,/turf/simulated/floor{icon_state = "grimy"},/area/hallway/secondary/entry/starboard) "aMA" = (/obj/structure/closet/secure_closet/freezer/meat,/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aMB" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aMC" = (/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aMD" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) -"aME" = (/obj/machinery/door/window/eastright{name = "Hydroponics Delivery"; icon_state = "right"; dir = 2; req_access_txt = "35"},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics) +"aME" = (/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/hallway/primary/fore) "aMF" = (/obj/structure/disposalpipe/segment,/obj/structure/window/reinforced{dir = 8},/obj/machinery/alarm{pixel_y = 22},/obj/machinery/camera{c_tag = "Hydroponics Pasture"},/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor{icon_state = "dark"},/area/hydroponics) "aMG" = (/obj/structure/sink/kitchen{pixel_y = 28},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor{icon_state = "dark"},/area/hydroponics) "aMH" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor{icon_state = "dark"},/area/hydroponics) @@ -2015,26 +2016,26 @@ "aMN" = (/obj/structure/sink/kitchen{pixel_y = 28},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "dark"},/area/hydroponics) "aMO" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor{icon_state = "dark"},/area/hydroponics) "aMP" = (/obj/machinery/light{dir = 8},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/wood,/area/library) -"aMQ" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor/wood,/area/library) +"aMQ" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "neutralcorner"; dir = 4},/area/hallway/primary/central_two) "aMR" = (/obj/structure/table/woodentable,/obj/machinery/recharger{pixel_y = 0},/turf/simulated/floor/wood,/area/library) "aMS" = (/obj/structure/table/woodentable,/obj/structure/disposalpipe/segment,/obj/item/weapon/deck,/turf/simulated/floor/wood,/area/library) -"aMT" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/simulated/floor/wood,/area/library) +"aMT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "neutralcorner"; dir = 1},/area/hallway/primary/central_two) "aMU" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/wood,/area/library) "aMV" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/camera{c_tag = "Chapel Crematorium"; dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) "aMW" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) -"aMX" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock{name = "Crematorium"; req_access_txt = "27"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) +"aMX" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_chapel_outer"; locked = 1; name = "Engineering External Access"; req_access = list(10,13)},/obj/effect/decal/cleanable/dirt,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aMY" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) -"aMZ" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) +"aMZ" = (/obj/structure/bed/chair/comfy/brown{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/carpet,/area/crew_quarters/bar) "aNa" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aNb" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) "aNc" = (/obj/machinery/light{dir = 8},/obj/machinery/camera{c_tag = "Chapel North"; dir = 4; network = list("SS13")},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) -"aNd" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "chapel"},/area/chapel/main) +"aNd" = (/obj/structure/bed/chair/comfy/brown{dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/carpet,/area/crew_quarters/bar) "aNe" = (/obj/structure/table,/obj/machinery/light/small,/turf/simulated/floor{icon_state = "chapel"},/area/chapel/main) "aNf" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/chapel/main) "aNg" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/shuttle/arrival/station) "aNh" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry/port) "aNi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/starboard) -"aNj" = (/obj/structure/stool/bed/chair/comfy/beige,/turf/simulated/floor{icon_state = "grimy"},/area/hallway/secondary/entry/starboard) +"aNj" = (/obj/structure/bed/chair/office/dark{dir = 1},/turf/simulated/floor/wood,/area/library) "aNk" = (/turf/simulated/floor{icon_state = "grimy"},/area/hallway/secondary/entry/starboard) "aNl" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green{pixel_x = 1; pixel_y = 5},/turf/simulated/floor{icon_state = "grimy"},/area/hallway/secondary/entry/starboard) "aNm" = (/obj/machinery/vending/cigarette,/turf/simulated/floor{icon_state = "dark"},/area/hallway/secondary/entry/starboard) @@ -2082,8 +2083,8 @@ "aOc" = (/turf/simulated/floor{icon_state = "L15"},/area/hallway/primary/central_one) "aOd" = (/obj/machinery/light{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/turf/simulated/floor,/area/hallway/primary/central_two) "aOe" = (/turf/simulated/floor{icon_state = "neutralcorner"; dir = 4},/area/hallway/primary/central_two) -"aOf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "neutralcorner"; dir = 1},/area/hallway/primary/central_two) -"aOg" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "neutralcorner"; dir = 4},/area/hallway/primary/central_two) +"aOf" = (/obj/structure/bed/chair/office/dark{dir = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/library) +"aOg" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/snacks/chips,/obj/random/single{icon = 'icons/obj/drinks.dmi'; icon_state = "cola"; name = "randomly spawned cola"; spawn_nothing_percentage = 50; spawn_object = /obj/item/weapon/reagent_containers/food/drinks/cans/cola},/turf/simulated/floor/carpet,/area/hallway/secondary/entry/starboard) "aOh" = (/obj/machinery/newscaster{pixel_y = 32},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "neutralcorner"; dir = 1},/area/hallway/primary/central_two) "aOi" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/camera{c_tag = "Central Hallway North-East"; dir = 2},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/hallway/primary/central_two) "aOj" = (/obj/machinery/light{dir = 1},/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/hallway/primary/central_two) @@ -2092,15 +2093,15 @@ "aOm" = (/obj/machinery/alarm{pixel_y = 23},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/hallway/primary/central_two) "aOn" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/hallway/primary/central_two) "aOo" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/obj/machinery/door_control{id = "bar"; name = "Bar Shutters"; pixel_y = 25; throw_range = 15},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) -"aOp" = (/obj/structure/table/reinforced,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/chem_dispenser/soda{pixel_x = 2; pixel_y = 4},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) -"aOq" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/table/reinforced,/obj/machinery/chem_dispenser/beer{pixel_x = -2; pixel_y = 9},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) +"aOp" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "solar_tool_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access = list(13)},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/solar/auxport) +"aOq" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "solar_chapel_pump"; tag_exterior_door = "solar_chapel_outer"; frequency = 1379; id_tag = "solar_chapel_airlock"; tag_interior_door = "solar_chapel_inner"; pixel_x = 25; req_access = list(13); tag_chamber_sensor = "solar_chapel_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_chapel_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "solar_chapel_pump"},/obj/effect/decal/cleanable/dirt,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/decal/warning_stripes,/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "aOr" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) -"aOs" = (/mob/living/carbon/monkey{name = "Pun Pun"; icon_state = "punpun1"},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) +"aOs" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_2_berth_hatch"; locked = 1; name = "Escape Pod"; req_access = list(13)},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) "aOt" = (/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aOu" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/table/reinforced,/obj/item/weapon/flame/lighter/zippo,/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) -"aOv" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/carpet,/area/crew_quarters/bar) +"aOv" = (/obj/structure/table/woodentable,/obj/random/single{icon = 'icons/obj/playing_cards.dmi'; icon_state = "deck"; name = "randomly spawned deck of cards"; spawn_nothing_percentage = 50; spawn_object = /obj/item/weapon/deck},/turf/simulated/floor{icon_state = "grimy"},/area/hallway/secondary/entry/starboard) "aOw" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/carpet,/area/crew_quarters/bar) -"aOx" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/carpet,/area/crew_quarters/bar) +"aOx" = (/obj/structure/bed/chair/comfy/beige{dir = 8},/turf/simulated/floor{icon_state = "grimy"},/area/hallway/secondary/entry/starboard) "aOy" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/light/small{dir = 8},/obj/structure/kitchenspike,/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aOz" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) "aOA" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) @@ -2110,7 +2111,7 @@ "aOE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "green"},/area/hydroponics) "aOF" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor{dir = 1; icon_state = "green"},/area/hydroponics) "aOG" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{dir = 5; icon_state = "green"},/area/hydroponics) -"aOH" = (/obj/machinery/door/airlock/glass{name = "Hydroponics Pasture"; req_access_txt = "35"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hydroponics) +"aOH" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) "aOI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 9; icon_state = "green"},/area/hydroponics) "aOJ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 1; icon_state = "green"},/area/hydroponics) "aOK" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "green"},/area/hydroponics) @@ -2118,8 +2119,8 @@ "aOM" = (/obj/machinery/camera/autoname{dir = 8},/obj/item/device/radio/intercom{pixel_x = 25},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{dir = 5; icon_state = "green"},/area/hydroponics) "aON" = (/turf/simulated/floor/wood,/area/library) "aOO" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/wood,/area/library) -"aOP" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/turf/simulated/floor/wood,/area/library) -"aOQ" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/library) +"aOP" = (/obj/machinery/seed_storage/garden,/turf/simulated/floor{icon_state = "green"; dir = 8},/area/hydroponics) +"aOQ" = (/obj/machinery/light/small{dir = 1},/obj/item/device/radio/intercom{broadcasting = 1; frequency = 1480; name = "Confessional Intercom"; pixel_x = 25},/obj/structure/bed/chair,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aOR" = (/obj/structure/morgue,/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) "aOS" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) "aOT" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor{icon_state = "grimy"},/area/chapel/office) @@ -2134,10 +2135,10 @@ "aPc" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry/port) "aPd" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/secondary/entry/port) "aPe" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/starboard) -"aPf" = (/obj/structure/table/woodentable,/obj/item/weapon/deck,/turf/simulated/floor{icon_state = "grimy"},/area/hallway/secondary/entry/starboard) -"aPg" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/snacks/chips,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/turf/simulated/floor/carpet,/area/hallway/secondary/entry/starboard) +"aPf" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/fancy/cigarettes{pixel_y = 2},/obj/random/single{icon = 'icons/obj/items.dmi'; icon_state = "lighter-g"; name = "randomly spawned lighter"; spawn_nothing_percentage = 50; spawn_object = /obj/item/weapon/flame/lighter},/turf/simulated/floor{icon_state = "grimy"},/area/hallway/secondary/entry/starboard) +"aPg" = (/obj/machinery/seed_storage/garden,/turf/simulated/floor,/area/hydroponics) "aPh" = (/turf/simulated/floor/carpet,/area/hallway/secondary/entry/starboard) -"aPi" = (/obj/structure/stool/bed/chair/comfy/beige{dir = 8},/turf/simulated/floor{icon_state = "grimy"},/area/hallway/secondary/entry/starboard) +"aPi" = (/obj/structure/bed/chair/comfy/beige{tag = "icon-comfychair (NORTH)"; icon_state = "comfychair"; dir = 1},/turf/simulated/floor{icon_state = "grimy"},/area/hallway/secondary/entry/starboard) "aPj" = (/obj/machinery/vending/coffee,/turf/simulated/floor{icon_state = "dark"},/area/hallway/secondary/entry/starboard) "aPk" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{desc = "\"This is a plaque in honour of our comrades on the G4407 Stations. Hopefully TG4407 model can live up to your fame and fortune.\" Scratched in beneath that is a crude image of a meteor and a spaceman. The spaceman is laughing. The meteor is exploding."; dir = 4; icon_state = "plaque"; name = "Comemmorative Plaque"; nitrogen = 30; oxygen = 70; temperature = 80},/area/hallway/secondary/entry/starboard) "aPl" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/hallway/secondary/entry/starboard) @@ -2181,10 +2182,10 @@ "aPX" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/central_two) "aPY" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=EVA2"; location = "Dorm"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/hallway/primary/central_two) "aPZ" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/hallway/primary/central_two) -"aQa" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor{dir = 8; icon_state = "escape"},/area/hallway/secondary/exit) +"aQa" = (/obj/item/weapon/stool{pixel_y = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aQb" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) -"aQc" = (/obj/effect/landmark/start{name = "Bartender"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) -"aQd" = (/obj/machinery/door/window{dir = 4; name = "Bar"; req_access_txt = "25"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) +"aQc" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_1_berth_hatch"; locked = 1; name = "Escape Pod"; req_access = list(13)},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore) +"aQd" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/fore) "aQe" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/crew_quarters/bar) "aQf" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/carpet,/area/crew_quarters/bar) "aQg" = (/obj/machinery/light/small{dir = 4},/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 32},/obj/structure/table/woodentable,/obj/item/ashtray/bronze{pixel_x = -1; pixel_y = 1},/turf/simulated/floor/carpet,/area/crew_quarters/bar) @@ -2197,17 +2198,17 @@ "aQn" = (/turf/simulated/floor,/area/hydroponics) "aQo" = (/obj/structure/disposalpipe/segment,/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "green"; dir = 4},/area/hydroponics) "aQp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hydroponics) -"aQq" = (/obj/machinery/vending/hydroseeds,/turf/simulated/floor{icon_state = "green"; dir = 8},/area/hydroponics) +"aQq" = (/obj/machinery/computer/security/telescreen/entertainment{pixel_x = -32},/obj/item/weapon/stool{pixel_y = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aQr" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hydroponics) "aQs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hydroponics) "aQt" = (/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor{icon_state = "green"; dir = 4},/area/hydroponics) "aQu" = (/obj/machinery/bookbinder{pixel_y = 0},/turf/simulated/floor/wood,/area/library) "aQv" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/wood,/area/library) "aQw" = (/obj/machinery/photocopier,/turf/simulated/floor/wood,/area/library) -"aQx" = (/obj/machinery/door/airlock/glass{name = "Chapel Office"; req_access_txt = "22"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) -"aQy" = (/obj/machinery/door/morgue{dir = 2; name = "Confession Booth (Chaplain)"; req_access_txt = "22"},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) -"aQz" = (/obj/machinery/light/small{dir = 1},/obj/item/device/radio/intercom{broadcasting = 1; frequency = 1480; name = "Confessional Intercom"; pixel_x = 25},/obj/structure/stool/bed/chair,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) -"aQA" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "nuke_shuttle_dock_airlock"; name = "interior access button"; pixel_x = -28; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13"},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry/port) +"aQx" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_tool_outer"; locked = 1; name = "Engineering External Access"; req_access = list(10,13)},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) +"aQy" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_chapel_inner"; locked = 1; name = "Engineering External Access"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible,/obj/effect/decal/cleanable/dirt,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) +"aQz" = (/obj/structure/bed/chair/comfy/brown{dir = 1},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/library) +"aQA" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "E.V.A. Maintenance"; req_one_access = list(1,5,11,18,24)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/ai_monitored/storage/eva) "aQB" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) "aQC" = (/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) "aQD" = (/obj/machinery/vending/snack,/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/hallway/secondary/entry/port) @@ -2217,7 +2218,7 @@ "aQH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) "aQI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) "aQJ" = (/obj/machinery/camera{c_tag = "Arrivals Center"; dir = 4; network = list("SS13")},/obj/structure/extinguisher_cabinet{pixel_x = -24},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry/port) -"aQK" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/fancy/cigarettes{pixel_y = 2},/obj/item/weapon/flame/lighter{pixel_x = 4; pixel_y = 2},/turf/simulated/floor{icon_state = "grimy"},/area/hallway/secondary/entry/starboard) +"aQK" = (/obj/machinery/light/small,/obj/item/device/radio/intercom{broadcasting = 1; frequency = 1480; name = "Confessional Intercom"; pixel_x = 25},/obj/structure/bed/chair{dir = 1},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aQL" = (/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/hallway/secondary/entry/starboard) "aQM" = (/obj/machinery/vending/cola,/turf/simulated/floor{icon_state = "dark"},/area/hallway/secondary/entry/starboard) "aQN" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/turf/simulated/floor,/area/hallway/secondary/entry/starboard) @@ -2250,18 +2251,18 @@ "aRo" = (/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central_two) "aRp" = (/turf/simulated/floor,/area/hallway/primary/central_two) "aRq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/central_two) -"aRr" = (/obj/structure/closet/coffin,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "chapel"; name = "Privacy Shutters"; opacity = 0},/obj/machinery/door/window/eastleft{dir = 8; name = "Coffin Storage"; req_access_txt = "22"},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) +"aRr" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "solar_tool_pump"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_tool_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "solar_tool_pump"; tag_exterior_door = "solar_tool_outer"; frequency = 1379; id_tag = "solar_tool_airlock"; tag_interior_door = "solar_tool_inner"; pixel_x = 25; req_access = list(13); tag_chamber_sensor = "solar_tool_sensor"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/decal/warning_stripes,/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "aRs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/blast/shutters{dir = 2; id = "bar"; layer = 3.1; name = "Bar Shutters"},/turf/simulated/floor/plating,/area/hallway/primary/central_two) "aRt" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/blast/shutters{dir = 8; id = "office_shutter"; layer = 3.1; name = "Office Shutters"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "aRu" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/carpet,/area/crew_quarters/bar) "aRv" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/carpet,/area/crew_quarters/bar) "aRw" = (/obj/machinery/vending/cigarette{pixel_x = 0; pixel_y = 0},/obj/structure/window/reinforced,/turf/simulated/floor/carpet,/area/crew_quarters/bar) -"aRx" = (/obj/machinery/door/airlock{name = "Kitchen cold room"; req_access_txt = "28"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "showroomfloor"},/area/crew_quarters/kitchen) +"aRx" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/maintenance/dormitory) "aRy" = (/obj/structure/table,/obj/item/weapon/hatchet,/obj/item/weapon/minihoe,/turf/simulated/floor{icon_state = "green"; dir = 8},/area/hydroponics) "aRz" = (/obj/machinery/biogenerator,/turf/simulated/floor,/area/hydroponics) "aRA" = (/obj/machinery/seed_extractor,/turf/simulated/floor,/area/hydroponics) "aRB" = (/obj/machinery/vending/hydronutrients,/turf/simulated/floor,/area/hydroponics) -"aRC" = (/obj/machinery/vending/hydroseeds,/turf/simulated/floor,/area/hydroponics) +"aRC" = (/obj/item/weapon/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Gardener"},/turf/simulated/floor{dir = 9; icon_state = "green"},/area/hydroponics/garden) "aRD" = (/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/disposal,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{icon_state = "green"; dir = 4},/area/hydroponics) "aRE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hydroponics) "aRF" = (/obj/machinery/vending/hydronutrients,/turf/simulated/floor{icon_state = "green"; dir = 8},/area/hydroponics) @@ -2296,15 +2297,15 @@ "aSi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/hallway/secondary/entry/port) "aSj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor{icon_state = "warningcorner"; dir = 4},/area/hallway/secondary/entry/port) "aSk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/starboard) -"aSl" = (/obj/structure/stool/bed/chair/comfy/beige{tag = "icon-comfychair (NORTH)"; icon_state = "comfychair"; dir = 1},/turf/simulated/floor{icon_state = "grimy"},/area/hallway/secondary/entry/starboard) +"aSl" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/bridge) "aSm" = (/obj/machinery/vending/snack,/turf/simulated/floor{icon_state = "dark"},/area/hallway/secondary/entry/starboard) "aSn" = (/obj/structure/cable/green,/obj/machinery/power/apc/high{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor,/area/hallway/secondary/entry/starboard) -"aSo" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/port) +"aSo" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/dormitory) "aSp" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/turf/simulated/floor,/area/hallway/primary/port) "aSq" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/port) "aSr" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/hallway/primary/port) "aSs" = (/obj/machinery/door/airlock/glass{name = "Art Storage"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hallway/primary/port) -"aSt" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/hallway/primary/port) +"aSt" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/dormitory) "aSu" = (/obj/structure/table,/turf/simulated/floor,/area/hallway/primary/port) "aSv" = (/obj/structure/table,/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor,/area/hallway/primary/port) "aSw" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/structure/closet/emcloset,/turf/simulated/floor,/area/hallway/primary/port) @@ -2314,19 +2315,19 @@ "aSA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aSB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aSC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) -"aSD" = (/obj/machinery/light/small{dir = 1},/obj/machinery/power/smes/buildable{charge = 5e+006; input_attempt = 1; output_level = 100000},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"aSD" = (/obj/structure/bed/chair{dir = 1},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/bridge) "aSE" = (/obj/machinery/flasher{pixel_x = 0; pixel_y = 24; id = "AI"},/obj/structure/cable/cyan{d2 = 4; icon_state = "0-4"},/obj/structure/cable/cyan{d2 = 2; icon_state = "0-2"},/obj/machinery/power/sensor{name = "Powernet Sensor - AI Subgrid"; name_tag = "AI Subgrid"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "aSF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/blast/shutters{dir = 8; id = "office_shutter"; layer = 3.1; name = "Office Shutters"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "aSG" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only,/obj/machinery/door/blast/shutters{dir = 2; id = "kitchen"; layer = 3.3; name = "Kitchen Shutters"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/hallway/primary/starboard) -"aSH" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/donut_box,/obj/machinery/door/firedoor/border_only,/obj/machinery/door/blast/shutters{dir = 2; id = "kitchen"; layer = 3.3; name = "Kitchen Shutters"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/hallway/primary/starboard) +"aSH" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/window/brigdoor{name = "Visitation Window"; req_access = list(63)},/turf/simulated/floor,/area/security/prison) "aSI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "heads_meeting"; name = "Meeting Room Window Shutters"; opacity = 0},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aSJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_two) "aSK" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_two) "aSL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_two) "aSM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_two) "aSN" = (/turf/simulated/floor{dir = 1; icon_state = "bluecorner"},/area/hallway/primary/central_two) -"aSO" = (/obj/machinery/computer/security/telescreen/entertainment{pixel_x = -32},/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"aSP" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) +"aSO" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/bridge) +"aSP" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aSQ" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aSR" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aSS" = (/turf/simulated/floor/wood,/area/crew_quarters/bar) @@ -2336,7 +2337,7 @@ "aSW" = (/obj/machinery/disposal,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aSX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/crew_quarters/kitchen) "aSY" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) -"aSZ" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/glass{name = "Hydroponics Pasture"; req_access_txt = "28"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"aSZ" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "arrivals_outer"; locked = 1; name = "Engineering External Access"; req_access = list(10,13)},/turf/simulated/floor/plating,/area/maintenance/arrivals) "aTa" = (/obj/machinery/smartfridge,/turf/simulated/wall,/area/crew_quarters/kitchen) "aTb" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/crew_quarters/kitchen) "aTc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/crew_quarters/kitchen) @@ -2347,7 +2348,7 @@ "aTh" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/wood,/area/library) "aTi" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/wood,/area/library) "aTj" = (/obj/machinery/light/small,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/library) -"aTk" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 1},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/library) +"aTk" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aTl" = (/obj/structure/cult/tome,/obj/item/clothing/under/suit_jacket/red,/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/library) "aTm" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 1; icon_state = "chapel"},/area/chapel/main) "aTn" = (/turf/simulated/floor{dir = 4; icon_state = "chapel"},/area/chapel/main) @@ -2355,7 +2356,7 @@ "aTp" = (/turf/simulated/floor{dir = 1; icon_state = "chapel"},/area/chapel/main) "aTq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 4; icon_state = "chapel"},/area/chapel/main) "aTr" = (/obj/machinery/door/morgue{dir = 2; name = "Confession Booth"},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) -"aTs" = (/obj/machinery/light/small,/obj/item/device/radio/intercom{broadcasting = 1; frequency = 1480; name = "Confessional Intercom"; pixel_x = 25},/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) +"aTs" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/bed/chair/wood/wings,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aTt" = (/obj/machinery/vending/cola,/turf/simulated/floor{icon_state = "dark"},/area/hallway/secondary/exit) "aTu" = (/obj/machinery/lapvend,/turf/simulated/floor{icon_state = "dark"},/area/hallway/secondary/exit) "aTv" = (/obj/structure/closet/emcloset,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/hallway/secondary/exit) @@ -2378,7 +2379,7 @@ "aTM" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/hallway/secondary/entry/starboard) "aTN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "neutralcorner"; dir = 1},/area/hallway/secondary/entry/starboard) "aTO" = (/obj/machinery/atm{pixel_x = 24},/turf/simulated/floor,/area/hallway/secondary/entry/starboard) -"aTP" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/maintenance/locker) +"aTP" = (/obj/machinery/door/airlock{name = "Brig Restroom"},/turf/simulated/floor,/area/security/prison) "aTQ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/locker) "aTR" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/locker) "aTS" = (/turf/simulated/wall,/area/crew_quarters/locker) @@ -2398,9 +2399,9 @@ "aUg" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/storage/art) "aUh" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor,/area/storage/art) "aUi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/locker) -"aUj" = (/obj/machinery/door/airlock{name = "Port Emergency Storage"; req_access_txt = "0"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/hallway/primary/port) +"aUj" = (/obj/structure/bed/chair{dir = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod{frequency = 1380; id_tag = "escape_pod_1"; pixel_x = -25; pixel_y = 0; tag_door = "escape_pod_1_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod1/station) "aUk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/primary/port) -"aUl" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass{name = "Auxiliary Tool Storage"; req_access_txt = "12"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/port) +"aUl" = (/obj/structure/bed/chair{dir = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod{frequency = 1380; id_tag = "escape_pod_2"; pixel_x = -25; pixel_y = 0; tag_door = "escape_pod_2_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod2/station) "aUm" = (/turf/simulated/wall,/area/storage/tools) "aUn" = (/obj/machinery/light{dir = 8},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor,/area/hallway/primary/central_one) "aUo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_one) @@ -2437,7 +2438,7 @@ "aUT" = (/obj/structure/closet/secure_closet/freezer/kitchen,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "aUU" = (/obj/machinery/light_switch{pixel_y = 28},/turf/simulated/floor{icon_state = "grimy"},/area/hydroponics/garden) "aUV" = (/obj/structure/table/reinforced,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor{icon_state = "grimy"},/area/hydroponics/garden) -"aUW" = (/obj/structure/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Gardener"},/turf/simulated/floor{dir = 9; icon_state = "green"},/area/hydroponics/garden) +"aUW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/bed/chair/wood/wings,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aUX" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{dir = 1; icon_state = "green"},/area/hydroponics/garden) "aUY" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 5; icon_state = "green"},/area/hydroponics/garden) "aUZ" = (/obj/structure/flora/ausbushes/brflowers,/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/grass,/area/hydroponics/garden) @@ -2446,7 +2447,7 @@ "aVc" = (/obj/structure/bookcase{name = "bookcase (Fiction)"},/turf/simulated/floor/wood,/area/library) "aVd" = (/obj/structure/bookcase{name = "bookcase (Non-Fiction)"},/turf/simulated/floor/wood,/area/library) "aVe" = (/obj/machinery/camera{c_tag = "Library South"; dir = 8; network = list("SS13")},/turf/simulated/floor/wood,/area/library) -"aVf" = (/obj/machinery/door/morgue{dir = 2; name = "Private Study"; req_access_txt = "37"},/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/library) +"aVf" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "arrivals_pump"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "arrivals_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "arrivals_pump"; tag_exterior_door = "arrivals_outer"; frequency = 1379; id_tag = "arrivals_airlock"; tag_interior_door = "arrivals_inner"; pixel_x = 25; req_access = list(13); tag_chamber_sensor = "arrivals_sensor"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/arrivals) "aVg" = (/obj/machinery/light{dir = 8},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aVh" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 8; icon_state = "chapel"},/area/chapel/main) "aVi" = (/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/chapel/main) @@ -2475,7 +2476,7 @@ "aVF" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/storage/art) "aVG" = (/turf/simulated/wall,/area/storage/emergency2) "aVH" = (/obj/machinery/light_switch{pixel_y = 28},/obj/structure/closet/hydrant{pixel_x = -32},/turf/simulated/floor/plating,/area/storage/emergency2) -"aVI" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "5;12;47"},/turf/simulated/floor/plating,/area/hallway/primary/starboard) +"aVI" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "arrivals_inner"; locked = 1; name = "Engineering External Access"; req_access = list(13)},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/arrivals) "aVJ" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/research_port) "aVK" = (/turf/simulated/floor/plating,/area/storage/emergency2) "aVL" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/machinery/camera{c_tag = "Auxiliary Tool Storage"; dir = 2},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor,/area/storage/tools) @@ -2485,29 +2486,29 @@ "aVP" = (/obj/structure/table,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor,/area/storage/tools) "aVQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/primary/central_one) "aVR" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor{icon_state = "red"; dir = 9},/area/bridge) -"aVS" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/bridge) +"aVS" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aVT" = (/turf/simulated/floor{icon_state = "red"; dir = 1},/area/bridge) "aVU" = (/obj/machinery/computer/rcon,/turf/simulated/floor{dir = 6; icon_state = "whitehall"},/area/bridge) "aVV" = (/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/bridge) -"aVW" = (/obj/structure/stool/bed/chair{dir = 1},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/bridge) +"aVW" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aVX" = (/turf/simulated/floor{dir = 5; icon_state = "blue"},/area/bridge) "aVY" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/computer/shuttle_control/mining,/turf/simulated/floor{icon_state = "red"; dir = 9},/area/bridge) "aVZ" = (/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/bridge) -"aWa" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/bridge) +"aWa" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "grimy"},/area/hydroponics/garden) "aWb" = (/turf/simulated/floor{icon_state = "whitehall"; dir = 5},/area/bridge) "aWc" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/primary/central_two) -"aWd" = (/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/bar) +"aWd" = (/obj/item/weapon/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Gardener"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "green"; dir = 8},/area/hydroponics/garden) "aWe" = (/obj/item/weapon/reagent_containers/food/condiment/peppermill{pixel_x = 2; pixel_y = 6},/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/condiment/saltshaker{pixel_x = -2; pixel_y = 4},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"aWf" = (/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"aWg" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/stool/bed/chair/wood/wings,/turf/simulated/floor/wood,/area/crew_quarters/bar) -"aWh" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/stool/bed/chair/wood/wings,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/crew_quarters/bar) +"aWf" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor{dir = 8; icon_state = "escape"},/area/hallway/secondary/exit) +"aWg" = (/obj/item/weapon/stool{pixel_y = 8},/turf/simulated/floor,/area/crew_quarters/locker) +"aWh" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aWi" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"aWj" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/crew_quarters/bar) +"aWj" = (/obj/item/weapon/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Gardener"},/turf/simulated/floor{icon_state = "green"; dir = 8},/area/hydroponics/garden) "aWk" = (/obj/structure/table/woodentable,/obj/item/weapon/kitchen/utensil/fork,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"aWl" = (/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/wood,/area/crew_quarters/bar) +"aWl" = (/obj/structure/bed/chair/comfy/black,/turf/simulated/floor/wood,/area/library) "aWm" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aWn" = (/obj/structure/table/reinforced,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) -"aWo" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Kitchen"; req_access_txt = "28"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"aWo" = (/obj/machinery/door/airlock/engineering{icon_state = "door_closed"; locked = 0; name = "Fore Port Solar Access"; req_access = list(10)},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "aWp" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "aWq" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "aWr" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) @@ -2515,16 +2516,16 @@ "aWt" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "aWu" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "aWv" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) -"aWw" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Kitchen"; req_access_txt = "28"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/hydroponics/garden) -"aWx" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "grimy"},/area/hydroponics/garden) +"aWw" = (/obj/machinery/door/airlock/glass_engineering{name = "Engineering Hardsuits"; req_one_access = list(11,24)},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) +"aWx" = (/obj/item/device/radio/intercom{pixel_x = 28},/obj/machinery/libraryscanner,/turf/simulated/floor/wood,/area/library) "aWy" = (/obj/structure/table/reinforced,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "grimy"},/area/hydroponics/garden) -"aWz" = (/obj/structure/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Gardener"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "green"; dir = 8},/area/hydroponics/garden) +"aWz" = (/obj/effect/landmark/start{name = "Librarian"},/obj/structure/bed/chair/office/dark,/turf/simulated/floor/wood,/area/library) "aWA" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hydroponics/garden) "aWB" = (/turf/simulated/floor{icon_state = "green"; dir = 4},/area/hydroponics/garden) "aWC" = (/obj/structure/flora/bush,/turf/simulated/floor/grass,/area/hydroponics/garden) "aWD" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/grass,/area/hydroponics/garden) "aWE" = (/obj/structure/flora/ausbushes/sparsegrass,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/grass,/area/hydroponics/garden) -"aWF" = (/obj/machinery/door/window/northright{base_state = "right"; dir = 8; icon_state = "right"; name = "Library Desk Door"; req_access_txt = "37"},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/library) +"aWF" = (/obj/machinery/door/airlock{name = "Unisex Showers"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "aWG" = (/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/wood,/area/library) "aWH" = (/obj/structure/table/woodentable,/obj/machinery/librarycomp{pixel_y = 0},/obj/machinery/light/small{dir = 4},/obj/machinery/light_switch{pixel_y = 28},/turf/simulated/floor/wood,/area/library) "aWI" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) @@ -2552,7 +2553,7 @@ "aXe" = (/turf/simulated/floor/plating,/area/maintenance/locker) "aXf" = (/obj/effect/decal/cleanable/generic,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/maintenance/locker) "aXg" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/closet/wardrobe/white,/turf/simulated/floor,/area/crew_quarters/locker) -"aXh" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/floor,/area/crew_quarters/locker) +"aXh" = (/obj/item/weapon/stool,/turf/simulated/floor{icon_state = "chapel"},/area/chapel/main) "aXi" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/turf/simulated/floor,/area/crew_quarters/locker) "aXj" = (/obj/structure/table,/turf/simulated/floor,/area/crew_quarters/locker) "aXk" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/crew_quarters/locker) @@ -2579,7 +2580,7 @@ "aXF" = (/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/bridge) "aXG" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/bridge) "aXH" = (/turf/simulated/floor{dir = 4; icon_state = "escapecorner"},/area/bridge) -"aXI" = (/obj/structure/table,/obj/machinery/camera{c_tag = "Bridge East"; dir = 2},/obj/item/weapon/storage/donut_box,/obj/structure/noticeboard{pixel_y = 27},/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/bridge) +"aXI" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/maintenance{name = "Bar Maintenance"; req_access = list(25)},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/crew_quarters/bar) "aXJ" = (/obj/machinery/computer/med_data,/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/bridge) "aXK" = (/turf/simulated/wall,/area/maintenance/substation/medical) "aXL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/central_two) @@ -2588,13 +2589,13 @@ "aXO" = (/obj/structure/table/woodentable,/obj/item/weapon/kitchen/utensil/fork,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aXP" = (/obj/structure/disposalpipe/segment,/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aXQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table/woodentable,/obj/item/weapon/deck{pixel_y = 4},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"aXR" = (/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/crew_quarters/bar) +"aXR" = (/obj/item/weapon/stool,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 8; icon_state = "chapel"},/area/chapel/main) "aXS" = (/obj/structure/table/woodentable,/obj/item/device/camera,/turf/simulated/floor/wood,/area/crew_quarters/bar) "aXT" = (/obj/structure/table/reinforced,/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "aXU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/crew_quarters/kitchen) "aXV" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "aXW" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/snacks/mint,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) -"aXX" = (/obj/structure/table,/obj/machinery/chem_dispenser/soda,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) +"aXX" = (/obj/effect/decal/cleanable/blood/oil,/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor/plating,/area/maintenance/arrivals) "aXY" = (/obj/structure/table,/obj/item/weapon/kitchen/rollingpin,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "aXZ" = (/obj/structure/table,/obj/item/weapon/book/manual/chef_recipes,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "aYa" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) @@ -2602,34 +2603,34 @@ "aYc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/hydroponics/garden) "aYd" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "grimy"},/area/hydroponics/garden) "aYe" = (/obj/structure/table/reinforced,/turf/simulated/floor{icon_state = "grimy"},/area/hydroponics/garden) -"aYf" = (/obj/structure/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Gardener"},/turf/simulated/floor{icon_state = "green"; dir = 8},/area/hydroponics/garden) +"aYf" = (/obj/item/weapon/stool,/turf/simulated/floor{dir = 8; icon_state = "chapel"},/area/chapel/main) "aYg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hydroponics/garden) "aYh" = (/obj/structure/flora/ausbushes/brflowers,/turf/simulated/floor/grass,/area/hydroponics/garden) "aYi" = (/obj/structure/flora/ausbushes/sunnybush,/obj/item/device/radio/intercom{pixel_x = 25},/turf/simulated/floor/grass,/area/hydroponics/garden) "aYj" = (/obj/structure/bookcase{name = "bookcase (Adult)"},/turf/simulated/floor/wood,/area/library) -"aYk" = (/obj/structure/stool/bed/chair/comfy/black,/turf/simulated/floor/wood,/area/library) +"aYk" = (/obj/item/weapon/stool,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "chapel"},/area/chapel/main) "aYl" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green{pixel_x = 1; pixel_y = 5},/turf/simulated/floor/wood,/area/library) -"aYm" = (/obj/effect/landmark/start{name = "Librarian"},/obj/structure/stool/bed/chair/office/dark,/turf/simulated/floor/wood,/area/library) -"aYn" = (/obj/item/device/radio/intercom{pixel_x = 25},/obj/machinery/libraryscanner,/turf/simulated/floor/wood,/area/library) -"aYo" = (/obj/structure/stool,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 8; icon_state = "chapel"},/area/chapel/main) -"aYp" = (/obj/structure/stool,/turf/simulated/floor{icon_state = "chapel"},/area/chapel/main) -"aYq" = (/obj/structure/stool,/turf/simulated/floor{dir = 8; icon_state = "chapel"},/area/chapel/main) +"aYm" = (/obj/structure/bed/chair{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{dir = 8; icon_state = "escape"},/area/hallway/secondary/exit) +"aYn" = (/obj/structure/bed/chair{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/bridge) +"aYo" = (/obj/structure/bed/chair{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/bridge) +"aYp" = (/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) +"aYq" = (/obj/machinery/door/airlock/maintenance{name = "Security Maintenance"; req_access = list(1)},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/security/checkpoint2) "aYr" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/blast/shutters{dir = 1; id = "office_shutter"; layer = 3.1; name = "Office Shutters"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/starboard) "aYs" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) -"aYt" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "escape"},/area/hallway/secondary/exit) +"aYt" = (/obj/structure/bed/chair/comfy/black{dir = 8},/turf/simulated/floor/wood,/area/library) "aYu" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/secondary/exit) "aYv" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/floor,/area/hallway/secondary/exit) -"aYw" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "escape_dock_north_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor,/area/hallway/secondary/exit) -"aYx" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_dock_north_inner"; locked = 1; name = "Escape Airlock"; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/mech_sensor{dir = 8; frequency = 1380; id_tag = "escape_dock_north_mech"; pixel_y = -19},/turf/simulated/floor/plating,/area/hallway/secondary/exit) -"aYy" = (/obj/machinery/light/small,/obj/machinery/embedded_controller/radio/airlock/docking_port_multi{frequency = 1380; id_tag = "escape_dock_north_airlock"; master_tag = "escape_dock"; pixel_y = 30; req_one_access_txt = "13"; tag_airlock_mech_sensor = "escape_dock_north_mech"; tag_airpump = "escape_dock_north_pump"; tag_chamber_sensor = "escape_dock_north_sensor"; tag_exterior_door = "escape_dock_north_outer"; tag_interior_door = "escape_dock_north_inner"; tag_shuttle_mech_sensor = "shuttle_dock_north_mech"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1380; id_tag = "escape_dock_north_pump"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) +"aYw" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/storage/primary) +"aYx" = (/obj/machinery/door/airlock{name = "Unisex Restrooms"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep) +"aYy" = (/obj/machinery/power/breakerbox/activated{RCon_tag = "Civilian East Substation Bypass"},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_east) "aYz" = (/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "escape_dock_north_sensor"; pixel_x = 0; pixel_y = -25},/turf/simulated/floor/plating,/area/hallway/secondary/exit) -"aYA" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_dock_north_outer"; locked = 1; name = "Escape Airlock"; req_access_txt = "13"},/obj/machinery/mech_sensor{dir = 8; frequency = 1380; id_tag = "escape_dock_north_mech"; pixel_y = -19},/turf/simulated/floor/plating,/area/hallway/secondary/exit) +"aYA" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_command{name = "E.V.A."; req_one_access = list(1,5,11,18,24)},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) "aYB" = (/turf/space,/area/shuttle/transport1/station) "aYC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "aYD" = (/obj/structure/closet/emcloset,/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/hallway/secondary/entry/aft) "aYE" = (/turf/simulated/floor{dir = 8; icon_state = "whitecorner"},/area/hallway/secondary/entry/port) "aYF" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/secondary/entry/aft) -"aYG" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{dir = 8; icon_state = "escape"},/area/hallway/secondary/exit) +"aYG" = (/obj/item/weapon/stool,/turf/simulated/floor{dir = 4; icon_state = "chapel"},/area/chapel/main) "aYH" = (/obj/structure/table,/turf/simulated/floor,/area/security/vacantoffice) "aYI" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/security/vacantoffice) "aYJ" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/vacantoffice) @@ -2644,22 +2645,22 @@ "aYS" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/locker) "aYT" = (/obj/structure/closet/wardrobe/grey,/obj/machinery/requests_console{department = "Locker Room"; pixel_x = -32; pixel_y = 0},/turf/simulated/floor,/area/crew_quarters/locker) "aYU" = (/obj/structure/table,/obj/item/clothing/head/soft/grey{pixel_x = -2; pixel_y = 3},/turf/simulated/floor,/area/crew_quarters/locker) -"aYV" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "nuke_shuttle_dock_airlock"; name = "exterior access button"; pixel_x = -5; pixel_y = 32; req_access_txt = "0"; req_one_access_txt = "13"},/turf/space,/area/space) +"aYV" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/maintenance/bar) "aYW" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/crew_quarters/locker) -"aYX" = (/obj/machinery/light/small{dir = 1},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/camera{c_tag = "Medical Substation"; dir = 2; network = list("SS13","Engineering")},/turf/simulated/floor/plating,/area/maintenance/substation/medical) +"aYX" = (/obj/item/weapon/stool,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 1; icon_state = "chapel"},/area/chapel/main) "aYY" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor,/area/storage/tools) "aYZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/storage/tools) "aZa" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 32},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/turf/simulated/floor{dir = 5; icon_state = "blue"},/area/hallway/primary/central_one) "aZb" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/bridge) "aZc" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/hallway/secondary/exit) "aZd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/bridge) -"aZe" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/bridge) +"aZe" = (/obj/item/weapon/stool,/turf/simulated/floor{dir = 1; icon_state = "chapel"},/area/chapel/main) "aZf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/bridge) "aZg" = (/obj/item/device/radio/beacon,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/bridge) "aZh" = (/obj/machinery/hologram/holopad,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/bridge) -"aZi" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/bridge) +"aZi" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "escape"},/area/hallway/secondary/exit) "aZj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{icon_state = "whitehall"; dir = 4},/area/bridge) -"aZk" = (/obj/structure/stool,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "chapel"},/area/chapel/main) +"aZk" = (/obj/structure/bed/chair/office/light{dir = 8},/turf/simulated/floor,/area/security/vacantoffice) "aZl" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 32},/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/hallway/primary/central_two) "aZm" = (/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/hallway/primary/central_two) "aZn" = (/obj/machinery/camera{c_tag = "Bridge East Entrance"; dir = 2},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/hallway/primary/central_two) @@ -2670,24 +2671,24 @@ "aZs" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/reagent_containers/glass/beaker{pixel_x = 5},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) "aZt" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/condiment/saltshaker{pixel_x = -3; pixel_y = 0},/obj/item/weapon/reagent_containers/food/condiment/peppermill{pixel_x = 3},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) "aZu" = (/obj/structure/table,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) -"aZv" = (/obj/machinery/processor,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/crew_quarters/kitchen) +"aZv" = (/obj/structure/bed/chair/office/dark{dir = 4},/turf/simulated/floor,/area/security/vacantoffice) "aZw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hydroponics/garden) "aZx" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/grass,/area/hydroponics/garden) "aZy" = (/obj/structure/flora/ausbushes/brflowers,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/grass,/area/hydroponics/garden) "aZz" = (/turf/simulated/wall,/area/hallway/primary/starboard) -"aZA" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/starboard) +"aZA" = (/obj/structure/disposalpipe/segment,/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aZB" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/carpet,/area/library) "aZC" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/carpet,/area/library) "aZD" = (/obj/structure/table/woodentable,/obj/item/weapon/paper,/turf/simulated/floor/wood,/area/library) -"aZE" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/simulated/floor/wood,/area/library) +"aZE" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/wood,/area/crew_quarters/bar) "aZF" = (/obj/structure/table/woodentable,/obj/item/device/camera_film,/obj/item/device/camera_film,/turf/simulated/floor/wood,/area/library) "aZG" = (/obj/structure/table/woodentable,/obj/item/weapon/pen/red{pixel_x = 2; pixel_y = 6},/obj/item/weapon/pen/blue{pixel_x = 5; pixel_y = 5},/turf/simulated/floor/wood,/area/library) "aZH" = (/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/library) "aZI" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/turf/simulated/floor/wood,/area/library) "aZJ" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) -"aZK" = (/obj/structure/stool,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 1; icon_state = "chapel"},/area/chapel/main) -"aZL" = (/obj/structure/stool,/turf/simulated/floor{dir = 4; icon_state = "chapel"},/area/chapel/main) -"aZM" = (/obj/structure/stool,/turf/simulated/floor{dir = 1; icon_state = "chapel"},/area/chapel/main) +"aZK" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/bar) +"aZL" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 2; sortType = "Library"; name = "Library"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/primary/starboard) +"aZM" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/smartfridge/drying_rack,/turf/simulated/floor{dir = 9; icon_state = "green"},/area/hydroponics/garden) "aZN" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/hallway/secondary/exit) "aZO" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/hallway/secondary/exit) "aZP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/hallway/secondary/exit) @@ -2700,9 +2701,9 @@ "aZW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/secondary/entry/aft) "aZX" = (/obj/machinery/hologram/holopad,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) "aZY" = (/obj/structure/table,/obj/item/ashtray/plastic{pixel_x = 4; pixel_y = 6},/turf/simulated/floor,/area/security/vacantoffice) -"aZZ" = (/obj/structure/stool/bed/chair/office/light{dir = 8},/turf/simulated/floor,/area/security/vacantoffice) +"aZZ" = (/obj/structure/disposalpipe/segment,/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/hallway/primary/starboard) "baa" = (/turf/simulated/floor,/area/security/vacantoffice) -"bab" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor,/area/security/vacantoffice) +"bab" = (/obj/structure/bed/chair/office/dark{dir = 8},/turf/simulated/floor,/area/security/vacantoffice) "bac" = (/obj/structure/table,/obj/structure/window/basic{dir = 4},/obj/item/weapon/folder/blue{pixel_x = 5},/turf/simulated/floor,/area/security/vacantoffice) "bad" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/security/vacantoffice) "bae" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/vacantoffice) @@ -2740,9 +2741,9 @@ "baK" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/hallway/primary/central_one) "baL" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/hallway/primary/central_one) "baM" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/hallway/primary/central_one) -"baN" = (/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access_txt = "19"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/bridge) +"baN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/bar) "baO" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/chapel/main) -"baP" = (/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access_txt = "19"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/bridge) +"baP" = (/obj/machinery/door/airlock/maintenance{name = "Chapel Maintenance"; req_one_access = list(12,22)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/chapel/main) "baQ" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/bridge) "baR" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/bridge) "baS" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "bluecorner"},/area/bridge) @@ -2751,16 +2752,16 @@ "baV" = (/obj/machinery/light,/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = -32},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "baW" = (/obj/machinery/camera{c_tag = "Bridge Center"; dir = 1},/obj/machinery/requests_console{announcementConsole = 1; department = "Bridge"; departmentType = 5; name = "Bridge RC"; pixel_y = -30},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "baX" = (/obj/structure/closet/fireaxecabinet{pixel_y = -32},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) -"baY" = (/obj/machinery/door_control{id = "bridge blast"; name = "Bridge Blast Door Control"; pixel_x = -1; pixel_y = -24; req_access_txt = "19"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) +"baY" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_east) "baZ" = (/obj/machinery/light,/obj/machinery/newscaster{pixel_y = -28},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "bba" = (/obj/machinery/light_switch{pixel_y = -25},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "bbb" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/bridge) "bbc" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/bridge) "bbd" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/bridge) "bbe" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/bridge) -"bbf" = (/obj/machinery/door/airlock/glass_command{id_tag = "sbridgedoor"; name = "Bridge"; req_access_txt = "19"},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/bridge) +"bbf" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_east) "bbg" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/bridge) -"bbh" = (/obj/machinery/door/airlock/glass_command{id_tag = "sbridgedoor"; name = "Bridge"; req_access_txt = "19"},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/bridge) +"bbh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/engineering{name = "Civilian West Substation"; req_one_access = list(11,24)},/turf/simulated/floor/plating,/area/maintenance/substation/civilian_west) "bbi" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/hallway/primary/central_two) "bbj" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/hallway/primary/central_two) "bbk" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/hallway/primary/central_two) @@ -2768,10 +2769,10 @@ "bbm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor,/area/hallway/primary/central_two) "bbn" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/hallway/primary/central_two) "bbo" = (/obj/structure/table/woodentable,/obj/item/weapon/flame/candle,/turf/simulated/floor/wood,/area/crew_quarters/bar) -"bbp" = (/obj/structure/disposalpipe/segment,/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"bbq" = (/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/wood,/area/crew_quarters/bar) +"bbp" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/tank/air{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/locker) +"bbq" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor,/area/hallway/primary/starboard) "bbr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/bar) -"bbs" = (/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/bar) +"bbs" = (/obj/structure/bed/chair/comfy/black{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/wood,/area/library) "bbt" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/food/snacks/pie,/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar) "bbu" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bbv" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) @@ -2783,7 +2784,7 @@ "bbB" = (/turf/simulated/floor{icon_state = "green"; dir = 8},/area/hydroponics/garden) "bbC" = (/obj/structure/flora/ausbushes/fernybush,/turf/simulated/floor/grass,/area/hydroponics/garden) "bbD" = (/obj/structure/flora/ausbushes/brflowers,/obj/machinery/camera/autoname{dir = 8},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/grass,/area/hydroponics/garden) -"bbE" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 2; sortType = "Library"; name = "Library"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/primary/starboard) +"bbE" = (/obj/structure/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/wood,/area/library) "bbF" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/hallway/primary/starboard) "bbG" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Library"},/turf/simulated/floor/carpet,/area/hallway/primary/starboard) "bbH" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/carpet,/area/library) @@ -2794,10 +2795,10 @@ "bbM" = (/turf/simulated/floor{icon_state = "warningcorner"; dir = 8},/area/hallway/secondary/exit) "bbN" = (/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/hallway/secondary/exit) "bbO" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/secondary/exit) -"bbP" = (/obj/structure/lattice,/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "escape_dock_north_airlock"; name = "exterior access button"; pixel_x = 5; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13"},/turf/space,/area/space) -"bbQ" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "centcom_shuttle_dock_outer"; locked = 1; name = "Docking Port Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) -"bbR" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "centcom_shuttle_dock_airlock"; pixel_x = 0; pixel_y = 30; req_access_txt = "0"; req_one_access_txt = "13"; tag_airpump = "centcom_shuttle_dock_pump"; tag_chamber_sensor = "centcom_shuttle_dock_sensor"; tag_exterior_door = "centcom_shuttle_dock_outer"; tag_interior_door = "centcom_shuttle_dock_inner"},/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "centcom_shuttle_dock_sensor"; pixel_x = 0; pixel_y = -25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "centcom_shuttle_dock_pump"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) -"bbS" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "centcom_shuttle_dock_inner"; locked = 1; name = "Docking Port Airlock"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) +"bbP" = (/obj/machinery/door/airlock/maintenance{name = "Library Maintenance"; req_one_access = list(12,37)},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/library) +"bbQ" = (/obj/machinery/door/airlock/maintenance{name = "Crematorium Maintenance"; req_access = list(27)},/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/chapel/office) +"bbR" = (/obj/structure/closet/coffin,/obj/machinery/door/window/eastleft{name = "Coffin Storage"; req_access = list(22)},/turf/simulated/floor{icon_state = "dark"},/area/chapel/main) +"bbS" = (/obj/machinery/door/window{dir = 8; name = "Mass Driver"; req_access = list(22)},/obj/machinery/mass_driver{dir = 4; id = "chapelgun"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/machinery/airlock_sensor{pixel_y = 25},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/chapel/main) "bbT" = (/obj/structure/table,/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/weapon/tape_roll,/turf/simulated/floor,/area/crew_quarters/locker) "bbU" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/secondary/entry/aft) "bbV" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/security/vacantoffice) @@ -2805,7 +2806,7 @@ "bbX" = (/obj/structure/table/rack{dir = 4},/obj/item/clothing/mask/gas,/turf/simulated/floor/plating,/area/maintenance/locker) "bbY" = (/obj/machinery/atmospherics/valve,/turf/simulated/floor/plating,/area/maintenance/locker) "bbZ" = (/turf/simulated/wall,/area/crew_quarters/locker/locker_toilet) -"bca" = (/obj/machinery/door/airlock{name = "Unisex Restrooms"; req_access_txt = "0"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet) +"bca" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/bar) "bcb" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/crew_quarters/locker) "bcc" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/crew_quarters/locker) "bcd" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "warningcorner"; dir = 2},/area/crew_quarters/locker) @@ -2817,7 +2818,7 @@ "bcj" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/locker) "bck" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bcl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/power/terminal{dir = 8},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable,/turf/simulated/floor/plating,/area/maintenance/substation/medical) -"bcm" = (/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Medical Substation"},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/maintenance/substation/medical) +"bcm" = (/obj/structure/bed/chair/comfy/black{dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/wood,/area/library) "bcn" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 2; sortType = "Robotics"; name = "Robotics"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/research_port) "bco" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/maintenance/locker) "bcp" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/storage/tools) @@ -2846,17 +2847,17 @@ "bcM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/crew_quarters/bar) "bcN" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/bar) "bcO" = (/turf/simulated/floor{icon_state = "wood"},/area/crew_quarters/bar) -"bcP" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass{name = "Kitchen"; req_access_txt = "28"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"bcP" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/maintenance/bar) "bcQ" = (/obj/machinery/light_switch{pixel_x = 16; pixel_y = -23},/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bcR" = (/obj/machinery/light,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) "bcS" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) -"bcT" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/door_control{id = "kitchen"; name = "Kitchen Shutters Control"; pixel_x = -1; pixel_y = -24; req_access_txt = "28"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) +"bcT" = (/obj/item/device/radio/intercom{pixel_x = 25},/obj/structure/window/reinforced,/obj/structure/closet/secure_closet/bar{req_access = list(25)},/turf/simulated/floor/wood,/area/crew_quarters/bar) "bcU" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/kitchen) -"bcV" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{dir = 9; icon_state = "green"},/area/hydroponics/garden) +"bcV" = (/obj/item/weapon/stool,/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/quartermaster/office) "bcW" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 1; icon_state = "green"},/area/hydroponics/garden) "bcX" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/hydroponics/garden) "bcY" = (/obj/structure/flora/ausbushes,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/grass,/area/hydroponics/garden) -"bcZ" = (/obj/structure/disposalpipe/segment,/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/hallway/primary/starboard) +"bcZ" = (/obj/machinery/light/small{dir = 1},/obj/machinery/power/smes/buildable{charge = 5e+006; input_attempt = 1; input_level = 200000; output_level = 200000},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "bda" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/hallway/primary/starboard) "bdb" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/starboard) "bdc" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Library"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/carpet,/area/hallway/primary/starboard) @@ -2881,10 +2882,10 @@ "bdv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "bdw" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry/aft) "bdx" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor,/area/hallway/secondary/entry/aft) -"bdy" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/simulated/floor,/area/security/vacantoffice) +"bdy" = (/obj/effect/decal/cleanable/cobweb2,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "bdz" = (/obj/structure/table,/obj/structure/window/basic{dir = 4},/turf/simulated/floor,/area/security/vacantoffice) "bdA" = (/obj/machinery/photocopier,/turf/simulated/floor,/area/security/vacantoffice) -"bdB" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/tank/air{dir = 4},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"; nitrogen = 0.01; oxygen = 0.01},/area/maintenance/locker) +"bdB" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/hallway/primary/starboard) "bdC" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/maintenance/locker) "bdD" = (/obj/structure/toilet{pixel_y = 8},/obj/machinery/light/small{dir = 8},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet) "bdE" = (/obj/machinery/door/airlock{name = "Unit 1"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet) @@ -2899,7 +2900,7 @@ "bdN" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/disposalpipe/segment,/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/crew_quarters/locker) "bdO" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/locker) "bdP" = (/turf/simulated/wall,/area/quartermaster/storage) -"bdQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/engineering{name = "Medbay Substation"; req_access_txt = "0"; req_one_access_txt = "11;24;5"},/turf/simulated/floor/plating,/area/maintenance/substation/medical) +"bdQ" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/door/window/brigdoor{dir = 1; name = "Security Checkpoint"; req_access = list(63)},/turf/simulated/floor{icon_state = "delivery"},/area/hallway/secondary/entry/starboard) "bdR" = (/obj/machinery/conveyor{dir = 4; id = "packageSort2"},/obj/machinery/light{dir = 8},/turf/simulated/floor/plating,/area/quartermaster/office) "bdS" = (/obj/machinery/conveyor{dir = 4; id = "packageSort2"},/turf/simulated/floor/plating,/area/quartermaster/office) "bdT" = (/obj/machinery/conveyor{dir = 4; id = "packageSort2"},/obj/structure/plasticflaps{opacity = 0},/turf/simulated/floor/plating,/area/quartermaster/office) @@ -2909,11 +2910,11 @@ "bdX" = (/obj/machinery/door/firedoor/border_only{name = "\improper Firelock South"},/turf/simulated/floor{icon_state = "bluecorner"},/area/hallway/primary/central_one) "bdY" = (/turf/simulated/wall/r_wall,/area/bridge/meeting_room) "bdZ" = (/turf/simulated/wall,/area/bridge/meeting_room) -"bea" = (/obj/machinery/door/airlock/command{name = "Conference Room"; req_access = null; req_access_txt = "19"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/wood,/area/bridge/meeting_room) +"bea" = (/obj/machinery/door/airlock/security{name = "Security Checkpoint"; req_access = list(1)},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/secondary/entry/starboard) "beb" = (/turf/simulated/wall/r_wall,/area/turret_protected/ai) "bec" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/wall/r_wall,/area/turret_protected/ai) "bed" = (/turf/simulated/wall/r_wall,/area/crew_quarters/captain) -"bee" = (/obj/machinery/door/airlock/command{id_tag = "captaindoor"; name = "Captain's Office"; req_access = null; req_access_txt = "20"},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/wood,/area/crew_quarters/captain) +"bee" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/central_one) "bef" = (/obj/machinery/computer/arcade,/turf/simulated/floor/wood,/area/crew_quarters/bar) "beg" = (/obj/machinery/vending/cola,/turf/simulated/floor/wood,/area/crew_quarters/bar) "beh" = (/obj/machinery/light,/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/wood,/area/crew_quarters/bar) @@ -2932,14 +2933,14 @@ "beu" = (/obj/structure/flora/grass/brown,/turf/simulated/floor/grass,/area/hydroponics/garden) "bev" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/primary/starboard) "bew" = (/turf/simulated/floor,/area/hallway/primary/starboard) -"bex" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor,/area/hallway/primary/starboard) +"bex" = (/obj/structure/bed/chair/comfy/black,/turf/simulated/floor/carpet,/area/bridge/meeting_room) "bey" = (/obj/machinery/vending/coffee,/turf/simulated/floor/wood,/area/library) -"bez" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/wood,/area/library) +"bez" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "beA" = (/obj/structure/table/woodentable,/obj/item/weapon/pen,/turf/simulated/floor/wood,/area/library) "beB" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/machinery/light/small,/turf/simulated/floor/wood,/area/library) -"beC" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/wood,/area/library) +"beC" = (/obj/structure/bed/chair/comfy/brown{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "beD" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green{pixel_x = 1; pixel_y = 5},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/wood,/area/library) -"beE" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/wood,/area/library) +"beE" = (/obj/structure/bed/chair/comfy/brown{dir = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "beF" = (/turf/simulated/floor{dir = 8; icon_state = "chapel"},/area/chapel/main) "beG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "chapel"},/area/chapel/main) "beH" = (/turf/simulated/floor/carpet{icon_state = "carpetsymbol"},/area/chapel/main) @@ -2947,8 +2948,8 @@ "beJ" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green,/turf/simulated/floor{dir = 8; icon_state = "escape"},/area/hallway/secondary/exit) "beK" = (/turf/simulated/floor{icon_state = "warningcorner"; dir = 2},/area/hallway/secondary/exit) "beL" = (/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/hallway/secondary/exit) -"beM" = (/obj/structure/lattice,/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "escape_dock_south_airlock"; name = "exterior access button"; pixel_x = 5; pixel_y = -25; req_access_txt = "0"; req_one_access_txt = "13"},/turf/space,/area/space) -"beN" = (/obj/structure/lattice,/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "centcom_shuttle_dock_airlock"; name = "exterior access button"; pixel_x = -5; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13"},/turf/space,/area/space) +"beM" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_command{name = "E.V.A. Cycler Access"; req_one_access = list(1,5,11,18,24)},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) +"beN" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/maintenance{name = "Kitchen Cold Room Maintenance"; req_access = list(28)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/maintenance/bar) "beO" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "beP" = (/obj/structure/closet/emcloset,/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/hallway/secondary/entry/aft) "beQ" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor{icon_state = "warningcorner"; dir = 4},/area/hallway/secondary/entry/aft) @@ -2970,7 +2971,7 @@ "bfg" = (/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) "bfh" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/module/power_control,/obj/item/weapon/cell{maxcharge = 2000},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) "bfi" = (/obj/machinery/conveyor{dir = 1; id = "packageSort1"},/turf/simulated/floor/plating,/area/quartermaster/office) -"bfj" = (/obj/structure/stool,/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/quartermaster/office) +"bfj" = (/obj/structure/bed/chair/comfy/black{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/bridge/meeting_room) "bfk" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/quartermaster/office) "bfl" = (/obj/machinery/conveyor_switch/oneway{id = "packageSort2"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/quartermaster/office) "bfm" = (/turf/simulated/wall,/area/quartermaster/office) @@ -2984,11 +2985,11 @@ "bfu" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor/wood,/area/bridge/meeting_room) "bfv" = (/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "bfw" = (/obj/machinery/alarm{pixel_y = 23},/obj/machinery/porta_turret,/turf/simulated/floor/bluegrid,/area/turret_protected/ai) -"bfx" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "solar_tool_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "13"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/solar/auxport) -"bfy" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "solar_chapel_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "10;13"},/obj/effect/decal/cleanable/dirt,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/solar/auxstarboard) +"bfx" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "Bar\\Library Maintenance"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/library) +"bfy" = (/obj/machinery/door/window/southleft{name = "Bar Delivery"; icon_state = "left"; dir = 8; req_access = list(25); base_state = "left"},/turf/simulated/floor{icon_state = "delivery"},/area/crew_quarters/bar) "bfz" = (/obj/machinery/power/terminal{dir = 8},/obj/structure/cable/green,/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "bfA" = (/obj/machinery/porta_turret,/turf/simulated/floor/bluegrid,/area/turret_protected/ai) -"bfB" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"bfB" = (/obj/structure/bed/chair/comfy/black{dir = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/bridge/meeting_room) "bfC" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bfD" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bfE" = (/obj/machinery/light_switch{pixel_y = 28},/turf/simulated/floor/wood,/area/crew_quarters/captain) @@ -3017,7 +3018,7 @@ "bgb" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/starboard) "bgc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/starboard) "bgd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/starboard) -"bge" = (/obj/structure/stool/bed/chair{dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/hallway/primary/starboard) +"bge" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "bgf" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/primary/starboard) "bgg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/hallway/primary/starboard) "bgh" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass{name = "Chapel"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/starboard) @@ -3033,7 +3034,7 @@ "bgr" = (/turf/simulated/wall,/area/hallway/secondary/entry/aft) "bgs" = (/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/hallway/secondary/entry/aft) "bgt" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/secondary/entry/aft) -"bgu" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/turf/simulated/floor/plating,/area/security/vacantoffice) +"bgu" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_tool_inner"; locked = 1; name = "Engineering External Access"; req_access = list(13)},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "bgv" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating,/area/maintenance/locker) "bgw" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/locker) "bgx" = (/obj/machinery/door/airlock{name = "Unit 2"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet) @@ -3051,11 +3052,11 @@ "bgJ" = (/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/turf/simulated/floor{icon_state = "arrival"; dir = 5},/area/quartermaster/office) "bgK" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/hallway/primary/central_one) "bgL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor,/area/hallway/primary/central_one) -"bgM" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Secure Gate"; name = "Security Blast Door"; opacity = 0},/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/window/brigdoor{name = "Visitation Window"; req_access_txt = "63"},/turf/simulated/floor,/area/security/prison) +"bgM" = (/obj/machinery/door/airlock/glass_medical{id_tag = null; name = "Medical Hardsuits"; req_access = list(5)},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) "bgN" = (/obj/machinery/recharger{pixel_y = 4},/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/bridge/meeting_room) "bgO" = (/turf/simulated/floor/wood,/area/bridge/meeting_room) "bgP" = (/turf/simulated/floor/carpet,/area/bridge/meeting_room) -"bgQ" = (/obj/structure/stool/bed/chair/comfy/black,/turf/simulated/floor/carpet,/area/bridge/meeting_room) +"bgQ" = (/obj/structure/bed/chair/comfy/brown{dir = 4},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "bgR" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/carpet,/area/bridge/meeting_room) "bgS" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/bridge/meeting_room) "bgT" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/wood,/area/bridge/meeting_room) @@ -3064,13 +3065,13 @@ "bgW" = (/obj/structure/cable/cyan{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "bgX" = (/obj/machinery/ai_slipper{icon_state = "motion0"},/obj/effect/landmark{name = "lightsout"},/obj/machinery/camera/all{c_tag = "AI Chamber"; dir = 1; pixel_x = 12},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "bgY" = (/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai) -"bgZ" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"bgZ" = (/obj/structure/bed/chair/comfy/brown{dir = 8},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "bha" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bhb" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bhc" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/wood,/area/crew_quarters/captain) -"bhd" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/crew_quarters/captain) -"bhe" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/donut_box,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/crew_quarters/captain) -"bhf" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/crew_quarters/captain) +"bhd" = (/obj/structure/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/carpet,/area/bridge/meeting_room) +"bhe" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_security{name = "Security Hardsuits"; req_access = list(1)},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva) +"bhf" = (/obj/structure/bed/chair/comfy/black{dir = 8},/turf/simulated/floor/carpet,/area/bridge/meeting_room) "bhg" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bhh" = (/obj/structure/flora/pottedplant{tag = "icon-plant-10"; icon_state = "plant-10"},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bhi" = (/obj/structure/disposalpipe/segment,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central_two) @@ -3100,16 +3101,16 @@ "bhG" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor{dir = 4; icon_state = "whitecorner"},/area/hallway/secondary/exit) "bhH" = (/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/hallway/secondary/exit) "bhI" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/turf/simulated/floor,/area/hallway/secondary/exit) -"bhJ" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "escape_dock_south_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = -25; req_access_txt = "0"; req_one_access_txt = "13"},/turf/simulated/floor,/area/hallway/secondary/exit) -"bhK" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_dock_south_inner"; locked = 1; name = "Escape Airlock"; req_access_txt = "13"},/obj/machinery/mech_sensor{dir = 8; frequency = 1380; id_tag = "escape_dock_south_mech"; pixel_y = 19},/turf/simulated/floor/plating,/area/hallway/secondary/exit) -"bhL" = (/obj/machinery/light/small{dir = 1},/obj/machinery/embedded_controller/radio/airlock/docking_port_multi{frequency = 1380; id_tag = "escape_dock_south_airlock"; master_tag = "escape_dock"; pixel_y = -30; req_one_access_txt = "13"; tag_airlock_mech_sensor = "escape_dock_south_mech"; tag_airpump = "escape_dock_south_pump"; tag_chamber_sensor = "escape_dock_south_sensor"; tag_exterior_door = "escape_dock_south_outer"; tag_interior_door = "escape_dock_south_inner"; tag_shuttle_mech_sensor = "shuttle_dock_south_mech"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1380; id_tag = "escape_dock_south_pump"},/turf/simulated/floor/plating,/area/hallway/secondary/exit) +"bhJ" = (/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 4; icon_state = "arrival"},/area/hallway/secondary/entry/fore) +"bhK" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "solar_chapel_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/obj/effect/decal/cleanable/dirt,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/maintenance/auxsolarstarboard) +"bhL" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "solar_tool_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access = list(13)},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport) "bhM" = (/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "escape_dock_south_sensor"; pixel_x = 0; pixel_y = 25},/turf/simulated/floor/plating,/area/hallway/secondary/exit) -"bhN" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_dock_south_outer"; locked = 1; name = "Escape Airlock"; req_access_txt = "13"},/obj/machinery/mech_sensor{dir = 8; frequency = 1380; id_tag = "escape_dock_south_mech"; pixel_y = 19},/turf/simulated/floor/plating,/area/hallway/secondary/exit) +"bhN" = (/obj/machinery/door/airlock{name = "Unisex Showers"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/toilet) "bhO" = (/turf/space,/area/shuttle/specops/station) "bhP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "bhQ" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/hallway/secondary/entry/aft) "bhR" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/hallway/secondary/entry/aft) -"bhS" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) +"bhS" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/crew_quarters/fitness) "bhT" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/locker) "bhU" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/locker) "bhV" = (/obj/effect/landmark{name = "blobstart"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plating,/area/maintenance/locker) @@ -3133,22 +3134,22 @@ "bin" = (/obj/structure/closet/coffin,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "chapel"; name = "Privacy Shutters"; opacity = 0},/turf/simulated/floor{icon_state = "dark"},/area/chapel/office) "bio" = (/obj/item/weapon/hand_labeler,/obj/item/device/assembly/timer,/obj/item/device/eftpos{eftpos_name = "Bridge EFTPOS scanner"},/obj/structure/table/woodentable,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/wood,/area/bridge/meeting_room) "bip" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/wood,/area/bridge/meeting_room) -"biq" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/bridge/meeting_room) +"biq" = (/obj/structure/table/reinforced,/obj/item/stack/sheet/plasteel{amount = 10},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/ai_monitored/storage/eva) "bir" = (/obj/item/weapon/folder/red,/obj/structure/table/woodentable,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/bridge/meeting_room) "bis" = (/obj/item/weapon/book/manual/security_space_law,/obj/structure/table/woodentable,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/bridge/meeting_room) -"bit" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/carpet,/area/bridge/meeting_room) +"bit" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/storage/primary) "biu" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/bridge/meeting_room) "biv" = (/obj/structure/table/woodentable,/obj/machinery/photocopier/faxmachine{department = "Bridge"},/turf/simulated/floor/wood,/area/bridge/meeting_room) "biw" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "bix" = (/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai) "biy" = (/turf/simulated/wall,/area/turret_protected/ai) -"biz" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"biz" = (/obj/structure/bed/chair,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/captain) "biA" = (/obj/machinery/vending/coffee,/turf/simulated/floor/wood,/area/crew_quarters/captain) "biB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/crew_quarters/captain) "biC" = (/turf/simulated/floor/wood,/area/crew_quarters/captain) -"biD" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 4},/turf/simulated/floor/carpet,/area/crew_quarters/captain) +"biD" = (/obj/machinery/door/airlock/engineering{icon_state = "door_closed"; locked = 0; name = "Fore Starboard Solar Access"; req_access = list(10)},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard) "biE" = (/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/crew_quarters/captain) -"biF" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 8},/turf/simulated/floor/carpet,/area/crew_quarters/captain) +"biF" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "biG" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/wood,/area/crew_quarters/captain) "biH" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/flora/pottedplant{tag = "icon-plant-01"; icon_state = "plant-01"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/wood,/area/crew_quarters/captain) "biI" = (/obj/structure/disposalpipe/segment,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = -32; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/hallway/primary/central_two) @@ -3185,13 +3186,13 @@ "bjn" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry/aft) "bjo" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/secondary/entry/aft) "bjp" = (/turf/simulated/wall,/area/maintenance/disposal) -"bjq" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "Disposal Access"; req_access_txt = "12"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/disposal) +"bjq" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "hazard door east"},/obj/machinery/door/airlock/research{name = "Miscellaneous Reseach Room"; req_access = list(47)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bjr" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/locker) "bjs" = (/obj/machinery/door/airlock{name = "Unit 3"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet) "bjt" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet) "bju" = (/obj/item/latexballon,/turf/simulated/floor/plating,/area/maintenance/locker) "bjv" = (/obj/effect/landmark{name = "blobstart"},/obj/item/latexballon,/turf/simulated/floor/plating,/area/maintenance/locker) -"bjw" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/crew_quarters/locker) +"bjw" = (/obj/machinery/meter,/obj/machinery/door_control{id = "mixvent"; name = "Mixing Room Vent Control"; pixel_x = -25; pixel_y = 5; req_access = list(7)},/obj/machinery/button/ignition{id = "mixingsparker"; pixel_x = -25; pixel_y = -5},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green,/turf/simulated/floor{dir = 4; icon_state = "warnwhitecorner"},/area/rnd/mixing) "bjx" = (/obj/structure/disposalpipe/tagger/partial{name = "Sorting Office"; sort_tag = "Sorting Office"},/turf/simulated/floor/plating,/area/maintenance/locker) "bjy" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) "bjz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) @@ -3201,22 +3202,22 @@ "bjD" = (/obj/structure/filingcabinet/filingcabinet,/turf/simulated/floor{icon_state = "arrival"; dir = 4},/area/quartermaster/office) "bjE" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central_one) "bjF" = (/obj/machinery/door/blast/regular{id = "chapelgun"; name = "Chapel Launcher Door"},/turf/simulated/floor/plating,/area/chapel/main) -"bjG" = (/obj/item/weapon/storage/donut_box,/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/bridge/meeting_room) -"bjH" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/carpet,/area/bridge/meeting_room) +"bjG" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod{frequency = 1380; id_tag = "escape_pod_5"; pixel_x = 0; pixel_y = -25; tag_door = "escape_pod_5_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod5/station) +"bjH" = (/obj/structure/sign/securearea{pixel_x = 32},/turf/simulated/floor{dir = 1; icon_state = "loadingarea"},/area/hallway/primary/starboard) "bjI" = (/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/bridge/meeting_room) "bjJ" = (/obj/item/weapon/folder/blue,/obj/structure/table/woodentable,/turf/simulated/floor/carpet,/area/bridge/meeting_room) -"bjK" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/simulated/floor/carpet,/area/bridge/meeting_room) +"bjK" = (/obj/structure/bed/chair{dir = 4},/obj/effect/landmark/start{name = "Cargo Technician"},/turf/simulated/floor,/area/quartermaster/office) "bjL" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/bridge/meeting_room) "bjM" = (/obj/structure/reagent_dispensers/water_cooler,/turf/simulated/floor/wood,/area/bridge/meeting_room) "bjN" = (/obj/effect/landmark{name = "tripai"},/obj/item/device/radio/intercom{anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; pixel_x = 0; pixel_y = 20},/obj/item/device/radio/intercom{anyai = 1; broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; pixel_x = 0; pixel_y = -26},/obj/item/device/radio/intercom{anyai = 1; broadcasting = 1; freerange = 1; listening = 1; name = "Common Channel"; pixel_x = -25; pixel_y = -4},/obj/structure/cable/cyan{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) -"bjO" = (/obj/machinery/door/window{dir = 4; name = "AI Core Door"; req_access_txt = "16"},/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"bjO" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_5_hatch"; locked = 1; name = "Escape Pod Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod5/station) "bjP" = (/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/cyan{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai) -"bjQ" = (/obj/item/device/radio/intercom{anyai = 1; broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; pixel_x = 28; pixel_y = 5},/obj/item/device/radio/intercom{anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; pixel_x = -27; pixel_y = 4},/obj/effect/landmark/start{name = "AI"},/obj/item/device/radio/intercom{broadcasting = 1; freerange = 1; listening = 1; name = "Common Channel"; pixel_y = 25},/obj/machinery/door_control{desc = "A remote control switch for the AI chamber door."; id = "AI Door"; name = "AI Chamber Door Control"; pixel_x = 16; pixel_y = 32; req_access_txt = "16"},/obj/machinery/newscaster/security_unit{pixel_x = 32; pixel_y = 32},/obj/machinery/requests_console{department = "AI"; departmentType = 5; pixel_x = -32; pixel_y = 32},/obj/structure/cable/cyan{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) -"bjR" = (/obj/machinery/door/window{base_state = "right"; dir = 8; icon_state = "right"; name = "AI Core Door"; req_access_txt = "16"},/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"bjQ" = (/obj/machinery/light/small{dir = 4},/obj/machinery/porta_turret{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"bjR" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_5_berth_hatch"; locked = 1; name = "Escape Pod"; req_access = list(13)},/turf/simulated/floor/plating,/area/maintenance/cargo) "bjS" = (/obj/effect/landmark{name = "tripai"},/obj/item/device/radio/intercom{anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; pixel_x = 0; pixel_y = 19},/obj/item/device/radio/intercom{anyai = 1; broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; pixel_x = 0; pixel_y = -26},/obj/item/device/radio/intercom{anyai = 1; broadcasting = 1; freerange = 1; listening = 1; name = "Common Channel"; pixel_x = 27; pixel_y = -3},/obj/structure/cable/cyan{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "bjT" = (/obj/machinery/vending/cigarette,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bjU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/captain) -"bjV" = (/obj/structure/stool/bed/chair,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/captain) +"bjV" = (/obj/machinery/light{dir = 1},/obj/item/weapon/stool,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/reception) "bjW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "bjX" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bjY" = (/obj/structure/table/woodentable,/obj/machinery/recharger{pixel_y = 4},/obj/machinery/camera{c_tag = "Captain's Office"; dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/wood,/area/crew_quarters/captain) @@ -3254,13 +3255,13 @@ "bkE" = (/obj/machinery/newscaster{pixel_y = -32},/turf/simulated/floor{dir = 2; icon_state = "escape"},/area/hallway/secondary/exit) "bkF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 2; icon_state = "escape"},/area/hallway/secondary/exit) "bkG" = (/obj/machinery/light,/turf/simulated/floor{dir = 2; icon_state = "escape"},/area/hallway/secondary/exit) -"bkH" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/embedded_controller/radio/docking_port_multi{child_names_txt = "Airlock One;Airlock Two"; child_tags_txt = "escape_dock_north_airlock;escape_dock_south_airlock"; frequency = 1380; id_tag = "escape_dock"; pixel_x = 0; pixel_y = -25; req_one_access_txt = "13"},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/hallway/secondary/exit) +"bkH" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Mental Health"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) "bkI" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32; pixel_y = 0},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/hallway/secondary/exit) "bkJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/exit) -"bkK" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_dock_outer"; locked = 1; name = "Docking Port Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) -"bkL" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "specops_dock_airlock"; pixel_x = 0; pixel_y = 30; req_access_txt = "0"; req_one_access_txt = "13"; tag_airpump = "specops_dock_pump"; tag_chamber_sensor = "specops_dock_sensor"; tag_exterior_door = "specops_dock_outer"; tag_interior_door = "specops_dock_inner"},/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "specops_dock_sensor"; pixel_x = 0; pixel_y = -25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "specops_dock_pump"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) -"bkM" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_dock_inner"; locked = 1; name = "Docking Port Airlock"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) -"bkN" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "specops_dock_airlock"; name = "interior access button"; pixel_x = -30; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/simulated/floor,/area/hallway/secondary/entry/aft) +"bkK" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Sub-Acute C"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_c) +"bkL" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Secondary Storage"; req_access = list(5)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "dark"},/area/medical/medbay2) +"bkM" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Medbay Diagnostics Maintenance Access"; req_access = list(5)},/turf/simulated/floor/plating,/area/medical/sleeper) +"bkN" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Patient Ward"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) "bkO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/power/apc/high{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green,/turf/simulated/floor,/area/hallway/secondary/entry/aft) "bkP" = (/obj/machinery/conveyor{dir = 5; id = "garbage"},/turf/simulated/floor/plating,/area/maintenance/disposal) "bkQ" = (/obj/machinery/conveyor{dir = 4; id = "garbage"},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/disposal) @@ -3268,10 +3269,10 @@ "bkS" = (/obj/structure/disposaloutlet{dir = 8},/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor/plating,/area/maintenance/disposal) "bkT" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/maintenance/disposal) "bkU" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/maintenance/locker) -"bkV" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/maintenance/locker) +"bkV" = (/obj/machinery/door/airlock/glass_medical{name = "Hygiene Facilities"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) "bkW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/locker) -"bkX" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/locker) -"bkY" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/locker) +"bkX" = (/obj/machinery/door/airlock/engineering{name = "Engineering Supplies"; req_one_access = list(10,24,5)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "yellowfull"; dir = 8},/area/engineering/break_room) +"bkY" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/maintenance/cargo) "bkZ" = (/obj/machinery/camera{c_tag = "Locker Room Toilets"; dir = 8; network = list("SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet) "bla" = (/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/locker) "blb" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/locker) @@ -3300,10 +3301,10 @@ "bly" = (/obj/machinery/vending/coffee,/turf/simulated/floor/wood,/area/bridge/meeting_room) "blz" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "blA" = (/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) -"blB" = (/obj/machinery/door/window{dir = 2; name = "AI Core Door"; req_access_txt = "109"},/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/cyan{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/flasher{id = "AI"; pixel_x = 22; pixel_y = 24},/obj/machinery/turretid/stun{check_synth = 1; name = "AI Chamber turret control"; pixel_x = 36; pixel_y = 24},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) -"blC" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/light/small{dir = 1},/obj/structure/cable/cyan{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc/super{dir = 1; name = "north bump"; pixel_y = 24},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"blB" = (/obj/machinery/camera{c_tag = "Medbay Lobby Port"; network = list("SS13")},/obj/item/weapon/stool,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/reception) +"blC" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Sub-Acute B"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) "blD" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) -"blE" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"blE" = (/obj/machinery/camera{c_tag = "Medbay Lobby Starboard"; network = list("SS13")},/obj/item/weapon/stool,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/reception) "blF" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_x = -30; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/item/device/megaphone,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/captain) "blG" = (/obj/structure/table/woodentable,/obj/item/weapon/folder/blue,/obj/item/weapon/stamp/captain,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/crew_quarters/captain) "blH" = (/obj/structure/table/woodentable,/obj/machinery/computer/skills{icon_state = "medlaptop"},/obj/item/weapon/hand_tele,/turf/simulated/floor/wood,/area/crew_quarters/captain) @@ -3318,7 +3319,7 @@ "blQ" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"},/turf/simulated/wall,/area/hallway/primary/starboard) "blR" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "scanhideside"; name = "Diagnostics Room Privacy Shutters"; opacity = 0},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay4) "blS" = (/obj/machinery/sparker{dir = 2; id = "mixingsparker"; pixel_x = 25},/obj/machinery/atmospherics/unary/outlet_injector{dir = 4; frequency = 1443; icon_state = "map_injector"; id = "air_in"; use_power = 1},/turf/simulated/floor/engine/vacuum,/area/rnd/mixing) -"blT" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Morgue"; req_access_txt = "6"},/turf/simulated/floor,/area/hallway/primary/starboard) +"blT" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/research{name = "Toxins Storage"; req_access = list(8)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/rnd/research) "blU" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 2; icon_state = "whitepurplecorner"},/area/medical/medbay2) "blV" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/hallway/primary/starboard) "blW" = (/turf/simulated/floor{dir = 1; icon_state = "loadingarea"},/area/hallway/primary/starboard) @@ -3328,7 +3329,7 @@ "bma" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{dir = 2; icon_state = "purple"},/area/hallway/primary/starboard) "bmb" = (/turf/simulated/floor{dir = 6; icon_state = "purple"},/area/hallway/primary/starboard) "bmc" = (/turf/simulated/wall/r_wall,/area/hallway/secondary/exit) -"bmd" = (/obj/machinery/door/airlock/maintenance{name = "Maintenance Access"; req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/secondary/exit) +"bmd" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "tox_airlock_pump"; tag_exterior_door = "tox_airlock_exterior"; id_tag = "tox_airlock_control"; tag_interior_door = "tox_airlock_interior"; pixel_x = -24; pixel_y = 0; tag_chamber_sensor = "tox_airlock_sensor"},/obj/machinery/atmospherics/tvalve/bypass{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 1; icon_state = "warnwhitecorner"},/area/rnd/mixing) "bme" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/wall,/area/hallway/secondary/exit) "bmf" = (/obj/machinery/light{dir = 4},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/secondary/entry/aft) "bmg" = (/obj/machinery/conveyor{dir = 1; id = "garbage"},/turf/simulated/floor/plating,/area/maintenance/disposal) @@ -3336,7 +3337,7 @@ "bmi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/disposal) "bmj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/locker) "bmk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/locker) -"bml" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/locker) +"bml" = (/obj/machinery/door_control{id = "scanhide"; name = "Diagnostics Room Separation Shutters"; pixel_x = -6; pixel_y = 25; req_access = list(5)},/obj/machinery/camera{c_tag = "Medbay Scanning"; network = list("SS13")},/obj/machinery/atmospherics/unary/freezer{dir = 8; icon_state = "freezer"},/obj/machinery/door_control{id = "scanhideside"; name = "Diagnostics Room Privacy Shutters"; pixel_x = 6; pixel_y = 25; req_access = list(5)},/turf/simulated/floor{icon_state = "delivery"},/area/medical/sleeper) "bmm" = (/obj/machinery/door/airlock{name = "Unit 4"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet) "bmn" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet) "bmo" = (/obj/item/stack/sheet/glass/reinforced,/obj/effect/decal/cleanable/cobweb,/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating,/area/maintenance/locker) @@ -3348,47 +3349,47 @@ "bmu" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/locker) "bmv" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/locker) "bmw" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) -"bmx" = (/obj/machinery/door_control{id = "qm_warehouse"; name = "Warehouse Door Control"; pixel_x = -1; pixel_y = -24; req_access_txt = "31"},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) +"bmx" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Sub-Acute A"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) "bmy" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) "bmz" = (/obj/structure/disposalpipe/sortjunction/untagged{dir = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) "bmA" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/wall,/area/quartermaster/office) "bmB" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 8; icon_state = "brown"},/area/quartermaster/office) -"bmC" = (/obj/structure/stool/bed/chair{dir = 4},/obj/effect/landmark/start{name = "Cargo Technician"},/turf/simulated/floor,/area/quartermaster/office) +"bmC" = (/obj/item/weapon/stool,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/reception) "bmD" = (/obj/structure/table/reinforced,/turf/simulated/floor{icon_state = "arrival"; dir = 4},/area/quartermaster/office) -"bmE" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/window{base_state = "right"; dir = 8; icon_state = "right"; name = "Mailing Room"; req_access_txt = "50"},/turf/simulated/floor{icon_state = "bot"},/area/hallway/primary/central_one) +"bmE" = (/obj/effect/decal/cleanable/blood/oil,/turf/simulated/floor/plating,/area/maintenance/cargo) "bmF" = (/obj/machinery/camera{c_tag = "Central Hallway West"; dir = 8},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor{icon_state = "bluecorner"},/area/hallway/primary/central_one) "bmG" = (/turf/simulated/wall/r_wall,/area/maintenance/substation/command) -"bmH" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/command{name = "Conference Room"; req_access = null; req_access_txt = "19"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/maintenance/substation/command) +"bmH" = (/obj/machinery/door/airlock/glass_research{autoclose = 0; frequency = 1379; glass = 1; icon_state = "door_locked"; id_tag = "tox_airlock_exterior"; locked = 1; name = "Mixing Room Exterior Airlock"; req_access = list(8)},/turf/simulated/floor/engine,/area/rnd/mixing) "bmI" = (/obj/machinery/light/small{dir = 8},/obj/machinery/porta_turret{dir = 4},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "bmJ" = (/obj/structure/cable/cyan{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai) "bmK" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "bmL" = (/obj/machinery/ai_slipper{icon_state = "motion0"},/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/cyan{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/cyan{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai) "bmM" = (/obj/structure/cable/cyan{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai) -"bmN" = (/obj/machinery/light/small{dir = 4},/obj/machinery/porta_turret{dir = 8},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"bmN" = (/obj/item/weapon/stool,/obj/machinery/camera{c_tag = "Medbay Examination Room"; network = list("SS13")},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) "bmO" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Captain's Desk"; departmentType = 5; name = "Captain RC"; pixel_x = -30; pixel_y = 0},/obj/structure/filingcabinet,/turf/simulated/floor/wood,/area/crew_quarters/captain) -"bmP" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 4},/obj/effect/landmark/start{name = "Captain"},/obj/machinery/door_control{desc = "A remote control-switch for the office door."; id = "captaindoor"; name = "Office Door Control"; normaldoorcontrol = 1; pixel_x = 15; pixel_y = 30; req_access_txt = "20"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door_control{desc = "A remote control-switch for the starboard bridge doors."; id = "sbridgedoor"; name = "Bridge Door Control"; normaldoorcontrol = 1; pixel_x = 15; pixel_y = 39; req_access_txt = "20"},/turf/simulated/floor/wood,/area/crew_quarters/captain) +"bmP" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/bed/chair/wheelchair,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) "bmQ" = (/obj/machinery/computer/communications,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bmR" = (/obj/structure/table/woodentable,/obj/item/device/eftpos{eftpos_name = "Captain EFTPOS scanner"},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bmS" = (/obj/structure/table/woodentable,/obj/item/weapon/melee/chainofcommand,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bmT" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/dropper,/obj/machinery/light{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) -"bmU" = (/obj/machinery/chem_dispenser,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) +"bmU" = (/obj/machinery/door/airlock/glass_research{autoclose = 0; frequency = 1379; glass = 1; icon_state = "door_locked"; id_tag = "tox_airlock_interior"; locked = 1; name = "Mixing Room Interior Airlock"; req_access = list(8)},/turf/simulated/floor/engine,/area/rnd/mixing) "bmV" = (/obj/machinery/camera{c_tag = "Chemistry"; network = list("SS13")},/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 30},/obj/machinery/chem_master,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bmW" = (/obj/structure/table/reinforced,/obj/item/stack/sheet/mineral/phoron,/obj/item/stack/sheet/mineral/phoron,/obj/item/stack/sheet/mineral/phoron,/obj/item/stack/sheet/mineral/phoron,/obj/item/stack/sheet/mineral/phoron,/obj/item/stack/sheet/mineral/phoron,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bmX" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/table/reinforced,/obj/machinery/door_control{id = "chemcounter"; name = "Pharmacy Counter Lockdown Control"; pixel_y = 25},/obj/machinery/reagentgrinder,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bmY" = (/obj/structure/sign/chemistry,/turf/simulated/wall/r_wall,/area/medical/chemistry) "bmZ" = (/obj/structure/reagent_dispensers/water_cooler,/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 0; pixel_y = 32},/turf/simulated/floor{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/reception) "bna" = (/obj/structure/table,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/item/weapon/storage/box/cups{pixel_x = 0; pixel_y = 0},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/reception) -"bnb" = (/obj/machinery/camera{c_tag = "Medbay Lobby Port"; network = list("SS13")},/obj/structure/stool,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/reception) -"bnc" = (/obj/machinery/light{dir = 1},/obj/structure/stool,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/reception) +"bnb" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 8; icon_state = "warnwhite"},/area/rnd/mixing) +"bnc" = (/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Substation - Command"},/turf/simulated/floor/plating,/area/maintenance/substation/command) "bnd" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 1; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/reception) "bne" = (/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/reception) -"bnf" = (/obj/machinery/camera{c_tag = "Medbay Lobby Starboard"; network = list("SS13")},/obj/structure/stool,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/reception) -"bng" = (/obj/structure/stool,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/reception) +"bnf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"bng" = (/obj/structure/bed/chair/office/dark{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bnh" = (/obj/machinery/newscaster{pixel_x = 30},/obj/machinery/computer/security/telescreen/entertainment{pixel_x = 0; pixel_y = 32},/obj/structure/flora/pottedplant{tag = "icon-plant-10"; icon_state = "plant-10"},/turf/simulated/floor{tag = "icon-whiteblue (NORTHEAST)"; icon_state = "whiteblue"; dir = 5},/area/medical/reception) "bni" = (/turf/simulated/wall,/area/medical/reception) "bnj" = (/obj/machinery/light{dir = 1},/obj/structure/closet/secure_closet/medical1,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) -"bnk" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/stool/bed/chair/wheelchair,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) -"bnl" = (/obj/structure/stool,/obj/machinery/camera{c_tag = "Medbay Examination Room"; network = list("SS13")},/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) +"bnk" = (/obj/structure/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Chemist"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{dir = 4; icon_state = "whiteyellow"},/area/medical/chemistry) +"bnl" = (/obj/item/weapon/stool,/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/reception) "bnm" = (/obj/machinery/light{dir = 1},/obj/machinery/disposal,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) "bnn" = (/turf/simulated/wall,/area/medical/exam_room) "bno" = (/obj/structure/table,/obj/item/device/camera{name = "Autopsy Camera"; pixel_x = -2; pixel_y = 7},/obj/item/weapon/paper_bin{pixel_y = -6},/obj/item/weapon/pen/red{pixel_x = -1; pixel_y = -9},/obj/item/weapon/pen/blue{pixel_x = 3; pixel_y = -5},/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/medical/morgue) @@ -3399,14 +3400,14 @@ "bnt" = (/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/morgue) "bnu" = (/obj/structure/morgue{tag = "icon-morgue1 (WEST)"; icon_state = "morgue1"; dir = 8},/turf/simulated/floor{dir = 5; icon_state = "blue"},/area/medical/morgue) "bnv" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) -"bnw" = (/obj/machinery/door/airlock{name = "Medbay Substation"; req_access_txt = "5"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/substation/medical) +"bnw" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Medbay Patient Wing Maintenance Access"; req_access = list(5)},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/medical/patient_wing) "bnx" = (/obj/machinery/door/blast/regular{id = "mixvent"; name = "Mixer Room Vent"},/turf/simulated/floor/engine/vacuum,/area/rnd/mixing) -"bny" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "psych"; name = "Mental Health Privacy Shutters"; opacity = 0},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/medical/medbay4) +"bny" = (/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/assembly/chargebay) "bnz" = (/obj/machinery/computer/rdconsole/robotics,/obj/machinery/alarm{pixel_y = 25},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bnA" = (/obj/structure/table,/obj/item/weapon/book/manual/robotics_cyborgs{pixel_x = 2; pixel_y = 5},/obj/item/weapon/storage/belt/utility,/obj/machinery/requests_console{department = "Robotics"; departmentType = 2; name = "Robotics RC"; pixel_y = 30},/obj/machinery/light{dir = 1},/obj/item/weapon/storage/belt/utility,/obj/item/weapon/reagent_containers/glass/beaker/large,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bnB" = (/obj/machinery/r_n_d/circuit_imprinter,/obj/item/weapon/reagent_containers/glass/beaker/sulphuric,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"bnC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "psych"; name = "Mental Health Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay4) -"bnD" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "medprivc"; name = "Patient Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/patient_c) +"bnC" = (/obj/structure/reagent_dispensers/acid{density = 0; pixel_x = -32},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) +"bnD" = (/obj/structure/bed/chair/office/light{dir = 1},/obj/effect/landmark/start{name = "Roboticist"},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bnE" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "scanhideside"; name = "Diagnostics Room Privacy Shutters"; opacity = 0},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay4) "bnF" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bnG" = (/obj/machinery/autolathe,/turf/simulated/floor{icon_state = "white"},/area/rnd/lab) @@ -3416,17 +3417,17 @@ "bnK" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/storage/emergency) "bnL" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating,/area/storage/emergency) "bnM" = (/turf/simulated/wall,/area/storage/emergency) -"bnN" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "specops_dock_airlock"; name = "exterior access button"; pixel_x = -5; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13"},/turf/space,/area/space) +"bnN" = (/obj/machinery/door_control{id = "misclab"; name = "Test Chamber Blast Doors"; pixel_x = 6; pixel_y = 30; req_access = list(47)},/obj/item/weapon/stool,/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bnO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "bnP" = (/obj/structure/closet/emcloset,/obj/machinery/camera{c_tag = "Arrivals Auxiliary Docking South"; dir = 4; network = list("SS13")},/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/hallway/secondary/entry/aft) "bnQ" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/hallway/secondary/entry/aft) "bnR" = (/obj/machinery/conveyor{dir = 1; id = "garbage"},/obj/structure/sign/vacuum{pixel_x = -32},/turf/simulated/floor/plating,/area/maintenance/disposal) -"bnS" = (/obj/machinery/door_control{id = "Disposal Exit"; name = "Disposal Vent Control"; pixel_x = -25; pixel_y = 4; req_access_txt = "12"},/obj/machinery/driver_button{id = "trash"; pixel_x = -26; pixel_y = -6},/turf/simulated/floor/plating,/area/maintenance/disposal) +"bnS" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "hazard door east"},/obj/machinery/door/airlock/research{name = "Miscellaneous Reseach Room"; req_access = list(47)},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bnT" = (/obj/machinery/conveyor_switch/oneway{convdir = -1; id = "garbage"; name = "disposal coveyor"},/turf/simulated/floor/plating,/area/maintenance/disposal) "bnU" = (/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/plating,/area/maintenance/disposal) "bnV" = (/obj/effect/decal/cleanable/blood/oil,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/maintenance/disposal) -"bnW" = (/obj/machinery/light/small{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/locker) -"bnX" = (/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plating,/area/maintenance/locker) +"bnW" = (/obj/machinery/door/window/eastleft{name = "Medical Delivery"; req_access = list(5)},/obj/machinery/door/firedoor,/turf/simulated/floor{icon_state = "delivery"},/area/medical/sleeper) +"bnX" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "toxin_test_pump"; tag_exterior_door = "toxin_test_outer"; frequency = 1379; id_tag = "toxin_test_airlock"; tag_interior_door = "toxin_test_inner"; pixel_x = 0; pixel_y = 25; req_access = list(13); tag_chamber_sensor = "toxin_test_sensor"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/research_starboard) "bnY" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/locker) "bnZ" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/locker) "boa" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/locker) @@ -3437,15 +3438,15 @@ "bof" = (/obj/machinery/light,/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor{dir = 2; icon_state = "whitegreencorner"},/area/rnd/research) "bog" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/quartermaster/storage) "boh" = (/obj/structure/disposaloutlet{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/trunk,/turf/simulated/floor/plating,/area/quartermaster/office) -"boi" = (/obj/machinery/door/window/eastleft{name = "Mail"; req_access_txt = "50"},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{icon_state = "delivery"},/area/quartermaster/office) +"boi" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "toxin_test_airlock"; name = "exterior access button"; pixel_x = -20; pixel_y = -20; req_access = list(13)},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating/airless,/area/space) "boj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 8; icon_state = "brown"},/area/quartermaster/office) "bok" = (/obj/item/weapon/folder/yellow,/obj/item/weapon/pen{pixel_x = 4; pixel_y = 4},/obj/structure/table/reinforced,/turf/simulated/floor{icon_state = "arrival"; dir = 4},/area/quartermaster/office) -"bol" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/floor{icon_state = "bluecorner"},/area/hallway/primary/central_one) +"bol" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "toxin_test_outer"; locked = 1; name = "Engineering External Access"; req_access = list(10,13)},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "bom" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/substation/command) "bon" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/terminal{dir = 4},/turf/simulated/floor/plating,/area/maintenance/substation/command) -"boo" = (/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/camera{c_tag = "Command Substation"; dir = 2; network = list("SS13","Engineering")},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Command Substation"},/turf/simulated/floor/plating,/area/maintenance/substation/command) -"bop" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/command{name = "Electrical Maintenance"; req_access = null; req_access_txt = "19"},/turf/simulated/floor/plating,/area/maintenance/substation/command) -"boq" = (/obj/machinery/camera{c_tag = "Engineering Washroom"; dir = 1; network = list("SS13")},/obj/machinery/light,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) +"boo" = (/obj/item/weapon/stool,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/assembly/robotics) +"bop" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "toxin_test_inner"; locked = 1; name = "Engineering External Access"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/research_starboard) +"boq" = (/obj/item/weapon/stool,/obj/effect/landmark/start{name = "Scientist"},/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/rnd/lab) "bor" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor/plating,/area/maintenance/substation/command) "bos" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/maintenance/substation/command) "bot" = (/turf/simulated/wall,/area/maintenance/substation/command) @@ -3455,7 +3456,7 @@ "box" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "boy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "boz" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) -"boA" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"boA" = (/obj/item/weapon/stool,/turf/simulated/floor/plating,/area/maintenance/disposal) "boB" = (/obj/item/device/radio/intercom{anyai = 1; broadcasting = 0; freerange = 1; listening = 1; name = "Captain's Intercom"; pixel_x = -27; pixel_y = -3},/obj/structure/closet/secure_closet/captains,/turf/simulated/floor/wood,/area/crew_quarters/captain) "boC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/crew_quarters/captain) "boD" = (/obj/machinery/computer/card,/obj/item/weapon/card/id/captains_spare,/turf/simulated/floor/wood,/area/crew_quarters/captain) @@ -3465,11 +3466,11 @@ "boH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/central_two) "boI" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor{dir = 8; icon_state = "whitegreencorner"},/area/rnd/research) "boJ" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/glass/beaker/large,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) -"boK" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) +"boK" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "toxin_test_airlock"; name = "interior access button"; pixel_x = 20; pixel_y = 20; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/research_starboard) "boL" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "boM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) -"boN" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Chemist"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{dir = 4; icon_state = "whiteyellow"},/area/medical/chemistry) -"boO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "medprivb"; name = "Patient Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/patient_b) +"boN" = (/obj/structure/bed,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) +"boO" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = 6},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "boP" = (/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/reception) "boQ" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/medical/reception) "boR" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/reception) @@ -3477,7 +3478,7 @@ "boT" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/medical/reception) "boU" = (/turf/simulated/floor{icon_state = "white"},/area/medical/reception) "boV" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "white"},/area/medical/reception) -"boW" = (/obj/structure/stool,/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/reception) +"boW" = (/obj/machinery/door/airlock/external{name = "Toxins Test Chamber"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating/airless,/area/rnd/test_area) "boX" = (/obj/structure/sign/examroom,/turf/simulated/wall,/area/medical/reception) "boY" = (/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) "boZ" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) @@ -3495,18 +3496,18 @@ "bpl" = (/turf/simulated/floor,/area/assembly/chargebay) "bpm" = (/obj/machinery/door_control{dir = 2; id = "Skynet_launch"; name = "Mech Bay Door Control"; pixel_x = 6; pixel_y = 24},/turf/simulated/floor{tag = "icon-warningcorner (WEST)"; icon_state = "warningcorner"; dir = 8},/area/assembly/chargebay) "bpn" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/assembly/chargebay) -"bpo" = (/obj/structure/sign/securearea{pixel_x = 32},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/assembly/chargebay) +"bpo" = (/obj/machinery/door/airlock/glass_medical{name = "Patient Ward"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) "bpp" = (/turf/simulated/wall,/area/assembly/robotics) "bpq" = (/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"bpr" = (/obj/structure/stool/bed/chair/office/light{dir = 1},/obj/effect/landmark/start{name = "Roboticist"},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) +"bpr" = (/obj/machinery/door_control{desc = "A remote control switch for the medbay foyer."; id = "MedbayFoyerStar"; name = "Medbay Doors Control"; normaldoorcontrol = 1; pixel_x = 6; pixel_y = 28},/obj/structure/bed/chair/office/dark{dir = 1},/obj/effect/landmark/start{name = "Medical Doctor"},/turf/simulated/floor{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/medical/reception) "bps" = (/obj/machinery/camera{c_tag = "Robotics"; dir = 2; network = list("SS13","Research"); pixel_x = 22},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor{dir = 4; icon_state = "whiteredcorner"},/area/assembly/robotics) "bpt" = (/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/assembly/robotics) -"bpu" = (/obj/structure/stool,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/assembly/robotics) -"bpv" = (/obj/structure/filingcabinet/chestdrawer,/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/assembly/robotics) -"bpw" = (/obj/machinery/door/airlock/research{name = "Research Division Access"; req_access_txt = "47"},/turf/simulated/floor{icon_state = "white"},/area/hallway/primary/starboard) +"bpu" = (/obj/structure/bed/chair/office/dark{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) +"bpv" = (/obj/item/weapon/stool,/obj/effect/landmark/start{name = "Roboticist"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/assembly/robotics) +"bpw" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Observation Room"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) "bpx" = (/obj/structure/sign/securearea,/turf/simulated/wall,/area/hallway/primary/starboard) "bpy" = (/obj/structure/table,/obj/item/stack/sheet/glass{amount = 50; pixel_x = 3; pixel_y = 3},/obj/item/stack/sheet/metal{amount = 50},/obj/item/clothing/glasses/welding,/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/rnd/lab) -"bpz" = (/obj/structure/stool,/obj/effect/landmark/start{name = "Scientist"},/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/rnd/lab) +"bpz" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/firealarm{pixel_y = 27},/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/quartermaster/office) "bpA" = (/obj/structure/table,/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/rnd/lab) "bpB" = (/obj/machinery/camera{c_tag = "Research and Development Lab"; dir = 2; network = list("SS13","Research")},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor{dir = 1; icon_state = "whitepurplecorner"},/area/rnd/lab) "bpC" = (/turf/simulated/floor{icon_state = "white"},/area/rnd/lab) @@ -3518,15 +3519,15 @@ "bpI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "bpJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "bpK" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/hallway/secondary/entry/aft) -"bpL" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/turf/simulated/floor,/area/hallway/secondary/entry/aft) +"bpL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor/plating,/area/rnd/xenobiology/xenoflora) "bpM" = (/obj/machinery/conveyor{dir = 1; id = "garbage"},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/disposal) "bpN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/disposal) -"bpO" = (/obj/structure/stool,/turf/simulated/floor/plating,/area/maintenance/disposal) +"bpO" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/cyan,/turf/simulated/floor/plating,/area/turret_protected/ai_upload) "bpP" = (/turf/simulated/floor/plating,/area/maintenance/disposal) "bpQ" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_x = 0; pixel_y = -29},/obj/machinery/light/small,/turf/simulated/floor/plating,/area/maintenance/disposal) "bpR" = (/obj/machinery/light_switch{pixel_y = -25},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/disposal) -"bpS" = (/obj/machinery/door/airlock/maintenance{name = "Disposal Access"; req_access_txt = "12"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/disposal) -"bpT" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plating,/area/maintenance/locker) +"bpS" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eng_eva_outer"; locked = 1; name = "Engineering EVA External Access"; req_access = list(13)},/turf/simulated/floor/airless{icon_state = "circuit"},/area/maintenance/atmos_control) +"bpT" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eng_eva_inner"; locked = 1; name = "Engineering EVA Internal Access"; req_access = list(13)},/turf/simulated/floor/plating,/area/maintenance/atmos_control) "bpU" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/maintenance/locker) "bpV" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plating,/area/maintenance/locker) "bpW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/locker) @@ -3539,7 +3540,7 @@ "bqd" = (/obj/structure/closet/secure_closet/cargotech,/turf/simulated/floor,/area/quartermaster/storage) "bqe" = (/obj/machinery/light{dir = 1},/obj/machinery/alarm{dir = 2; pixel_y = 24},/turf/simulated/floor,/area/quartermaster/storage) "bqf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/quartermaster/storage) -"bqg" = (/obj/machinery/door_control{id = "qm_warehouse"; name = "Warehouse Door Control"; pixel_x = -1; pixel_y = 24; req_access_txt = "31"},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/quartermaster/storage) +"bqg" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_command{name = "Chief Engineer"; req_access = list(56)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/crew_quarters/heads/chief) "bqh" = (/obj/structure/sign/poster{pixel_x = 0; pixel_y = 0},/turf/simulated/wall,/area/quartermaster/storage) "bqi" = (/obj/machinery/photocopier,/turf/simulated/floor,/area/quartermaster/office) "bqj" = (/obj/structure/disposalpipe/sortjunction{dir = 1; name = "Sorting Office"; sortType = "Sorting Office"},/turf/simulated/floor,/area/quartermaster/office) @@ -3560,7 +3561,7 @@ "bqy" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/hallway/primary/central_three) "bqz" = (/obj/structure/table/rack,/obj/item/weapon/tank/jetpack/oxygen,/obj/item/clothing/mask/gas,/obj/item/clothing/suit/armor/captain,/obj/item/clothing/head/helmet/space/capspace,/obj/machinery/newscaster/security_unit{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bqA" = (/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = -24},/turf/simulated/floor/wood,/area/crew_quarters/captain) -"bqB" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Captain's Desk Door"; req_access_txt = "20"},/turf/simulated/floor/wood,/area/crew_quarters/captain) +"bqB" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Break Room"; req_one_access = list(10,24,5)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/break_room) "bqC" = (/obj/machinery/light,/turf/simulated/floor/wood,/area/crew_quarters/captain) "bqD" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/wood,/area/crew_quarters/captain) "bqE" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/crew_quarters/captain) @@ -3571,13 +3572,14 @@ "bqJ" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bqK" = (/obj/machinery/camera{c_tag = "Common Brig Northwest"; dir = 4; network = list("SS13","Prison")},/obj/machinery/computer/arcade,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/security/prison) "bqL" = (/turf/simulated/wall/r_wall,/area/medical/chemistry) +"bqM" = (/obj/structure/bed,/obj/item/weapon/bedsheet/captain,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "bqN" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/reception) "bqO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/reception) "bqP" = (/turf/simulated/floor{dir = 4; icon_state = "whiteblue_ex"; tag = "icon-whiteblue (EAST)"},/area/medical/reception) -"bqQ" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/medical{name = "Examination room"; req_access_txt = "5"},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/exam_room) +"bqQ" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/engineering{name = "Engineering Washroom"; req_one_access = list(10,24,5)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/break_room) "bqR" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) "bqS" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) -"bqT" = (/obj/structure/stool/bed,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) +"bqT" = (/obj/structure/table,/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000; pixel_x = 5; pixel_y = -5},/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bqU" = (/obj/structure/filingcabinet/chestdrawer{desc = "A large drawer filled with autopsy reports."; name = "Autopsy Reports"},/obj/machinery/light{dir = 8},/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/morgue) "bqV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/medical/morgue) "bqW" = (/obj/machinery/optable,/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/medical/morgue) @@ -3586,11 +3588,11 @@ "bqZ" = (/turf/simulated/floor/bluegrid,/area/assembly/chargebay) "bra" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor,/area/assembly/chargebay) "brb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/assembly/chargebay) -"brc" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "hazard door east"},/obj/machinery/door/airlock/glass_research{name = "Robotics Lab"; req_access_txt = "29"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) +"brc" = (/obj/structure/closet/secure_closet{name = "Psychiatrist's Locker"; req_access = list(64)},/obj/item/clothing/suit/straight_jacket{layer = 3},/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/pill/methylphenidate,/obj/item/weapon/reagent_containers/pill/citalopram,/obj/item/weapon/reagent_containers/pill/citalopram,/obj/item/weapon/reagent_containers/pill/methylphenidate,/obj/item/weapon/reagent_containers/syringe,/turf/simulated/floor{icon_state = "bcarpet04"},/area/medical/psych) "brd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "bre" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "brf" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"brg" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = 6},/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) +"brg" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor,/area/shuttle/research/station) "brh" = (/turf/simulated/wall/r_wall,/area/assembly/robotics) "bri" = (/obj/structure/closet/emcloset,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 9; icon_state = "warnwhite"},/area/rnd/research) "brj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) @@ -3599,14 +3601,14 @@ "brm" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/lab) "brn" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor{icon_state = "white"},/area/rnd/lab) "bro" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/lab) -"brp" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/rnd/lab) +"brp" = (/obj/effect/landmark/start{name = "Cargo Technician"},/obj/structure/bed/chair/office/dark{dir = 4},/turf/simulated/floor,/area/quartermaster/office) "brq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/storage/emergency) "brr" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/storage/emergency) "brs" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "brt" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "admin_shuttle_dock_pump"},/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/hallway/secondary/entry/aft) -"bru" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "admin_shuttle_dock_airlock"; pixel_x = 0; pixel_y = 30; req_access_txt = "0"; req_one_access_txt = "13"; tag_airpump = "admin_shuttle_dock_pump"; tag_chamber_sensor = "admin_shuttle_dock_sensor"; tag_exterior_door = "admin_shuttle_dock_outer"; tag_interior_door = "admin_shuttle_dock_inner"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1; icon_state = "map"; tag = "icon-manifold-f (NORTH)"},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/hallway/secondary/entry/aft) -"brv" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "admin_shuttle_dock_inner"; locked = 1; name = "Docking Port Airlock"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) -"brw" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "admin_shuttle_dock_airlock"; name = "interior access button"; pixel_x = -8; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry/aft) +"bru" = (/obj/structure/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/ward) +"brv" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/machinery/holosign/surgery,/obj/machinery/door/airlock/glass_medical{id_tag = "Surgery"; name = "Pre-Op Prep Room"; req_access = list(5)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) +"brw" = (/obj/machinery/door/firedoor,/obj/machinery/holosign/surgery,/obj/machinery/door/airlock/glass_medical{id_tag = "Surgery"; name = "Pre-Op Prep Room"; req_access = list(5)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) "brx" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry/aft) "bry" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor{icon_state = "warningcorner"; dir = 4},/area/hallway/secondary/entry/aft) "brz" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor,/area/hallway/secondary/entry/aft) @@ -3618,14 +3620,14 @@ "brF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/locker) "brG" = (/turf/simulated/wall/r_wall,/area/maintenance/locker) "brH" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/locker) -"brI" = (/obj/machinery/door/airlock/maintenance{name = "Cargo Bay Maintenance"; req_access_txt = "31"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/quartermaster/storage) +"brI" = (/obj/machinery/seed_storage/xenobotany,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) "brJ" = (/turf/simulated/floor,/area/quartermaster/storage) "brK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/quartermaster/storage) "brL" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/quartermaster/storage) "brM" = (/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/quartermaster/office) "brN" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/quartermaster/office) "brO" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/item/device/radio/intercom{pixel_y = 23},/turf/simulated/floor,/area/quartermaster/office) -"brP" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass_mining{name = "Delivery Office"; req_access_txt = "50"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/quartermaster/office) +"brP" = (/obj/machinery/botany/editor,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology/xenoflora) "brQ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/quartermaster/office) "brR" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/quartermaster/office) "brS" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/quartermaster/office) @@ -3643,33 +3645,33 @@ "bse" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/table,/obj/machinery/cell_charger,/turf/simulated/floor/plating,/area/maintenance/substation/command) "bsf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor/plating,/area/maintenance/substation/medical) "bsg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green,/obj/machinery/power/sensor{name = "Powernet Sensor - Medbay Subgrid"; name_tag = "Medbay Subgrid"},/turf/simulated/floor/plating,/area/maintenance/substation/medical) -"bsh" = (/obj/machinery/door/airlock/highsecurity{icon_state = "door_closed"; locked = 0; name = "AI Upload Access"; req_access_txt = "16"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "vault"},/area/hallway/primary/central_three) +"bsh" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/light_switch{pixel_x = -6; pixel_y = 26},/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/hydroponics{closed_system = 1; name = "isolation tray"},/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) "bsi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/cyan{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/turret_protected/ai_upload) -"bsj" = (/obj/structure/table,/obj/item/weapon/aiModule/asimov,/obj/item/weapon/aiModule/freeformcore,/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Core Modules"; req_access_txt = "20"},/obj/structure/window/reinforced,/obj/item/weapon/aiModule/corp,/obj/item/weapon/aiModule/paladin,/obj/item/weapon/aiModule/robocop,/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) +"bsj" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Xenobiology Research"; req_access = list(47)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "bsk" = (/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "bsl" = (/obj/machinery/computer/borgupload,/obj/item/device/radio/intercom{broadcasting = 1; frequency = 1447; name = "Private AI Channel"; pixel_x = -5; pixel_y = 22},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "bsm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/flasher{id = "AI"; pixel_x = -22; pixel_y = 24},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "bsn" = (/obj/machinery/alarm{pixel_y = 23},/obj/machinery/computer/aiupload,/obj/machinery/light{dir = 1},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) -"bso" = (/obj/structure/table,/obj/item/weapon/aiModule/oxygen,/obj/item/weapon/aiModule/oneHuman,/obj/machinery/door/window{base_state = "left"; dir = 8; icon_state = "left"; name = "High-Risk Modules"; req_access_txt = "20"},/obj/item/weapon/aiModule/purge,/obj/structure/window/reinforced,/obj/item/weapon/aiModule/antimov,/obj/item/weapon/aiModule/teleporterOffline,/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) +"bso" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/engineering{name = "Science Substation"; req_one_access = list(11,24,47)},/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/substation/research) "bsp" = (/turf/simulated/wall,/area/crew_quarters/captain) -"bsq" = (/obj/machinery/door/airlock/command{name = "Captain's Quarters"; req_access = null; req_access_txt = "20"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/carpet,/area/crew_quarters/captain) -"bsr" = (/obj/machinery/door/airlock/maintenance{name = "Captain's Office Maintenance"; req_access_txt = "20"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/supply,/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor/plating,/area/crew_quarters/captain) +"bsq" = (/obj/machinery/door/airlock/maintenance{name = "Miscellaneous Reseach Maintenance"; req_access = list(47)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/substation/research) +"bsr" = (/obj/machinery/door/firedoor/border_only{name = "hazard door south"},/obj/machinery/door/airlock/research{name = "Xenobiology Research"; req_access = list(47)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bss" = (/obj/structure/extinguisher_cabinet{pixel_x = -27; pixel_y = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/central_two) "bst" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bsu" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) -"bsv" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/syringes,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) +"bsv" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{autoclose = 0; name = "Diagnostics Room"; req_access = list(5)},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay4) "bsw" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/reception) "bsx" = (/obj/structure/table,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/item/weapon/storage/box/cups,/obj/item/weapon/storage/box/cups{pixel_x = 2; pixel_y = 5},/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/medical/reception) -"bsy" = (/obj/structure/table,/obj/machinery/door/window/northright{name = "Medbay Lobby"; req_access_txt = "5"},/obj/item/weapon/reagent_containers/spray/cleaner{pixel_x = -5},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/reception) +"bsy" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_command{name = "Chief Engineer"; req_access = list(56)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/crew_quarters/heads/chief) "bsz" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/machinery/computer/med_data/laptop,/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/reception) "bsA" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/paper_bin,/obj/item/weapon/folder/white,/obj/item/weapon/pen,/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/reception) -"bsB" = (/obj/structure/table,/obj/machinery/door/window/northright{name = "Medbay Lobby"; req_access_txt = "5"},/obj/item/device/radio/intercom{broadcasting = 0; canhear_range = 5; freerange = 0; frequency = 1485; listening = 0; name = "Station Intercom (Medbay)"; pixel_x = 0; pixel_y = 3},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/reception) +"bsB" = (/obj/machinery/door/airlock/external{name = "Toxins Test Chamber"},/turf/simulated/floor/plating/airless,/area/rnd/test_area) "bsC" = (/obj/structure/filingcabinet/chestdrawer{name = "Medical Forms"},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{dir = 5; icon_state = "blue"},/area/medical/reception) "bsD" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/reception) "bsE" = (/obj/structure/table,/obj/structure/closet/secure_closet/medical_wall{name = "Pill Cabinet"; pixel_y = -32},/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/storage/pill_bottle/antitox,/obj/item/weapon/storage/pill_bottle/tramadol,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) "bsF" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) "bsG" = (/obj/structure/table,/obj/item/weapon/cane,/obj/item/weapon/cane{pixel_x = -3; pixel_y = 2},/obj/item/weapon/cane{pixel_x = -6; pixel_y = 4},/obj/item/weapon/storage/box/rxglasses,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) -"bsH" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_y = -10},/obj/item/weapon/folder/white{pixel_y = 0},/obj/item/weapon/pen,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 16; req_access_txt = "0"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) +"bsH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "bsI" = (/obj/structure/table,/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/box/bodybags,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/morgue) "bsJ" = (/obj/machinery/mech_bay_recharge_port,/turf/simulated/floor/plating,/area/assembly/chargebay) "bsK" = (/turf/simulated/floor/mech_bay_recharge_floor,/area/assembly/chargebay) @@ -3695,7 +3697,7 @@ "bte" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/tank/oxygen,/obj/item/weapon/storage/belt/utility,/obj/item/clothing/mask/breath,/turf/simulated/floor/plating,/area/storage/emergency) "btf" = (/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "admin_shuttle_dock_sensor"; pixel_x = -30; pixel_y = 8},/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/hallway/secondary/entry/aft) "btg" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1380; id_tag = "admin_shuttle_dock_pump"},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/hallway/secondary/entry/aft) -"bth" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "admin_shuttle_dock_inner"; locked = 1; name = "Docking Port Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) +"bth" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "bti" = (/turf/simulated/floor{icon_state = "warning"},/area/hallway/secondary/entry/aft) "btj" = (/obj/machinery/light,/turf/simulated/floor{icon_state = "warning"},/area/hallway/secondary/entry/aft) "btk" = (/obj/machinery/disposal/deliveryChute{dir = 1; name = "disposal inlet"},/obj/structure/disposalpipe/trunk{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/disposal) @@ -3709,20 +3711,20 @@ "bts" = (/obj/machinery/light{dir = 1},/obj/machinery/firealarm{pixel_y = 27},/turf/simulated/floor,/area/quartermaster/storage) "btt" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/quartermaster/storage) "btu" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/quartermaster/storage) -"btv" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass_mining{name = "Cargo Bay"; req_access_txt = "31"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/quartermaster/storage) +"btv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "btw" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{dir = 8; icon_state = "brown"},/area/quartermaster/office) "btx" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/quartermaster/office) "bty" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/quartermaster/office) "btz" = (/obj/machinery/status_display/supply_display,/turf/simulated/wall,/area/quartermaster/office) "btA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/office) -"btB" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_mining{name = "Delivery Office"; req_access_txt = "50"},/turf/simulated/floor,/area/quartermaster/office) +"btB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 10},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "btC" = (/turf/simulated/wall,/area/hallway/primary/central_three) "btD" = (/obj/machinery/light{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central_three) "btE" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/central_three) "btF" = (/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor,/area/hallway/primary/central_three) "btG" = (/turf/simulated/wall/r_wall,/area/hallway/primary/central_three) "btH" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/tank/emergency_oxygen,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/plating,/area/maintenance/substation/command) -"btI" = (/obj/machinery/door/airlock/command{name = "Head of Personnel"; req_access = null; req_access_txt = "57"},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/maintenance/substation/command) +"btI" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_one_access = list(12,47)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/rnd/xenobiology) "btJ" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/cyan,/obj/structure/cable/cyan{d2 = 2; icon_state = "0-2"},/obj/structure/cable/cyan{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/turret_protected/ai_upload) "btK" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/porta_turret{dir = 4},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "btL" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) @@ -3733,7 +3735,7 @@ "btQ" = (/obj/structure/displaycase,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "btR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/carpet,/area/crew_quarters/captain) "btS" = (/obj/machinery/light_switch{pixel_y = 28},/turf/simulated/floor/carpet,/area/crew_quarters/captain) -"btT" = (/obj/machinery/door/airlock{name = "Private Restroom"; req_access_txt = "0"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/captain) +"btT" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_one_access = list(12,47)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor/plating,/area/rnd/xenobiology) "btU" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/structure/mirror{pixel_x = 28},/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/captain) "btV" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/supply,/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor/plating,/area/crew_quarters/captain) "btW" = (/obj/structure/disposalpipe/segment,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor,/area/hallway/primary/central_two) @@ -3746,15 +3748,15 @@ "bud" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"; pixel_x = -32},/turf/simulated/floor{tag = "icon-whiteblue (SOUTHWEST)"; icon_state = "whiteblue"; dir = 10},/area/medical/reception) "bue" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/reception) "buf" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/computer/crew,/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/reception) -"bug" = (/obj/machinery/door_control{desc = "A remote control switch for the medbay foyer."; id = "MedbayFoyerPort"; name = "Medbay Doors Control"; normaldoorcontrol = 1; pixel_x = -16; pixel_y = 28; req_access_txt = null},/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/effect/landmark/start{name = "Medical Doctor"},/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/medical/reception) +"bug" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/office) "buh" = (/obj/structure/table,/obj/item/device/radio{anchored = 1; broadcasting = 0; canhear_range = 1; frequency = 1487; icon = 'icons/obj/items.dmi'; icon_state = "red_phone"; listening = 1; name = "Reception Emergency Phone"},/turf/simulated/floor,/area/medical/reception) -"bui" = (/obj/structure/table,/obj/machinery/door_control{id = "medbayrecquar"; name = "Medbay Entrance Lockdown Shutters Control"; pixel_x = 6; pixel_y = 8; req_access_txt = "5"},/obj/item/device/radio{anchored = 1; broadcasting = 0; canhear_range = 1; frequency = 1487; icon = 'icons/obj/items.dmi'; icon_state = "red_phone"; listening = 1; name = "Reception Emergency Phone"; pixel_x = -5},/turf/simulated/floor,/area/medical/reception) -"buj" = (/obj/machinery/door_control{desc = "A remote control switch for the medbay foyer."; id = "MedbayFoyerStar"; name = "Medbay Doors Control"; normaldoorcontrol = 1; pixel_x = 6; pixel_y = 28},/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/effect/landmark/start{name = "Medical Doctor"},/turf/simulated/floor{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/medical/reception) +"bui" = (/obj/item/weapon/shard,/turf/simulated/floor/plating,/area/maintenance/research_port) +"buj" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "hop_office_desk"; name = "Desk Privacy Shutter"; pixel_x = 16; pixel_y = 28},/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/crew_quarters/heads/hop) "buk" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/filingcabinet/medical{pixel_y = 0},/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/medical/reception) "bul" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-whiteblue"; icon_state = "whiteblue"},/area/medical/reception) "bum" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"; pixel_x = 32},/turf/simulated/floor{tag = "icon-whiteblue (SOUTHEAST)"; icon_state = "whiteblue"; dir = 6},/area/medical/reception) "bun" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) -"buo" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) +"buo" = (/obj/structure/bed/chair/comfy/brown{dir = 4},/obj/machinery/camera{c_tag = "Captain's Quarters"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "bup" = (/obj/structure/table,/obj/machinery/computer/med_data/laptop,/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -28},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) "buq" = (/obj/structure/morgue,/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/medical/morgue) "bur" = (/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = -22},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/medical/morgue) @@ -3767,7 +3769,7 @@ "buy" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/assembly/chargebay) "buz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/assembly/robotics) "buA" = (/obj/structure/table,/obj/item/stack/sheet/plasteel{amount = 10},/obj/item/stack/cable_coil,/obj/item/device/flash,/obj/item/device/flash,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/assembly/robotics) -"buB" = (/obj/structure/stool,/obj/effect/landmark/start{name = "Roboticist"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/assembly/robotics) +"buB" = (/obj/structure/table/woodentable,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/item/weapon/storage/box/matches,/obj/item/clothing/mask/smokable/cigarette/cigar,/obj/item/weapon/reagent_containers/food/drinks/flask{pixel_x = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "buC" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "bot"},/area/assembly/robotics) "buD" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "bot"},/area/assembly/robotics) "buE" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/hologram/holopad,/turf/simulated/floor{dir = 8; icon_state = "warnwhite"},/area/assembly/robotics) @@ -3785,8 +3787,8 @@ "buQ" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/research/station) "buR" = (/obj/structure/window/shuttle,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/research/station) "buS" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/shuttle/research/station) -"buT" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "admin_shuttle_dock_airlock"; name = "exterior access button"; pixel_x = 30; pixel_y = -5; req_access_txt = "0"; req_one_access_txt = "13"},/turf/space,/area/space) -"buU" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "admin_shuttle_dock_outer"; locked = 1; name = "Docking Port Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) +"buT" = (/obj/structure/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0},/obj/machinery/camera{c_tag = "Medbay Patient C"; dir = 8; network = list("SS13")},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/patient_c) +"buU" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Break Room"; req_one_access = list(10,24,5)},/turf/simulated/floor,/area/engineering/break_room) "buV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "buW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "buX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) @@ -3801,7 +3803,7 @@ "bvg" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/quartermaster/storage) "bvh" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/quartermaster/storage) "bvi" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/quartermaster/storage) -"bvj" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass_mining{name = "Cargo Bay"; req_access_txt = "31"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/quartermaster/storage) +"bvj" = (/obj/structure/closet/secure_closet/engineering_chief,/obj/item/weapon/tank/emergency_oxygen/engi,/turf/simulated/floor,/area/crew_quarters/heads/chief) "bvk" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "brown"},/area/quartermaster/office) "bvl" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/quartermaster/office) "bvm" = (/obj/structure/disposalpipe/tagger/partial{name = "Sorting Office"; sort_tag = "Sorting Office"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/office) @@ -3809,7 +3811,7 @@ "bvo" = (/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/clipboard,/obj/item/weapon/pen/red{pixel_x = 2; pixel_y = 6},/obj/structure/table,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/quartermaster/office) "bvp" = (/obj/machinery/computer/ordercomp,/turf/simulated/floor,/area/quartermaster/office) "bvq" = (/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor,/area/quartermaster/office) -"bvr" = (/obj/structure/stool/bed/chair{dir = 8},/obj/machinery/firealarm{pixel_y = 27},/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/quartermaster/office) +"bvr" = (/obj/machinery/light/small{dir = 1},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/maintenance/substation/medical) "bvs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/hallway/primary/central_three) "bvt" = (/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central_three) "bvu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/primary/central_three) @@ -3821,7 +3823,7 @@ "bvA" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/crew_quarters/heads/hop) "bvB" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/crew_quarters/heads/hop) "bvC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload_foyer) -"bvD" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{dir = 4},/obj/structure/cable/cyan,/turf/simulated/floor/plating,/area/turret_protected/ai_upload) +"bvD" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 28},/turf/simulated/floor{icon_state = "bot"},/area/rnd/research) "bvE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/cyan{d2 = 4; icon_state = "0-4"},/obj/structure/cable/cyan{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload_foyer) "bvF" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/structure/cable/cyan{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/cyan{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload_foyer) "bvG" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/maintenance/substation/command) @@ -3829,11 +3831,11 @@ "bvI" = (/obj/structure/table,/obj/item/weapon/aiModule/nanotrasen,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "bvJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) "bvK" = (/obj/machinery/hologram/holopad,/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) -"bvL" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/supply{dir = 4},/obj/structure/cable/cyan,/turf/simulated/floor/plating,/area/turret_protected/ai_upload) +"bvL" = (/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = 3},/obj/item/weapon/stock_parts/scanning_module{pixel_x = 2; pixel_y = 3},/obj/item/weapon/stock_parts/scanning_module,/obj/machinery/light_switch{pixel_x = 27},/obj/structure/reagent_dispensers/acid{density = 0; pixel_y = -32},/turf/simulated/floor{icon_state = "white"},/area/rnd/lab) "bvM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) "bvN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "bvO" = (/obj/structure/table,/obj/item/weapon/aiModule/freeform,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) -"bvP" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/captain,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/carpet,/area/crew_quarters/captain) +"bvP" = (/obj/structure/grille,/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/window/reinforced/polarized{dir = 4},/obj/structure/window/reinforced/polarized{dir = 1},/obj/structure/window/reinforced/polarized{dir = 8},/turf/simulated/floor/plating,/area/crew_quarters/heads/hop) "bvQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/carpet,/area/crew_quarters/captain) "bvR" = (/obj/structure/toilet{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/captain) "bvS" = (/obj/machinery/light/small{dir = 8},/obj/effect/decal/cleanable/dirt,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/supply,/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor/plating,/area/crew_quarters/captain) @@ -3843,31 +3845,31 @@ "bvW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/medical/chemistry) "bvX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/medical/chemistry) "bvY" = (/obj/machinery/smartfridge/secure/medbay,/turf/simulated/wall,/area/medical/chemistry) -"bvZ" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Chemistry Laboratory"; req_access_txt = "33"},/obj/structure/sign/chemistry{pixel_x = 32},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) +"bvZ" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "eng_eva_airlock"; name = "interior access button"; pixel_x = 0; pixel_y = 25; req_access = list(13)},/turf/simulated/floor{dir = 8; icon_state = "floorgrimecaution"},/area/maintenance/atmos_control) "bwa" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "scanhideside"; name = "Diagnostics Room Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay4) -"bwb" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "medpriva"; name = "Patient Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/patient_a) -"bwc" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Medical Reception"; req_access_txt = "5"},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/medical/reception) +"bwb" = (/obj/structure/table,/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/item/weapon/reagent_containers/glass/bottle/stoxin{pixel_x = -6; pixel_y = 10},/obj/item/weapon/reagent_containers/glass/bottle/antitoxin{pixel_x = 5; pixel_y = 5},/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline{pixel_x = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/random/medical,/turf/simulated/floor{dir = 8; icon_state = "whiteyellow"},/area/medical/chemistry) +"bwc" = (/obj/machinery/keycard_auth{pixel_x = -24; pixel_y = 0},/obj/machinery/door_control{desc = "A remote control-switch for engine core."; id = "EngineVent"; name = "Engine Ventillatory Control"; pixel_x = -24; pixel_y = 10; req_access = list(10)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door_control{desc = "A remote control-switch for the engine core airlock hatch bolts."; id = "engine_access_hatch"; name = "Engine Hatch Bolt Control"; normaldoorcontrol = 1; pixel_x = -24; pixel_y = -10; req_access = list(10); specialfunctions = 4},/turf/simulated/floor,/area/crew_quarters/heads/chief) "bwd" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor,/area/medical/reception) "bwe" = (/turf/simulated/floor,/area/medical/reception) "bwf" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor,/area/medical/reception) -"bwg" = (/obj/machinery/door/window/eastright{name = "Medical Reception"; req_access_txt = "5"},/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = -22},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/medical/reception) +"bwg" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "eng_eva_pump"; tag_exterior_door = "eng_eva_outer"; frequency = 1379; id_tag = "eng_eva_airlock"; tag_interior_door = "eng_eva_inner"; name = "Engineering Airlock Console"; pixel_y = 25; req_access = list(13); tag_chamber_sensor = "eng_eva_sensor"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/simulated/floor{dir = 5; icon_state = "floorgrimecaution"},/area/maintenance/atmos_control) "bwh" = (/obj/machinery/door/blast/regular{id = "toxinsdriver"; name = "Toxins Launcher Bay Door"},/turf/simulated/floor/plating/airless,/area/rnd/mixing) "bwi" = (/obj/machinery/door/blast/regular{id = "toxinsdriver"; name = "Toxins Launcher Bay Door"},/turf/simulated/floor/plating/airless,/area/rnd/test_area) "bwj" = (/obj/structure/table,/obj/item/roller,/obj/item/roller{pixel_y = 8},/obj/item/roller{pixel_y = 16},/turf/simulated/floor,/area/medical/reception) "bwk" = (/turf/simulated/wall,/area/medical/medbay2) -"bwl" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Examination Room"; req_access_txt = "5"},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) +"bwl" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "eng_eva_airlock"; name = "exterior access button"; pixel_x = 0; pixel_y = 25; req_access = list(13)},/turf/simulated/floor/plating/airless,/area/maintenance/atmos_control) "bwm" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/medbay2) -"bwn" = (/obj/machinery/door/airlock/medical{name = "Morgue"; req_access_txt = "6;5"},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/medical/medbay2) +"bwn" = (/obj/machinery/door/airlock/glass_mining{name = "Quartermaster"; req_access = list(41)},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/quartermaster/qm) "bwo" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/assembly/chargebay) "bwp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/assembly/chargebay) "bwq" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/assembly/robotics) "bwr" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor,/area/assembly/robotics) "bws" = (/turf/simulated/floor,/area/assembly/robotics) "bwt" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) -"bwu" = (/obj/structure/table,/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000; pixel_x = 5; pixel_y = -5},/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) +"bwu" = (/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Substation - Medical"},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/maintenance/substation/medical) "bwv" = (/obj/machinery/status_display,/turf/simulated/wall/r_wall,/area/assembly/robotics) "bww" = (/turf/simulated/wall/r_wall,/area/rnd/research) -"bwx" = (/obj/machinery/door/airlock/research{name = "Research Division Access"; req_access_txt = "47"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) +"bwx" = (/obj/structure/table,/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "mining_shuttle"; pixel_x = 25; pixel_y = -8; req_one_access = list(13,48); tag_door = "mining_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/mining/station) "bwy" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/rnd/research) "bwz" = (/obj/machinery/newscaster{pixel_x = -27; pixel_y = 1},/turf/simulated/floor{icon_state = "warnwhite"; dir = 1},/area/rnd/lab) "bwA" = (/turf/simulated/floor{icon_state = "warnwhite"; dir = 1},/area/rnd/lab) @@ -3878,7 +3880,7 @@ "bwF" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/storage/emergency) "bwG" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/shuttle/research/station) "bwH" = (/obj/structure/closet/crate,/turf/simulated/shuttle/floor,/area/shuttle/research/station) -"bwI" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor,/area/shuttle/research/station) +"bwI" = (/obj/structure/grille,/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = -32},/obj/structure/cable/green,/obj/structure/window/reinforced/polarized,/obj/structure/window/reinforced/polarized{dir = 4},/obj/structure/window/reinforced/polarized{dir = 8},/turf/simulated/floor/plating,/area/crew_quarters/heads/hop) "bwJ" = (/turf/simulated/shuttle/floor,/area/shuttle/research/station) "bwK" = (/obj/structure/table,/turf/simulated/shuttle/floor,/area/shuttle/research/station) "bwL" = (/turf/space,/area/shuttle/administration/station) @@ -3894,16 +3896,16 @@ "bwV" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/quartermaster/office) "bwW" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 1; sortType = "Cargo Bay"; name = "Cargo Bay"},/turf/simulated/floor,/area/quartermaster/office) "bwX" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/office) -"bwY" = (/obj/effect/landmark/start{name = "Cargo Technician"},/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor,/area/quartermaster/office) -"bwZ" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/window/westleft{name = "Cargo Desk"; req_access_txt = "50"},/obj/structure/noticeboard{pixel_y = 27},/turf/simulated/floor,/area/quartermaster/office) +"bwY" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/fire{pixel_x = 5; pixel_y = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/random/firstaid,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) +"bwZ" = (/obj/machinery/door/airlock{name = "Custodial Closet"; req_access = list(26)},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hallway/primary/central_three) "bxa" = (/turf/simulated/floor{icon_state = "delivery"},/area/quartermaster/office) -"bxb" = (/obj/structure/stool/bed/chair{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/office) +"bxb" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/toxin{pixel_x = 5; pixel_y = 5},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/random/firstaid,/turf/simulated/floor{dir = 8; icon_state = "whiteyellowcorner"},/area/medical/chemistry) "bxc" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/primary/central_three) "bxd" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/hallway/primary/central_three) "bxe" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "loadingarea"},/area/hallway/primary/central_three) "bxf" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor{icon_state = "delivery"},/area/hallway/primary/central_three) "bxg" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "scanhideside"; name = "Diagnostics Room Privacy Shutters"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay4) -"bxh" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "hop_office_desk"; name = "Desk Privacy Shutter"; pixel_x = 16; pixel_y = 28},/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "hop_office_window"; name = "Window Privacy Shutters"; pixel_x = 16; pixel_y = 38},/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/crew_quarters/heads/hop) +"bxh" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{pixel_x = 5; pixel_y = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/random/firstaid,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bxi" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/carpet,/area/crew_quarters/heads/hop) "bxj" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/carpet,/area/crew_quarters/heads/hop) "bxk" = (/turf/simulated/floor/carpet,/area/crew_quarters/heads/hop) @@ -3915,9 +3917,9 @@ "bxq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green,/obj/machinery/power/sensor{name = "Powernet Sensor - Command Subgrid"; name_tag = "Command Subgrid"},/turf/simulated/floor/plating,/area/maintenance/substation/command) "bxr" = (/turf/simulated/wall/r_wall,/area/turret_protected/ai_upload) "bxs" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor,/area/maintenance/substation/command) -"bxt" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 4},/obj/machinery/camera{c_tag = "Captain's Quarters"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/carpet,/area/crew_quarters/captain) -"bxu" = (/obj/structure/table/woodentable,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/item/weapon/storage/box/matches,/obj/item/clothing/mask/cigarette/cigar,/obj/item/weapon/reagent_containers/food/drinks/flask{pixel_x = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/carpet,/area/crew_quarters/captain) -"bxv" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 1; icon_state = "left"; name = "Shower"; req_access_txt = "0"},/obj/machinery/shower{icon_state = "shower"; dir = 4},/obj/item/weapon/soap/deluxe,/obj/item/weapon/bikehorn/rubberducky,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/captain) +"bxt" = (/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = -5; pixel_y = -22},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/extinguisher_cabinet{pixel_x = 6; pixel_y = -29},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) +"bxu" = (/obj/machinery/cryopod/robot/right,/turf/simulated/floor,/area/assembly/chargebay) +"bxv" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/central_two) "bxw" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/central_two) "bxx" = (/obj/structure/table,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{dir = 1; icon_state = "whiteyellowcorner"},/area/medical/chemistry) "bxy" = (/obj/structure/closet/secure_closet/medical1,/turf/simulated/floor{dir = 1; icon_state = "whiteyellow"},/area/medical/chemistry) @@ -3925,12 +3927,12 @@ "bxA" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bxB" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bxC" = (/turf/simulated/wall,/area/medical/medbay) -"bxD" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/multi_tile/glass{id_tag = "MedbayFoyerPort"; req_access_txt = "5"},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/medical/medbay) +"bxD" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/central_three) "bxE" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/medical/medbay) "bxF" = (/turf/simulated/wall,/area/medical/medbay3) "bxG" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/medbay3) -"bxH" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Medbay Reception"; req_access_txt = "5"},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/medbay3) -"bxI" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/multi_tile/glass{id_tag = "MedbayFoyerStar"; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/medical/medbay2) +"bxH" = (/obj/machinery/camera{c_tag = "EMT Storage"; dir = 1; network = list("SS13")},/obj/machinery/door_control{id = "acutesep"; name = "Acute Separation Shutters"; pixel_y = -25; req_access = list(5)},/obj/item/weapon/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Paramedic"},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bxI" = (/obj/machinery/light/small{dir = 4; pixel_y = 8},/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "mining_dock_airlock"; pixel_x = 25; pixel_y = -5; req_one_access = list(13,48); tag_airpump = "mining_dock_pump"; tag_chamber_sensor = "mining_dock_sensor"; tag_exterior_door = "mining_dock_outer"; tag_interior_door = "mining_dock_inner"},/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "mining_dock_sensor"; pixel_x = 25; pixel_y = 8},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1; icon_state = "map"; tag = "icon-manifold-f (NORTH)"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/quartermaster/miningdock) "bxJ" = (/obj/machinery/door/firedoor,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/medical/medbay2) "bxK" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-white_ex"; icon_state = "white_ex"; dir = 2},/area/medical/medbay2) "bxL" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) @@ -3941,8 +3943,8 @@ "bxQ" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 1; icon_state = "whitehall_m"; tag = "icon-whitehall_m"},/area/medical/medbay2) "bxR" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor{dir = 1; icon_state = "whitecorner"},/area/medical/medbay2) "bxS" = (/obj/machinery/vending/medical,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) -"bxT" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "toxin_test_airlock"; name = "exterior access button"; pixel_x = -20; pixel_y = -20; req_access_txt = "13"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating/airless,/area/space) -"bxU" = (/obj/structure/table/reinforced,/obj/machinery/ignition_switch{id = "Xenobio"; pixel_x = -6; pixel_y = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) +"bxT" = (/obj/machinery/door/window/westleft{name = "Janitoral Delivery"; req_access = list(26)},/turf/simulated/floor{icon_state = "delivery"},/area/janitor) +"bxU" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/effect/landmark{name = "JoinLateCyborg"},/obj/machinery/computer/cryopod/robot{pixel_y = -30},/turf/simulated/floor,/area/assembly/chargebay) "bxV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/research_port) "bxW" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bxX" = (/obj/structure/extinguisher_cabinet{pixel_x = -27},/obj/machinery/light{dir = 8},/turf/simulated/floor/bluegrid,/area/assembly/chargebay) @@ -3957,12 +3959,12 @@ "byg" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor{icon_state = "white"},/area/rnd/lab) "byh" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = 2; pixel_y = 3},/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/turf/simulated/floor{icon_state = "white"},/area/rnd/lab) "byi" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/lab) -"byj" = (/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = 3},/obj/item/weapon/stock_parts/scanning_module{pixel_x = 2; pixel_y = 3},/obj/item/weapon/stock_parts/scanning_module,/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor{icon_state = "white"},/area/rnd/lab) +"byj" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor,/area/quartermaster/office) "byk" = (/obj/structure/closet/crate,/obj/item/weapon/coin/silver,/turf/simulated/floor/plating,/area/storage/emergency) "byl" = (/obj/structure/shuttle/engine/propulsion/burst{dir = 4},/turf/space,/area/shuttle/research/station) "bym" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/shuttle/engine/heater{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/shuttle/research/station) "byn" = (/obj/machinery/computer/shuttle_control/research,/turf/simulated/shuttle/floor,/area/shuttle/research/station) -"byo" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "cargo_bay_door"; locked = 1; name = "Cargo Docking Hatch"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/quartermaster/storage) +"byo" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "CMO's Office"; req_access = list(40)},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) "byp" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/turf/simulated/floor/plating,/area/quartermaster/storage) "byq" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/quartermaster/storage) "byr" = (/turf/simulated/floor{dir = 4; icon_state = "loadingarea"},/area/quartermaster/storage) @@ -3988,13 +3990,13 @@ "byL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/cyan{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) "byM" = (/obj/item/device/radio/intercom{broadcasting = 1; frequency = 1447; name = "Private AI Channel"; pixel_x = 0; pixel_y = -27},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "byN" = (/turf/simulated/wall/r_wall,/area/teleporter) -"byO" = (/obj/machinery/door/airlock/maintenance{name = "Teleporter Maintenance"; req_access_txt = "17"},/obj/structure/sign/securearea{pixel_x = -32; pixel_y = 0},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/supply,/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor/plating,/area/teleporter) +"byO" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Staff Room"; req_access = list(5)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/medbay2) "byP" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/central_two) -"byQ" = (/obj/structure/table,/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/item/weapon/reagent_containers/glass/bottle/stoxin{pixel_x = -6; pixel_y = 10},/obj/item/weapon/reagent_containers/glass/bottle/antitoxin{pixel_x = 5; pixel_y = 5},/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline{pixel_x = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 8; icon_state = "whiteyellow"},/area/medical/chemistry) +"byQ" = (/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20},/obj/structure/bed/chair/office/dark{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_cyborg_station) "byR" = (/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "byS" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "byT" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whiteyellow"},/area/medical/chemistry) -"byU" = (/obj/machinery/door_control{desc = "A remote control switch for the medbay foyer."; id = "MedbayFoyerPort"; name = "Medbay Doors Control"; normaldoorcontrol = 1; pixel_x = -24; pixel_y = 26; req_access_txt = null},/obj/machinery/computer/guestpass{pixel_x = -28},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/medbay) +"byU" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "CMO's Office"; req_access = list(40)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) "byV" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{tag = "icon-whiteblue (NORTHEAST)"; icon_state = "whiteblue"; dir = 5},/area/medical/medbay) "byW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/medbay) "byX" = (/obj/structure/table,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/item/device/flashlight/pen,/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/medbay3) @@ -4012,12 +4014,12 @@ "bzj" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-j2"; dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bzk" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-j2"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bzl" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) -"bzm" = (/obj/machinery/door_control{id = "misclab"; name = "Test Chamber Blast Doors"; pixel_x = 6; pixel_y = 30; req_access_txt = "47"},/obj/structure/stool,/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) +"bzm" = (/obj/item/weapon/stool,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/teleporter) "bzn" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) "bzo" = (/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = -22},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 2; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/patient_wing) "bzp" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) "bzq" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{tag = "icon-whitebluecorner (WEST)"; icon_state = "whitebluecorner"; dir = 8},/area/medical/patient_wing) -"bzr" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock{name = "Starboard Emergency Storage"; req_access_txt = "29"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/assembly/chargebay) +"bzr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_one_access = list(8,12)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/research_shuttle) "bzs" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/assembly/chargebay) "bzt" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor,/area/assembly/chargebay) "bzu" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/assembly/chargebay) @@ -4033,15 +4035,15 @@ "bzE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/rnd/research) "bzF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/rnd/research) "bzG" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/rnd/research) -"bzH" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/glass_research{name = "Research and Development"; req_access_txt = "7"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) +"bzH" = (/obj/machinery/door/airlock/glass_command{name = "Research Director"; req_access = list(30)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/rnd/research) "bzI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/rnd/research) -"bzJ" = (/obj/machinery/door/airlock{name = "Starboard Emergency Storage"; req_access_txt = "0"; req_one_access_txt = "12;47"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/storage/emergency) +"bzJ" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/window/westleft{dir = 8; name = "Server Room"; opacity = 1; req_access = list(30)},/obj/machinery/door/window/westleft{dir = 4; name = "Server Room"; opacity = 1; req_access = list(30)},/turf/simulated/floor{icon_state = "dark"},/area/server) "bzK" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/docking) "bzL" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/docking) "bzM" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/docking) "bzN" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall,/area/rnd/docking) -"bzO" = (/obj/structure/table,/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "research_shuttle"; pixel_x = -8; pixel_y = -25; req_access_txt = "0"; req_one_access_txt = "13;65"; tag_door = "research_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/research/station) -"bzP" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "cargo_bay_door"; locked = 1; name = "Cargo Docking Hatch"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/quartermaster/storage) +"bzO" = (/obj/machinery/door_control{id = "acute1"; name = "EMT Storage Privacy Shutters"; pixel_x = 26; pixel_y = 25; req_access = list(5)},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bzP" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{id_tag = "cmodoor"; name = "CMO's Office"; req_access = list(40)},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) "bzQ" = (/turf/simulated/floor/plating,/area/quartermaster/storage) "bzR" = (/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/quartermaster/storage) "bzS" = (/turf/simulated/floor{icon_state = "bot"},/area/quartermaster/storage) @@ -4056,7 +4058,7 @@ "bAb" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/central_three) "bAc" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/central_three) "bAd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/primary/central_three) -"bAe" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/rnd/xenobiology/xenoflora) +"bAe" = (/obj/structure/table/rack,/obj/item/weapon/crowbar,/obj/item/weapon/crowbar,/obj/item/weapon/storage/toolbox/mechanical,/obj/machinery/vending/wallmed1{pixel_x = -32; pixel_y = 0},/obj/item/roller,/obj/item/roller,/obj/item/roller,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bAf" = (/obj/structure/closet/secure_closet/hop,/turf/simulated/floor,/area/crew_quarters/heads/hop) "bAg" = (/obj/structure/disposalpipe/segment,/obj/machinery/firealarm{dir = 4; layer = 3.3; pixel_x = 26},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/crew_quarters/heads/hop) "bAh" = (/turf/simulated/wall/r_wall,/area/turret_protected/ai_server_room) @@ -4070,26 +4072,26 @@ "bAp" = (/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/teleporter) "bAq" = (/obj/machinery/light_switch{pixel_x = 27},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/teleporter) "bAr" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/hallway/primary/central_two) -"bAs" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/toxin{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/toxin,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{dir = 8; icon_state = "whiteyellowcorner"},/area/medical/chemistry) -"bAt" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/fire{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/fire,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) -"bAu" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/o2,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) +"bAs" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{pixel_x = 5; pixel_y = 5},/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/random/firstaid,/turf/simulated/floor{dir = 8; icon_state = "whiteyellowcorner"},/area/medical/chemistry) +"bAt" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/machinery/camera/autoname{dir = 8},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/rnd/docking) +"bAu" = (/obj/structure/bed/chair{dir = 8},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -35},/obj/machinery/light,/turf/simulated/floor,/area/quartermaster/office) "bAv" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bAw" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) -"bAx" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Medicine Storage"; req_access_txt = "5"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) +"bAx" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{autoclose = 1; name = "EMT Storage"; req_access = list(5)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) "bAy" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bAz" = (/obj/structure/disposalpipe/sortjunction{dir = 1; icon_state = "pipe-j1s"; sortType = "Medbay"; name = "Medbay"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) -"bAA" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Medical Equipment"; req_access_txt = "5"},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) +"bAA" = (/obj/machinery/door/airlock/maintenance{name = "Custodial Maintenance"; req_access = list(26)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/janitor) "bAB" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay3) "bAC" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay3) "bAD" = (/obj/machinery/hologram/holopad,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay3) "bAE" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay3) -"bAF" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Medical Equipment"; req_access_txt = "5"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) +"bAF" = (/obj/machinery/door/airlock/highsecurity{name = "Secure Tech Storage"; req_access = list(19,23)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/storage/tech) "bAG" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bAH" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bAI" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bAJ" = (/obj/machinery/door/firedoor,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bAK" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) -"bAL" = (/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = -22},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) +"bAL" = (/obj/structure/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Head of Personnel"},/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "hop_office_desk"; name = "Desk Privacy Shutter"; pixel_x = 26; pixel_y = 17},/obj/machinery/button/windowtint{pixel_x = 36; pixel_y = 18},/turf/simulated/floor,/area/crew_quarters/heads/hop) "bAM" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{dir = 2; icon_state = "whitepurplecorner"},/area/medical/medbay2) "bAN" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/medical/medbay2) "bAO" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 8; icon_state = "whitepurplecorner"},/area/medical/medbay2) @@ -4100,8 +4102,8 @@ "bAT" = (/obj/machinery/hologram/holopad,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "whitered_c"; tag = "icon-whitered_c (WEST)"},/area/medical/patient_wing) "bAU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) "bAV" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/machinery/camera{c_tag = "Medbay Patient Hallway - Starboard"; dir = 1; network = list("SS13")},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) -"bAW" = (/obj/structure/table,/turf/simulated/floor,/area/assembly/chargebay) -"bAX" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/assembly/chargebay) +"bAW" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor,/area/crew_quarters/heads/hop) +"bAX" = (/obj/machinery/door/airlock/engineering{name = "Tech Storage"; req_access = list(23)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/aft) "bAY" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor,/area/assembly/chargebay) "bAZ" = (/obj/machinery/recharge_station,/turf/simulated/floor{icon_state = "bot"},/area/assembly/chargebay) "bBa" = (/obj/structure/table,/obj/item/weapon/storage/box/bodybags{pixel_x = -1; pixel_y = -2},/obj/item/weapon/pen,/turf/simulated/floor{icon_state = "whitehall"; dir = 4},/area/assembly/robotics) @@ -4120,27 +4122,27 @@ "bBn" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/rnd/research) "bBo" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "whitepurplecorner"},/area/rnd/research) "bBp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/rnd/xenobiology/xenoflora) -"bBq" = (/obj/machinery/door/airlock/research{name = "Research Division Access"; req_access_txt = "47"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) +"bBq" = (/obj/structure/sign/securearea{pixel_x = -32},/obj/structure/sign/securearea{pixel_x = -32},/obj/structure/sign/securearea{pixel_x = -32},/turf/simulated/floor{icon_state = "warningcorner"; dir = 4},/area/rnd/mixing) "bBr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) "bBs" = (/obj/machinery/light/small{dir = 1},/obj/machinery/camera{c_tag = "Research Shuttle Maintainance"; dir = 2},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) -"bBt" = (/obj/machinery/door/airlock/research{name = "Research Shuttle Dock"; req_access_txt = "65"},/obj/machinery/door/firedoor/border_only,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) +"bBt" = (/obj/structure/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0},/obj/machinery/camera{c_tag = "Medbay Patient A"; dir = 8; network = list("SS13")},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/patient_a) "bBu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/rnd/xenobiology/xenoflora_storage) "bBv" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/rnd/docking) "bBw" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/rnd/docking) "bBx" = (/obj/structure/closet/emcloset,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/rnd/docking) "bBy" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/shuttle/plating,/area/rnd/docking) "bBz" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/shuttle/research/station) -"bBA" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "research_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/floor,/area/shuttle/research/station) +"bBA" = (/obj/machinery/door_control{id = "scanhide"; name = "Diagnostics Room Separation Shutters"; pixel_x = -6; pixel_y = -25; req_access = list(5)},/obj/machinery/door_control{id = "acute2"; name = "Acute Treatment Privacy Shutters"; pixel_x = 6; pixel_y = -25; req_access = list(5)},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bBB" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/shuttle/research/station) "bBC" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/storage) "bBD" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/storage) -"bBE" = (/obj/machinery/camera{c_tag = "Cargo Recieving Dock"; dir = 4},/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "cargo_bay"; name = "cargo bay hatch controller"; pixel_x = -30; pixel_y = 0; req_access_txt = "0"; req_one_access_txt = "13;31"; tag_door = "cargo_bay_door"},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/quartermaster/storage) +"bBE" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) "bBF" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "QM #2"},/obj/machinery/bot/mulebot{home_destination = "QM #2"; suffix = "#2"},/turf/simulated/floor{icon_state = "bot"},/area/quartermaster/storage) "bBG" = (/obj/structure/table,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/item/weapon/folder/yellow,/obj/item/device/eftpos{eftpos_name = "Cargo Bay EFTPOS scanner"},/turf/simulated/floor,/area/quartermaster/office) "bBH" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/quartermaster/office) "bBI" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/office) -"bBJ" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass_mining{name = "Cargo Office"; req_access_txt = "50"},/turf/simulated/floor,/area/quartermaster/office) -"bBK" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor,/area/quartermaster/office) +"bBJ" = (/obj/structure/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0},/obj/machinery/camera{c_tag = "Medbay Patient B"; dir = 8; network = list("SS13")},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/patient_b) +"bBK" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/accessory/stethoscope,/obj/machinery/camera{c_tag = "Medbay Equipment Storage"; dir = 1},/obj/item/clothing/accessory/stethoscope,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = -22},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay3) "bBL" = (/obj/structure/closet/secure_closet/hop2,/turf/simulated/floor,/area/crew_quarters/heads/hop) "bBM" = (/turf/simulated/floor,/area/crew_quarters/heads/hop) "bBN" = (/obj/structure/table,/obj/item/weapon/pen,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/device/megaphone,/turf/simulated/floor,/area/crew_quarters/heads/hop) @@ -4148,18 +4150,18 @@ "bBP" = (/obj/machinery/message_server,/turf/simulated/floor/bluegrid,/area/turret_protected/ai_server_room) "bBQ" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/cyan{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_server_room) "bBR" = (/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_server_room) -"bBS" = (/obj/machinery/door/airlock/highsecurity{icon_state = "door_closed"; locked = 0; name = "AI Upload"; req_access_txt = "16"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) -"bBT" = (/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20},/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_cyborg_station) +"bBS" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "mining_dock_airlock"; name = "exterior access button"; pixel_x = -5; pixel_y = 25; req_one_access = list(13,48)},/turf/space,/area/space) +"bBT" = (/obj/machinery/light_switch{pixel_y = 28},/turf/simulated/floor/plating,/area/medical/genetics) "bBU" = (/obj/structure/table,/obj/item/weapon/phone{pixel_x = -3; pixel_y = 3},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/cyan{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai_cyborg_station) "bBV" = (/obj/machinery/computer/aifixer,/turf/simulated/floor/bluegrid,/area/turret_protected/ai_cyborg_station) "bBW" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor,/area/teleporter) -"bBX" = (/obj/structure/stool,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/teleporter) +"bBX" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/aft) "bBY" = (/obj/machinery/hologram/holopad,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/teleporter) "bBZ" = (/obj/item/device/radio/beacon,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/teleporter) "bCa" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/teleporter) "bCb" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/teleporter) -"bCc" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/command{name = "Teleport Access"; req_access_txt = "17"},/turf/simulated/floor,/area/hallway/primary/central_two) -"bCd" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/regular,/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/turf/simulated/floor{dir = 8; icon_state = "whiteyellowcorner"},/area/medical/chemistry) +"bCc" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_one_access = list(8,12)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/research_starboard) +"bCd" = (/obj/machinery/door/window/southright{name = "Toxins Launcher"; req_access = list(8)},/obj/machinery/door/window/southright{dir = 1; name = "Toxins Launcher"; req_access = list(8)},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/mixing) "bCe" = (/turf/simulated/floor{dir = 2; icon_state = "whiteyellow"},/area/medical/chemistry) "bCf" = (/obj/structure/closet/wardrobe/chemistry_white,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor{dir = 2; icon_state = "whiteyellowcorner"},/area/medical/chemistry) "bCg" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) @@ -4169,11 +4171,11 @@ "bCk" = (/obj/structure/table,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/storage/box/syringes{pixel_x = 4; pixel_y = 4},/obj/item/weapon/storage/box/syringes,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 28},/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/medbay3) "bCl" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/medbay2) "bCm" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) -"bCn" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = "GeneticsDoor"; name = "Cloning Laboratory"; req_access_txt = "5"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) -"bCo" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/glass_medical{id_tag = "GeneticsDoor"; name = "Genetics Laboratory"; req_access_txt = "9"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) +"bCn" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "CMO's Office"; req_access = list(40)},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) +"bCo" = (/obj/machinery/door/window/southright{dir = 1; name = "Test Chamber"; req_access = list(47)},/obj/machinery/door/window/southright{name = "Test Chamber"; req_access = list(47)},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "misclab"; name = "Test Chamber Blast Doors"; opacity = 0},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bCp" = (/turf/simulated/wall,/area/medical/genetics) "bCq" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) -"bCr" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/airlock/glass_research{name = "Robotics Lab"; req_access_txt = "29; 47"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) +"bCr" = (/obj/machinery/door/window/southleft{dir = 1; name = "Test Chamber"; req_access = list(47)},/obj/machinery/door/window/southleft{name = "Test Chamber"; req_access = list(47)},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "misclab"; name = "Test Chamber Blast Doors"; opacity = 0},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bCs" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/rnd/research) "bCt" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/rnd/research) "bCu" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) @@ -4182,39 +4184,39 @@ "bCx" = (/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bCy" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bCz" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) -"bCA" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acutesep"; name = "Acute Separation Shutters"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) +"bCA" = (/turf/simulated/floor{dir = 2; icon_state = "cmo"},/area/rnd/docking) "bCB" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "Research Division"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor{icon_state = "bot"},/area/rnd/research) "bCC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) "bCD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) -"bCE" = (/obj/machinery/door/airlock/research{name = "Research Shuttle Dock"; req_access_txt = "65"},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) +"bCE" = (/obj/structure/sign/nosmoking_2{pixel_x = -32},/obj/machinery/camera{c_tag = "Toxins Lab"; dir = 4; network = list("SS13","Research")},/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 6},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) "bCF" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay3) "bCG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) "bCH" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) -"bCI" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/rnd/docking) +"bCI" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1380; id_tag = "research_dock_pump"},/obj/machinery/camera/autoname{dir = 2; network = list("SS13","Supermatter","Atmospherics")},/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/rnd/docking) "bCJ" = (/turf/simulated/wall,/area/rnd/docking) -"bCK" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "research_dock_outer"; locked = 1; name = "Shuttle Airlock"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/rnd/docking) -"bCL" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "research_dock_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = 8; req_access_txt = "0"; req_one_access_txt = "13;65"},/turf/space,/area/space) +"bCK" = (/obj/machinery/door/airlock/maintenance{name = "Firefighting equipment"; req_access = list(12)},/turf/simulated/floor/plating,/area/maintenance/engineering) +"bCL" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "mining_dock_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = 25; req_one_access = list(13,48)},/turf/simulated/floor{dir = 8; icon_state = "brown"},/area/quartermaster/miningdock) "bCM" = (/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/quartermaster/storage) "bCN" = (/obj/machinery/conveyor_switch/oneway{convdir = -1; id = "QMLoad"},/turf/simulated/floor,/area/quartermaster/storage) "bCO" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/quartermaster/storage) "bCP" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "QM #3"},/turf/simulated/floor{icon_state = "bot"},/area/quartermaster/storage) "bCQ" = (/obj/structure/table,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/item/weapon/storage/belt/utility,/turf/simulated/floor,/area/quartermaster/office) "bCR" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/quartermaster/office) -"bCS" = (/obj/structure/stool/bed/chair{dir = 8},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -35},/obj/machinery/light,/turf/simulated/floor,/area/quartermaster/office) +"bCS" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bCT" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "bluecorner"},/area/hallway/primary/central_three) "bCU" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor{icon_state = "bot"},/area/hallway/primary/central_three) "bCV" = (/obj/machinery/keycard_auth{pixel_x = -24; pixel_y = 0},/obj/machinery/account_database,/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/crew_quarters/heads/hop) -"bCW" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Head of Personnel"},/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "hop_office_desk"; name = "Desk Privacy Shutter"; pixel_x = 26; pixel_y = 17},/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "hop_office_window"; name = "Window Privacy Shutters"; pixel_x = 38; pixel_y = 17},/turf/simulated/floor,/area/crew_quarters/heads/hop) +"bCW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bCX" = (/obj/structure/table,/obj/item/weapon/folder/blue,/obj/item/weapon/stamp/hop,/obj/item/device/eftpos{eftpos_name = "HoP EFTPOS scanner"},/turf/simulated/floor,/area/crew_quarters/heads/hop) -"bCY" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor,/area/crew_quarters/heads/hop) +"bCY" = (/obj/structure/bed/chair/office/light{dir = 8},/obj/effect/landmark/start{name = "Research Director"},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor) "bCZ" = (/obj/machinery/computer/message_monitor,/obj/machinery/light/small{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_server_room) "bDa" = (/obj/structure/cable/cyan{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_server_room) "bDb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_server_room) -"bDc" = (/obj/machinery/door/airlock/highsecurity{name = "Messaging Server"; req_access_txt = "30"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_server_room) +"bDc" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "mining_dock_inner"; locked = 1; name = "Mining Dock Airlock"; req_access = list(13)},/turf/simulated/floor,/area/quartermaster/miningdock) "bDd" = (/obj/item/device/radio/intercom{broadcasting = 1; frequency = 1447; name = "Private AI Channel"; pixel_x = -12; pixel_y = 20},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/turretid/stun{control_area = "\improper AI Upload Chamber"; name = "AI Upload turret control"; pixel_x = 6; pixel_y = 24},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload_foyer) -"bDe" = (/obj/structure/closet/crate,/obj/item/weapon/circuitboard/smes,/obj/item/weapon/circuitboard/smes,/obj/item/weapon/smes_coil,/obj/item/weapon/smes_coil,/obj/item/weapon/smes_coil,/obj/item/weapon/smes_coil,/turf/simulated/floor/plating,/area/engine/storage_hard) -"bDf" = (/obj/machinery/door_control{id = "engineering_cubicle"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = -25; pixel_y = 8; req_access_txt = "0"; specialfunctions = 4},/obj/structure/toilet{dir = 1},/obj/machinery/light/small{dir = 4},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) -"bDg" = (/obj/machinery/door/airlock/highsecurity{name = "Cyborg Station"; req_access_txt = "16"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_cyborg_station) +"bDe" = (/obj/structure/bed/chair/office/dark,/obj/effect/landmark/start{name = "Quartermaster"},/turf/simulated/floor,/area/quartermaster/qm) +"bDf" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "mining_dock_outer"; locked = 1; name = "Mining Dock Airlock"; req_access = list(13)},/turf/simulated/floor/plating,/area/quartermaster/miningdock) +"bDg" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "mining_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/shuttle/mining/station) "bDh" = (/obj/effect/landmark/start{name = "Cyborg"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_cyborg_station) "bDi" = (/obj/effect/landmark/start{name = "Cyborg"},/obj/structure/cable/cyan{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_cyborg_station) "bDj" = (/obj/effect/landmark/start{name = "Cyborg"},/obj/machinery/light/small{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 1},/area/turret_protected/ai_cyborg_station) @@ -4228,15 +4230,15 @@ "bDr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor,/area/hallway/primary/central_two) "bDs" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"; pixel_x = 32},/turf/simulated/floor,/area/hallway/primary/central_two) "bDt" = (/turf/simulated/wall,/area/medical/sleeper) -"bDu" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/backpack/medic,/obj/item/roller,/obj/item/roller,/obj/item/roller,/obj/item/weapon/storage/toolbox/emergency,/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/device/radio{frequency = 1487; name = "Medbay Emergency Radio Link"},/obj/machinery/door/window/eastright{dir = 1; name = "Emergency Kit"; req_access_txt = "5"},/obj/machinery/door/firedoor,/turf/simulated/floor{dir = 1; icon_state = "whiteyellow"},/area/medical/sleeper) +"bDu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acute1"; name = "EMT Storage Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/sleeper) "bDv" = (/obj/structure/closet/secure_closet/medical_wall{name = "Pill Cabinet"},/obj/item/weapon/storage/pill_bottle/antitox,/obj/item/weapon/storage/pill_bottle/tramadol,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/inaprovaline,/turf/simulated/wall,/area/medical/sleeper) -"bDw" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Medicine Storage"; req_access_txt = "5"},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bDw" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/glass_research{name = "Toxins Lab"; req_access = list(8)},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bDx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/sleeper) "bDy" = (/obj/machinery/status_display,/turf/simulated/wall,/area/medical/medbay) "bDz" = (/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bDA" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/medbay) "bDB" = (/obj/structure/table,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/mask/muzzle,/obj/machinery/light,/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor{tag = "icon-whiteblue (SOUTHWEST)"; icon_state = "whiteblue"; dir = 10},/area/medical/medbay3) -"bDC" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/clothing/tie/stethoscope,/obj/item/clothing/tie/stethoscope,/obj/item/clothing/tie/stethoscope,/obj/item/clothing/tie/stethoscope,/obj/machinery/camera{c_tag = "Medbay Equipment Storage"; dir = 1},/obj/item/clothing/tie/stethoscope,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = -22},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay3) +"bDC" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acute1"; name = "EMT Storage Privacy Shutters"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) "bDD" = (/obj/structure/table,/obj/machinery/light,/obj/item/weapon/storage/box/gloves{pixel_x = 4; pixel_y = 4},/obj/item/weapon/storage/box/masks{pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{tag = "icon-whiteblue (SOUTHEAST)"; icon_state = "whiteblue"; dir = 6},/area/medical/medbay3) "bDE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/medbay2) "bDF" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) @@ -4249,11 +4251,11 @@ "bDM" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) "bDN" = (/obj/item/apc_frame,/obj/effect/decal/cleanable/dirt,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/medical/genetics) "bDO" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/medical/genetics) -"bDP" = (/obj/machinery/camera{c_tag = "Genetics Fore"; network = list("SS13")},/obj/machinery/light_switch{pixel_y = 28},/turf/simulated/floor/plating,/area/medical/genetics) +"bDP" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acute1"; name = "EMT Storage Privacy Shutters"; opacity = 0},/obj/machinery/light_switch{pixel_x = 22; pixel_y = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) "bDQ" = (/obj/item/weapon/table_parts,/turf/simulated/floor/plating,/area/medical/genetics) "bDR" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plating,/area/medical/genetics) "bDS" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay2) -"bDT" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "acute1"; name = "Acute One Privacy Shutters"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) +"bDT" = (/obj/structure/extinguisher_cabinet{pixel_x = -25},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) "bDU" = (/obj/structure/sign/securearea,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/rnd/research) "bDV" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/medical/medbay3) "bDW" = (/obj/machinery/light{dir = 1},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 8; name = "hazard door west"},/turf/simulated/floor{dir = 8; icon_state = "whiteblue"},/area/rnd/research) @@ -4271,18 +4273,18 @@ "bEi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/research) "bEj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/research) "bEk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/research) -"bEl" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;47"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/research_shuttle) -"bEm" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;47"},/turf/simulated/floor/plating,/area/maintenance/research_shuttle) +"bEl" = (/obj/structure/bed/chair/office/dark,/obj/effect/landmark/start{name = "Geneticist"},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) +"bEm" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Shaft Miner"},/turf/simulated/floor,/area/quartermaster/miningdock) "bEn" = (/turf/simulated/wall,/area/maintenance/research_shuttle) "bEo" = (/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) "bEp" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/rnd/docking) -"bEq" = (/obj/machinery/camera{c_tag = "Research Dock"; dir = 2; network = list("SS13","Research")},/turf/simulated/floor{dir = 2; icon_state = "cmo"},/area/rnd/docking) -"bEr" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "research_dock_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = -25; req_access_txt = "0"; req_one_access_txt = "13;65"},/turf/simulated/floor{dir = 2; icon_state = "cmo"},/area/rnd/docking) -"bEs" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "research_dock_inner"; locked = 1; name = "Shuttle Airlock"; req_access_txt = "13"},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) -"bEt" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1380; id_tag = "research_dock_pump"},/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/rnd/docking) +"bEq" = (/turf/simulated/floor/mech_bay_recharge_floor,/area/medical/sleeper) +"bEr" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{autoclose = 0; name = "Acute Treatment"; req_access = list(5)},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) +"bEs" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/camera{c_tag = "Medbay Acute"; network = list("SS13")},/obj/machinery/door_control{id = "acutesep"; name = "Acute Separation Shutters"; pixel_y = 25; req_access = list(5)},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bEt" = (/obj/machinery/mech_bay_recharge_port,/obj/structure/sign/poster{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating,/area/medical/sleeper) "bEu" = (/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/rnd/docking) "bEv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/rnd/docking) -"bEw" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "cargo_bay_door"; locked = 1; name = "Cargo Docking Hatch"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/quartermaster/storage) +"bEw" = (/obj/machinery/door/airlock/maintenance{name = "Mining Maintenance"; req_access = list(48)},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/quartermaster/miningdock) "bEx" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/turf/simulated/floor/plating,/area/quartermaster/storage) "bEy" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/obj/machinery/status_display/supply_display{pixel_y = -32},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/quartermaster/storage) "bEz" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/obj/machinery/light,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -35},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/quartermaster/storage) @@ -4311,7 +4313,7 @@ "bEW" = (/obj/machinery/light_switch{pixel_y = -25},/obj/machinery/camera{c_tag = "Messaging Server"; dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_server_room) "bEX" = (/obj/machinery/camera{c_tag = "AI Upload Access"; dir = 1},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/light,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload_foyer) "bEY" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload_foyer) -"bEZ" = (/obj/structure/window/basic{dir = 4},/obj/machinery/shower{dir = 1},/obj/structure/curtain/open/shower{color = "#FFA500"; layer = 3.3},/obj/machinery/door/window/northleft{name = "Shower"; req_access_txt = "0"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) +"bEZ" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/research{name = "Toxins Launch Room"; req_access = list(8)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/rnd/mixing) "bFa" = (/obj/machinery/light_switch{pixel_y = -25},/obj/machinery/camera{c_tag = "Cyborg Station"; dir = 1},/obj/structure/closet/crate{name = "Camera Assembly Crate"},/obj/item/weapon/camera_assembly,/obj/item/weapon/camera_assembly,/obj/item/weapon/camera_assembly,/obj/item/weapon/camera_assembly,/obj/item/weapon/camera_assembly,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_cyborg_station) "bFb" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/recharge_station,/turf/simulated/floor/bluegrid,/area/turret_protected/ai_cyborg_station) "bFc" = (/obj/machinery/recharge_station,/turf/simulated/floor/bluegrid,/area/turret_protected/ai_cyborg_station) @@ -4329,7 +4331,7 @@ "bFo" = (/obj/machinery/camera{c_tag = "Medbay Emergency Entrance"; dir = 2; network = list("SS13")},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bFp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bFq" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/medical/medbay) -"bFr" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Medical Equipment"; req_access_txt = "5"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay3) +"bFr" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/research{name = "Toxins Launch Room Access"; req_access = list(8)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) "bFs" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/medbay2) "bFt" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bFu" = (/obj/machinery/door/firedoor,/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/medbay2) @@ -4343,9 +4345,9 @@ "bFC" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/plating,/area/medical/genetics) "bFD" = (/turf/simulated/floor/plating,/area/medical/genetics) "bFE" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating,/area/medical/genetics) -"bFF" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Genetics Research"; req_access_txt = "9"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) +"bFF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) "bFG" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; external_pressure_bound = 0; external_pressure_bound_default = 0; icon_state = "map_vent_in"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/bluegrid{name = "Server Base"; nitrogen = 500; oxygen = 0; temperature = 80},/area/server) -"bFH" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "acute1"; name = "Acute One Privacy Shutters"; opacity = 0},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) +"bFH" = (/obj/machinery/computer/mech_bay_power_console,/obj/machinery/light{dir = 1},/turf/simulated/floor/bluegrid,/area/medical/sleeper) "bFI" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay) "bFJ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 8; name = "hazard door west"},/turf/simulated/floor{dir = 8; icon_state = "whiteblue"},/area/rnd/research) "bFK" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) @@ -4359,7 +4361,7 @@ "bFS" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bFT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/research) "bFU" = (/obj/structure/table,/obj/item/weapon/folder/white,/obj/item/weapon/stamp/rd{pixel_x = 3; pixel_y = -2},/obj/item/weapon/paper/monitorkey,/obj/item/device/megaphone,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor) -"bFV" = (/obj/machinery/computer/security/telescreen{desc = "Used for watching the RD's goons from the safety of his office."; name = "Research Monitor"; network = list("Research","Toxins Test Area","Robots","Anomaly Isolation"); pixel_x = 0; pixel_y = 2},/obj/structure/table,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor) +"bFV" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) "bFW" = (/obj/machinery/computer/aifixer,/obj/machinery/requests_console{announcementConsole = 1; department = "Research Director's Desk"; departmentType = 5; name = "Research Director RC"; pixel_x = -2; pixel_y = 30},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor) "bFX" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{dir = 8; icon_state = "warnwhite"},/area/crew_quarters/heads/hor) "bFY" = (/obj/structure/lamarr,/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/hor) @@ -4374,7 +4376,7 @@ "bGh" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor{dir = 2; icon_state = "cmo"},/area/rnd/docking) "bGi" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/shuttle/plating,/area/rnd/docking) "bGj" = (/obj/machinery/atmospherics/pipe/manifold/hidden,/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "research_dock_sensor"; pixel_x = 0; pixel_y = -25},/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/rnd/docking) -"bGk" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1380; id_tag = "research_dock_pump"},/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "research_dock_airlock"; pixel_x = 25; pixel_y = 0; req_access_txt = "0"; req_one_access_txt = "13;65"; tag_airpump = "research_dock_pump"; tag_chamber_sensor = "research_dock_sensor"; tag_exterior_door = "research_dock_outer"; tag_interior_door = "research_dock_inner"},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/rnd/docking) +"bGk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) "bGl" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/storage) "bGm" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/storage) "bGn" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/storage) @@ -4384,7 +4386,7 @@ "bGr" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/storage) "bGs" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/storage) "bGt" = (/turf/simulated/wall,/area/quartermaster/miningdock) -"bGu" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/door/airlock/mining{name = "Mining Dock"; req_access_txt = "48"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/miningdock) +"bGu" = (/obj/effect/landmark/start{name = "Scientist"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) "bGv" = (/turf/simulated/wall,/area/quartermaster/qm) "bGw" = (/obj/structure/filingcabinet,/turf/simulated/floor,/area/quartermaster/qm) "bGx" = (/obj/machinery/computer/supplycomp,/turf/simulated/floor,/area/quartermaster/qm) @@ -4392,12 +4394,12 @@ "bGz" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor,/area/quartermaster/qm) "bGA" = (/obj/structure/disposalpipe/segment,/obj/machinery/camera{c_tag = "Cargo Bay Entrance"; dir = 8; network = list("SS13")},/turf/simulated/floor{dir = 4; icon_state = "bluecorner"},/area/hallway/primary/central_three) "bGB" = (/obj/machinery/status_display,/turf/simulated/wall,/area/hallway/primary/central_three) -"bGC" = (/obj/machinery/door/airlock/command{name = "Head of Personnel"; req_access = null; req_access_txt = "57"},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/central_three) -"bGD" = (/obj/structure/window/basic{dir = 8},/obj/machinery/shower{dir = 1},/obj/structure/curtain/open/shower{color = "#FFA500"; layer = 3.3},/obj/machinery/door/window/northright{name = "Shower"; req_access_txt = "0"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) -"bGE" = (/obj/machinery/door/airlock/multi_tile/glass{autoclose = 1; dir = 2; req_access_txt = "5"},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/medical/sleeper) +"bGC" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) +"bGD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) +"bGE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) "bGF" = (/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bGG" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) -"bGH" = (/obj/machinery/light,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bGH" = (/obj/machinery/vending/medical,/turf/simulated/wall,/area/medical/medbay) "bGI" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bGJ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bGK" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 1; sortType = "Chemistry"; name = "Chemistry"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/medbay) @@ -4412,11 +4414,11 @@ "bGT" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whiteredcorner"},/area/medical/cryo) "bGU" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/cryo) "bGV" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/cryo) -"bGW" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = "GeneticsDoor"; name = "Cloning Laboratory"; req_access_txt = "5"},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/cryo) +"bGW" = (/obj/machinery/door/airlock/glass_research{name = "Toxins Lab"; req_access = list(8)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bGX" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) "bGY" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/hologram/holopad,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) "bGZ" = (/obj/structure/disposalpipe/junction{dir = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) -"bHa" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = "GeneticsDoor"; name = "Genetics Laboratory"; req_access_txt = "9"},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) +"bHa" = (/obj/structure/bed/chair/office/dark{dir = 1},/obj/effect/landmark/start{name = "Chief Medical Officer"},/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "cmooffice"; name = "CMO Privacy Shutters"; pixel_x = 38; pixel_y = 21},/obj/machinery/door_control{desc = "A remote control switch for the CMO's office."; id = "cmodoor"; name = "CMO Office Door Control"; normaldoorcontrol = 1; pixel_x = 28; pixel_y = 21},/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "virologyquar"; name = "Virology Emergency Lockdown Control"; pixel_x = -15; pixel_y = 38; req_access = list(5)},/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "medbayquar"; name = "Medbay Emergency Lockdown Control"; pixel_x = -15; pixel_y = 30; req_access = list(5)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) "bHb" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/medical/genetics) "bHc" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/medical/genetics) "bHd" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/medical/genetics) @@ -4424,11 +4426,11 @@ "bHf" = (/obj/item/light_fixture_frame,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{icon_state = "floorgrime"},/area/medical/genetics) "bHg" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay2) "bHh" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; dir = 0; icon_state = "shutter0"; id = "staffroom"; name = "Staff Room Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/cryo) -"bHi" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/airlock/command{name = "Server Room"; req_access = null; req_access_txt = "30"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "dark"},/area/rnd/research) -"bHj" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/research{name = "Toxins Storage"; req_access_txt = "8"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/rnd/research) +"bHi" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/bed/roller,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = -32},/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/structure/closet/secure_closet/medical_wall{name = "O- Blood Locker"; pixel_x = -32},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/sleeper) +"bHj" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/airlock/glass_research{name = "Robotics Lab"; req_access = list(29,47)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bHk" = (/obj/machinery/vending/coffee,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) -"bHl" = (/obj/structure/table,/obj/machinery/door_control{id = "Biohazard"; name = "Biohazard Shutter Control"; pixel_x = 5; pixel_y = 15; req_access_txt = "47"},/obj/machinery/computer/skills{icon_state = "medlaptop"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor) -"bHm" = (/obj/structure/stool/bed/chair/office/light{dir = 8},/obj/effect/landmark/start{name = "Research Director"},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor) +"bHl" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Research Division Delivery"; req_access = list(47)},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor{icon_state = "delivery"},/area/rnd/research) +"bHm" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/maintenance{req_one_access = list(5,12,47)},/turf/simulated/floor/plating,/area/maintenance/research_port) "bHn" = (/obj/machinery/computer/robotics,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor) "bHo" = (/turf/simulated/floor{dir = 10; icon_state = "warnwhite"},/area/crew_quarters/heads/hor) "bHp" = (/turf/simulated/floor{dir = 2; icon_state = "warnwhite"},/area/crew_quarters/heads/hor) @@ -4442,7 +4444,7 @@ "bHx" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/miningdock) "bHy" = (/obj/structure/table/rack{dir = 1},/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/machinery/light{dir = 1},/obj/machinery/light_switch{pixel_y = 24},/obj/item/weapon/storage/belt/utility,/turf/simulated/floor,/area/quartermaster/miningdock) "bHz" = (/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_x = -30; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/quartermaster/qm) -"bHA" = (/obj/structure/stool/bed/chair/office/dark,/obj/effect/landmark/start{name = "Quartermaster"},/turf/simulated/floor,/area/quartermaster/qm) +"bHA" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) "bHB" = (/turf/simulated/floor,/area/quartermaster/qm) "bHC" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/quartermaster/qm) "bHD" = (/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor,/area/hallway/primary/central_three) @@ -4457,7 +4459,7 @@ "bHM" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/camera{c_tag = "Central Primary Hallway South South-West"; dir = 2},/turf/simulated/floor,/area/hallway/primary/central_three) "bHN" = (/obj/machinery/ai_status_display{pixel_y = 32},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/hallway/primary/central_three) "bHO" = (/obj/structure/sign/securearea{pixel_y = 32},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "warningcorner"; dir = 8},/area/hallway/primary/central_three) -"bHP" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/engine/locker_room) +"bHP" = (/obj/structure/bed/chair/office/light,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor{icon_state = "dark"},/area/server) "bHQ" = (/obj/structure/sign/securearea{pixel_y = 32},/turf/simulated/floor{icon_state = "warningcorner"; dir = 4},/area/hallway/primary/central_three) "bHR" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/hallway/primary/central_three) "bHS" = (/obj/machinery/camera{c_tag = "Central Primary Hallway South South-East"; dir = 2},/turf/simulated/floor,/area/hallway/primary/central_three) @@ -4482,14 +4484,14 @@ "bIl" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/floor{dir = 10; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/cryo) "bIm" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/cryo) "bIn" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/cryo) -"bIo" = (/obj/structure/stool/bed/chair/office/dark,/obj/effect/landmark/start{name = "Geneticist"},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) +"bIo" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/glass_medical{id_tag = "GeneticsDoor"; name = "Genetics Laboratory"; req_access = list(9)},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bIp" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics_cloning) "bIq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/genetics) "bIr" = (/obj/item/light_fixture_frame,/turf/simulated/floor/plating,/area/medical/genetics) "bIs" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/medical/genetics) "bIt" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/medical/genetics) "bIu" = (/obj/item/weapon/table_parts,/turf/simulated/floor{icon_state = "floorgrime"},/area/medical/genetics) -"bIv" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "9;12;47"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/research_port) +"bIv" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = "GeneticsDoor"; name = "Cloning Laboratory"; req_access = list(5)},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bIw" = (/turf/simulated/wall/r_wall,/area/maintenance/research_port) "bIx" = (/turf/simulated/wall/r_wall,/area/server) "bIy" = (/obj/machinery/r_n_d/server/robotics,/turf/simulated/floor/bluegrid{name = "Server Base"; nitrogen = 500; oxygen = 0; temperature = 80},/area/server) @@ -4514,7 +4516,7 @@ "bIR" = (/obj/structure/table,/obj/item/device/taperecorder{pixel_x = -3},/obj/item/device/paicard{pixel_x = 4},/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/obj/item/weapon/circuitboard/teleporter,/obj/item/weapon/circuitboard/aicore{pixel_x = -2; pixel_y = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor) "bIS" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/maintenance/research_shuttle) "bIT" = (/obj/structure/table,/obj/item/weapon/folder/yellow,/obj/item/weapon/pen,/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_x = -30; pixel_y = 0},/turf/simulated/floor,/area/quartermaster/miningdock) -"bIU" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Shaft Miner"},/turf/simulated/floor,/area/quartermaster/miningdock) +"bIU" = (/obj/machinery/door/airlock/research{name = "Research Shuttle Dock"; req_access = list(65)},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) "bIV" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/miningdock) "bIW" = (/obj/structure/table/rack{dir = 1},/obj/item/weapon/pickaxe{pixel_x = 5},/obj/item/weapon/shovel{pixel_x = -5},/turf/simulated/floor,/area/quartermaster/miningdock) "bIX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/quartermaster/qm) @@ -4532,7 +4534,7 @@ "bJj" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "hazard door west"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/central_three) "bJk" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/hallway/primary/central_three) "bJl" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=AftH"; location = "AIW"},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/central_three) -"bJm" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/engine/locker_room) +"bJm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bJn" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=CHE"; location = "AIE"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/central_three) "bJo" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/central_three) "bJp" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor,/area/hallway/primary/central_three) @@ -4543,13 +4545,13 @@ "bJu" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/central_two) "bJv" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/central_two) "bJw" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=HOP"; location = "CHE"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/hallway/primary/central_two) -"bJx" = (/obj/machinery/iv_drip,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/sleeper) -"bJy" = (/obj/machinery/door_control{id = "acute1"; name = "Acute One Privacy Shutters"; pixel_x = 6; pixel_y = 25; req_access_txt = "5"},/obj/machinery/camera{c_tag = "Medbay Acute 1"; network = list("SS13")},/obj/machinery/door_control{id = "acute1em"; name = "Acute One Entry Shutters"; pixel_x = -6; pixel_y = 25; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bJx" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) +"bJy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bJz" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay2) "bJA" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) "bJB" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay) -"bJC" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "acute2"; name = "Acute Two Privacy Shutters"; opacity = 0},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) -"bJD" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{id_tag = "cmodoor"; name = "CMO's Office"; req_access_txt = "40"},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) +"bJC" = (/obj/structure/extinguisher_cabinet{pixel_x = -24},/turf/simulated/floor,/area/rnd/storage) +"bJD" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "research_dock_outer"; locked = 1; name = "Shuttle Airlock"; req_access = list(13)},/turf/simulated/floor/plating,/area/rnd/docking) "bJE" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/medical/medbay4) "bJF" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay4) "bJG" = (/obj/structure/disposalpipe/segment,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) @@ -4567,9 +4569,9 @@ "bJS" = (/obj/machinery/alarm/server{dir = 4; pixel_x = -22; pixel_y = 0},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Server Walkway"; nitrogen = 500; oxygen = 0; temperature = 80},/area/server) "bJT" = (/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Server Walkway"; nitrogen = 500; oxygen = 0; temperature = 80},/area/server) "bJU" = (/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Server Walkway"; nitrogen = 500; oxygen = 0; temperature = 80},/area/server) -"bJV" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/window/westleft{dir = 8; name = "Server Room"; opacity = 1; req_access_txt = "30"},/obj/machinery/door/window/westleft{dir = 4; name = "Server Room"; opacity = 1; req_access_txt = "30"},/turf/simulated/floor{icon_state = "dark"},/area/server) +"bJV" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "research_dock_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = 8; req_one_access = list(13,65)},/turf/space,/area/space) "bJW" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/turf/simulated/floor{icon_state = "dark"},/area/server) -"bJX" = (/obj/structure/stool/bed/chair/office/light,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor{icon_state = "dark"},/area/server) +"bJX" = (/obj/item/weapon/stool{pixel_y = 8},/obj/effect/landmark/start{name = "Paramedic"},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bJY" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor{icon_state = "dark"},/area/server) "bJZ" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/rnd/storage) "bKa" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/storage) @@ -4577,7 +4579,7 @@ "bKc" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/rnd/research) "bKd" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bKe" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 9; icon_state = "whitehall"},/area/rnd/research) -"bKf" = (/obj/machinery/door/airlock/glass_command{name = "Research Director"; req_access_txt = "30"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/rnd/research) +"bKf" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/command{name = "Teleport Access"; req_access = list(17)},/turf/simulated/floor,/area/hallway/primary/central_two) "bKg" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor) "bKh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor) "bKi" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hop) @@ -4623,11 +4625,11 @@ "bKW" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor,/area/hallway/primary/central_two) "bKX" = (/obj/machinery/light,/turf/simulated/floor,/area/hallway/primary/central_two) "bKY" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor,/area/hallway/primary/central_two) -"bKZ" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = -25; pixel_y = 0; req_access_txt = "0"},/obj/structure/stool/bed,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/sleeper) -"bLa" = (/obj/machinery/sleeper,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bKZ" = (/obj/structure/closet/secure_closet/medical1,/obj/item/device/radio/intercom{broadcasting = 0; canhear_range = 5; freerange = 0; frequency = 1485; listening = 1; name = "Station Intercom (Medbay)"; pixel_x = 0; pixel_y = -31},/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/random/medical,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bLa" = (/obj/machinery/door/airlock/highsecurity{icon_state = "door_closed"; locked = 0; name = "AI Upload"; req_access = list(16)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_upload) "bLb" = (/obj/machinery/sleep_console,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bLc" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "scanhide"; name = "Diagnostics Room Separation Shutters"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) -"bLd" = (/turf/simulated/floor{icon_state = "white_1"},/area/medical/medbay) +"bLd" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/structure/closet/fireaxecabinet{pixel_x = 32; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bLe" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) "bLf" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "scanhide"; name = "Diagnostics Room Separation Shutters"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) "bLg" = (/obj/machinery/light{dir = 1},/obj/structure/filingcabinet/chestdrawer{dir = 1},/turf/simulated/floor{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/crew_quarters/heads/cmo) @@ -4637,7 +4639,7 @@ "bLk" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "scanhide"; name = "Diagnostics Room Separation Shutters"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) "bLl" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay4) "bLm" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay4) -"bLn" = (/obj/machinery/door/window/southright{dir = 1; name = "Test Chamber"; req_access_txt = "47"},/obj/machinery/door/window/southright{name = "Test Chamber"; req_access_txt = "47"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "misclab"; name = "Test Chamber Blast Doors"; opacity = 0},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) +"bLn" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass_mining{name = "Cargo Office"; req_access = list(50)},/turf/simulated/floor,/area/quartermaster/office) "bLo" = (/turf/simulated/wall,/area/medical/genetics_cloning) "bLp" = (/obj/structure/computerframe,/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor{icon_state = "floorgrime"},/area/medical/genetics) "bLq" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/constructable_frame/machine_frame,/turf/simulated/floor/plating,/area/medical/genetics) @@ -4647,13 +4649,13 @@ "bLu" = (/obj/structure/disposalpipe/segment,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/research_port) "bLv" = (/obj/structure/reagent_dispensers/watertank,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/research_port) "bLw" = (/obj/machinery/r_n_d/server/core,/turf/simulated/floor/bluegrid{name = "Server Base"; nitrogen = 500; oxygen = 0; temperature = 80},/area/server) -"bLx" = (/obj/machinery/door/window/southleft{dir = 1; name = "Test Chamber"; req_access_txt = "47"},/obj/machinery/door/window/southleft{name = "Test Chamber"; req_access_txt = "47"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "misclab"; name = "Test Chamber Blast Doors"; opacity = 0},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) +"bLx" = (/obj/machinery/camera{c_tag = "Cargo Recieving Dock"; dir = 4},/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "cargo_bay"; name = "cargo bay hatch controller"; pixel_x = -30; pixel_y = 0; req_one_access = list(13,31); tag_door = "cargo_bay_door"},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/quartermaster/storage) "bLy" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Server Walkway"; nitrogen = 500; oxygen = 0; temperature = 80},/area/server) "bLz" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/sign/securearea{desc = "A warning sign which reads 'SERVER ROOM'."; name = "SERVER ROOM"; pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor/plating,/area/server) "bLA" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor{icon_state = "dark"},/area/server) "bLB" = (/obj/machinery/computer/rdservercontrol,/turf/simulated/floor{icon_state = "dark"},/area/server) "bLC" = (/obj/machinery/computer/message_monitor,/turf/simulated/floor{icon_state = "dark"},/area/server) -"bLD" = (/turf/simulated/floor,/area/rnd/storage) +"bLD" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 28},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) "bLE" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/storage) "bLF" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bLG" = (/obj/machinery/light_switch{pixel_y = -23},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor) @@ -4674,7 +4676,7 @@ "bLV" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/shuttle/mining/station) "bLW" = (/obj/structure/table,/turf/simulated/shuttle/floor,/area/shuttle/mining/station) "bLX" = (/obj/machinery/computer/shuttle_control/mining,/turf/simulated/shuttle/floor,/area/shuttle/mining/station) -"bLY" = (/obj/structure/table,/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "mining_shuttle"; pixel_x = 25; pixel_y = -8; req_access_txt = "0"; req_one_access_txt = "13;48"; tag_door = "mining_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/mining/station) +"bLY" = (/obj/machinery/door/airlock/research{name = "Research Division Access"; req_access = list(47)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) "bLZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/miningdock) "bMa" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/floor/plating,/area/quartermaster/miningdock) "bMb" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/miningdock) @@ -4683,23 +4685,23 @@ "bMe" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/quartermaster/miningdock) "bMf" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/miningdock) "bMg" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/quartermaster/miningdock) -"bMh" = (/obj/machinery/door/airlock/glass_mining{name = "Quartermaster"; req_access_txt = "41"},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/quartermaster/qm) +"bMh" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Medical Equipment"; req_access = list(5)},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bMi" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor,/area/quartermaster/qm) "bMj" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/quartermaster/qm) "bMk" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/quartermaster/qm) -"bMl" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/central_three) +"bMl" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Medicine Storage"; req_access = list(5)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bMm" = (/obj/machinery/door/firedoor/border_only,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor,/area/hallway/primary/central_three) "bMn" = (/obj/machinery/door/firedoor/border_only,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/hallway/primary/central_three) "bMo" = (/obj/machinery/door/firedoor/border_only,/obj/structure/disposalpipe/junction,/turf/simulated/floor,/area/hallway/primary/central_three) -"bMp" = (/obj/machinery/door/airlock{name = "Custodial Closet"; req_access_txt = "26"},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hallway/primary/central_three) -"bMq" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/central_two) +"bMp" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Medical Equipment"; req_access = list(5)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) +"bMq" = (/obj/machinery/door/airlock{name = "Medbay Substation"; req_access = list(5)},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/substation/medical) "bMr" = (/obj/machinery/vending/cigarette,/turf/simulated/floor{icon_state = "dark"},/area/hallway/primary/central_two) -"bMs" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/item/roller,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/sleeper) -"bMt" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) -"bMu" = (/obj/machinery/door_control{id = "acutesep"; name = "Acute Separation Shutters"; pixel_y = -25; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) -"bMv" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{autoclose = 0; name = "Acute One"; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) -"bMw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) -"bMx" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 28},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) +"bMs" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/mining/station) +"bMt" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acutesep"; name = "Acute Separation Shutters"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/sleeper) +"bMu" = (/obj/structure/bed/chair,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) +"bMv" = (/obj/structure/bed/chair,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) +"bMw" = (/obj/item/weapon/stool,/obj/effect/landmark/start{name = "Medical Doctor"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) +"bMx" = (/obj/item/weapon/stool,/obj/effect/landmark/start{name = "Medical Doctor"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) "bMy" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/structure/table,/obj/machinery/photocopier/faxmachine{department = "CMO's Office"},/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/crew_quarters/heads/cmo) "bMz" = (/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) "bMA" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) @@ -4731,14 +4733,14 @@ "bNa" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/research_shuttle) "bNb" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/research_shuttle) "bNc" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "misclab"; name = "Test Chamber Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) -"bNd" = (/obj/machinery/door/airlock/external{name = "Toxins Test Chamber"; req_access_txt = "0"},/turf/simulated/floor/plating/airless,/area/rnd/test_area) +"bNd" = (/obj/machinery/door/airlock/research{name = "Research Shuttle Dock"; req_access = list(65)},/obj/machinery/door/firedoor/border_only,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) "bNe" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating/airless,/area/rnd/test_area) "bNf" = (/obj/machinery/camera{c_tag = "Toxins Test Chamber North"; network = list("Toxins Test Area")},/obj/machinery/light{dir = 1},/turf/simulated/floor/airless,/area/rnd/test_area) "bNg" = (/turf/simulated/shuttle/floor,/area/shuttle/mining/station) -"bNh" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/mining/station) +"bNh" = (/obj/machinery/light_switch{pixel_x = 22; pixel_y = 0},/obj/structure/bed,/obj/item/weapon/bedsheet/blue,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) "bNi" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/miningdock) "bNj" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "mining_dock_pump"},/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/quartermaster/miningdock) -"bNk" = (/obj/machinery/light/small{dir = 4; pixel_y = 8},/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "mining_dock_airlock"; pixel_x = 25; pixel_y = -5; req_access_txt = "0"; req_one_access_txt = "13;48"; tag_airpump = "mining_dock_pump"; tag_chamber_sensor = "mining_dock_sensor"; tag_exterior_door = "mining_dock_outer"; tag_interior_door = "mining_dock_inner"},/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "mining_dock_sensor"; pixel_x = 25; pixel_y = 8},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1; icon_state = "map"; tag = "icon-manifold-f (NORTH)"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/quartermaster/miningdock) +"bNk" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "research_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/shuttle/research/station) "bNl" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/wall,/area/quartermaster/miningdock) "bNm" = (/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor{dir = 8; icon_state = "brown"},/area/quartermaster/miningdock) "bNn" = (/obj/effect/landmark/start{name = "Shaft Miner"},/turf/simulated/floor,/area/quartermaster/miningdock) @@ -4770,32 +4772,32 @@ "bNN" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/janitor) "bNO" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/janitor) "bNP" = (/turf/simulated/floor,/area/janitor) -"bNQ" = (/obj/machinery/door/window/westleft{name = "Janitoral Delivery"; req_access_txt = "26"},/turf/simulated/floor{icon_state = "delivery"},/area/janitor) +"bNQ" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "cargo_bay_door"; locked = 1; name = "Cargo Docking Hatch"; req_access = list(13)},/turf/simulated/floor/plating,/area/quartermaster/storage) "bNR" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "Janitor"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "bot"},/area/janitor) "bNS" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/engineering) "bNT" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/engineering) "bNU" = (/turf/simulated/wall,/area/maintenance/engineering) -"bNV" = (/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/structure/closet/secure_closet/medical_wall{name = "O- Blood Locker"},/turf/simulated/wall,/area/medical/sleeper) +"bNV" = (/obj/machinery/door_control{desc = "A remote control switch for the medbay foyer."; id = "MedbayFoyerPort"; name = "Medbay Doors Control"; normaldoorcontrol = 1; pixel_x = -24; pixel_y = 26},/obj/machinery/computer/guestpass{pixel_x = -28},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/medical/medbay) "bNW" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "misclab"; name = "Test Chamber Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) -"bNX" = (/obj/machinery/vending/medical,/obj/machinery/light_switch{pixel_x = 22; pixel_y = 0},/turf/simulated/wall,/area/medical/sleeper) -"bNY" = (/obj/structure/sign/greencross,/turf/simulated/wall,/area/medical/medbay) +"bNX" = (/obj/item/weapon/camera_assembly,/turf/simulated/floor/plating,/area/medical/genetics) +"bNY" = (/obj/item/weapon/stool,/obj/effect/landmark/start{name = "Janitor"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/janitor) "bNZ" = (/obj/machinery/hologram/holopad,/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bOa" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) -"bOb" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "CMO's Office"; req_access_txt = "40"},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) -"bOc" = (/obj/structure/stool/bed/chair,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) -"bOd" = (/obj/structure/stool/bed/chair,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) +"bOb" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/glass_research{name = "Research and Development"; req_access = list(7)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) +"bOc" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/machinery/sleeper,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/sleeper) +"bOd" = (/obj/machinery/door/airlock{name = "Starboard Emergency Storage"; req_one_access = list(12,47)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/storage/emergency) "bOe" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) -"bOf" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "CMO's Office"; req_access_txt = "40"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) +"bOf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/engineering{name = "Medbay Substation"; req_one_access = list(11,24,5)},/turf/simulated/floor/plating,/area/maintenance/substation/medical) "bOg" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "bOh" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) -"bOi" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Staff Room"; req_access_txt = "5"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/medbay2) +"bOi" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock{name = "Starboard Emergency Storage"; req_access = list(29)},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/assembly/chargebay) "bOj" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) -"bOk" = (/obj/structure/stool,/obj/effect/landmark/start{name = "Medical Doctor"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) -"bOl" = (/obj/structure/stool,/obj/effect/landmark/start{name = "Medical Doctor"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) +"bOk" = (/obj/structure/table,/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "research_shuttle"; pixel_x = -8; pixel_y = -25; req_one_access = list(13,65); tag_door = "research_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/research/station) +"bOl" = (/obj/item/weapon/stool,/obj/effect/landmark/start{name = "Medical Doctor"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) "bOm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) -"bOn" = (/obj/machinery/light_switch{pixel_x = 22; pixel_y = 0},/obj/structure/stool/bed,/obj/item/weapon/bedsheet/blue,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) +"bOn" = (/obj/item/weapon/stool,/obj/effect/landmark/start{name = "Geneticist"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) "bOo" = (/obj/machinery/light,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/medical/genetics) -"bOp" = (/obj/machinery/camera{c_tag = "Genetics Aft"; dir = 1; network = list("SS13")},/turf/simulated/floor/plating,/area/medical/genetics) +"bOp" = (/obj/machinery/button/driver{dir = 2; id = "toxinsdriver"; pixel_y = 24},/turf/simulated/floor,/area/rnd/mixing) "bOq" = (/obj/machinery/portable_atmospherics/canister,/turf/simulated/floor/engine,/area/rnd/misc_lab) "bOr" = (/obj/machinery/portable_atmospherics/canister,/obj/machinery/light{dir = 1},/turf/simulated/floor/engine,/area/rnd/misc_lab) "bOs" = (/turf/simulated/floor/engine,/area/rnd/misc_lab) @@ -4819,14 +4821,14 @@ "bOK" = (/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor{dir = 9; icon_state = "warnwhite"},/area/rnd/mixing) "bOL" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "warnwhite"; dir = 1},/area/rnd/mixing) "bOM" = (/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor{icon_state = "warnwhite"; dir = 5},/area/rnd/mixing) -"bON" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "8;12"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/research_shuttle) +"bON" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "cargo_bay_door"; locked = 1; name = "Cargo Docking Hatch"; req_access = list(13)},/turf/simulated/floor/plating,/area/quartermaster/storage) "bOO" = (/turf/simulated/wall,/area/rnd/mixing) "bOP" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'BOMB RANGE"; name = "BOMB RANGE"},/turf/simulated/wall,/area/rnd/test_area) -"bOQ" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "mining_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/floor,/area/shuttle/mining/station) -"bOR" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "mining_dock_outer"; locked = 1; name = "Mining Dock Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/quartermaster/miningdock) +"bOQ" = (/obj/machinery/door/airlock/maintenance{name = "Teleporter Maintenance"; req_access = list(17)},/obj/structure/sign/securearea{pixel_x = -32; pixel_y = 0},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/supply,/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor/plating,/area/teleporter) +"bOR" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/multi_tile/glass{id_tag = "MedbayFoyerPort"; req_access = list(5)},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/medical/medbay) "bOS" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/quartermaster/miningdock) -"bOT" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "mining_dock_inner"; locked = 1; name = "Mining Dock Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor,/area/quartermaster/miningdock) -"bOU" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "mining_dock_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13;48"},/turf/simulated/floor{dir = 8; icon_state = "brown"},/area/quartermaster/miningdock) +"bOT" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Medbay Reception"; req_access = list(5)},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/medbay3) +"bOU" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/multi_tile/glass{id_tag = "MedbayFoyerStar"; req_access = list(5)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/medical/medbay2) "bOV" = (/obj/structure/disposalpipe/segment,/obj/effect/landmark/start{name = "Shaft Miner"},/turf/simulated/floor,/area/quartermaster/miningdock) "bOW" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/quartermaster/miningdock) "bOX" = (/obj/item/weapon/cigbutt,/turf/simulated/floor/plating,/area/maintenance/cargo) @@ -4845,7 +4847,7 @@ "bPk" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/turf/simulated/floor,/area/hallway/primary/aft) "bPl" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) "bPm" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor,/area/janitor) -"bPn" = (/obj/structure/stool,/obj/effect/landmark/start{name = "Janitor"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/janitor) +"bPn" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/computer/security/telescreen{desc = "Used for watching the test chamber."; layer = 4; name = "Test Chamber Telescreen"; network = list("Toxins Test Area"); pixel_x = 32; pixel_y = 0},/turf/simulated/floor,/area/rnd/mixing) "bPo" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/janitor) "bPp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/janitor) "bPq" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/janitor) @@ -4853,24 +4855,24 @@ "bPs" = (/obj/structure/mopbucket,/obj/item/weapon/mop,/turf/simulated/floor,/area/janitor) "bPt" = (/turf/simulated/wall,/area/janitor) "bPu" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/engineering) -"bPv" = (/obj/machinery/door/airlock/maintenance{name = "Firefighting equipment"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/engineering) +"bPv" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/window/westleft{name = "Cargo Desk"; req_access = list(50)},/obj/structure/noticeboard{pixel_y = 27},/turf/simulated/floor,/area/quartermaster/office) "bPw" = (/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/engineering) "bPx" = (/turf/simulated/floor/plating,/area/maintenance/engineering) "bPy" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire/firefighter,/obj/item/weapon/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/weapon/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/clothing/glasses/meson,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plating,/area/maintenance/engineering) -"bPz" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) -"bPA" = (/obj/machinery/door_control{id = "acutesep"; name = "Acute Separation Shutters"; pixel_y = 25; req_access_txt = "5"},/obj/machinery/camera{c_tag = "Medbay Acute 2"; network = list("SS13")},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) -"bPB" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{autoclose = 0; name = "Acute Two"; req_access_txt = "5"},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay) +"bPz" = (/obj/structure/table/reinforced,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/noticeboard{pixel_y = 27},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "hop_office_desk"; name = "HoP Office Privacy Shutters"; opacity = 0},/obj/machinery/door/window/northleft{dir = 8; icon_state = "left"; name = "Reception Window"},/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 4; icon_state = "rightsecure"; name = "Head of Personnel's Desk"; req_access = list(57)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/crew_quarters/heads/hop) +"bPA" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acute2"; name = "Acute Privacy Shutters"; opacity = 0},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/medbay) +"bPB" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 1; icon_state = "left"; name = "Shower"},/obj/machinery/shower{icon_state = "shower"; dir = 4},/obj/item/weapon/soap/deluxe,/obj/item/weapon/bikehorn/rubberducky,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/captain) "bPC" = (/obj/machinery/camera{c_tag = "Medbay Port Corridor"; dir = 8; network = list("SS13")},/obj/structure/disposalpipe/segment,/obj/machinery/light_switch{pixel_x = 22; pixel_y = -9},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay) "bPD" = (/obj/machinery/camera{c_tag = "Medbay CMO Office"; dir = 4; network = list("SS13")},/obj/machinery/light_switch{pixel_x = -22; pixel_y = -9},/obj/machinery/requests_console{announcementConsole = 1; department = "Chief Medical Officer's Desk"; departmentType = 5; name = "Chief Medical Officer RC"; pixel_x = -34; pixel_y = 2},/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/crew_quarters/heads/cmo) "bPE" = (/obj/structure/table,/obj/machinery/computer/skills{pixel_y = 4},/obj/item/device/megaphone,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) -"bPF" = (/obj/structure/table,/obj/item/weapon/paper{desc = "A few notes scratched out by the last CMO before they departed the station."; info = "
        To the incoming CMO of Exodus:


        I wish you and your crew well. Do take note:


        The Medical Emergency Red Phone system has proven itself well. Take care to keep the phones in their designated places as they have been optimised for broadcast. The two handheld green radios (I have left one in this office, and one near the Emergency Entrance) are free to be used. The system has proven effective at alerting Medbay of important details, especially during power outages.

        I think I may have left the toilet cubicle doors shut. It might be a good idea to open them so the staff and patients know they are not engaged.

        The new syringe gun has been stored in secondary storage. I tend to prefer it stored in my office, but 'guidelines' are 'guidelines'.

        Also in secondary storage is the grenade equipment crate. I've just realised I've left it open - you may wish to shut it.

        There were a few problems with their installation, but the Medbay Quarantine shutters should now be working again - they lock down the Emergency and Main entrances to prevent travel in and out. Pray you shan't have to use them.

        The new version of the Medical Diagnostics Manual arrived. I distributed them to the shelf in the staff break room, and one on the table in the corner of this room.

        The exam/triage room has the walking canes in it. I'm not sure why we'd need them - but there you have it.

        Emergency Cryo bags are beside the emergency entrance, along with a kit.

        Spare paper cups for the reception are on the left side of the reception desk.

        I've fed Runtime. She should be fine.


        That should be all. Good luck!
        "; name = "Outgoing CMO's Notes"},/obj/item/device/radio{frequency = 1487; name = "Medbay Emergency Radio Link"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) +"bPF" = (/obj/structure/table,/obj/item/weapon/paper{desc = "A few notes scratched out by the last CMO before they departed the station."; info = "\[i]\[center]To the incoming CMO of Exodus:\[/i]\[/center]\[br]\[br]I wish you and your crew well. Do take note:\[br]\[br]\[br]The Medical Emergency Red Phone system has proven itself well. Take care to keep the phones in their designated places as they have been optimised for broadcast. The two handheld green radios (I have left one in this office, and one near the Emergency Entrance) are free to be used. The system has proven effective at alerting Medbay of important details, especially during power outages.\[br]\[br]I think I may have left the toilet cubicle doors shut. It might be a good idea to open them so the staff and patients know they are not engaged.\[br]\[br]The new syringe gun has been stored in secondary storage. I tend to prefer it stored in my office, but 'guidelines' are 'guidelines'.\[br]\[br]Also in secondary storage is the grenade equipment crate. I've just realised I've left it open - you may wish to shut it.\[br]\[br]There were a few problems with their installation, but the Medbay Quarantine shutters should now be working again - they lock down the Emergency and Main entrances to prevent travel in and out. Pray you shan't have to use them.\[br]\[br]The new version of the Medical Diagnostics Manual arrived. I distributed them to the shelf in the staff break room, and one on the table in the corner of this room.\[br]\[br]The exam/triage room has the walking canes in it. I'm not sure why we'd need them - but there you have it.\[br]\[br]Emergency Cryo bags are beside the emergency entrance, along with a kit.\[br]\[br]Spare paper cups for the reception are on the left side of the reception desk.\[br]\[br]I've fed Runtime. She should be fine.\[br]\[br]\[br]\[center]That should be all. Good luck!\[/center]"; name = "Outgoing CMO's Notes"},/obj/item/device/radio{frequency = 1487; name = "Medbay Emergency Radio Link"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) "bPG" = (/obj/structure/table,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/computer/med_data/laptop{pixel_x = 3; pixel_y = 4},/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/crew_quarters/heads/cmo) "bPH" = (/obj/machinery/camera{c_tag = "Medbay Starboard Corridor"; dir = 4; network = list("SS13")},/obj/machinery/light_switch{pixel_x = -22; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/medbay2) "bPI" = (/obj/structure/disposalpipe/segment,/obj/machinery/newscaster{pixel_x = 30},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) -"bPJ" = (/obj/structure/stool,/obj/effect/landmark/start{name = "Medical Doctor"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) +"bPJ" = (/mob/living/simple_animal/cat/fluff/Runtime,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) "bPK" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 0},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) "bPL" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/britcup,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) -"bPM" = (/obj/structure/stool,/obj/effect/landmark/start{name = "Geneticist"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) +"bPM" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = 36},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/machinery/button/windowtint{id = "isoA_window_tint"; pixel_y = 26},/turf/simulated/floor{dir = 5; icon_state = "whitered"},/area/medical/patient_a) "bPN" = (/obj/machinery/computer/med_data,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) "bPO" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/research_port) "bPP" = (/obj/machinery/sparker{id = "Xenobio"; pixel_x = -25},/turf/simulated/floor/engine,/area/rnd/misc_lab) @@ -4881,7 +4883,7 @@ "bPU" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/rnd/storage) "bPV" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bPW" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 9; icon_state = "whitehall"},/area/rnd/research) -"bPX" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/glass_research{name = "Toxins Lab"; req_access_txt = "8"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) +"bPX" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_one_access = list(9,12,47)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/research_port) "bPY" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) "bPZ" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) "bQa" = (/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) @@ -4892,8 +4894,8 @@ "bQf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "floorgrime"},/area/rnd/mixing) "bQg" = (/obj/machinery/light/small{dir = 4},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "warningcorner"; dir = 2},/area/rnd/mixing) "bQh" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/rnd/mixing) -"bQi" = (/obj/machinery/driver_button{dir = 2; id = "toxinsdriver"; pixel_y = 24},/turf/simulated/floor,/area/rnd/mixing) -"bQj" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/computer/security/telescreen{desc = "Used for watching the test chamber."; layer = 4; name = "Test Chamber Telescreen"; network = list("Toxins Test Area"); pixel_x = 32; pixel_y = 0},/turf/simulated/floor,/area/rnd/mixing) +"bQi" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = 36},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/machinery/button/windowtint{id = "isoB_window_tint"; pixel_y = 26},/turf/simulated/floor{dir = 5; icon_state = "whitered"},/area/medical/patient_b) +"bQj" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/computer/security/telescreen{desc = "Used for watching the test chamber."; layer = 4; name = "Test Chamber Telescreen"; network = list("Toxins Test Area"); pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor,/area/rnd/mixing) "bQk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/mixing) "bQl" = (/turf/simulated/floor/airless{dir = 9; icon_state = "warning"},/area/rnd/test_area) "bQm" = (/turf/simulated/floor/airless{icon_state = "warning"; dir = 1},/area/rnd/test_area) @@ -4904,7 +4906,7 @@ "bQr" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = -32},/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor{dir = 10; icon_state = "brown"},/area/quartermaster/miningdock) "bQs" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor,/area/quartermaster/miningdock) "bQt" = (/obj/structure/disposalpipe/sortjunction{dir = 8; icon_state = "pipe-j1s"; sortType = "QM Office"; name = "QM Office"},/turf/simulated/floor,/area/quartermaster/miningdock) -"bQu" = (/obj/machinery/door/airlock/maintenance{name = "Mining Maintenance"; req_access_txt = "48"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/quartermaster/miningdock) +"bQu" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/research{name = "Toxins Storage"; req_access = list(8)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/rnd/research) "bQv" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/cargo) "bQw" = (/obj/structure/disposalpipe/sortjunction{dir = 8; icon_state = "pipe-j1s"; sortType = "HoP Office"; name = "HoP Office"},/turf/simulated/floor/plating,/area/maintenance/cargo) "bQx" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/cargo) @@ -4917,7 +4919,7 @@ "bQE" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/pandemic{pixel_x = -3; pixel_y = 3},/obj/item/weapon/circuitboard/rdconsole,/obj/item/weapon/circuitboard/destructive_analyzer,/obj/item/weapon/circuitboard/protolathe,/obj/item/weapon/circuitboard/rdserver{pixel_x = 3; pixel_y = -3},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/storage/tech) "bQF" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/arcade,/obj/item/weapon/circuitboard/message_monitor{pixel_x = 3; pixel_y = -3},/turf/simulated/floor/plating,/area/storage/tech) "bQG" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/security/mining,/obj/item/weapon/circuitboard/autolathe{pixel_x = 3; pixel_y = -3},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/storage/tech) -"bQH" = (/obj/machinery/requests_console{department = "Tech storage"; pixel_x = 28; pixel_y = 0},/turf/simulated/floor/plating,/area/storage/tech) +"bQH" = (/obj/structure/disposalpipe/segment,/obj/machinery/camera{c_tag = "Aft Primary Hallway"; dir = 8; network = list("SS13")},/obj/machinery/atmospherics/unary/vent_pump/on,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) "bQI" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "bQJ" = (/turf/simulated/floor,/area/hallway/primary/aft) "bQK" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) @@ -4933,22 +4935,22 @@ "bQU" = (/obj/structure/closet,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/engineering) "bQV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bQW" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "misclab"; name = "Test Chamber Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/engine,/area/rnd/misc_lab) -"bQX" = (/turf/simulated/floor{icon_state = "white_2"},/area/medical/medbay) +"bQX" = (/obj/machinery/sleeper,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/sleeper) "bQY" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 4; frequency = 1441; icon_state = "map_injector"; id = "n2_in"; use_power = 1},/turf/simulated/floor/engine,/area/rnd/misc_lab) "bQZ" = (/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/crew_quarters/heads/cmo) -"bRa" = (/mob/living/simple_animal/cat/Runtime,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) -"bRb" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/effect/landmark/start{name = "Chief Medical Officer"},/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "cmooffice"; name = "CMO Privacy Shutters"; pixel_x = 38; pixel_y = 21},/obj/machinery/door_control{desc = "A remote control switch for the CMO's office."; id = "cmodoor"; name = "CMO Office Door Control"; normaldoorcontrol = 1; pixel_x = 28; pixel_y = 21},/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "virologyquar"; name = "Virology Emergency Lockdown Control"; pixel_x = -15; pixel_y = 38; req_access_txt = "5"},/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "medbayquar"; name = "Medbay Emergency Lockdown Control"; pixel_x = -15; pixel_y = 30; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) +"bRa" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/airlock/command{name = "Server Room"; req_access = list(30)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "dark"},/area/rnd/research) +"bRb" = (/obj/structure/table/rack,/obj/item/clothing/accessory/stethoscope,/obj/item/clothing/glasses/hud/health,/obj/item/device/flashlight/pen,/obj/item/weapon/storage/belt/medical,/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = -24},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -38},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/crew_quarters/heads/cmo) "bRc" = (/obj/structure/table,/obj/item/weapon/folder/white{pixel_y = 10},/obj/item/weapon/clipboard,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/item/weapon/stamp/cmo,/turf/simulated/floor{tag = "icon-whiteblue (EAST)"; icon_state = "whiteblue"; dir = 4},/area/crew_quarters/heads/cmo) -"bRd" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/research{name = "Toxins Launch Room"; req_access_txt = "8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/rnd/mixing) -"bRe" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/research{name = "Toxins Launch Room Access"; req_access_txt = "8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) +"bRd" = (/obj/structure/table,/obj/machinery/door_control{id = "Biohazard"; name = "Biohazard Shutter Control"; pixel_x = 5; pixel_y = 15; req_access = list(47)},/obj/machinery/computer/skills{icon_state = "medlaptop"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor) +"bRe" = (/obj/machinery/door/airlock/multi_tile/glass{autoclose = 1; dir = 2; req_access = list(5)},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/medical/sleeper) "bRf" = (/obj/machinery/computer/crew,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) "bRg" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/closet/secure_closet/personal/patient,/turf/simulated/floor{dir = 9; icon_state = "whitered"},/area/medical/patient_a) "bRh" = (/obj/machinery/light{dir = 1},/obj/machinery/newscaster{pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/hologram/holopad,/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/medical/patient_a) -"bRi" = (/obj/machinery/door_control{id = "medpriva"; name = "Privacy Shutters"; pixel_y = 25},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = 36},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{dir = 5; icon_state = "whitered"},/area/medical/patient_a) +"bRi" = (/obj/item/weapon/stool,/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -30},/obj/effect/landmark/start{name = "Chemist"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) "bRj" = (/turf/simulated/wall,/area/medical/patient_a) "bRk" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/closet/secure_closet/personal/patient,/turf/simulated/floor{dir = 9; icon_state = "whitered"},/area/medical/patient_b) "bRl" = (/obj/machinery/light{dir = 1},/obj/machinery/newscaster{pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/hologram/holopad,/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/medical/patient_b) -"bRm" = (/obj/machinery/door_control{id = "medprivb"; name = "Privacy Shutters"; pixel_y = 25},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = 36},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{dir = 5; icon_state = "whitered"},/area/medical/patient_b) +"bRm" = (/obj/item/weapon/stool,/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/effect/landmark/start{name = "Chemist"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) "bRn" = (/turf/simulated/wall,/area/medical/patient_b) "bRo" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/engine,/area/rnd/misc_lab) "bRp" = (/obj/structure/table,/obj/item/device/assembly/igniter,/turf/simulated/floor/engine,/area/rnd/misc_lab) @@ -4957,13 +4959,13 @@ "bRs" = (/obj/structure/extinguisher_cabinet{pixel_x = -24},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/rnd/research) "bRt" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bRu" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 9; icon_state = "whitehall"},/area/rnd/research) -"bRv" = (/obj/machinery/door/airlock/glass_research{name = "Toxins Lab"; req_access_txt = "8"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) +"bRv" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = "GeneticsDoor"; name = "Genetics Laboratory"; req_access = list(9)},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) "bRw" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) -"bRx" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) -"bRy" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) -"bRz" = (/obj/effect/landmark/start{name = "Scientist"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) -"bRA" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) -"bRB" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) +"bRx" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{id_tag = "GeneticsDoor"; name = "Cloning Laboratory"; req_access = list(5)},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/cryo) +"bRy" = (/obj/machinery/door/airlock/command{name = "Head of Personnel"; req_access = list(57)},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/central_three) +"bRz" = (/obj/machinery/door/airlock/highsecurity{icon_state = "door_closed"; locked = 0; name = "AI Upload Access"; req_access = list(16)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "vault"},/area/hallway/primary/central_three) +"bRA" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/door/airlock/mining{name = "Mining Dock"; req_access = list(48)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/miningdock) +"bRB" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1380; id_tag = "research_dock_pump"},/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "research_dock_airlock"; pixel_x = 25; pixel_y = 0; req_one_access = list(13,65); tag_airpump = "research_dock_pump"; tag_chamber_sensor = "research_dock_sensor"; tag_exterior_door = "research_dock_outer"; tag_interior_door = "research_dock_inner"},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/rnd/docking) "bRC" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay) "bRD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/rnd/mixing) "bRE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor{icon_state = "floorgrime"},/area/rnd/mixing) @@ -4971,7 +4973,7 @@ "bRG" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "cmooffice"; name = "CMO Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay2) "bRH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/rnd/mixing) "bRI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/rnd/mixing) -"bRJ" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/computer/security/telescreen{desc = "Used for watching the test chamber."; layer = 4; name = "Test Chamber Telescreen"; network = list("Toxins Test Area"); pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor,/area/rnd/mixing) +"bRJ" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/structure/bed/chair/office/dark,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/patient_a) "bRK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/mixing) "bRL" = (/turf/simulated/floor/airless{dir = 8; icon_state = "warning"},/area/rnd/test_area) "bRM" = (/obj/structure/closet/crate,/turf/simulated/shuttle/floor,/area/shuttle/mining/station) @@ -4984,44 +4986,44 @@ "bRT" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/storage/tech) "bRU" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/crew{pixel_x = -1; pixel_y = 1},/obj/item/weapon/circuitboard/card{pixel_x = 2; pixel_y = -2},/obj/item/weapon/circuitboard/communications{pixel_x = 5; pixel_y = -5},/obj/machinery/light/small{dir = 8},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/storage/tech) "bRV" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/storage/tech) -"bRW" = (/obj/machinery/door/airlock/highsecurity{name = "Secure Tech Storage"; req_access_txt = "19;23"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/storage/tech) +"bRW" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Medical Equipment"; req_access = list(5)},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay3) "bRX" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/storage/tech) "bRY" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/storage/tech) "bRZ" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/storage/tech) "bSa" = (/obj/effect/landmark{name = "blobstart"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/storage/tech) "bSb" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/storage/tech) -"bSc" = (/obj/machinery/door/airlock/engineering{name = "Tech Storage"; req_access_txt = "23"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/aft) +"bSc" = (/obj/machinery/computer/security/telescreen{desc = "Used for watching the RD's goons from the safety of his office."; name = "Research Monitor"; network = list("Research","Toxins Test Area","Robots","Anomaly Isolation","Research Outpost"); pixel_x = 0; pixel_y = 2},/obj/structure/table,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor) "bSd" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "bSe" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/hallway/primary/aft) -"bSf" = (/obj/structure/disposalpipe/segment,/obj/machinery/camera{c_tag = "Aft Primary Hallway"; dir = 8; network = list("SS13")},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"bSg" = (/obj/machinery/door/airlock/maintenance{name = "Custodial Maintenance"; req_access_txt = "26"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/janitor) +"bSf" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Genetics Research"; req_access = list(9)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/genetics) +"bSg" = (/obj/machinery/door/firedoor/border_only,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/research{name = "Research Division Access"; req_access = list(47)},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bSh" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/engineering) "bSi" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/engineering) "bSj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/engineering) "bSk" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/engineering) "bSl" = (/obj/structure/table,/obj/item/device/t_scanner,/turf/simulated/floor/plating,/area/maintenance/engineering) "bSm" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) -"bSn" = (/obj/machinery/door_control{id = "acute2"; name = "Acute Two Privacy Shutters"; pixel_x = 6; pixel_y = -25; req_access_txt = "5"},/obj/machinery/door_control{id = "scanhide"; name = "Diagnostics Room Separation Shutters"; pixel_x = -6; pixel_y = -25; req_access_txt = "5"},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) +"bSn" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/structure/bed/chair/office/dark,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/patient_b) "bSo" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay) "bSp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "staffroom"; name = "Staff Room Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/medbay2) "bSq" = (/obj/machinery/light,/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor{dir = 10; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/crew_quarters/heads/cmo) -"bSr" = (/obj/structure/table/rack,/obj/item/clothing/tie/stethoscope,/obj/item/clothing/glasses/hud/health,/obj/item/device/flashlight/pen,/obj/item/weapon/storage/belt/medical,/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = -24},/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -38},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/crew_quarters/heads/cmo) +"bSr" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "cargo_bay_door"; locked = 1; name = "Cargo Docking Hatch"; req_access = list(13)},/turf/simulated/floor/plating,/area/quartermaster/storage) "bSs" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/crew_quarters/heads/cmo) "bSt" = (/obj/machinery/computer/crew,/obj/machinery/light,/turf/simulated/floor{dir = 6; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/crew_quarters/heads/cmo) -"bSu" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Research Division Delivery"; req_access_txt = "47"},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor{icon_state = "delivery"},/area/rnd/research) +"bSu" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "research_dock_inner"; locked = 1; name = "Shuttle Airlock"; req_access = list(13)},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking) "bSv" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) -"bSw" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "5;12;47"},/turf/simulated/floor/plating,/area/maintenance/research_port) +"bSw" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "research_dock_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = -25; req_one_access = list(13,65)},/turf/simulated/floor{dir = 2; icon_state = "cmo"},/area/rnd/docking) "bSx" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/machinery/light,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) -"bSy" = (/obj/structure/stool,/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/effect/landmark/start{name = "Chemist"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) -"bSz" = (/obj/structure/stool,/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -30},/obj/effect/landmark/start{name = "Chemist"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) +"bSy" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) +"bSz" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/computer/security/telescreen{desc = "Used for watching the test chamber."; layer = 4; name = "Test Chamber Telescreen"; network = list("Toxins Test Area"); pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/rnd/mixing) "bSA" = (/obj/item/device/radio/intercom{broadcasting = 0; canhear_range = 5; freerange = 0; frequency = 1485; listening = 1; name = "Station Intercom (Medbay Lobby)"; pixel_x = 0; pixel_y = -30},/obj/machinery/hologram/holopad,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) "bSB" = (/obj/machinery/light,/obj/machinery/vending/snack,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak) -"bSC" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/structure/stool/bed/chair/office/dark,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/patient_a) +"bSC" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = -24},/turf/simulated/floor{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) "bSD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_a) -"bSE" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0; req_access_txt = "0"},/obj/machinery/camera{c_tag = "Medbay Patient A"; dir = 8; network = list("SS13")},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/patient_a) -"bSF" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/structure/stool/bed/chair/office/dark,/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/patient_b) +"bSE" = (/obj/machinery/atmospherics/binary/passive_gate{dir = 8},/turf/simulated/floor{dir = 4; icon_state = "warnwhite"},/area/rnd/mixing) +"bSF" = (/obj/structure/table/reinforced,/obj/machinery/door/window/eastright{dir = 1; name = "Emergency Kit"; req_access = list(5)},/obj/machinery/door/firedoor,/obj/item/weapon/storage/toolbox/emergency,/obj/item/bodybag/cryobag{pixel_x = 6},/obj/item/bodybag/cryobag{pixel_x = 6},/obj/item/bodybag/cryobag,/obj/item/device/radio{frequency = 1487; name = "Medbay Emergency Radio Link"},/turf/simulated/floor{dir = 1; icon_state = "whiteyellow"},/area/medical/sleeper) "bSG" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_b) -"bSH" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0; req_access_txt = "0"},/obj/machinery/camera{c_tag = "Medbay Patient B"; dir = 8; network = list("SS13")},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/patient_b) +"bSH" = (/obj/machinery/light/small{dir = 4},/obj/machinery/requests_console{department = "Tech storage"; pixel_x = 28; pixel_y = 0},/turf/simulated/floor/plating,/area/storage/tech) "bSI" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/rnd/storage) "bSJ" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/storage) "bSK" = (/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/rnd/research) @@ -5033,20 +5035,20 @@ "bSQ" = (/obj/item/device/assembly/timer{pixel_x = 5; pixel_y = 4},/obj/item/device/assembly/timer{pixel_x = -4; pixel_y = 2},/obj/item/device/assembly/timer{pixel_x = 6; pixel_y = -4},/obj/item/device/assembly/timer{pixel_x = 0; pixel_y = 0},/obj/structure/table,/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/rnd/mixing) "bSR" = (/obj/item/device/transfer_valve{pixel_x = -5},/obj/item/device/transfer_valve{pixel_x = -5},/obj/item/device/transfer_valve{pixel_x = 0},/obj/item/device/transfer_valve{pixel_x = 0},/obj/item/device/transfer_valve{pixel_x = 5},/obj/item/device/transfer_valve{pixel_x = 5},/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/rnd/mixing) "bSS" = (/obj/structure/dispenser,/turf/simulated/floor{dir = 5; icon_state = "whitepurple"},/area/rnd/mixing) -"bST" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) -"bSU" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) -"bSV" = (/obj/structure/sign/securearea{pixel_x = -32},/turf/simulated/floor{icon_state = "warningcorner"; dir = 4},/area/rnd/mixing) +"bST" = (/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/hallway/primary/aft) +"bSU" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) +"bSV" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Medicine Storage"; req_access = list(5)},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper) "bSW" = (/obj/machinery/camera{c_tag = "Toxins Launch Room Access"; dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "warningcorner"; dir = 8},/area/rnd/mixing) "bSX" = (/obj/machinery/disposal,/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = -30; pixel_y = 0},/obj/structure/disposalpipe/trunk,/turf/simulated/floor{icon_state = "warningcorner"; dir = 2},/area/rnd/mixing) "bSY" = (/turf/simulated/floor{icon_state = "warning"},/area/rnd/mixing) -"bSZ" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/computer/security/telescreen{desc = "Used for watching the test chamber."; layer = 4; name = "Test Chamber Telescreen"; network = list("Toxins Test Area"); pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/rnd/mixing) +"bSZ" = (/turf/simulated/wall,/area/engineering/break_room) "bTa" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/mixing) "bTb" = (/turf/simulated/floor/airless{dir = 4; icon_state = "warning"},/area/rnd/test_area) "bTc" = (/turf/simulated/floor/airless{icon_state = "warningcorner"; dir = 1},/area/rnd/test_area) "bTd" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/shuttle/mining/station) "bTe" = (/obj/structure/shuttle/engine/propulsion/burst,/turf/space,/area/shuttle/mining/station) "bTf" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/shuttle/mining/station) -"bTg" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "mining_dock_airlock"; name = "exterior access button"; pixel_x = -5; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13;48"},/turf/space,/area/space) +"bTg" = (/obj/machinery/door/airlock/maintenance{req_one_access = list(12,47)},/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/maintenance/research_shuttle) "bTh" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/miningdock) "bTi" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/miningdock) "bTj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/miningdock) @@ -5063,10 +5065,10 @@ "bTu" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/powermonitor{pixel_x = -2; pixel_y = 2},/obj/item/weapon/circuitboard/stationalert{pixel_x = 1; pixel_y = -1},/obj/item/weapon/circuitboard/security/engineering,/obj/item/weapon/circuitboard/atmos_alert{pixel_x = 3; pixel_y = -3},/turf/simulated/floor/plating,/area/storage/tech) "bTv" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/circuitboard/secure_data{pixel_x = -2; pixel_y = 2},/obj/item/weapon/circuitboard/security{pixel_x = 1; pixel_y = -1},/obj/item/weapon/circuitboard/skills{pixel_x = 4; pixel_y = -3},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/storage/tech) "bTw" = (/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor/plating,/area/storage/tech) -"bTx" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{dir = 8; icon_state = "cautioncorner"},/area/hallway/primary/aft) +"bTx" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 6},/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/medical/sleeper) "bTy" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) "bTz" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"bTA" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/primary/aft) +"bTA" = (/obj/machinery/door/airlock/maintenance{req_one_access = list(12,47)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/turf/simulated/floor/plating,/area/maintenance/research_shuttle) "bTB" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/engineering) "bTC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/engineering) "bTD" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/engineering) @@ -5078,10 +5080,10 @@ "bTJ" = (/turf/simulated/wall,/area/medical/medbay4) "bTK" = (/obj/machinery/door/firedoor,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) "bTL" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whiteblue"; tag = "icon-whitehall (WEST)"},/area/medical/medbay4) -"bTM" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = -32},/obj/structure/cable/green,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "hop_office_window"; name = "HoP Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/crew_quarters/heads/hop) -"bTN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "hop_office_window"; name = "HoP Office Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/crew_quarters/heads/hop) -"bTO" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "CMO's Office"; req_access_txt = "40"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) -"bTP" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor{icon_state = "bot"},/area/rnd/research) +"bTM" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/medical/sleeper) +"bTN" = (/obj/machinery/light{dir = 1},/obj/structure/bed/chair/comfy/teal{tag = "icon-comfychair (EAST)"; icon_state = "comfychair"; dir = 4},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay4) +"bTO" = (/obj/machinery/door/airlock/highsecurity{name = "Messaging Server"; req_access = list(30)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_server_room) +"bTP" = (/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 26},/obj/structure/bed/chair/comfy/teal{tag = "icon-comfychair (WEST)"; icon_state = "comfychair"; dir = 8},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay4) "bTQ" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "bot"},/area/rnd/research) "bTR" = (/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/medbay4) "bTS" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) @@ -5093,38 +5095,38 @@ "bTY" = (/obj/machinery/iv_drip,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{dir = 6; icon_state = "whitered"},/area/medical/patient_b) "bTZ" = (/obj/machinery/shieldwallgen{anchored = 1; req_access = list(47)},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bUa" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "bot"},/area/rnd/research) -"bUb" = (/obj/structure/table/reinforced,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/noticeboard{pixel_y = 27},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "hop_office_desk"; name = "HoP Office Privacy Shutters"; opacity = 0},/obj/machinery/door/window/northleft{dir = 8; icon_state = "left"; name = "Reception Window"; req_access_txt = "0"},/obj/machinery/door/window/brigdoor{base_state = "rightsecure"; dir = 4; icon_state = "rightsecure"; name = "Head of Personnel's Desk"; req_access_txt = "57"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/crew_quarters/heads/hop) +"bUb" = (/obj/machinery/door/airlock/highsecurity{name = "Cyborg Station"; req_access = list(16)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "dark"},/area/turret_protected/ai_cyborg_station) "bUc" = (/obj/machinery/atmospherics/unary/freezer{dir = 2; icon_state = "freezer_1"; use_power = 1; power_setting = 20; set_temperature = 73},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "dark"},/area/server) "bUd" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; icon_state = "map_vent_out"; use_power = 1},/turf/simulated/floor/bluegrid{name = "Server Base"; nitrogen = 500; oxygen = 0; temperature = 80},/area/server) -"bUe" = (/obj/machinery/door/firedoor,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "acute1em"; name = "Acute One Entry Shutters"; opacity = 0},/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/sleeper) +"bUe" = (/obj/machinery/vending/medical,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/patient_wing) "bUf" = (/obj/structure/sign/science{pixel_x = 32},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bUg" = (/turf/simulated/wall,/area/rnd/misc_lab) "bUh" = (/obj/machinery/light_switch{pixel_y = -23},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor{icon_state = "floorgrime"},/area/rnd/storage) "bUi" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "warningcorner"; dir = 8},/area/rnd/storage) "bUj" = (/obj/structure/sign/fire{pixel_x = 32; pixel_y = 0},/turf/simulated/floor{dir = 9; icon_state = "whitehall"},/area/rnd/research) "bUk" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/turf/simulated/wall/r_wall,/area/rnd/mixing) -"bUl" = (/obj/structure/sign/nosmoking_2{pixel_x = -32},/obj/machinery/camera{c_tag = "Toxins Lab"; dir = 4; network = list("SS13","Research")},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) -"bUm" = (/obj/machinery/power/apc/high{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green,/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing) +"bUl" = (/obj/structure/grille,/obj/structure/window/reinforced/polarized{id = "isoA_window_tint"},/obj/structure/window/reinforced/polarized{dir = 4; id = "isoA_window_tint"},/obj/structure/window/reinforced/polarized{dir = 1; id = "isoA_window_tint"},/obj/structure/window/reinforced/polarized{dir = 8; id = "isoA_window_tint"},/turf/simulated/floor/plating,/area/medical/patient_a) +"bUm" = (/obj/structure/grille,/obj/structure/window/reinforced/polarized{dir = 4; id = "isoA_window_tint"},/obj/structure/window/reinforced/polarized{id = "isoA_window_tint"},/obj/structure/window/reinforced/polarized{dir = 1; id = "isoA_window_tint"},/obj/structure/window/reinforced/polarized{dir = 8; id = "isoA_window_tint"},/turf/simulated/floor/plating,/area/medical/patient_a) "bUn" = (/turf/simulated/wall,/area/maintenance/research_starboard) -"bUo" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "8;12"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/research_starboard) +"bUo" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "specops_dock_airlock"; name = "exterior access button"; pixel_x = -5; pixel_y = 25; req_one_access = list(13)},/turf/space,/area/space) "bUp" = (/obj/structure/disposaloutlet,/obj/structure/window/reinforced{dir = 1},/obj/structure/disposalpipe/trunk{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating/airless,/area/rnd/mixing) -"bUq" = (/obj/machinery/door/window/southright{name = "Toxins Launcher"; req_access_txt = "8"; req_one_access_txt = "0"},/obj/machinery/door/window/southright{dir = 1; name = "Toxins Launcher"; req_access_txt = "8"},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/mixing) +"bUq" = (/obj/effect/decal/cleanable/generic,/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/plating,/area/maintenance/locker) "bUr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/mixing) "bUs" = (/turf/simulated/floor/airless{icon_state = "warning"},/area/rnd/test_area) "bUt" = (/turf/simulated/floor/airless{dir = 6; icon_state = "warning"},/area/rnd/test_area) "bUu" = (/turf/simulated/floor/airless{dir = 10; icon_state = "warning"},/area/rnd/test_area) "bUv" = (/turf/simulated/wall/r_wall,/area/maintenance/cargo) -"bUw" = (/obj/effect/decal/cleanable/blood/oil{amount = 0},/turf/simulated/floor/plating,/area/maintenance/cargo) +"bUw" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/locker) "bUx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/maintenance/cargo) "bUy" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/storage/tech) "bUz" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/storage/tech) "bUA" = (/obj/structure/table,/obj/item/stack/cable_coil{pixel_x = -3; pixel_y = 3},/obj/item/stack/cable_coil,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plating,/area/storage/tech) "bUB" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/plating,/area/storage/tech) -"bUC" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/storage/tech) +"bUC" = (/obj/structure/grille,/obj/structure/window/reinforced/polarized{id = "isoB_window_tint"},/obj/structure/window/reinforced/polarized{dir = 4; id = "isoB_window_tint"},/obj/structure/window/reinforced/polarized{dir = 1; id = "isoB_window_tint"},/obj/structure/window/reinforced/polarized{dir = 8; id = "isoB_window_tint"},/turf/simulated/floor/plating,/area/medical/patient_b) "bUD" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/hallway/primary/aft) "bUE" = (/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/primary/aft) -"bUF" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"bUG" = (/turf/simulated/wall,/area/engine/break_room) +"bUF" = (/obj/structure/table/reinforced,/obj/machinery/button/ignition{id = "Xenobio"; pixel_x = -6; pixel_y = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) +"bUG" = (/obj/machinery/airlock_sensor{id_tag = "tox_airlock_sensor"; master_tag = "tox_airlock_control"; pixel_y = 24},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/obj/machinery/atmospherics/binary/pump{dir = 8},/turf/simulated/floor/engine,/area/rnd/mixing) "bUH" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/engineering) "bUI" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/engineering) "bUJ" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/maintenance/engineering) @@ -5132,31 +5134,31 @@ "bUL" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/engineering) "bUM" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plating,/area/maintenance/engineering) "bUN" = (/obj/machinery/atmospherics/unary/cryo_cell,/turf/simulated/floor{icon_state = "red"; dir = 9},/area/medical/sleeper) -"bUO" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/medical/sleeper) -"bUP" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor,/area/medical/sleeper) +"bUO" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warnwhite"},/area/rnd/mixing) +"bUP" = (/obj/machinery/light/small{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/locker) "bUQ" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/medical/sleeper) -"bUR" = (/obj/machinery/door_control{id = "scanhide"; name = "Diagnostics Room Separation Shutters"; pixel_x = -6; pixel_y = 25; req_access_txt = "5"},/obj/machinery/camera{c_tag = "Medbay Scanning"; network = list("SS13")},/obj/machinery/atmospherics/unary/freezer{dir = 8; icon_state = "freezer"},/obj/machinery/door_control{id = "scanhideside"; name = "Diagnostics Room Privacy Shutters"; pixel_x = 6; pixel_y = 25; req_access_txt = "5"},/turf/simulated/floor{icon_state = "delivery"},/area/medical/sleeper) +"bUR" = (/obj/machinery/door_control{id = "Disposal Exit"; name = "Disposal Vent Control"; pixel_x = -25; pixel_y = 4; req_access = list(12)},/obj/machinery/button/driver{id = "trash"; pixel_x = -26; pixel_y = -6},/turf/simulated/floor/plating,/area/maintenance/disposal) "bUS" = (/obj/structure/disposalpipe/segment,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bUT" = (/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) "bUU" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/medbay4) -"bUV" = (/obj/machinery/light{dir = 1},/obj/structure/stool/bed/chair/comfy/teal{tag = "icon-comfychair (EAST)"; icon_state = "comfychair"; dir = 4},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay4) +"bUV" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/mixing) "bUW" = (/obj/machinery/camera{c_tag = "Medbay Lounge"; network = list("SS13")},/obj/structure/table,/obj/structure/disposalpipe/segment,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay4) -"bUX" = (/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 26},/obj/structure/stool/bed/chair/comfy/teal{tag = "icon-comfychair (WEST)"; icon_state = "comfychair"; dir = 8},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay4) +"bUX" = (/obj/machinery/vending/cigarette,/turf/simulated/floor/carpet,/area/engineering/break_room) "bUY" = (/obj/machinery/vending/coffee,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay4) "bUZ" = (/obj/machinery/light{dir = 1},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay4) "bVa" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 1; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/medbay4) "bVb" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) -"bVc" = (/obj/machinery/vending/medical,/obj/machinery/light{dir = 1},/turf/simulated/wall,/area/medical/medbay4) +"bVc" = (/obj/machinery/light{dir = 1},/obj/machinery/door/firedoor,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay4) "bVd" = (/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20},/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/patient_wing) "bVe" = (/obj/structure/table,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/patient_wing) -"bVf" = (/obj/structure/stool/bed/roller,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/patient_wing) +"bVf" = (/obj/structure/table/woodentable,/obj/item/weapon/dice,/turf/simulated/floor/carpet,/area/engineering/break_room) "bVg" = (/obj/structure/closet/secure_closet/personal/patient,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/patient_wing) "bVh" = (/obj/machinery/iv_drip,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/patient_wing) "bVi" = (/turf/simulated/wall,/area/medical/patient_wing) "bVj" = (/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "medbayquar"; name = "Medbay Emergency Quarantine Shutters"; opacity = 0},/obj/machinery/door/firedoor,/turf/simulated/floor{dir = 4; icon_state = "loadingarea"; tag = "loading"},/area/hallway/primary/central_two) -"bVk" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Sub-Acute A"; req_access_txt = "0"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) +"bVk" = (/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor{icon_state = "bluecorner"},/area/hallway/primary/central_one) "bVl" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 2; sortType = "RD Office"; name = "RD Office"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) -"bVm" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Sub-Acute B"; req_access_txt = "0"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) +"bVm" = (/obj/machinery/door/window/eastleft{name = "Mail"; req_access = list(50)},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{icon_state = "delivery"},/area/quartermaster/office) "bVn" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 6},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bVo" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bVp" = (/obj/structure/table/reinforced,/obj/item/weapon/wrench,/obj/item/weapon/crowbar/red,/obj/item/clothing/glasses/science,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) @@ -5165,16 +5167,16 @@ "bVs" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bVt" = (/obj/structure/table/reinforced,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bVu" = (/obj/machinery/computer/security/telescreen{desc = "Used to monitor the proceedings inside the test chamber."; name = "Test Chamber Monitor"; network = list("Miscellaneous Reseach"); pixel_x = 32; pixel_y = 0},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) -"bVv" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/research{name = "Toxins Storage"; req_access_txt = "8"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/rnd/research) +"bVv" = (/obj/machinery/door/airlock/research{name = "Research Division Access"; req_access = list(47)},/turf/simulated/floor{icon_state = "white"},/area/hallway/primary/starboard) "bVw" = (/obj/machinery/vending/cigarette{pixel_x = 0; pixel_y = 2},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bVx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/research) -"bVy" = (/obj/machinery/door/firedoor/border_only,/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/research{name = "Research Division Access"; req_access_txt = "47"},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) +"bVy" = (/obj/structure/filingcabinet/chestdrawer,/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/assembly/robotics) "bVz" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/engine/vacuum,/area/rnd/mixing) "bVA" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "bot"},/area/rnd/research) "bVB" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/wall/r_wall,/area/rnd/mixing) -"bVC" = (/obj/machinery/airlock_sensor{id_tag = "tox_airlock_sensor"; master_tag = "tox_airlock_control"; pixel_y = 24},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/obj/machinery/atmospherics/binary/pump{dir = 4},/turf/simulated/floor/engine,/area/rnd/mixing) -"bVD" = (/obj/machinery/meter,/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "tox_airlock_pump"; tag_exterior_door = "tox_airlock_exterior"; id_tag = "tox_airlock_control"; tag_interior_door = "tox_airlock_interior"; pixel_x = -24; pixel_y = 0; tag_chamber_sensor = "tox_airlock_sensor"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "warnwhitecorner"},/area/rnd/mixing) -"bVE" = (/obj/machinery/atmospherics/valve{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warnwhite"},/area/rnd/mixing) +"bVC" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green,/turf/simulated/floor/carpet,/area/engineering/break_room) +"bVD" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/engineering_guide{pixel_x = 3; pixel_y = 2},/obj/item/weapon/book/manual/atmospipes,/obj/machinery/light{dir = 1},/turf/simulated/floor/carpet,/area/engineering/break_room) +"bVE" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/engineering_construction,/obj/item/weapon/book/manual/evaguide{pixel_x = -2; pixel_y = 7},/turf/simulated/floor/carpet,/area/engineering/break_room) "bVF" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/rnd/mixing) "bVG" = (/obj/item/weapon/wrench,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/maintenance/research_starboard) "bVH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/research_starboard) @@ -5198,18 +5200,18 @@ "bVZ" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = -1},/obj/item/device/multitool,/obj/item/clothing/glasses/meson,/turf/simulated/floor/plating,/area/storage/tech) "bWa" = (/obj/machinery/door/airlock/glass{name = "Central Access"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/hallway/primary/aft) "bWb" = (/obj/machinery/door/airlock/glass{name = "Central Access"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/primary/aft) -"bWc" = (/obj/machinery/vending/cigarette,/turf/simulated/floor/carpet,/area/engine/break_room) -"bWd" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green,/turf/simulated/floor/carpet,/area/engine/break_room) -"bWe" = (/obj/structure/table/woodentable,/obj/item/weapon/dice,/turf/simulated/floor/carpet,/area/engine/break_room) -"bWf" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/engineering_construction,/obj/item/weapon/book/manual/evaguide{pixel_x = -2; pixel_y = 7},/turf/simulated/floor/carpet,/area/engine/break_room) -"bWg" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/engineering_guide{pixel_x = 3; pixel_y = 2},/obj/item/weapon/book/manual/atmospipes,/obj/machinery/light{dir = 1},/turf/simulated/floor/carpet,/area/engine/break_room) -"bWh" = (/obj/structure/bookcase/manuals/engineering,/turf/simulated/floor/carpet,/area/engine/break_room) -"bWi" = (/turf/simulated/wall,/area/engine/engineering_supply) +"bWc" = (/obj/structure/bookcase/manuals/engineering,/turf/simulated/floor/carpet,/area/engineering/break_room) +"bWd" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/medical/sleeper) +"bWe" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor,/area/medical/sleeper) +"bWf" = (/obj/structure/bed/chair/comfy/teal,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "whiteredcorner"},/area/medical/patient_wing) +"bWg" = (/obj/structure/bed/chair/comfy/teal,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteredcorner"},/area/medical/patient_wing) +"bWh" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/window/eastright{dir = 8; name = "Chemistry Desk"; req_access = list(33)},/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "chemcounter"; name = "Pharmacy Counter Shutters"; opacity = 0},/obj/structure/table/reinforced,/turf/simulated/floor{icon_state = "yellowfull"; dir = 8},/area/medical/chemistry) +"bWi" = (/obj/structure/bed/chair/office/light{dir = 1},/obj/effect/landmark/start{name = "Scientist"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bWj" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=4"; freq = 1400; location = "Medbay"},/obj/structure/plasticflaps{opacity = 1},/turf/simulated/floor{icon_state = "bot"},/area/medical/sleeper) -"bWk" = (/obj/machinery/door/window/eastleft{name = "Medical Delivery"; req_access_txt = "5"},/obj/machinery/door/firedoor,/turf/simulated/floor{icon_state = "delivery"},/area/medical/sleeper) +"bWk" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/locker) "bWl" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/medical/sleeper) -"bWm" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/medical/sleeper) -"bWn" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/medical/sleeper) +"bWm" = (/obj/structure/bed/chair/comfy/brown{dir = 4},/obj/effect/landmark/start{name = "Captain"},/obj/machinery/door_control{desc = "A remote control-switch for the office door."; id = "captaindoor"; name = "Office Door Control"; normaldoorcontrol = 1; pixel_x = 15; pixel_y = 30; req_access = list(20)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door_control{desc = "A remote control-switch for the starboard bridge doors."; id = "sbridgedoor"; name = "Bridge Door Control"; normaldoorcontrol = 1; pixel_x = 15; pixel_y = 39; req_access = list(20)},/turf/simulated/floor/wood,/area/crew_quarters/captain) +"bWn" = (/obj/structure/bed/chair{dir = 8},/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod5/station) "bWo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor,/area/medical/sleeper) "bWp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/medical/sleeper) "bWq" = (/obj/machinery/door/blast/shutters{dir = 2; id = "qm_warehouse"; name = "Warehouse Shutters"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/quartermaster/storage) @@ -5229,31 +5231,31 @@ "bWE" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) "bWF" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteredcorner"},/area/medical/patient_wing) "bWG" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor{dir = 1; icon_state = "whitered_a"; tag = "icon-whitered_a (WEST)"},/area/medical/patient_wing) -"bWH" = (/obj/structure/stool/bed/chair/comfy/teal,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "whiteredcorner"},/area/medical/patient_wing) +"bWH" = (/obj/machinery/light_switch{pixel_x = -22; pixel_y = -10},/turf/simulated/floor/carpet,/area/engineering/break_room) "bWI" = (/obj/machinery/light{dir = 1},/obj/machinery/alarm{pixel_y = 25},/obj/structure/table,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) -"bWJ" = (/obj/structure/stool/bed/chair/comfy/teal,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteredcorner"},/area/medical/patient_wing) +"bWJ" = (/obj/structure/bed/chair/comfy/beige,/obj/effect/landmark/start{name = "Station Engineer"},/turf/simulated/floor/carpet,/area/engineering/break_room) "bWK" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor{dir = 1; icon_state = "whitered_b"; tag = "icon-whitered_b (WEST)"},/area/medical/patient_wing) "bWL" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "whiteredcorner"},/area/medical/patient_wing) -"bWM" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Medbay Patient Wing Maintenance Access"; req_access_txt = "5"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/medical/patient_wing) +"bWM" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/command{name = "Conference Room"; req_access = list(19)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/maintenance/substation/command) "bWN" = (/obj/effect/landmark/start{name = "Scientist"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bWO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bWP" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bWQ" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) -"bWR" = (/obj/machinery/door/airlock/glass_medical{name = "Hygiene Facilities"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) +"bWR" = (/turf/simulated/floor/carpet,/area/engineering/break_room) "bWS" = (/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bWT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) -"bWU" = (/obj/structure/stool/bed/chair/office/light{dir = 1},/obj/effect/landmark/start{name = "Scientist"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) -"bWV" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "hazard door east"},/obj/machinery/door/airlock/research{name = "Miscellaneous Reseach Room"; req_access_txt = "47"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) +"bWU" = (/obj/structure/extinguisher_cabinet{pixel_x = 25},/turf/simulated/floor/carpet,/area/engineering/break_room) +"bWV" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/window{base_state = "right"; dir = 8; icon_state = "right"; name = "Mailing Room"; req_access = list(50)},/turf/simulated/floor{icon_state = "bot"},/area/hallway/primary/central_one) "bWW" = (/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bWX" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bWY" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bWZ" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bXa" = (/turf/simulated/floor/engine/vacuum,/area/rnd/mixing) "bXb" = (/obj/machinery/air_sensor{frequency = 1430; id_tag = "toxins_mixing_exterior"; output = 63},/turf/simulated/floor/engine/vacuum,/area/rnd/mixing) -"bXc" = (/obj/machinery/door/airlock/glass_research{autoclose = 0; frequency = 1379; glass = 1; icon_state = "door_locked"; id_tag = "tox_airlock_exterior"; locked = 1; name = "Mixing Room Exterior Airlock"; req_access_txt = "8"},/turf/simulated/floor/engine,/area/rnd/mixing) +"bXc" = (/obj/machinery/door_control{id = "qm_warehouse"; name = "Warehouse Door Control"; pixel_x = -1; pixel_y = -24; req_access = list(31)},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage) "bXd" = (/obj/machinery/atmospherics/binary/dp_vent_pump/high_volume{dir = 2; frequency = 1379; id = "tox_airlock_pump"},/obj/machinery/air_sensor{frequency = 1430; id_tag = "toxins_mixing_interior"; output = 63; pixel_x = -8; pixel_y = -18},/turf/simulated/floor/engine,/area/rnd/mixing) -"bXe" = (/obj/machinery/door/airlock/glass_research{autoclose = 0; frequency = 1379; glass = 1; icon_state = "door_locked"; id_tag = "tox_airlock_interior"; locked = 1; name = "Mixing Room Interior Airlock"; req_access_txt = "8"},/turf/simulated/floor/engine,/area/rnd/mixing) -"bXf" = (/turf/simulated/floor{dir = 8; icon_state = "warnwhite"},/area/rnd/mixing) +"bXe" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/weapon/folder/white,/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/window/eastright{base_state = "left"; dir = 2; icon_state = "left"; name = "Robotics Desk"; req_access = list(29)},/turf/simulated/floor/plating,/area/hallway/primary/starboard) +"bXf" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/window/southright{name = "Research and Development Desk"; req_access = list(7)},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/hallway/primary/starboard) "bXg" = (/turf/simulated/floor{dir = 4; icon_state = "warnwhite"},/area/rnd/mixing) "bXh" = (/obj/machinery/computer/general_air_control{frequency = 1430; name = "Mixing Chamber Monitor"; sensors = list("toxins_mixing_exterior" = "Mixing Chamber - Exterior", "toxins_mixing_interior" = "Mixing Chamber - Interior")},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/mixing) "bXi" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/research_starboard) @@ -5261,20 +5263,20 @@ "bXk" = (/turf/simulated/floor/airless{dir = 5; icon_state = "warning"},/area/rnd/test_area) "bXl" = (/turf/simulated/floor/airless{icon_state = "warningcorner"; dir = 4},/area/rnd/test_area) "bXm" = (/obj/structure/window/shuttle,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/escape_pod5/station) -"bXn" = (/obj/structure/stool/bed/chair{dir = 8},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod{frequency = 1380; id_tag = "escape_pod_5"; pixel_x = 0; pixel_y = -25; req_access_txt = "0"; req_one_access_txt = "0"; tag_door = "escape_pod_5_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod5/station) -"bXo" = (/obj/structure/stool/bed/chair{dir = 8},/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod5/station) -"bXp" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_5_hatch"; locked = 1; name = "Escape Pod Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod5/station) -"bXq" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_5_berth_hatch"; locked = 1; name = "Escape Pod"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/cargo) +"bXn" = (/obj/structure/closet/wardrobe/engineering_yellow,/turf/simulated/floor{dir = 4; icon_state = "whiteyellowfull"},/area/crew_quarters/sleep/engi_wash) +"bXo" = (/obj/structure/table,/obj/item/bodybag/cryobag{pixel_x = 6},/obj/item/stack/medical/bruise_pack{pixel_x = -4; pixel_y = 3},/obj/item/stack/medical/bruise_pack{pixel_x = -4; pixel_y = 3},/obj/item/stack/medical/ointment{pixel_y = 10},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "yellowfull"; dir = 8},/area/crew_quarters/sleep/engi_wash) +"bXp" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/research{name = "Mech Bay"; req_access = list(29)},/turf/simulated/floor,/area/hallway/primary/starboard) +"bXq" = (/obj/machinery/chemical_dispenser/full,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "bXr" = (/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth{frequency = 1380; id_tag = "escape_pod_5_berth"; pixel_x = -25; pixel_y = 25; tag_door = "escape_pod_5_berth_hatch"},/turf/simulated/floor/plating,/area/maintenance/cargo) "bXs" = (/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/cargo) "bXt" = (/obj/machinery/door/firedoor/border_only,/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"bXu" = (/obj/machinery/light_switch{pixel_x = -22; pixel_y = -10},/turf/simulated/floor/carpet,/area/engine/break_room) -"bXv" = (/turf/simulated/floor/carpet,/area/engine/break_room) -"bXw" = (/obj/structure/stool/bed/chair/comfy/beige,/obj/effect/landmark/start{name = "Station Engineer"},/turf/simulated/floor/carpet,/area/engine/break_room) -"bXx" = (/obj/structure/extinguisher_cabinet{pixel_x = 25},/turf/simulated/floor/carpet,/area/engine/break_room) -"bXy" = (/obj/structure/table,/obj/item/bodybag/cryobag{pixel_x = 6},/obj/item/stack/medical/bruise_pack{pixel_x = -4; pixel_y = 3},/obj/item/stack/medical/bruise_pack{pixel_x = -4; pixel_y = 3},/obj/item/stack/medical/ointment{pixel_y = 10},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "yellowfull"; dir = 8},/area/engine/engineering_supply) -"bXz" = (/obj/structure/closet/wardrobe/engineering_yellow,/turf/simulated/floor{dir = 4; icon_state = "whiteyellowfull"},/area/engine/engineering_supply) -"bXA" = (/obj/structure/closet/wardrobe/atmospherics_yellow,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor{icon_state = "yellowfull"; dir = 8},/area/engine/engineering_supply) +"bXu" = (/obj/structure/closet/wardrobe/atmospherics_yellow,/turf/simulated/floor{icon_state = "yellowfull"; dir = 8},/area/crew_quarters/sleep/engi_wash) +"bXv" = (/obj/structure/sign/fire{pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/obj/machinery/atmospherics/binary/pump{dir = 4},/turf/simulated/floor/engine,/area/rnd/mixing) +"bXw" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "specops_dock_airlock"; pixel_x = 0; pixel_y = 30; req_one_access = list(13); tag_airpump = "specops_dock_pump"; tag_chamber_sensor = "specops_dock_sensor"; tag_exterior_door = "specops_dock_outer"; tag_interior_door = "specops_dock_inner"},/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "specops_dock_sensor"; pixel_x = 0; pixel_y = -25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "specops_dock_pump"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) +"bXx" = (/obj/machinery/atm{pixel_y = 28},/turf/simulated/floor{dir = 4; icon_state = "yellowpatch"},/area/engineering/foyer) +"bXy" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/crew_quarters/heads/chief) +"bXz" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engineering/foyer) +"bXA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/foyer) "bXB" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"; pixel_x = 32},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/engineering) "bXC" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor,/area/medical/sleeper) "bXD" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{dir = 2; icon_state = "redcorner"},/area/medical/sleeper) @@ -5300,21 +5302,21 @@ "bXX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/patient_wing) "bXY" = (/turf/simulated/wall/r_wall,/area/maintenance/substation/research) "bXZ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/substation/research) -"bYa" = (/obj/machinery/door/airlock/maintenance{name = "Miscellaneous Reseach Maintenance"; req_access_txt = "47"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/substation/research) +"bYa" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_dock_outer"; locked = 1; name = "Docking Port Airlock"; req_access = list(13)},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "bYb" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/research_port) "bYc" = (/turf/simulated/wall,/area/maintenance/substation/research) "bYd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/research_port) -"bYe" = (/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Research Substation"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/maintenance/substation/research) +"bYe" = (/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor{dir = 2; icon_state = "yellowpatch"},/area/engineering/foyer) "bYf" = (/turf/simulated/wall,/area/maintenance/research_port) "bYg" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"; pixel_x = -32},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/research_port) "bYh" = (/obj/machinery/atmospherics/binary/pump{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bYi" = (/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green,/obj/machinery/power/sensor{name = "Powernet Sensor - Research Subgrid"; name_tag = "Research Subgrid"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/substation/research) -"bYj" = (/obj/machinery/power/breakerbox/activated{RCon_tag = "Research Substation Bypass"},/obj/machinery/camera{c_tag = "Research Substation"; dir = 2; network = list("SS13","Engineering")},/turf/simulated/floor/plating,/area/maintenance/substation/research) +"bYj" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/engineering/foyer) "bYk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_port) "bYl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/maintenance/research_port) "bYm" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bYn" = (/obj/machinery/light_switch{pixel_x = 7; pixel_y = -23},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) -"bYo" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "hazard door east"},/obj/machinery/door/airlock/research{name = "Miscellaneous Reseach Room"; req_access_txt = "47"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) +"bYo" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plating,/area/maintenance/locker) "bYp" = (/obj/machinery/light,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bYq" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bYr" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) @@ -5322,9 +5324,9 @@ "bYt" = (/obj/machinery/camera{c_tag = "Research Division South"; dir = 1; network = list("SS13","Research"); pixel_x = 0},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bYu" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "bYv" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/rnd/research) -"bYw" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/window/eastright{dir = 8; name = "Chemistry Desk"; req_access_txt = "33"},/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "chemcounter"; name = "Pharmacy Counter Shutters"; opacity = 0},/obj/structure/table/reinforced,/turf/simulated/floor{icon_state = "yellowfull"; dir = 8},/area/medical/chemistry) -"bYx" = (/obj/structure/sign/fire{pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/obj/machinery/atmospherics/binary/pump{dir = 8},/turf/simulated/floor/engine,/area/rnd/mixing) -"bYy" = (/obj/machinery/meter,/obj/machinery/door_control{id = "mixvent"; name = "Mixing Room Vent Control"; pixel_x = -25; pixel_y = 5; req_access_txt = "7"},/obj/machinery/ignition_switch{id = "mixingsparker"; pixel_x = -25; pixel_y = -5},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warnwhitecorner"},/area/rnd/mixing) +"bYw" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/locker) +"bYx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engineering/break_room) +"bYy" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/supermatter_engine{pixel_x = -3},/turf/simulated/floor/carpet,/area/engineering/break_room) "bYz" = (/obj/machinery/atmospherics/valve{dir = 4},/obj/machinery/light,/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -29},/turf/simulated/floor{dir = 4; icon_state = "warnwhite"},/area/rnd/mixing) "bYA" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/rnd/mixing) "bYB" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 6; icon_state = "intact"; tag = "icon-intact-f (SOUTHEAST)"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/maintenance/research_starboard) @@ -5333,7 +5335,7 @@ "bYE" = (/obj/machinery/light/small,/turf/simulated/floor/plating,/area/maintenance/cargo) "bYF" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/wall,/area/maintenance/cargo) "bYG" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating,/area/maintenance/cargo) -"bYH" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/maintenance/cargo) +"bYH" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/locker) "bYI" = (/turf/simulated/wall/r_wall,/area/crew_quarters/heads/chief) "bYJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/crew_quarters/heads/chief) "bYK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/crew_quarters/heads/chief) @@ -5342,25 +5344,25 @@ "bYN" = (/obj/structure/table/reinforced,/obj/machinery/light{dir = 1},/obj/machinery/light_switch{pixel_x = 0; pixel_y = 27},/obj/machinery/computer/skills{icon_state = "medlaptop"},/turf/simulated/floor,/area/crew_quarters/heads/chief) "bYO" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/crew_quarters/heads/chief) "bYP" = (/obj/machinery/alarm{pixel_y = 23},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/crew_quarters/heads/chief) -"bYQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/hallway/primary/aft) -"bYR" = (/obj/machinery/atm{pixel_y = 28},/turf/simulated/floor{dir = 4; icon_state = "yellowpatch"},/area/hallway/primary/aft) -"bYS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/aft) -"bYT" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/primary/aft) -"bYU" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/aft) -"bYV" = (/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor{dir = 2; icon_state = "yellowpatch"},/area/hallway/primary/aft) -"bYW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/aft) -"bYX" = (/obj/structure/stool/bed/chair/comfy/beige{tag = "icon-comfychair (EAST)"; icon_state = "comfychair"; dir = 4},/obj/effect/landmark/start{name = "Station Engineer"},/turf/simulated/floor/carpet,/area/engine/break_room) -"bYY" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/supermatter_engine{pixel_x = -3},/turf/simulated/floor/carpet,/area/engine/break_room) -"bYZ" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/turf/simulated/floor/carpet,/area/engine/break_room) -"bZa" = (/obj/structure/stool/bed/chair/comfy/beige{dir = 8},/obj/effect/landmark/start{name = "Atmospheric Technician"},/turf/simulated/floor/carpet,/area/engine/break_room) -"bZb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/carpet,/area/engine/break_room) -"bZc" = (/obj/machinery/door/airlock/engineering{name = "Engineering Supplies"; req_one_access_txt = "10;24;5"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "yellowfull"; dir = 8},/area/engine/break_room) -"bZd" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = -20; pixel_y = 22},/turf/simulated/floor{icon_state = "yellowfull"; dir = 8},/area/engine/engineering_supply) -"bZe" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteyellowfull"},/area/engine/engineering_supply) -"bZf" = (/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/light,/obj/machinery/camera{c_tag = "Engineering Supplies"; dir = 1; network = list("SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteyellowfull"},/area/engine/engineering_supply) -"bZg" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "yellowfull"; dir = 8},/area/engine/engineering_supply) +"bYQ" = (/obj/structure/bed/chair/comfy/beige{tag = "icon-comfychair (EAST)"; icon_state = "comfychair"; dir = 4},/obj/effect/landmark/start{name = "Station Engineer"},/turf/simulated/floor/carpet,/area/engineering/break_room) +"bYR" = (/obj/structure/bed/chair/comfy/beige{dir = 8},/obj/effect/landmark/start{name = "Atmospheric Technician"},/turf/simulated/floor/carpet,/area/engineering/break_room) +"bYS" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/turf/simulated/floor/carpet,/area/engineering/break_room) +"bYT" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/locker) +"bYU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/carpet,/area/engineering/break_room) +"bYV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteyellowfull"},/area/crew_quarters/sleep/engi_wash) +"bYW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = -20; pixel_y = 22},/turf/simulated/floor{icon_state = "yellowfull"; dir = 8},/area/crew_quarters/sleep/engi_wash) +"bYX" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "yellowfull"; dir = 8},/area/crew_quarters/sleep/engi_wash) +"bYY" = (/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteyellowfull"},/area/crew_quarters/sleep/engi_wash) +"bYZ" = (/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "psych"; name = "Mental Health Privacy Shutters"; opacity = 0},/obj/structure/window/reinforced/polarized,/obj/structure/window/reinforced/polarized{dir = 8},/obj/structure/window/reinforced/polarized{dir = 1},/turf/simulated/floor/plating,/area/medical/medbay4) +"bZa" = (/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "psych"; name = "Mental Health Privacy Shutters"; opacity = 0},/obj/structure/window/reinforced/polarized,/obj/structure/window/reinforced/polarized{dir = 1},/obj/structure/window/reinforced/polarized{dir = 4},/turf/simulated/floor/plating,/area/medical/medbay4) +"bZb" = (/obj/structure/grille,/obj/structure/window/reinforced/polarized{id = "isoC_window_tint"},/obj/structure/window/reinforced/polarized{dir = 4; id = "isoC_window_tint"},/obj/structure/window/reinforced/polarized{dir = 1; id = "isoC_window_tint"},/obj/structure/window/reinforced/polarized{dir = 8; id = "isoC_window_tint"},/turf/simulated/floor/plating,/area/medical/patient_c) +"bZc" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_dock_inner"; locked = 1; name = "Docking Port Airlock"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) +"bZd" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = -29},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) +"bZe" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/wall/r_wall,/area/rnd/mixing) +"bZf" = (/turf/simulated/wall/r_wall,/area/maintenance/atmos_control) +"bZg" = (/turf/simulated/wall,/area/maintenance/atmos_control) "bZh" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/maintenance/engineering) -"bZi" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Medbay Diagnostics Maintenance Access"; req_access_txt = "5"},/turf/simulated/floor/plating,/area/medical/sleeper) +"bZi" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "specops_dock_airlock"; name = "interior access button"; pixel_x = -30; pixel_y = 25; req_one_access = list(13)},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/simulated/floor,/area/hallway/secondary/entry/aft) "bZj" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor,/area/medical/sleeper) "bZk" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor,/area/medical/sleeper) "bZl" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/medical/sleeper) @@ -5369,27 +5371,27 @@ "bZo" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) "bZp" = (/obj/structure/disposalpipe/junction{dir = 1; icon_state = "pipe-j2"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) "bZq" = (/obj/structure/sign/greencross,/turf/simulated/wall,/area/medical/medbay4) -"bZr" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Patient Ward"; req_access_txt = "0"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) -"bZs" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Mental Health"; req_access_txt = "0"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) +"bZr" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/light/small{dir = 1},/obj/structure/cable/cyan{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc/super/equipment{dir = 1; name = "north bump"; pixel_y = 24},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) +"bZs" = (/obj/machinery/door/window{dir = 2; name = "AI Core Door"; req_access = list(109)},/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/cyan{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/flasher{id = "AI"; pixel_x = 22; pixel_y = 24},/obj/machinery/turretid/stun{check_synth = 1; name = "AI Chamber turret control"; pixel_x = 36; pixel_y = 24},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "bZt" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/hallway/primary/starboard) -"bZu" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/weapon/folder/white,/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/window/eastright{base_state = "left"; dir = 2; icon_state = "left"; name = "Robotics Desk"; req_access_txt = "29"},/turf/simulated/floor/plating,/area/hallway/primary/starboard) +"bZu" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Morgue"; req_access = list(6)},/turf/simulated/floor,/area/hallway/primary/starboard) "bZv" = (/obj/machinery/camera{c_tag = "Medbay Patient Hallway - Port"; dir = 4; network = list("SS13")},/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) "bZw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/research_port) "bZx" = (/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) "bZy" = (/turf/simulated/wall,/area/medical/biostorage) -"bZz" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Secondary Storage"; req_access_txt = "5"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "dark"},/area/medical/medbay2) +"bZz" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{req_one_access = list(5,12,47)},/turf/simulated/floor/plating,/area/hallway/primary/starboard) "bZA" = (/turf/simulated/wall,/area/medical/patient_c) -"bZB" = (/obj/structure/table/reinforced,/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/window/southright{name = "Research and Development Desk"; req_access_txt = "7"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor/plating,/area/hallway/primary/starboard) -"bZC" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Sub-Acute C"; req_access_txt = "0"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_c) +"bZB" = (/obj/machinery/door/airlock/maintenance{name = "Maintenance Access"; req_access = list(12)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hallway/secondary/exit) +"bZC" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "Disposal Access"; req_access = list(12)},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/disposal) "bZD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_port) "bZE" = (/obj/machinery/light,/obj/machinery/atmospherics/portables_connector{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bZF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_port) "bZG" = (/obj/structure/sign/securearea{pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"bZH" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"bZH" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/wall,/area/maintenance/atmos_control) "bZI" = (/obj/machinery/disposal,/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/structure/disposalpipe/trunk{dir = 8},/obj/machinery/camera{c_tag = "Telescience Control Room"; dir = 1; network = list("SS13","Research"); pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bZJ" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/structure/closet/bombcloset,/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) "bZK" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/light,/obj/machinery/suit_storage_unit/standard_unit,/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab) -"bZL" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/airlock/research{name = "Mech Bay"; req_access_txt = "29"; req_one_access_txt = "0"},/turf/simulated/floor,/area/hallway/primary/starboard) +"bZL" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/crew_quarters/locker) "bZM" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/door/blast/shutters{dir = 2; id = "Skynet_launch"; name = "Mech Bay"},/turf/simulated/floor{icon_state = "delivery"},/area/hallway/primary/starboard) "bZN" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "medbayquar"; name = "Medbay Emergency Quarantine Shutters"; opacity = 0},/turf/simulated/floor{tag = "icon-whiteblue (NORTHWEST)"; icon_state = "whiteblue"; dir = 9},/area/hallway/primary/starboard) "bZO" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/research_starboard) @@ -5397,40 +5399,40 @@ "bZQ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/obj/machinery/meter,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/maintenance/research_starboard) "bZR" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/research_starboard) "bZS" = (/obj/structure/lattice,/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/space,/area/space) -"bZT" = (/turf/simulated/wall/r_wall,/area/engine/engine_eva_maintenance) -"bZU" = (/turf/simulated/wall,/area/engine/engine_eva_maintenance) -"bZV" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/wall,/area/engine/engine_eva_maintenance) -"bZW" = (/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "floorgrime"},/area/engine/engine_eva_maintenance) -"bZX" = (/obj/machinery/space_heater,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor{icon_state = "floorgrime"},/area/engine/engine_eva_maintenance) +"bZT" = (/obj/machinery/space_heater,/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/atmos_control) +"bZU" = (/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/atmos_control) +"bZV" = (/obj/machinery/button/driver{id = "enginecore"; name = "Emergency Core Eject"; pixel_x = -20; pixel_y = 0},/obj/structure/window/basic{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/heads/chief) +"bZW" = (/obj/structure/bed/chair/office/light{dir = 4},/obj/effect/landmark/start{name = "Chief Engineer"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/crew_quarters/heads/chief) +"bZX" = (/obj/structure/bed/chair{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/crew_quarters/heads/chief) "bZY" = (/obj/structure/table/reinforced,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd,/turf/simulated/floor{dir = 8; icon_state = "neutralfull"},/area/crew_quarters/heads/chief) "bZZ" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/crew_quarters/heads/chief) -"caa" = (/obj/machinery/driver_button{id = "enginecore"; name = "Emergency Core Eject"; pixel_x = -20; pixel_y = 0},/obj/structure/window/basic{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/heads/chief) +"caa" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/engineering/foyer) "cab" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor,/area/crew_quarters/heads/chief) -"cac" = (/obj/structure/stool/bed/chair/office/light{dir = 4},/obj/effect/landmark/start{name = "Chief Engineer"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/crew_quarters/heads/chief) +"cac" = (/obj/machinery/door/window{base_state = "right"; dir = 8; icon_state = "right"; name = "AI Core Door"; req_access = list(16)},/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "cad" = (/obj/structure/table/reinforced,/obj/item/weapon/folder/yellow,/obj/item/weapon/stamp/ce,/obj/item/weapon/pen,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/flame/lighter/zippo,/obj/item/device/megaphone,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "neutralfull"},/area/crew_quarters/heads/chief) -"cae" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/crew_quarters/heads/chief) +"cae" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/engineering/foyer) "caf" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor,/area/crew_quarters/heads/chief) -"cag" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_command{name = "Chief Engineer"; req_access_txt = "56"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) -"cah" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cai" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) -"caj" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/hallway/primary/aft) -"cak" = (/obj/structure/disposalpipe/sortjunction{sortType = "CE Office"; name = "CE Office"},/turf/simulated/floor,/area/hallway/primary/aft) -"cal" = (/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cam" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/hallway/primary/aft) -"can" = (/obj/structure/table/woodentable,/obj/item/weapon/folder/yellow,/turf/simulated/floor/carpet,/area/engine/break_room) -"cao" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/snacks/chips,/turf/simulated/floor/carpet,/area/engine/break_room) -"cap" = (/obj/machinery/newscaster{pixel_x = 28; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/carpet,/area/engine/break_room) +"cag" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/foyer) +"cah" = (/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/engineering/foyer) +"cai" = (/obj/structure/disposalpipe/sortjunction{sortType = "CE Office"; name = "CE Office"},/turf/simulated/floor,/area/engineering/foyer) +"caj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engineering/break_room) +"cak" = (/obj/structure/table/woodentable,/obj/item/weapon/folder/yellow,/turf/simulated/floor/carpet,/area/engineering/break_room) +"cal" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/snacks/chips,/turf/simulated/floor/carpet,/area/engineering/break_room) +"cam" = (/obj/machinery/newscaster{pixel_x = 28; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/carpet,/area/engineering/break_room) +"can" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/machinery/iv_drip,/turf/simulated/floor,/area/medical/sleeper) +"cao" = (/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -28},/obj/structure/bed/roller,/turf/simulated/floor,/area/medical/sleeper) +"cap" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/structure/bed/chair/comfy/teal{tag = "icon-comfychair (EAST)"; icon_state = "comfychair"; dir = 4},/turf/simulated/floor{dir = 9; icon_state = "whitered"},/area/medical/ward) "caq" = (/turf/simulated/wall,/area/crew_quarters/sleep/engi_wash) "car" = (/obj/item/weapon/cigbutt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/engineering) "cas" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor{icon_state = "delivery"},/area/medical/sleeper) "cat" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = -22},/turf/simulated/floor,/area/medical/sleeper) -"cau" = (/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = -28},/obj/structure/stool/bed/roller,/turf/simulated/floor,/area/medical/sleeper) -"cav" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/turf/simulated/floor,/area/medical/sleeper) +"cau" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/structure/bed/roller,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) +"cav" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 6},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/research_starboard) "caw" = (/obj/machinery/power/apc/high{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green,/turf/simulated/floor,/area/medical/sleeper) -"cax" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{autoclose = 0; name = "Diagnostics Room"; req_access_txt = "5"},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/medbay4) +"cax" = (/obj/item/device/radio/intercom{anyai = 1; broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; pixel_x = 28; pixel_y = 5},/obj/item/device/radio/intercom{anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; pixel_x = -27; pixel_y = 4},/obj/effect/landmark/start{name = "AI"},/obj/item/device/radio/intercom{broadcasting = 1; freerange = 1; listening = 1; name = "Common Channel"; pixel_y = 25},/obj/machinery/newscaster/security_unit{pixel_x = 32; pixel_y = 32},/obj/machinery/requests_console{department = "AI"; departmentType = 5; pixel_x = -32; pixel_y = 32},/obj/structure/cable/cyan{d2 = 2; icon_state = "0-2"},/obj/machinery/door_control{desc = "A remote control-switch for the AI core maintenance door."; id = "AICore"; name = "AI Maintenance Hatch"; pixel_x = 17; pixel_y = 25; req_access = list(109)},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "cay" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) "caz" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) -"caA" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/structure/stool/bed/chair/comfy/teal{tag = "icon-comfychair (EAST)"; icon_state = "comfychair"; dir = 4},/turf/simulated/floor{dir = 9; icon_state = "whitered"},/area/medical/ward) +"caA" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "caB" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/medical/ward) "caC" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/medical/ward) "caD" = (/obj/machinery/iv_drip,/obj/machinery/light_switch{pixel_x = 22; pixel_y = 0},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{dir = 5; icon_state = "whitered"},/area/medical/ward) @@ -5439,7 +5441,7 @@ "caG" = (/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/wood,/area/medical/psych) "caH" = (/obj/structure/table/woodentable,/obj/machinery/computer/med_data/laptop,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/wood,/area/medical/psych) "caI" = (/turf/simulated/wall,/area/medical/psych) -"caJ" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) +"caJ" = (/obj/machinery/atmospherics/tvalve{dir = 4; name = "siphon switching valve"},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "caK" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) "caL" = (/obj/structure/table,/obj/item/weapon/storage/box/lights/mixed,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = 22},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) "caM" = (/obj/structure/table,/obj/machinery/computer/med_data/laptop,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{dir = 9; icon_state = "whitered"},/area/medical/patient_c) @@ -5452,65 +5454,65 @@ "caT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/meter,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor/plating,/area/maintenance/research_port) "caU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating,/area/maintenance/research_port) "caV" = (/obj/effect/decal/cleanable/cobweb2,/obj/effect/decal/cleanable/spiderling_remains,/turf/simulated/floor/plating,/area/maintenance/research_port) -"caW" = (/obj/machinery/door/firedoor/border_only{name = "hazard door south"},/obj/machinery/door/airlock/research{name = "Xenobiology Research"; req_access_txt = "47"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) +"caW" = (/obj/machinery/door/window{dir = 4; name = "AI Core Door"; req_access = list(16)},/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "caX" = (/obj/structure/table/rack{dir = 1},/obj/item/weapon/extinguisher,/obj/item/device/flashlight,/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "caY" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/research_starboard) "caZ" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/research_starboard) "cba" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/research_starboard) -"cbb" = (/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/maintenance/research_starboard) +"cbb" = (/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "cbc" = (/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/research_starboard) "cbd" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "cbe" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "cbf" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/research_starboard) "cbg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/research_starboard) "cbh" = (/obj/effect/decal/cleanable/spiderling_remains,/obj/machinery/atmospherics/valve,/turf/simulated/floor/plating,/area/maintenance/research_starboard) -"cbi" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless,/area/engine/engine_eva_maintenance) -"cbj" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "eng_eva_airlock"; name = "exterior access button"; pixel_x = 0; pixel_y = 25; req_access_txt = "13"},/turf/simulated/floor/plating/airless,/area/engine/engine_eva_maintenance) -"cbk" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eng_eva_outer"; locked = 1; name = "Engineering EVA External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/airless{icon_state = "circuit"},/area/engine/engine_eva_maintenance) -"cbl" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "eng_eva_sensor"; pixel_x = 0; pixel_y = 25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "eng_eva_pump"},/turf/simulated/floor{dir = 9; icon_state = "floorgrimecaution"},/area/engine/engine_eva_maintenance) -"cbm" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "eng_eva_pump"; tag_exterior_door = "eng_eva_outer"; frequency = 1379; id_tag = "eng_eva_airlock"; tag_interior_door = "eng_eva_inner"; name = "Engineering Airlock Console"; pixel_y = 25; req_access_txt = "13"; tag_chamber_sensor = "eng_eva_sensor"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/simulated/floor{dir = 5; icon_state = "floorgrimecaution"},/area/engine/engine_eva_maintenance) -"cbn" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eng_eva_inner"; locked = 1; name = "Engineering EVA Internal Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/engine/engine_eva_maintenance) -"cbo" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "eng_eva_airlock"; name = "interior access button"; pixel_x = 0; pixel_y = 25; req_access_txt = "13"},/turf/simulated/floor{dir = 8; icon_state = "floorgrimecaution"},/area/engine/engine_eva_maintenance) -"cbp" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "floorgrime"},/area/engine/engine_eva_maintenance) -"cbq" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/light/small{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/engine/engine_eva_maintenance) -"cbr" = (/obj/structure/closet/secure_closet/engineering_chief{req_access_txt = "0"},/obj/item/weapon/tank/emergency_oxygen/engi,/turf/simulated/floor,/area/crew_quarters/heads/chief) +"cbi" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless,/area/maintenance/atmos_control) +"cbj" = (/obj/item/weapon/storage/box/donut,/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/bridge/meeting_room) +"cbk" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/embedded_controller/radio/docking_port_multi{child_names_txt = "Airlock One;Airlock Two"; child_tags_txt = "escape_dock_north_airlock;escape_dock_south_airlock"; frequency = 1380; id_tag = "escape_dock"; pixel_x = 0; pixel_y = -25; req_one_access = list(13)},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/hallway/secondary/exit) +"cbl" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass_mining{name = "Cargo Bay"; req_access = list(31)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/quartermaster/storage) +"cbm" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "eng_eva_sensor"; pixel_x = 0; pixel_y = 25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "eng_eva_pump"},/turf/simulated/floor{dir = 9; icon_state = "floorgrimecaution"},/area/maintenance/atmos_control) +"cbn" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "admin_shuttle_dock_airlock"; name = "exterior access button"; pixel_x = 30; pixel_y = -5; req_one_access = list(13)},/turf/space,/area/space) +"cbo" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "admin_shuttle_dock_outer"; locked = 1; name = "Docking Port Airlock"; req_access = list(13)},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) +"cbp" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/light/small{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/atmos_control) +"cbq" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/atmos_control) +"cbr" = (/obj/machinery/door/airlock/research{name = "Research Division Access"; req_access = list(47)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/research) "cbs" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/crew_quarters/heads/chief) -"cbt" = (/obj/machinery/keycard_auth{pixel_x = -24; pixel_y = 0},/obj/machinery/door_control{desc = "A remote control-switch for engine core."; id = "EngineVent"; name = "Engine Ventillatory Control"; pixel_x = -24; pixel_y = 10; req_access_txt = "10"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door_control{desc = "A remote control-switch for the engine core airlock hatch bolts."; id = "engine_access_hatch"; name = "Engine Hatch Bolt Control"; normaldoorcontrol = 1; pixel_x = -24; pixel_y = -10; req_access_txt = "10"; specialfunctions = 4},/turf/simulated/floor,/area/crew_quarters/heads/chief) +"cbt" = (/obj/machinery/door/window/eastright{base_state = "left"; dir = 8; icon_state = "left"; name = "Medical Reception"; req_access = list(5)},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/medical/reception) "cbu" = (/obj/structure/table/reinforced,/obj/machinery/photocopier/faxmachine{department = "Chief Engineer's Office"},/turf/simulated/floor,/area/crew_quarters/heads/chief) "cbv" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/clothing/glasses/meson{pixel_y = 4},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/clothing/glasses/welding/superior,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/book/manual/supermatter_engine,/turf/simulated/floor{dir = 8; icon_state = "neutralfull"},/area/crew_quarters/heads/chief) "cbw" = (/obj/machinery/hologram/holopad,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/crew_quarters/heads/chief) "cbx" = (/obj/structure/disposalpipe/segment,/obj/machinery/firealarm{dir = 4; layer = 3.3; pixel_x = 26},/turf/simulated/floor,/area/crew_quarters/heads/chief) -"cby" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/hallway/primary/aft) -"cbz" = (/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cbA" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cbB" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Break Room"; req_one_access_txt = "10;24;5"},/turf/simulated/floor,/area/hallway/primary/aft) -"cbC" = (/obj/structure/stool/bed/chair/comfy/beige{tag = "icon-comfychair (NORTH)"; icon_state = "comfychair"; dir = 1},/obj/effect/landmark/start{name = "Station Engineer"},/turf/simulated/floor/carpet,/area/engine/break_room) -"cbD" = (/obj/structure/stool/bed/chair/comfy/beige{tag = "icon-comfychair (NORTH)"; icon_state = "comfychair"; dir = 1},/obj/effect/landmark/start{name = "Atmospheric Technician"},/turf/simulated/floor/carpet,/area/engine/break_room) -"cbE" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/camera{c_tag = "Engineering Break Room"; dir = 8; network = list("SS13")},/turf/simulated/floor/carpet,/area/engine/break_room) +"cby" = (/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/engineering/foyer) +"cbz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/crew_quarters/heads/chief) +"cbA" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/engineering/foyer) +"cbB" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Chemistry Laboratory"; req_access = list(33)},/obj/structure/sign/chemistry{pixel_x = 32},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) +"cbC" = (/obj/structure/bed/chair/comfy/beige{tag = "icon-comfychair (NORTH)"; icon_state = "comfychair"; dir = 1},/obj/effect/landmark/start{name = "Station Engineer"},/turf/simulated/floor/carpet,/area/engineering/break_room) +"cbD" = (/obj/structure/bed/chair/comfy/beige{tag = "icon-comfychair (NORTH)"; icon_state = "comfychair"; dir = 1},/obj/effect/landmark/start{name = "Atmospheric Technician"},/turf/simulated/floor/carpet,/area/engineering/break_room) +"cbE" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/camera{c_tag = "Engineering Break Room"; dir = 8; network = list("SS13")},/turf/simulated/floor/carpet,/area/engineering/break_room) "cbF" = (/obj/structure/mirror{pixel_y = 32},/obj/structure/sink{pixel_y = 16},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) "cbG" = (/obj/structure/mirror{pixel_y = 32},/obj/structure/sink{pixel_y = 16},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) "cbH" = (/obj/structure/urinal{pixel_y = 32},/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) "cbI" = (/turf/simulated/wall,/area/medical/surgeryobs) "cbJ" = (/obj/machinery/camera{c_tag = "Medbay Surgery Access"; dir = 4; network = list("SS13")},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) -"cbK" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) -"cbL" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{pixel_x = -26},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/ward) +"cbK" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) +"cbL" = (/obj/structure/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{pixel_x = -26},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/ward) "cbM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/ward) "cbN" = (/turf/simulated/floor{icon_state = "white"},/area/medical/ward) -"cbO" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0; req_access_txt = "0"},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/ward) +"cbO" = (/obj/machinery/door/airlock/medical{name = "Morgue"; req_access = list(6,5)},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/medical/medbay2) "cbP" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/wood,/area/medical/psych) -"cbQ" = (/obj/structure/table/woodentable,/obj/machinery/light_switch{pixel_x = -4},/obj/machinery/door_control{id = "psych"; name = "Mental Health Privacy Shutters Control"; pixel_x = 6; pixel_y = 0},/turf/simulated/floor/wood,/area/medical/psych) -"cbR" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/wood,/area/medical/psych) +"cbQ" = (/obj/structure/table/woodentable,/obj/machinery/light_switch{pixel_x = -4},/obj/machinery/button/windowtint{pixel_x = 3},/turf/simulated/floor/wood,/area/medical/psych) +"cbR" = (/obj/structure/bed/chair/office/dark{dir = 1},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor/wood,/area/medical/psych) "cbS" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) "cbT" = (/obj/structure/closet/crate{icon_state = "crateopen"; name = "Grenade Crate"; opened = 1},/obj/item/weapon/grenade/chem_grenade,/obj/item/weapon/grenade/chem_grenade,/obj/item/weapon/grenade/chem_grenade,/obj/item/weapon/grenade/chem_grenade,/obj/item/device/assembly/igniter,/obj/item/device/assembly/igniter,/obj/item/device/assembly/igniter,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/obj/item/device/assembly/timer,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) -"cbU" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/structure/stool/bed/chair/office/dark{dir = 1},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/patient_c) +"cbU" = (/obj/structure/bed/roller,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) "cbV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_c) -"cbW" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0; req_access_txt = "0"},/obj/machinery/camera{c_tag = "Medbay Patient C"; dir = 8; network = list("SS13")},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/patient_c) +"cbW" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/structure/bed/chair/office/dark{dir = 1},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/patient_c) "cbX" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/substation/research) "cbY" = (/obj/structure/cable/green,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/substation/research) "cbZ" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/maintenance/substation/research) "cca" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_port) "ccb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/patient_wing) -"ccc" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/engineering{name = "Science Substation"; req_access_txt = "0"; req_one_access_txt = "11;24;47"},/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/substation/research) +"ccc" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Examination Room"; req_access = list(5)},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2) "ccd" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall,/area/maintenance/substation/research) "cce" = (/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/simulated/floor/plating,/area/maintenance/research_port) "ccf" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/medical/patient_wing) @@ -5521,50 +5523,50 @@ "cck" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/research_port) "ccl" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_port) "ccm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plating,/area/maintenance/research_port) -"ccn" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Virology Access"; req_access_txt = "39"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/medical/virologyaccess) +"ccn" = (/obj/machinery/door/window/eastright{name = "Medical Reception"; req_access = list(5)},/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = -22},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/medical/reception) "cco" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/research_port) "ccp" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/research_port) -"ccq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"ccr" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;47"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/rnd/xenobiology) -"ccs" = (/obj/machinery/light/small,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_starboard) +"ccq" = (/obj/machinery/door/airlock{name = "Private Restroom"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/captain) +"ccr" = (/obj/machinery/door/airlock/command{name = "Head of Personnel"; req_access = list(57)},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/maintenance/substation/command) +"ccs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/patient_wing) "cct" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_starboard) -"ccu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/research_starboard) +"ccu" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/door/airlock/glass_mining{name = "Cargo Bay"; req_access = list(31)},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/quartermaster/storage) "ccv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/research_starboard) "ccw" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "ccx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "ccy" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/maintenance/research_starboard) "ccz" = (/obj/structure/table/rack,/obj/item/clothing/mask/gas,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/maintenance/research_starboard) -"ccA" = (/turf/simulated/floor/plating/airless,/area/engine/engine_eva_maintenance) -"ccB" = (/obj/machinery/light/small,/turf/simulated/floor{dir = 10; icon_state = "floorgrimecaution"},/area/engine/engine_eva_maintenance) -"ccC" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "eng_eva_pump"},/obj/machinery/camera{c_tag = "Engineering EVA Airlock"; dir = 1},/turf/simulated/floor{dir = 6; icon_state = "floorgrimecaution"},/area/engine/engine_eva_maintenance) -"ccD" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "floorgrimecaution"},/area/engine/engine_eva_maintenance) -"ccE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/engine/engine_eva_maintenance) -"ccF" = (/obj/structure/disposalpipe/segment,/obj/structure/extinguisher_cabinet{pixel_x = 25},/turf/simulated/floor/plating,/area/engine/engine_eva_maintenance) +"ccA" = (/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Substation - Research"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/maintenance/substation/research) +"ccB" = (/obj/machinery/power/breakerbox/activated{RCon_tag = "Research Substation Bypass"},/turf/simulated/floor/plating,/area/maintenance/substation/research) +"ccC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"ccD" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"ccE" = (/obj/machinery/light/small,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_starboard) +"ccF" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_mining{name = "Delivery Office"; req_access = list(50)},/turf/simulated/floor,/area/quartermaster/office) "ccG" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/mask/breath,/obj/item/weapon/rig/ce,/turf/simulated/floor{dir = 8; icon_state = "neutralfull"},/area/crew_quarters/heads/chief) "ccH" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/crew_quarters/heads/chief) "ccI" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/crew_quarters/heads/chief) -"ccJ" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_command{name = "Chief Engineer"; req_access_txt = "56"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/crew_quarters/heads/chief) +"ccJ" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "admin_shuttle_dock_inner"; locked = 1; name = "Docking Port Airlock"; req_access = list(13)},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) "ccK" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/crew_quarters/heads/chief) "ccL" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Chief Engineer's Desk"; departmentType = 6; name = "Chief Engineer RC"; pixel_x = 0; pixel_y = -34},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/crew_quarters/heads/chief) "ccM" = (/obj/machinery/camera{c_tag = "Chief Engineer's Office"; dir = 1; network = list("SS13")},/obj/item/device/radio/intercom{layer = 4; name = "Station Intercom (General)"; pixel_y = -29},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/crew_quarters/heads/chief) "ccN" = (/obj/machinery/newscaster{layer = 3.3; pixel_x = 0; pixel_y = -27},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/crew_quarters/heads/chief) "ccO" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor,/area/crew_quarters/heads/chief) -"ccP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/hallway/primary/aft) -"ccQ" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"ccR" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/aft) -"ccS" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 2; name = "Engineering Break Room"; sortType = "Engineering Break Room"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) -"ccT" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"ccU" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Break Room"; req_one_access_txt = "10;24;5"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) -"ccV" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/engine/break_room) -"ccW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor/carpet,/area/engine/break_room) -"ccX" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/engine/break_room) -"ccY" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/engine/break_room) -"ccZ" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/engine/break_room) -"cda" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/carpet,/area/engine/break_room) -"cdb" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/engineering{name = "Engineering Washroom"; req_one_access_txt = "10;24;5"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/break_room) +"ccP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 9},/turf/simulated/floor/plating,/area/maintenance/research_starboard) +"ccQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_starboard) +"ccR" = (/obj/machinery/door_control{desc = "A remote control switch for the medbay foyer."; id = "MedbayFoyerPort"; name = "Medbay Doors Control"; normaldoorcontrol = 1; pixel_x = -16; pixel_y = 28},/obj/structure/bed/chair/office/dark{dir = 1},/obj/effect/landmark/start{name = "Medical Doctor"},/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/medical/reception) +"ccS" = (/turf/simulated/floor/plating/airless,/area/maintenance/atmos_control) +"ccT" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "eng_eva_pump"},/obj/machinery/camera{c_tag = "Engineering EVA Airlock"; dir = 1},/turf/simulated/floor{dir = 6; icon_state = "floorgrimecaution"},/area/maintenance/atmos_control) +"ccU" = (/obj/machinery/light/small,/turf/simulated/floor{dir = 10; icon_state = "floorgrimecaution"},/area/maintenance/atmos_control) +"ccV" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "floorgrimecaution"},/area/maintenance/atmos_control) +"ccW" = (/obj/structure/disposalpipe/segment,/obj/structure/extinguisher_cabinet{pixel_x = 25},/turf/simulated/floor/plating,/area/maintenance/atmos_control) +"ccX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/atmos_control) +"ccY" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/engineering/foyer) +"ccZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/crew_quarters/heads/chief) +"cda" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/foyer) +"cdb" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/engineering/foyer) "cdc" = (/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = -20; pixel_y = -21},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) "cdd" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) -"cde" = (/obj/machinery/camera{c_tag = "Engineering Substation"; dir = 2; network = list("SS13","Engineering")},/obj/machinery/light{dir = 1},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/power/sensor{name = "Powernet Sensor - Engineering Subgrid"; name_tag = "Engineering Subgrid"},/turf/simulated/floor/plating,/area/maintenance/substation/engineering) +"cde" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/engineering/foyer) "cdf" = (/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) "cdg" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/medical/surgeryobs) "cdh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/surgeryobs) @@ -5572,10 +5574,10 @@ "cdj" = (/obj/machinery/camera{c_tag = "Medbay Surgery Observation"; network = list("SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/surgeryobs) "cdk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/surgeryobs) "cdl" = (/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = 22},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 5; icon_state = "blue"},/area/medical/surgeryobs) -"cdm" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Observation Room"; req_access_txt = "0"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) +"cdm" = (/obj/structure/table,/obj/machinery/door_control{id = "medbayrecquar"; name = "Medbay Entrance Lockdown Shutters Control"; pixel_x = 6; pixel_y = 8; req_access = list(5)},/obj/item/device/radio{anchored = 1; broadcasting = 0; canhear_range = 1; frequency = 1487; icon = 'icons/obj/items.dmi'; icon_state = "red_phone"; listening = 1; name = "Reception Emergency Phone"; pixel_x = -5},/turf/simulated/floor,/area/medical/reception) "cdn" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor{icon_state = "white_halfo"},/area/medical/medbay4) "cdo" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white_halfp"},/area/medical/medbay4) -"cdp" = (/obj/machinery/door/airlock/glass_medical{name = "Patient Ward"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) +"cdp" = (/obj/machinery/door/airlock/maintenance{name = "Cargo Bay Maintenance"; req_access = list(31)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/quartermaster/storage) "cdq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/ward) "cdr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/ward) "cds" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/medical/ward) @@ -5584,14 +5586,14 @@ "cdv" = (/turf/simulated/floor{icon_state = "bcarpet02"},/area/medical/psych) "cdw" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "bcarpet03"},/area/medical/psych) "cdx" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/light/small{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) -"cdy" = (/obj/structure/table,/obj/item/weapon/storage/box/cdeathalarm_kit,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) +"cdy" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 2; name = "Engineering Break Room"; sortType = "Engineering Break Room"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/foyer) "cdz" = (/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/structure/closet/secure_closet/personal/patient,/turf/simulated/floor{dir = 10; icon_state = "whitered"},/area/medical/patient_c) "cdA" = (/obj/machinery/light,/obj/machinery/newscaster{pixel_y = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/hologram/holopad,/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/patient_c) -"cdB" = (/obj/machinery/door_control{id = "medprivc"; name = "Privacy Shutters"; pixel_y = -25},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = -36},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{dir = 6; icon_state = "whitered"},/area/medical/patient_c) +"cdB" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/engineering/break_room) "cdC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/research_port) "cdD" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_port) "cdE" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/medical/virologyaccess) -"cdF" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/effect/landmark{name = "blobstart"},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor,/area/medical/virologyaccess) +"cdF" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass_mining{name = "Delivery Office"; req_access = list(50)},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/quartermaster/office) "cdG" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance,/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/medical/virologyaccess) "cdH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/medical/virologyaccess) "cdI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_port) @@ -5602,7 +5604,7 @@ "cdN" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "heads_meeting"; name = "Meeting Room Window Shutters"; opacity = 0},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/hallway/primary/central_one) "cdO" = (/turf/simulated/wall/r_wall,/area/rnd/xenobiology) "cdP" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/machinery/light/small,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/rnd/xenobiology) -"cdQ" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/rnd/xenobiology) +"cdQ" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/engineering/break_room) "cdR" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/machinery/light/small,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/rnd/xenobiology) "cdS" = (/turf/simulated/wall/r_wall,/area/rnd/xenobiology/xenoflora) "cdT" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "medbayrecquar"; name = "Medbay Emergency Quarantine Shutters"; opacity = 0},/turf/simulated/floor,/area/medical/reception) @@ -5610,45 +5612,45 @@ "cdV" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "medbayrecquar"; name = "Medbay Emergency Quarantine Shutters"; opacity = 0},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/medical/reception) "cdW" = (/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "medbayrecquar"; name = "Medbay Emergency Quarantine Shutters"; opacity = 0},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/medical/reception) "cdX" = (/obj/machinery/atmospherics/pipe/simple/visible{icon_state = "intact"; dir = 6},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/research_starboard) -"cdY" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "toxin_test_airlock"; name = "interior access button"; pixel_x = 20; pixel_y = 20; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/research_starboard) -"cdZ" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "toxin_test_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/research_starboard) +"cdY" = (/obj/structure/table,/obj/item/weapon/aiModule/asimov,/obj/item/weapon/aiModule/freeformcore,/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Core Modules"; req_access = list(20)},/obj/structure/window/reinforced,/obj/item/weapon/aiModule/corp,/obj/item/weapon/aiModule/paladin,/obj/item/weapon/aiModule/robocop,/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) +"cdZ" = (/obj/structure/table,/obj/item/weapon/aiModule/oxygen,/obj/item/weapon/aiModule/oneHuman,/obj/machinery/door/window{base_state = "left"; dir = 8; icon_state = "left"; name = "High-Risk Modules"; req_access = list(20)},/obj/item/weapon/aiModule/purge,/obj/structure/window/reinforced,/obj/item/weapon/aiModule/antimov,/obj/item/weapon/aiModule/teleporterOffline,/turf/simulated/floor/bluegrid,/area/turret_protected/ai_upload) "cea" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "toxin_test_pump"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "toxin_test_sensor"; pixel_x = 0; pixel_y = 16},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/research_starboard) -"ceb" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "toxin_test_pump"; tag_exterior_door = "toxin_test_outer"; frequency = 1379; id_tag = "toxin_test_airlock"; tag_interior_door = "toxin_test_inner"; pixel_x = 0; pixel_y = 25; req_access_txt = "13"; tag_chamber_sensor = "toxin_test_sensor"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/maintenance/research_starboard) -"cec" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "toxin_test_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/research_starboard) +"ceb" = (/obj/machinery/door/airlock/maintenance{name = "Captain's Office Maintenance"; req_access = list(20)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/supply,/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor/plating,/area/crew_quarters/captain) +"cec" = (/obj/machinery/door/airlock/command{name = "Captain's Quarters"; req_access = list(20)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/carpet,/area/crew_quarters/captain) "ced" = (/obj/machinery/conveyor{dir = 1; id = "garbage"},/obj/machinery/door/blast/regular{density = 1; icon_state = "pdoor1"; id = "Disposal Exit"; name = "Disposal Exit Vent"; opacity = 1},/turf/simulated/floor/plating,/area/maintenance/disposal) -"cee" = (/obj/machinery/door/blast/regular{desc = "For use by authorized NanoTrasen AI maintenance technicians or in case of emergency only."; id = "AI Door"; name = "AI Chamber Maintenance Door"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/turret_protected/ai) -"cef" = (/obj/machinery/door/airlock/external{name = "Toxins Test Chamber"; req_access_txt = "0"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating/airless,/area/rnd/test_area) +"cee" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor/carpet,/area/engineering/break_room) +"cef" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "admin_shuttle_dock_airlock"; pixel_x = 0; pixel_y = 30; req_one_access = list(13); tag_airpump = "admin_shuttle_dock_pump"; tag_chamber_sensor = "admin_shuttle_dock_sensor"; tag_exterior_door = "admin_shuttle_dock_outer"; tag_interior_door = "admin_shuttle_dock_inner"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1; icon_state = "map"; tag = "icon-manifold-f (NORTH)"},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/hallway/secondary/entry/aft) "ceg" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating/airless,/area/rnd/test_area) "ceh" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating/airless,/area/rnd/test_area) "cei" = (/obj/machinery/camera{c_tag = "Toxins Test Chamber South"; dir = 1; network = list("Toxins Test Area")},/obj/machinery/light,/turf/simulated/floor/airless,/area/rnd/test_area) "cej" = (/turf/simulated/wall,/area/construction) -"cek" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/engine/engine_eva_maintenance) -"cel" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/disposalpipe/segment,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/engine/engine_eva_maintenance) -"cem" = (/turf/simulated/wall/r_wall,/area/engine/engine_eva) -"cen" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/engine/engine_eva) -"ceo" = (/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/hallway/primary/aft) -"cep" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/hallway/primary/aft) -"ceq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced,/obj/structure/cable/green,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/primary/aft) -"cer" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"ces" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cet" = (/obj/structure/stool/bed/chair/office/dark,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engine/break_room) -"ceu" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engine/break_room) -"cev" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engine/break_room) -"cew" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engine/break_room) -"cex" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engine/break_room) -"cey" = (/obj/structure/noticeboard{pixel_x = 32; pixel_y = 0},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engine/break_room) +"cek" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/engineering/break_room) +"cel" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/engineering/break_room) +"cem" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "admin_shuttle_dock_airlock"; name = "interior access button"; pixel_x = -8; pixel_y = 25; req_one_access = list(13)},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/hallway/secondary/entry/aft) +"cen" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/carpet,/area/engineering/break_room) +"ceo" = (/obj/machinery/iv_drip,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) +"cep" = (/obj/structure/table,/obj/item/weapon/storage/box/cdeathalarm_kit,/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/bodybag/cryobag{pixel_x = -3},/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) +"ceq" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/table,/obj/item/weapon/clipboard,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = -36},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/machinery/button/windowtint{id = "isoC_window_tint"; pixel_y = -26},/turf/simulated/floor{dir = 6; icon_state = "whitered"},/area/medical/patient_c) +"cer" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/rnd/xenobiology) +"ces" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "admin_shuttle_dock_inner"; locked = 1; name = "Docking Port Airlock"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/aft) +"cet" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/disposalpipe/segment,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/maintenance/atmos_control) +"ceu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/atmos_control) +"cev" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/crew_quarters/heads/chief) +"cew" = (/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/crew_quarters/heads/chief) +"cex" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/engineering/foyer) +"cey" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced,/obj/structure/cable/green,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/crew_quarters/heads/chief) "cez" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) "ceA" = (/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/maintenance/substation/engineering) "ceB" = (/obj/machinery/door/airlock/medical{autoclose = 0; icon_state = "door_open"; id_tag = "engineering_cubicle"; name = "Restroom"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) -"ceC" = (/obj/machinery/door/airlock/engineering{name = "Engineering Substation"; req_access_txt = "0"; req_one_access_txt = "11;24"},/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/substation/engineering) +"ceC" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/syringes,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/item/weapon/screwdriver,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry) "ceD" = (/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/surgeryobs) -"ceE" = (/obj/structure/stool/bed/chair,/turf/simulated/floor,/area/medical/surgeryobs) +"ceE" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/engineering/foyer) "ceF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "bluecorner"},/area/medical/surgeryobs) "ceG" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green,/turf/simulated/floor{icon_state = "blue"; dir = 6},/area/medical/surgeryobs) -"ceH" = (/obj/machinery/door/firedoor,/obj/machinery/holosign/surgery,/obj/machinery/door/airlock/glass_medical{id_tag = "Surgery"; name = "Pre-Op Prep Room"; req_access_txt = "5"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) -"ceI" = (/obj/machinery/door/firedoor,/obj/structure/disposalpipe/segment,/obj/machinery/holosign/surgery,/obj/machinery/door/airlock/glass_medical{id_tag = "Surgery"; name = "Pre-Op Prep Room"; req_access_txt = "5"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay4) +"ceH" = (/obj/structure/table,/obj/machinery/door/window/northright{name = "Medbay Lobby"; req_access = list(5)},/obj/item/weapon/reagent_containers/spray/cleaner{pixel_x = -5},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/reception) +"ceI" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_y = -10},/obj/item/weapon/folder/white{pixel_y = 0},/obj/item/weapon/pen,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 16},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room) "ceJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/ward) -"ceK" = (/obj/structure/closet/secure_closet{name = "Psychiatrist's Locker"; req_access = null; req_access_txt = "64"},/obj/item/clothing/suit/straight_jacket{layer = 3},/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/pill/methylphenidate,/obj/item/weapon/reagent_containers/pill/citalopram,/obj/item/weapon/reagent_containers/pill/citalopram,/obj/item/weapon/reagent_containers/pill/methylphenidate,/obj/item/weapon/reagent_containers/syringe,/turf/simulated/floor{icon_state = "bcarpet04"},/area/medical/psych) +"ceK" = (/obj/structure/table,/obj/machinery/door/window/northright{name = "Medbay Lobby"; req_access = list(5)},/obj/item/device/radio/intercom{broadcasting = 0; canhear_range = 5; freerange = 0; frequency = 1485; listening = 0; name = "Station Intercom (Medbay)"; pixel_x = 0; pixel_y = 3},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/reception) "ceL" = (/turf/simulated/floor{icon_state = "bcarpet05"},/area/medical/psych) "ceM" = (/obj/structure/bookcase,/turf/simulated/floor{icon_state = "bcarpet06"},/area/medical/psych) "ceN" = (/obj/machinery/vending/medical,/turf/simulated/floor{icon_state = "white"},/area/medical/patient_wing) @@ -5656,27 +5658,27 @@ "ceP" = (/obj/structure/closet/l3closet,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/suit/bio_suit/general,/obj/item/clothing/suit/bio_suit/general,/obj/item/clothing/suit/bio_suit/general,/obj/item/clothing/mask/gas,/obj/item/clothing/head/bio_hood/general,/obj/item/clothing/head/bio_hood/general,/obj/item/clothing/head/bio_hood/general,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) "ceQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/research_port) "ceR" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/structure/mirror{pixel_x = 32},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/patient_wing) -"ceS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/research_port) -"ceT" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/engine/locker_room) -"ceU" = (/turf/simulated/wall,/area/engine/locker_room) +"ceS" = (/obj/structure/bed/chair/office/dark,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engineering/break_room) +"ceT" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engineering/break_room) +"ceU" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engineering/break_room) "ceV" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/maintenance/substation/engineering) -"ceW" = (/obj/structure/table,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor,/area/engine/locker_room) -"ceX" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table,/obj/machinery/camera{c_tag = "Engineering Washroom"; dir = 1; network = list("SS13")},/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor,/area/engine/locker_room) -"ceY" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/engine/locker_room) +"ceW" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engineering/break_room) +"ceX" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engineering/break_room) +"ceY" = (/obj/structure/noticeboard{pixel_x = 32; pixel_y = 0},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engineering/break_room) "ceZ" = (/obj/structure/table,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/item/weapon/hand_labeler,/turf/simulated/floor{tag = "icon-whitegreen (NORTHWEST)"; icon_state = "whitegreen"; dir = 9},/area/rnd/xenobiology/xenoflora_storage) -"cfa" = (/obj/structure/closet/crate/hydroponics/prespawned,/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora_storage) +"cfa" = (/obj/machinery/light,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) "cfb" = (/obj/structure/closet/secure_closet/hydroponics{req_access = list(47)},/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora_storage) -"cfc" = (/obj/structure/closet/secure_closet/hydroponics{req_access = list(47)},/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor{tag = "icon-whitegreen_v (NORTHEAST)"; icon_state = "whitegreen_v"; dir = 5},/area/rnd/xenobiology/xenoflora_storage) +"cfc" = (/obj/structure/bed/chair,/turf/simulated/floor,/area/medical/surgeryobs) "cfd" = (/obj/structure/sign/biohazard,/turf/simulated/wall,/area/rnd/xenobiology) -"cfe" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Xenobiology Research"; req_access_txt = "47"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"cfe" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/light_switch{pixel_x = 27},/obj/machinery/smartfridge/drying_rack,/turf/simulated/floor{tag = "icon-whitegreen_v (NORTHEAST)"; icon_state = "whitegreen_v"; dir = 5},/area/rnd/xenobiology/xenoflora_storage) "cff" = (/obj/structure/sign/securearea,/turf/simulated/wall,/area/rnd/xenobiology) "cfg" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/disposalpipe/trunk,/obj/machinery/disposal,/obj/structure/sign/deathsposal{pixel_x = 0; pixel_y = 32},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) "cfh" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/hydroponics{closed_system = 1; name = "isolation tray"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology/xenoflora) -"cfi" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/light_switch{pixel_x = -6; pixel_y = 26},/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) -"cfj" = (/obj/machinery/vending/hydroseeds,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) +"cfi" = (/obj/machinery/door_control{id = "qm_warehouse"; name = "Warehouse Door Control"; pixel_x = -1; pixel_y = 24; req_access = list(31)},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/quartermaster/storage) +"cfj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/vault/bolted{name = "AI core"; req_access = list(16)},/obj/machinery/door/blast/regular{id = "AICore"; name = "AI core maintenance hatch"},/turf/simulated/floor/bluegrid,/area/turret_protected/ai) "cfk" = (/obj/machinery/vending/hydronutrients,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) "cfl" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/structure/table,/obj/item/weapon/storage/box/botanydisk,/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) -"cfm" = (/obj/machinery/botany/editor,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology/xenoflora) +"cfm" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Captain's Desk Door"; req_access = list(20)},/turf/simulated/floor/wood,/area/crew_quarters/captain) "cfn" = (/obj/machinery/botany/extractor,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology/xenoflora) "cfo" = (/obj/structure/table,/obj/machinery/reagentgrinder,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology/xenoflora) "cfp" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/smartfridge,/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) @@ -5684,33 +5686,33 @@ "cfr" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/research_starboard) "cfs" = (/obj/machinery/light/small{dir = 4},/obj/machinery/camera{c_tag = "Aft Starboard Solar Access"; dir = 1},/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/maintenance/research_starboard) "cft" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/rnd/test_area) -"cfu" = (/obj/item/clothing/mask/cigarette,/turf/simulated/floor/plating/airless,/area/rnd/test_area) +"cfu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/command{name = "Electrical Maintenance"; req_access = list(19)},/turf/simulated/floor/plating,/area/maintenance/substation/command) "cfv" = (/obj/machinery/light/small,/turf/simulated/floor/plating/airless,/area/rnd/test_area) "cfw" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/plating,/area/construction) "cfx" = (/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/plating,/area/construction) "cfy" = (/obj/structure/table,/obj/item/weapon/tank/emergency_oxygen/engi,/obj/random/tech_supply,/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/construction) "cfz" = (/obj/structure/table,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor,/area/construction) "cfA" = (/obj/structure/table,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor,/area/construction) -"cfB" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "floorgrime"},/area/engine/engine_eva_maintenance) -"cfC" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/engine/engine_eva_maintenance) -"cfD" = (/obj/structure/sign/pods,/turf/simulated/wall/r_wall,/area/engine/engine_eva) -"cfE" = (/obj/structure/dispenser{phorontanks = 0},/turf/simulated/floor,/area/engine/engine_eva) -"cfF" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/engine/engine_eva) -"cfG" = (/obj/structure/table/rack{dir = 8; layer = 2.6},/obj/item/clothing/shoes/magboots,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/void/engineering,/obj/machinery/light{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/southleft{name = "Engineering Hardsuits"; req_access_txt = "11"},/obj/item/clothing/suit/space/void/engineering,/turf/simulated/floor,/area/engine/engine_eva) -"cfH" = (/obj/item/clothing/shoes/magboots,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/void/engineering,/obj/machinery/door/window/southleft{name = "Engineering Hardsuits"; req_access_txt = "11"},/obj/structure/table/rack{dir = 8; layer = 2.6},/obj/item/clothing/suit/space/void/engineering,/turf/simulated/floor,/area/engine/engine_eva) -"cfI" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/floor{icon_state = "red"; dir = 1},/area/hallway/primary/aft) -"cfJ" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/powered/pump,/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/hallway/primary/aft) -"cfK" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/powered/pump,/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/hallway/primary/aft) -"cfL" = (/obj/machinery/newscaster{pixel_x = 31; pixel_y = 3},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cfM" = (/obj/machinery/computer/station_alert,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engine/break_room) -"cfN" = (/obj/machinery/light,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green,/obj/structure/flora/pottedplant{icon_state = "plant-20"; tag = "icon-plant-22"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engine/break_room) -"cfO" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engine/break_room) -"cfP" = (/obj/structure/table,/obj/item/weapon/storage/box/drinkingglasses{pixel_x = 1; pixel_y = 4},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engine/break_room) -"cfQ" = (/obj/machinery/light,/obj/structure/table,/obj/machinery/chem_dispenser/soda,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engine/break_room) -"cfR" = (/obj/machinery/vending/snack,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engine/break_room) +"cfB" = (/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor,/area/hallway/secondary/entry/aft) +"cfC" = (/obj/item/clothing/mask/smokable/cigarette,/turf/simulated/floor/plating/airless,/area/rnd/test_area) +"cfD" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/atmos_control) +"cfE" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/atmos_control) +"cfF" = (/obj/structure/dispenser{phorontanks = 0},/turf/simulated/floor,/area/engineering/engine_eva) +"cfG" = (/obj/structure/sign/pods,/turf/simulated/wall/r_wall,/area/engineering/engine_eva) +"cfH" = (/obj/machinery/door/airlock/maintenance{name = "Disposal Access"; req_access = list(12)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/disposal) +"cfI" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/engineering/engine_eva) +"cfJ" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/locker) +"cfK" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/floor{icon_state = "red"; dir = 1},/area/engineering/foyer) +"cfL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engineering/engine_eva) +"cfM" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/powered/pump,/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/engineering/foyer) +"cfN" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/powered/pump,/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/engineering/foyer) +"cfO" = (/obj/machinery/newscaster{pixel_x = 31; pixel_y = 3},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/engineering/foyer) +"cfP" = (/obj/machinery/computer/station_alert,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engineering/break_room) +"cfQ" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engineering/break_room) +"cfR" = (/obj/machinery/light,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green,/obj/structure/flora/pottedplant{icon_state = "plant-20"; tag = "icon-plant-22"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engineering/break_room) "cfS" = (/obj/structure/closet/secure_closet/personal,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms) "cfT" = (/obj/machinery/power/tracker,/obj/structure/cable/yellow,/turf/simulated/floor/plating/airless,/area/solar/starboard) -"cfU" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "10;24"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/maintenance/substation/engineering) +"cfU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/locker) "cfV" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/medical/surgeryobs) "cfW" = (/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/medical/surgeryobs) "cfX" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "blue"; dir = 6},/area/medical/surgeryobs) @@ -5722,133 +5724,133 @@ "cgd" = (/obj/structure/closet/secure_closet/personal/patient,/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{dir = 7; icon_state = "whitered"},/area/medical/ward) "cge" = (/obj/structure/closet/secure_closet/personal/patient,/obj/machinery/camera{c_tag = "Medbay Recovery Ward"; dir = 1; network = list("SS13")},/turf/simulated/floor{dir = 6; icon_state = "whitered"},/area/medical/ward) "cgf" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin,/obj/item/weapon/pen,/obj/machinery/camera{c_tag = "Medbay Mental Health Room"; dir = 1; network = list("SS13")},/turf/simulated/floor{icon_state = "bcarpet04"},/area/medical/psych) -"cgg" = (/obj/structure/stool/bed/chair/comfy/brown,/obj/effect/landmark/start{name = "Psychiatrist"},/turf/simulated/floor{icon_state = "bcarpet06"},/area/medical/psych) +"cgg" = (/obj/structure/table,/obj/item/weapon/storage/box/drinkingglasses{pixel_x = 1; pixel_y = 4},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engineering/break_room) "cgh" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/medical/patient_wing) -"cgi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/engine/locker_room) +"cgi" = (/obj/machinery/vending/snack,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engineering/break_room) "cgj" = (/obj/structure/table,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/medical/patient_wing) "cgk" = (/obj/item/weapon/storage/toolbox/emergency,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) "cgl" = (/obj/structure/table/rack,/obj/item/clothing/suit/radiation,/obj/item/clothing/head/radiation,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) -"cgm" = (/obj/structure/reagent_dispensers/fueltank,/obj/effect/decal/cleanable/blood/oil{amount = 0},/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/maintenance/research_port) +"cgm" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/locker) "cgn" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/patient_wing) -"cgo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/engine/locker_room) -"cgp" = (/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor,/area/engine/locker_room) +"cgo" = (/obj/structure/bed/chair/comfy/brown,/obj/effect/landmark/start{name = "Psychiatrist"},/turf/simulated/floor{icon_state = "bcarpet06"},/area/medical/psych) +"cgp" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/machinery/camera/autoname{dir = 4},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/closet/crate/hydroponics/prespawned,/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora_storage) "cgq" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/terminal{dir = 8},/turf/simulated/floor/plating,/area/maintenance/substation/engineering) -"cgr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engine/locker_room) +"cgr" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cgs" = (/turf/simulated/wall/r_wall,/area/maintenance/substation/engineering) -"cgt" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Aft Starboard Solar"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) -"cgu" = (/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Engineering Substation"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/maintenance/substation/engineering) +"cgt" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/purple{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"cgu" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/binary/pump{dir = 8; name = "Isolation to Waste"},/turf/simulated/floor{tag = "icon-whitegreen_v (SOUTHWEST)"; icon_state = "whitegreen_v"; dir = 10},/area/rnd/xenobiology/xenoflora) "cgv" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/medical/virology) "cgw" = (/obj/structure/disposalpipe/trunk{dir = 1},/obj/structure/disposaloutlet,/turf/simulated/floor/plating/airless,/area/rnd/xenobiology) -"cgx" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/machinery/camera/autoname{dir = 4},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora_storage) +"cgx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor/plating,/area/rnd/xenobiology/xenoflora) "cgy" = (/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology/xenoflora_storage) "cgz" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora_storage) "cgA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/rnd/xenobiology) -"cgB" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "co2_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/atmos) -"cgC" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1441; icon_state = "map_injector"; id = "co2_in"; use_power = 1; pixel_y = 1},/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/atmos) -"cgD" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/rnd/xenobiology/xenoflora) -"cgE" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{tag = "icon-whitegreen_v (SOUTHWEST)"; icon_state = "whitegreen_v"; dir = 10},/area/rnd/xenobiology/xenoflora) -"cgF" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) +"cgB" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor{dir = 6; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) +"cgC" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/medical{name = "Examination room"; req_access = list(5)},/turf/simulated/floor{tag = "icon-whitebluefull"; icon_state = "whitebluefull"},/area/medical/exam_room) +"cgD" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/rnd/lab) +"cgE" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) +"cgF" = (/obj/structure/grille,/turf/simulated/wall/r_wall,/area/engineering/atmos) "cgG" = (/obj/machinery/atmospherics/pipe/manifold/visible,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) -"cgH" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4},/turf/simulated/floor{dir = 6; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) +"cgH" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/atmos_control) "cgI" = (/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) "cgJ" = (/turf/simulated/floor{tag = "icon-whitegreen_v (SOUTHWEST)"; icon_state = "whitegreen_v"; dir = 10},/area/rnd/xenobiology/xenoflora) -"cgK" = (/obj/structure/stool,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) +"cgK" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/atmos_control) "cgL" = (/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) "cgM" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{dir = 6; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) "cgN" = (/turf/simulated/wall/r_wall,/area/maintenance/starboardsolar) -"cgO" = (/obj/machinery/door/airlock/engineering{name = "Aft Starboard Solar Access"; req_access_txt = "10"},/obj/machinery/atmospherics/pipe/simple/visible,/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) +"cgO" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "hazard door east"},/obj/machinery/door/airlock/glass_research{name = "Robotics Lab"; req_access = list(29)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics) "cgP" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/starboardsolar) "cgQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/rnd/test_area) -"cgR" = (/obj/structure/grille,/turf/simulated/wall/r_wall,/area/atmos) +"cgR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engineering/engine_eva) "cgS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/construction) "cgT" = (/turf/simulated/floor/plating,/area/construction) "cgU" = (/turf/simulated/floor,/area/construction) "cgV" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/table,/obj/item/clothing/gloves/black,/obj/item/device/multitool{pixel_x = 5},/obj/random/tech_supply,/turf/simulated/floor,/area/construction) -"cgW" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "floorgrime"},/area/engine/engine_eva_maintenance) -"cgX" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "floorgrime"},/area/engine/engine_eva_maintenance) -"cgY" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/engineering{name = "Engineering EVA Storage"; req_access_txt = "12"; req_one_access_txt = "11;24"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "floorgrime"},/area/engine/engine_eva) -"cgZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engine/engine_eva) -"cha" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/engine/engine_eva) -"chb" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engine/engine_eva) -"chc" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/engine_eva) -"chd" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/engine_eva) -"che" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering EVA Storage"; req_one_access_txt = "11;24"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) -"chf" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) -"chg" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) -"chh" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) -"chi" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) -"chj" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"chk" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) -"chl" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/primary/aft) -"chm" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/hallway/primary/aft) -"chn" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/camera{c_tag = "Engineering Foyer"; dir = 8; network = list("SS13")},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cho" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "waste_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) -"chp" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1441; icon_state = "map_injector"; id = "waste_in"; use_power = 1; pixel_y = 1},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) -"chq" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "n2o_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) +"cgW" = (/turf/space,/area/skipjack_station/southeast_solars) +"cgX" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engineering/engine_eva) +"cgY" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/engineering/engine_eva) +"cgZ" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/engine_eva) +"cha" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/engine_eva) +"chb" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/foyer) +"chc" = (/obj/machinery/door/airlock/maintenance_hatch{name = "SMES Access"; req_access = list(11)},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/engineering/engine_monitoring) +"chd" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/foyer) +"che" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/foyer) +"chf" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/engineering/foyer) +"chg" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/foyer) +"chh" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engineering/foyer) +"chi" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/foyer) +"chj" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/camera{c_tag = "Engineering Foyer"; dir = 8; network = list("SS13")},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/engineering/foyer) +"chk" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engineering/foyer) +"chl" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/structure/bed/chair/comfy/brown{dir = 4},/turf/simulated/floor{icon_state = "bcarpet08"},/area/medical/psych) +"chm" = (/obj/structure/bed/psych,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor{icon_state = "bcarpet09"},/area/medical/psych) +"chn" = (/obj/structure/table,/obj/item/weapon/gun/launcher/syringe,/obj/item/weapon/storage/box/syringegun,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) +"cho" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "engineering_dock_outer"; locked = 1; name = "Engineering Dock Airlock"; req_access = list(13)},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) +"chp" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"chq" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "engineering_dock_outer"; locked = 1; name = "Engineering Dock Airlock"; req_access = list(13)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "chr" = (/obj/structure/table,/obj/item/weapon/storage/box/gloves{pixel_x = 4; pixel_y = 4},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/item/weapon/storage/box/masks,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/medical/surgeryprep) "chs" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 1; icon_state = "bluecorner"},/area/medical/surgeryprep) "cht" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{dir = 4; icon_state = "blue"},/area/medical/surgeryprep) -"chu" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/structure/stool/bed/chair/comfy/brown{dir = 4},/turf/simulated/floor{icon_state = "bcarpet08"},/area/medical/psych) -"chv" = (/obj/structure/stool/bed/psych,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor{icon_state = "bcarpet09"},/area/medical/psych) +"chu" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "engineering_dock_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -8; req_one_access = list(13,11,24)},/turf/space,/area/space) +"chv" = (/obj/structure/table,/obj/item/weapon/tape_roll,/obj/item/device/analyzer/plant_analyzer,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) "chw" = (/obj/structure/sign/biohazard,/turf/simulated/wall,/area/medical/virologyaccess) "chx" = (/obj/structure/disposaloutlet,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/plating/airless,/area/medical/virology) "chy" = (/obj/structure/bedsheetbin,/obj/structure/table,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) -"chz" = (/obj/structure/table,/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/bodybag/cryobag{pixel_x = -3},/obj/item/weapon/gun/syringe,/turf/simulated/floor{icon_state = "dark"},/area/medical/biostorage) +"chz" = (/obj/machinery/door/airlock/maintenance_hatch{frequency = 1379; icon_state = "door_closed"; id_tag = "engine_airlock_exterior"; locked = 0; name = "Engine Airlock Exterior"; req_access = list(10)},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/engineering/engine_airlock) "chA" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/research_port) "chB" = (/turf/simulated/floor/plating,/area/maintenance/research_port) "chC" = (/obj/machinery/door/airlock/medical{autoclose = 0; icon_state = "door_open"; id_tag = "cubicle1"; name = "Cubicle 1"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/patient_wing) "chD" = (/obj/machinery/door/airlock/medical{autoclose = 0; icon_state = "door_open"; id_tag = "cubicle2"; name = "Cubicle 2"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/patient_wing) -"chE" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 5},/turf/simulated/floor/plating/airless,/area/medical/virology) -"chF" = (/turf/simulated/floor/plating/airless,/area/medical/virology) -"chG" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/void/atmos,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/void/atmos,/obj/machinery/door/window/northright{name = "Atmospherics Hardsuits"; req_access_txt = "24"},/turf/simulated/floor,/area/engine/engine_eva) -"chH" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/void/atmos,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/void/atmos,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/northleft{name = "Atmospherics Hardsuits"; req_access_txt = "24"},/turf/simulated/floor,/area/engine/engine_eva) +"chE" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) +"chF" = (/obj/machinery/computer/reconstitutor,/obj/machinery/light_switch{pixel_x = 26; pixel_y = -6},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) +"chG" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Solar - Aft Starboard"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) +"chH" = (/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/engineering/atmos) "chI" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora_storage) "chJ" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology/xenoflora_storage) "chK" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora_storage) -"chL" = (/obj/machinery/door/airlock/research{name = "Xenoflora Storage"; req_access_txt = "47"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"chL" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/engineering/atmos) "chM" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"chN" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"chN" = (/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/engineering/atmos) "chO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"chP" = (/obj/machinery/door/airlock/research{name = "Xenoflora Research"; req_access_txt = "47"},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology/xenoflora) +"chP" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/engineering/atmos) "chQ" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"chR" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"chS" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"chT" = (/obj/machinery/atmospherics/binary/pump{dir = 8; name = "Isolation to Waste"},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"chU" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"chV" = (/obj/structure/table,/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"chW" = (/obj/structure/table,/obj/item/weapon/tape_roll,/obj/item/device/analyzer/plant_analyzer,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"chX" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"chY" = (/obj/machinery/computer/reconstitutor,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) +"chR" = (/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/engineering/atmos) +"chS" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/engineering/atmos) +"chT" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/atmos_control) +"chU" = (/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/atmos_control) +"chV" = (/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/table/reinforced{icon_state = "table"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor,/area/engineering/engine_eva) +"chW" = (/turf/simulated/wall/r_wall,/area/engineering/engine_eva) +"chX" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/engineering/engine_eva) +"chY" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/engineering/engine_eva) "chZ" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) "cia" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) "cib" = (/obj/machinery/power/breakerbox/activated{RCon_tag = "Engineering Substation Bypass"},/turf/simulated/floor/plating,/area/maintenance/substation/engineering) -"cic" = (/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/atmos) -"cid" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/atmos) -"cie" = (/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/atmos) -"cif" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/atmos) -"cig" = (/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/atmos) -"cih" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/atmos) +"cic" = (/turf/simulated/floor,/area/engineering/engine_eva) +"cid" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/engineering/engine_eva) +"cie" = (/turf/simulated/floor,/area/engineering/foyer) +"cif" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/shuttle/constructionsite/station) +"cig" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/turf/simulated/floor,/area/engineering/foyer) +"cih" = (/obj/machinery/hologram/holopad,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engineering/foyer) "cii" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/construction) "cij" = (/obj/structure/table,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/construction) -"cik" = (/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "floorgrime"},/area/engine/engine_eva_maintenance) -"cil" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "floorgrime"},/area/engine/engine_eva_maintenance) -"cim" = (/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/table/reinforced{icon_state = "table"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor,/area/engine/engine_eva) -"cin" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/engine/engine_eva) -"cio" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/engine/engine_eva) -"cip" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/engine/engine_eva) -"ciq" = (/turf/simulated/floor,/area/engine/engine_eva) -"cir" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering EVA Storage"; req_one_access_txt = "11;24"},/turf/simulated/floor,/area/hallway/primary/aft) -"cis" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/turf/simulated/floor,/area/hallway/primary/aft) -"cit" = (/obj/machinery/hologram/holopad,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/primary/aft) -"ciu" = (/obj/machinery/firealarm{dir = 4; layer = 3.3; pixel_x = 26},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"civ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/hallway/primary/aft) -"ciw" = (/obj/structure/closet/secure_closet/engineering_personal,/obj/item/weapon/tank/emergency_oxygen/engi,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/engine/locker_room) -"cix" = (/obj/structure/closet/secure_closet/engineering_personal,/obj/item/weapon/tank/emergency_oxygen/engi,/turf/simulated/floor,/area/engine/locker_room) -"ciy" = (/obj/structure/closet/secure_closet/engineering_personal,/obj/machinery/light{dir = 1},/obj/item/weapon/tank/emergency_oxygen/engi,/turf/simulated/floor,/area/engine/locker_room) +"cik" = (/obj/machinery/firealarm{dir = 4; layer = 3.3; pixel_x = 26},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/engineering/foyer) +"cil" = (/obj/structure/closet/secure_closet/engineering_personal,/obj/item/weapon/tank/emergency_oxygen/engi,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/engineering/locker_room) +"cim" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engineering/locker_room) +"cin" = (/obj/structure/closet/secure_closet/engineering_personal,/obj/machinery/light{dir = 1},/obj/item/weapon/tank/emergency_oxygen/engi,/turf/simulated/floor,/area/engineering/locker_room) +"cio" = (/obj/structure/closet/secure_closet/engineering_personal,/obj/item/weapon/tank/emergency_oxygen/engi,/turf/simulated/floor,/area/engineering/locker_room) +"cip" = (/obj/structure/closet/secure_closet/engineering_personal,/obj/item/weapon/tank/emergency_oxygen/engi,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor,/area/engineering/locker_room) +"ciq" = (/turf/simulated/wall,/area/engineering/locker_room) +"cir" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/engineering/locker_room) +"cis" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/unary/freezer{dir = 2; icon_state = "freezer"},/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora_storage) +"cit" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor{dir = 6; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora_storage) +"ciu" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/unary/heater{dir = 2; icon_state = "heater"},/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora_storage) +"civ" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/purple,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"ciw" = (/obj/machinery/atmospherics/pipe/manifold/hidden/purple{dir = 1},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) +"cix" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 10},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) +"ciy" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/constructionsite/station) "ciz" = (/obj/structure/table/rack{dir = 1},/obj/item/weapon/storage/toolbox/emergency,/turf/simulated/floor/plating,/area/maintenance/engineering) "ciA" = (/turf/simulated/wall,/area/maintenance/substation/engineering) "ciB" = (/obj/structure/table/rack{dir = 1},/obj/item/weapon/extinguisher,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/maintenance/medbay) -"ciC" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire/firefighter,/obj/item/weapon/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/weapon/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/clothing/glasses/meson,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) +"ciC" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "engineering_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/floor/plating,/area/shuttle/constructionsite/station) "ciD" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/plating,/area/maintenance/engineering) "ciE" = (/obj/structure/table/rack{dir = 1},/obj/item/weapon/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/device/flashlight,/turf/simulated/floor/plating,/area/maintenance/engineering) "ciF" = (/obj/structure/table/rack,/obj/item/weapon/extinguisher,/obj/item/weapon/storage/belt/utility,/obj/item/clothing/mask/gas,/turf/simulated/floor/plating,/area/maintenance/engi_engine) @@ -5857,158 +5859,158 @@ "ciI" = (/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "ciJ" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "ciK" = (/obj/machinery/door_control{id = "surgeryobs"; name = "Privacy Shutters"; pixel_y = 25},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/surgery) -"ciL" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre 1"; req_access_txt = "45"},/turf/simulated/floor,/area/medical/surgeryprep) +"ciL" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "engineering_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/shuttle/constructionsite/station) "ciM" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/surgeryprep) "ciN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/medical/surgeryprep) "ciO" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/medical/surgeryprep) -"ciP" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre 2"; req_access_txt = "45"},/turf/simulated/floor,/area/medical/surgeryprep) +"ciP" = (/turf/simulated/shuttle/wall{icon_state = "swall_s6"; dir = 2},/area/shuttle/constructionsite/station) "ciQ" = (/obj/machinery/door_control{id = "surgeryobs2"; name = "Privacy Shutters"; pixel_y = 25},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/surgery2) "ciR" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) "ciS" = (/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) "ciT" = (/obj/structure/closet/secure_closet/medical2,/obj/machinery/light_switch{pixel_x = 22; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) "ciU" = (/turf/simulated/wall,/area/medical/surgery2) "ciV" = (/obj/machinery/camera{c_tag = "Virology Access Fore"; dir = 4; network = list("SS13","Research")},/turf/simulated/floor,/area/medical/virologyaccess) -"ciW" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1441; icon_state = "map_injector"; id = "n2o_in"; use_power = 1; pixel_y = 1},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) +"ciW" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) "ciX" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/medical/surgeryprep) "ciY" = (/obj/structure/toilet{dir = 1},/obj/machinery/light/small{dir = 4},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/patient_wing) "ciZ" = (/obj/machinery/shower{dir = 1},/obj/machinery/light/small{dir = 8},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/patient_wing) -"cja" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "tox_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{carbon_dioxide = 0; name = "phoron floor"; nitrogen = 0; oxygen = 0; phoron = 70000},/area/atmos) -"cjb" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1441; icon_state = "map_injector"; id = "tox_in"; use_power = 1; pixel_y = 1},/turf/simulated/floor/engine{carbon_dioxide = 0; name = "phoron floor"; nitrogen = 0; oxygen = 0; phoron = 70000},/area/atmos) -"cjc" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/regular{density = 0; dir = 4; icon_state = "pdoor0"; id = "EngineBlast"; name = "Engine Monitoring Room Blast Doors"; opacity = 0},/turf/simulated/floor/plating,/area/engine/engine_room) -"cjd" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/regular{density = 0; dir = 4; icon_state = "pdoor0"; id = "EngineBlast"; name = "Engine Monitoring Room Blast Doors"; opacity = 0},/turf/simulated/floor/plating,/area/engine/engine_room) -"cje" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/regular{density = 0; dir = 4; icon_state = "pdoor0"; id = "EngineBlast"; name = "Engine Monitoring Room Blast Doors"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/engine/engine_room) +"cja" = (/obj/item/weapon/stool,/obj/machinery/camera{c_tag = "Aft Starboard Solar Control"; dir = 4; network = list("SS13")},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) +"cjb" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/engineering/atmos) +"cjc" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/engineering/atmos) +"cjd" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/engineering/atmos) +"cje" = (/obj/machinery/light/small{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/atmos_control) "cjf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/research_port) "cjg" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{tag = "icon-whitegreen_v (SOUTHWEST)"; icon_state = "whitegreen_v"; dir = 10},/area/rnd/xenobiology/xenoflora_storage) -"cjh" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora_storage) -"cji" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor{dir = 6; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora_storage) +"cjh" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/atmos_control) +"cji" = (/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 6},/obj/item/weapon/storage/briefcase/inflatable{pixel_y = 3},/obj/structure/table/reinforced{icon_state = "table"},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = -3; pixel_y = 0},/turf/simulated/floor,/area/engineering/engine_eva) "cjj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/light,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor/plating,/area/rnd/xenobiology) "cjk" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"cjl" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/purple{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"cjl" = (/obj/machinery/camera{c_tag = "Engineering EVA Storage"; dir = 1; network = list("SS13")},/obj/machinery/suit_cycler/engineering,/turf/simulated/floor,/area/engineering/engine_eva) "cjm" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/atmospherics/pipe/manifold/hidden/purple,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cjn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/light,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor/plating,/area/rnd/xenobiology/xenoflora) "cjo" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"cjp" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"cjq" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) +"cjp" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor,/area/engineering/engine_eva) +"cjq" = (/obj/structure/table/reinforced,/obj/machinery/door_control{desc = "A remote control-switch for the engine control room blast doors."; id = "EngineBlast"; name = "Engine Monitoring Room Blast Doors"; pixel_x = 0; pixel_y = -3; req_access = list(10)},/obj/machinery/door_control{desc = "A remote control-switch for the engine charging port."; id = "SupermatterPort"; name = "Reactor Blast Doors"; pixel_x = -6; pixel_y = 7; req_access = list(10)},/obj/machinery/door_control{desc = "A remote control-switch for the engine emitter."; id = "EngineEmitter"; name = "Engine Emitter"; normaldoorcontrol = 2; pixel_x = 6; pixel_y = 7; req_access = list(10)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/engine_monitoring) "cjr" = (/obj/structure/table,/obj/item/clothing/gloves/latex,/obj/item/weapon/hand_labeler,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) "cjs" = (/obj/structure/table,/obj/item/weapon/storage/box/syringes,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"cjt" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) +"cjt" = (/turf/simulated/shuttle/wall{icon_state = "swall1"; dir = 2},/area/shuttle/constructionsite/station) "cju" = (/obj/structure/table,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"cjv" = (/obj/structure/stool,/obj/machinery/camera{c_tag = "Aft Starboard Solar Control"; dir = 4; network = list("SS13")},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) +"cjv" = (/obj/machinery/power/terminal{dir = 8},/obj/machinery/light,/obj/machinery/door_control{id = "engine_electrical_maintenance"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 5; pixel_y = -25; req_access = list(10); specialfunctions = 4},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/engineering/engine_smes) "cjw" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/effect/decal/cleanable/dirt,/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) "cjx" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/machinery/light/small{dir = 4},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) -"cjy" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/atmos) -"cjz" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/atmos) -"cjA" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/atmos) +"cjy" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/turf/simulated/floor,/area/engineering/foyer) +"cjz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engineering/engine_eva) +"cjA" = (/obj/structure/table/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/obj/item/weapon/folder/yellow,/turf/simulated/floor,/area/engineering/foyer) "cjB" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/construction) -"cjC" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/engineering{name = "Construction Area"; req_access_txt = "32"},/turf/simulated/floor/plating,/area/construction) -"cjD" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engine/engine_eva_maintenance) -"cjE" = (/obj/machinery/light/small{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "floorgrime"},/area/engine/engine_eva_maintenance) -"cjF" = (/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 6},/obj/item/weapon/storage/briefcase/inflatable{pixel_y = 3},/obj/structure/table/reinforced{icon_state = "table"},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = -3; pixel_y = 0},/turf/simulated/floor,/area/engine/engine_eva) -"cjG" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor,/area/engine/engine_eva) -"cjH" = (/obj/machinery/camera{c_tag = "Engineering EVA Storage"; dir = 1; network = list("SS13")},/obj/machinery/suit_cycler/engineering,/turf/simulated/floor,/area/engine/engine_eva) -"cjI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; dir = 4; icon_state = "pdoor0"; id = "EngineBlast"; name = "Engine Monitoring Room Blast Doors"; opacity = 0},/turf/simulated/floor/plating,/area/engine/engine_room) -"cjJ" = (/obj/machinery/atmospherics/omni/filter{use_power = 0; tag_east = 1; tag_north = 0; tag_south = 4; tag_west = 2},/turf/simulated/floor/plating,/area/engine/engine_room) -"cjK" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/turf/simulated/floor,/area/hallway/primary/aft) -"cjL" = (/obj/structure/table/reinforced,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor,/area/hallway/primary/aft) -"cjM" = (/obj/structure/table/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/obj/item/weapon/folder/yellow,/turf/simulated/floor,/area/hallway/primary/aft) -"cjN" = (/obj/structure/table/reinforced,/obj/machinery/recharger{pixel_y = 0},/turf/simulated/floor,/area/hallway/primary/aft) -"cjO" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/hallway/primary/aft) -"cjP" = (/obj/machinery/atmospherics/unary/vent_pump/on,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cjQ" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Locker Room"; req_one_access_txt = "11;24"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/hallway/primary/aft) -"cjR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engine/locker_room) -"cjS" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engine/locker_room) -"cjT" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/brigdoor{dir = 8; name = "Engine Waste"; req_access = null; req_access_txt = "0"; req_one_access_txt = "10;24"},/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor/plating{icon_state = "platebot"},/area/engine/engine_waste) -"cjU" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "EngineEmitterPortWest"; layer = 3.3; name = "Engine Waste Handling Access"},/turf/simulated/floor/plating,/area/engine/engine_room) +"cjC" = (/turf/simulated/shuttle/wall,/area/shuttle/constructionsite/station) +"cjD" = (/obj/structure/table/reinforced,/obj/item/weapon/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor,/area/engineering/foyer) +"cjE" = (/obj/structure/table/reinforced,/obj/machinery/recharger{pixel_y = 0},/turf/simulated/floor,/area/engineering/foyer) +"cjF" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/engineering/foyer) +"cjG" = (/obj/machinery/atmospherics/unary/vent_pump/on,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/engineering/foyer) +"cjH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engineering/locker_room) +"cjI" = (/turf/simulated/shuttle/wall{tag = "icon-propulsion (EAST)"; icon_state = "propulsion"; dir = 4},/area/shuttle/constructionsite/station) +"cjJ" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engineering/locker_room) +"cjK" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/engineering/locker_room) +"cjL" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor,/area/engineering/locker_room) +"cjM" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/engineering/locker_room) +"cjN" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 28},/turf/simulated/floor,/area/engineering/locker_room) +"cjO" = (/obj/machinery/light{dir = 1},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/power/sensor{name = "Powernet Sensor - Engineering Subgrid"; name_tag = "Engineering Subgrid"},/turf/simulated/floor/plating,/area/maintenance/substation/engineering) +"cjP" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/effect/landmark{name = "blobstart"},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/medical/virologyaccess) +"cjQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/medical/virologyaccess) +"cjR" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora_storage) +"cjS" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora_storage) +"cjT" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/manifold/visible,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora_storage) +"cjU" = (/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) "cjV" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating/airless,/area/solar/port) "cjW" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating/airless,/area/solar/port) -"cjX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/visible/purple{dir = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engine/engine_waste) -"cjY" = (/obj/machinery/door/window/brigdoor{dir = 8; name = "Engine Waste"; req_access = null; req_access_txt = "0"; req_one_access_txt = "10;24"},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 9},/turf/simulated/floor/plating{icon_state = "platebot"},/area/engine/engine_waste) -"cjZ" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 1; sortType = "Atmospherics"; name = "Atmospherics"},/obj/machinery/atmospherics/pipe/simple/visible/universal,/turf/simulated/floor,/area/atmos) +"cjX" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) +"cjY" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{tag = "icon-whitegreen_v (NORTHEAST)"; icon_state = "whitegreen_v"; dir = 5},/area/rnd/xenobiology/xenoflora) +"cjZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) "cka" = (/obj/structure/table,/obj/item/weapon/FixOVein,/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/item/weapon/surgicaldrill,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "ckb" = (/obj/machinery/computer/operating,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "ckc" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "ckd" = (/obj/structure/table,/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; name = "Surgery Cleaner"},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/surgery) -"cke" = (/obj/machinery/atmospherics/omni/filter{use_power = 0; tag_east = 1; tag_north = 4; tag_south = 0; tag_west = 2},/turf/simulated/floor/plating,/area/engine/engine_room) +"cke" = (/turf/simulated/floor{tag = "icon-whitegreen (NORTHWEST)"; icon_state = "whitegreen"; dir = 9},/area/rnd/xenobiology/xenoflora) "ckf" = (/obj/structure/table,/obj/item/device/radio{anchored = 1; broadcasting = 0; canhear_range = 7; frequency = 1487; icon = 'icons/obj/items.dmi'; icon_state = "red_phone"; listening = 1; name = "Surgery Emergency Phone"},/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/surgeryprep) "ckg" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/medical/surgeryprep) "ckh" = (/obj/structure/disposalpipe/segment,/obj/item/roller,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/medical/surgeryprep) -"cki" = (/obj/machinery/door/window/brigdoor{dir = 8; name = "Engine Waste"; req_access = null; req_access_txt = "0"; req_one_access_txt = "10;24"},/obj/structure/window/reinforced,/obj/machinery/atmospherics/binary/pump{dir = 8; name = "waste pump"},/turf/simulated/floor/plating{icon_state = "platebot"},/area/engine/engine_waste) +"cki" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) "ckj" = (/obj/structure/table,/obj/item/weapon/reagent_containers/spray/cleaner{desc = "Someone has crossed out the Space from Space Cleaner and written in Surgery. 'Do not remove under punishment of death!!!' is scrawled on the back."; name = "Surgery Cleaner"},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/surgery2) "ckk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) "ckl" = (/obj/machinery/computer/operating,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) "ckm" = (/obj/structure/table,/obj/item/weapon/FixOVein,/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/obj/item/weapon/surgicaldrill,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) -"ckn" = (/obj/effect/decal/cleanable/cobweb,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating,/area/maintenance/medbay) -"cko" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/medbay) +"ckn" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/shuttle/constructionsite/station) +"cko" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/shuttle/constructionsite/station) "ckp" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance,/obj/structure/disposalpipe/segment,/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/medical/virologyaccess) "ckq" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/medical/virologyaccess) -"ckr" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "EngineEmitterPortWest"; layer = 3.3; name = "Engine Waste Handling Access"},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/plating,/area/engine/engine_room) -"cks" = (/obj/machinery/atmospherics/omni/filter{use_power = 1; tag_east = 1; tag_north = 4; tag_south = 7; tag_west = 2},/turf/simulated/floor,/area/atmos) +"ckr" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1443; icon_state = "map_vent_in"; id_tag = "air_out"; internal_pressure_bound = 2000; internal_pressure_bound_default = 2000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/engineering/atmos) +"cks" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 2; frequency = 1443; icon_state = "map_injector"; id = "air_in"; use_power = 1},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/engineering/atmos) "ckt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/research_port) -"cku" = (/obj/machinery/atmospherics/omni/filter{use_power = 1; tag_east = 1; tag_north = 3; tag_south = 6; tag_west = 2},/turf/simulated/floor,/area/atmos) +"cku" = (/obj/machinery/air_sensor{frequency = 1443; id_tag = "air_sensor"; output = 7},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/engineering/atmos) "ckv" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating/airless,/area/solar/starboard) "ckw" = (/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating/airless,/area/solar/starboard) "ckx" = (/turf/simulated/floor/plating/airless,/area/solar/starboard) "cky" = (/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating/airless,/area/solar/starboard) -"ckz" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor,/area/atmos) -"ckA" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor,/area/atmos) -"ckB" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor,/area/atmos) -"ckC" = (/obj/machinery/door/window/northright{name = "Xenoflora Containment"; req_access_txt = "47"},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora_storage) -"ckD" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora_storage) +"ckz" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 2; frequency = 1441; icon_state = "map_injector"; id = "o2_in"; use_power = 1},/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/engineering/atmos) +"ckA" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "o2_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/engineering/atmos) +"ckB" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "o2_sensor"},/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/engineering/atmos) +"ckC" = (/obj/machinery/computer/station_alert,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/constructionsite/station) +"ckD" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 2; frequency = 1441; icon_state = "map_injector"; id = "n2_in"; use_power = 1},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/engineering/atmos) "ckE" = (/obj/structure/sign/biohazard,/turf/simulated/wall/r_wall,/area/rnd/xenobiology) -"ckF" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "xeno_airlock_control"; name = "Xenobiology Access Button"; pixel_x = -24; pixel_y = 0; req_access_txt = "55"},/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xeno_airlock_exterior"; locked = 1; name = "Xenobiology External Airlock"; req_access_txt = "55"},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"ckF" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "engineering_shuttle"; pixel_x = 0; pixel_y = 25; req_one_access = list(13,11,24); tag_door = "engineering_shuttle_hatch"},/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/constructionsite/station) "ckG" = (/obj/structure/sign/biohazard,/turf/simulated/wall/r_wall,/area/rnd/xenobiology/xenoflora) "ckH" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor{tag = "icon-whitegreen (NORTHWEST)"; icon_state = "whitegreen"; dir = 9},/area/rnd/xenobiology/xenoflora) -"ckI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) -"ckJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) -"ckK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{tag = "icon-whitegreen_v (NORTHEAST)"; icon_state = "whitegreen_v"; dir = 5},/area/rnd/xenobiology/xenoflora) +"ckI" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "n2_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/engineering/atmos) +"ckJ" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "n2_sensor"},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/engineering/atmos) +"ckK" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/plating,/area/maintenance/atmos_control) "ckL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"ckM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{tag = "icon-whitegreen (NORTHWEST)"; icon_state = "whitegreen"; dir = 9},/area/rnd/xenobiology/xenoflora) -"ckN" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) +"ckM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/atmos_control) +"ckN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/shuttle/constructionsite/station) "ckO" = (/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_x = 30; pixel_y = 0},/turf/simulated/floor{tag = "icon-whitegreen_v (NORTHEAST)"; icon_state = "whitegreen_v"; dir = 5},/area/rnd/xenobiology/xenoflora) "ckP" = (/obj/machinery/power/solar_control{id = "starboardsolar"; name = "Aft Starboard Solar Control"; track = 0},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/maintenance/starboardsolar) -"ckQ" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "solar_xeno_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "10;13"},/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/starboardsolar) +"ckQ" = (/obj/machinery/computer/shuttle_control/engineering,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/constructionsite/station) "ckR" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = -32},/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/maintenance/starboardsolar) "ckS" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating/airless,/area/solar/starboard) -"ckT" = (/obj/machinery/air_sensor{frequency = 1443; id_tag = "air_sensor"; output = 7},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/atmos) +"ckT" = (/obj/machinery/computer/station_alert,/turf/simulated/floor,/area/engineering/foyer) "ckU" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating/airless,/area/solar/starboard) "ckV" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating/airless,/area/solar/starboard) -"ckW" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "o2_sensor"},/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/atmos) +"ckW" = (/obj/structure/bed/chair/office/dark{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/turf/simulated/floor,/area/engineering/foyer) "ckX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio1"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/rnd/xenobiology) -"ckY" = (/obj/structure/table,/obj/item/device/multitool{pixel_x = 5},/obj/item/device/t_scanner,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor,/area/engine/workshop) -"ckZ" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "n2_sensor"},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/atmos) -"cla" = (/obj/structure/disposalpipe/segment,/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/power/sensor{name = "Powernet Sensor - Atmospherics Subgrid"; name_tag = "Atmospherics Subgrid"},/obj/structure/cable/cyan{d2 = 4; icon_state = "0-4"},/obj/structure/cable/cyan,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/atmos) +"ckY" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/tape_roll,/turf/simulated/floor,/area/engineering/foyer) +"ckZ" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=AIE"; location = "AftH"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/engineering/foyer) +"cla" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor,/area/engineering/foyer) "clb" = (/obj/item/weapon/wirecutters,/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/turf/simulated/floor/plating,/area/construction) -"clc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/engine/engine_eva_maintenance) -"cld" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/plating,/area/engine/engine_eva_maintenance) -"cle" = (/turf/simulated/wall/r_wall,/area/hallway/primary/aft) -"clf" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "nuke_shuttle_dock_inner"; locked = 1; name = "Docking Port Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/hallway/secondary/entry/port) -"clg" = (/obj/machinery/computer/station_alert,/turf/simulated/floor,/area/hallway/primary/aft) -"clh" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/turf/simulated/floor,/area/hallway/primary/aft) -"cli" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/medical/virologyaccess) -"clj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor,/area/hallway/primary/aft) -"clk" = (/obj/machinery/navbeacon{codes_txt = "patrol;next_patrol=AIE"; location = "AftH"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/hallway/primary/aft) -"cll" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) -"clm" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cln" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Locker Room"; req_one_access_txt = "11;24"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/primary/aft) +"clc" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/engineering/foyer) +"cld" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/foyer) +"cle" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/engineering/locker_room) +"clf" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/constructionsite/station) +"clg" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/shuttle/constructionsite/station) +"clh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/engineering/locker_room) +"cli" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engineering/locker_room) +"clj" = (/turf/simulated/floor,/area/engineering/locker_room) +"clk" = (/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor,/area/engineering/locker_room) +"cll" = (/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Substation - Engineering"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/maintenance/substation/engineering) +"clm" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/medical/virologyaccess) +"cln" = (/obj/machinery/light/small,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/medical/virologyaccess) "clo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio6"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/disposalpipe/segment,/obj/structure/cable/green,/turf/simulated/floor/plating,/area/rnd/xenobiology) -"clp" = (/obj/machinery/door/window/southright{name = "Containment Pen"; req_access_txt = "47"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio5"; name = "Containment Blast Doors"; opacity = 0},/turf/simulated/floor/engine,/area/rnd/xenobiology) +"clp" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/shuttle/constructionsite/station) "clq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio5"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/rnd/xenobiology) "clr" = (/obj/structure/table,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/machinery/light{dir = 8},/turf/simulated/floor,/area/storage/art) "cls" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio5"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/disposalpipe/segment,/obj/structure/cable/green,/turf/simulated/floor/plating,/area/rnd/xenobiology) -"clt" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/tape_roll,/turf/simulated/floor,/area/hallway/primary/aft) -"clu" = (/obj/machinery/door/window/southright{name = "Containment Pen"; req_access_txt = "47"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio4"; name = "Containment Blast Doors"; opacity = 0},/turf/simulated/floor/engine,/area/rnd/xenobiology) -"clv" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor,/area/atmos) +"clt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor/plating,/area/maintenance/research_port) +"clu" = (/obj/machinery/door/airlock/maintenance_hatch{frequency = 1379; icon_state = "door_closed"; id_tag = "engine_airlock_interior"; locked = 0; name = "Engine Airlock Interior"; req_access = list(10)},/turf/simulated/floor/plating,/area/engineering/engine_room) +"clv" = (/obj/machinery/light,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) "clw" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall,/area/maintenance/substation/engineering) "clx" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/maintenance/engineering) "cly" = (/obj/structure/table,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/item/weapon/circular_saw{pixel_y = 8},/obj/item/weapon/scalpel,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "clz" = (/obj/machinery/optable,/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "clA" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "clB" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/surgery) -"clC" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre 1"; req_access_txt = "45"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/medical/surgeryprep) +"clC" = (/obj/machinery/door/airlock/maintenance{name = "Drone Fabrication/Engine Waste Handling"; req_one_access = list(10,24)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) "clD" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/surgeryprep) "clE" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/medical/surgeryprep) "clF" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/medical/surgeryprep) -"clG" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre 2"; req_access_txt = "45"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/medical/surgeryprep) +"clG" = (/obj/machinery/door/airlock/hatch{icon_state = "door_locked"; id_tag = "engine_electrical_maintenance"; locked = 1; name = "Electrical Maintenance"; req_access = list(10)},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/engineering/engine_room) "clH" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/surgery2) "clI" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) "clJ" = (/obj/machinery/optable,/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) @@ -6016,16 +6018,16 @@ "clL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/medbay) "clM" = (/turf/simulated/floor/plating,/area/maintenance/medbay) "clN" = (/turf/simulated/wall/r_wall,/area/medical/virologyaccess) -"clO" = (/obj/machinery/light/small,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{dir = 8; icon_state = "bluecorner"},/area/medical/virologyaccess) -"clP" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/medical/virologyaccess) +"clO" = (/obj/machinery/portable_atmospherics/hydroponics,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology/xenoflora) +"clP" = (/obj/machinery/light,/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = -32},/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) "clQ" = (/obj/machinery/light/small,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "bluecorner"},/area/medical/virologyaccess) "clR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/research_port) "clS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/research_port) "clT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/research_port) "clU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio4"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/rnd/xenobiology) -"clV" = (/obj/machinery/door/window/southright{name = "Containment Pen"; req_access_txt = "47"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio6"; name = "Containment Blast Doors"; opacity = 0},/turf/simulated/floor/engine,/area/rnd/xenobiology) +"clV" = (/turf/simulated/shuttle/wall{tag = "icon-swall2"; icon_state = "swall2"; dir = 2},/area/shuttle/constructionsite/station) "clW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio6"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable/green,/turf/simulated/floor/plating,/area/rnd/xenobiology) -"clX" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 140; external_pressure_bound_default = 140; icon_state = "map_vent_out"; use_power = 1; pressure_checks = 0; pressure_checks_default = 0},/turf/simulated/floor/plating/airless,/area/medical/virology) +"clX" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/meter{frequency = 1443; id = "mair_out_meter"; name = "Mixed Air Tank Out"},/turf/simulated/wall/r_wall,/area/engineering/atmos) "clY" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 0; external_pressure_bound_default = 0; icon_state = "map_vent_in"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/obj/structure/sign/securearea{desc = "A warning sign which reads 'VACUUM'"; icon_state = "space"; layer = 4; name = "VACUUM"; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/engine/vacuum,/area/maintenance/incinerator) "clZ" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1443; icon_state = "map_injector"; id = "air_in"; use_power = 1},/obj/machinery/sparker{id = "Incinerator"; pixel_x = -20},/turf/simulated/floor/engine/vacuum,/area/maintenance/incinerator) "cma" = (/obj/machinery/light,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = 0; pixel_y = -22},/obj/machinery/atmospherics/portables_connector{dir = 4},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora_storage) @@ -6037,62 +6039,62 @@ "cmg" = (/obj/structure/closet/emcloset,/obj/machinery/camera/xray{c_tag = "Xenobiology Access"},/turf/simulated/floor{icon_state = "warnwhite"; dir = 5},/area/rnd/xenobiology) "cmh" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) "cmi" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology/xenoflora) -"cmj" = (/obj/machinery/light,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) +"cmj" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/meter{frequency = 1443; id = "mair_in_meter"; name = "Mixed Air Tank In"},/turf/simulated/wall/r_wall,/area/engineering/atmos) "cmk" = (/obj/machinery/biogenerator,/obj/machinery/camera/autoname{dir = 1},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) "cml" = (/obj/machinery/seed_extractor,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) -"cmm" = (/obj/machinery/light,/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = -32},/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) +"cmm" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engineering/atmos) "cmn" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) "cmo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) -"cmp" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_xeno_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) +"cmp" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 10},/obj/machinery/alarm/nobreach{dir = 2; pixel_y = 22},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_room) "cmq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) "cmr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) -"cms" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/meter{frequency = 1443; id = "mair_out_meter"; name = "Mixed Air Tank Out"},/turf/simulated/wall/r_wall,/area/atmos) -"cmt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/atmos) -"cmu" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/meter{frequency = 1443; id = "mair_in_meter"; name = "Mixed Air Tank In"},/turf/simulated/wall/r_wall,/area/atmos) -"cmv" = (/obj/structure/grille,/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/wall/r_wall,/area/atmos) -"cmw" = (/obj/structure/grille,/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/green,/turf/simulated/wall/r_wall,/area/atmos) -"cmx" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/yellow,/obj/machinery/meter,/turf/simulated/wall/r_wall,/area/atmos) -"cmy" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/green,/obj/machinery/meter,/turf/simulated/wall/r_wall,/area/atmos) +"cms" = (/obj/structure/grille,/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/wall/r_wall,/area/engineering/atmos) +"cmt" = (/obj/structure/grille,/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/green,/turf/simulated/wall/r_wall,/area/engineering/atmos) +"cmu" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/atmos_control) +"cmv" = (/obj/structure/sign/securearea{pixel_x = -32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/atmos_control) +"cmw" = (/obj/machinery/door_control{desc = "A remote control-switch for the engine control room blast doors."; id = "EngineEmitterPortWest"; name = "Engine Room Blast Doors"; pixel_x = 0; pixel_y = 25; req_access = list(10)},/obj/machinery/atmospherics/portables_connector{dir = 4},/turf/simulated/floor/plating{icon_state = "platebot"},/area/engineering/engine_room) +"cmx" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=4"; freq = 1400; location = "Engineering"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor{icon_state = "bot"},/area/engineering/foyer) +"cmy" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/light,/turf/simulated/floor,/area/engineering/foyer) "cmz" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/construction) "cmA" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor,/area/construction) -"cmB" = (/obj/structure/sign/securearea{pixel_x = -32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/engine/engine_eva_maintenance) -"cmC" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/engine/engine_eva_maintenance) -"cmD" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=4"; freq = 1400; location = "Engineering"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor{icon_state = "bot"},/area/hallway/primary/aft) -"cmE" = (/obj/machinery/door/window/eastright{name = "Engineering Delivery"; req_one_access_txt = "11;24"},/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 6; icon_state = "intact"; tag = "icon-intact-f (SOUTHEAST)"},/turf/simulated/floor{icon_state = "delivery"},/area/hallway/primary/aft) -"cmF" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor{dir = 4; icon_state = "loadingarea"},/area/hallway/primary/aft) -"cmG" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/light,/turf/simulated/floor,/area/hallway/primary/aft) -"cmH" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor,/area/hallway/primary/aft) -"cmI" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/computer/guestpass{pixel_y = -28},/turf/simulated/floor,/area/hallway/primary/aft) -"cmJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/requests_console{announcementConsole = 0; department = "Engineering"; departmentType = 4; name = "Engineering RC"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor,/area/hallway/primary/aft) -"cmK" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor,/area/hallway/primary/aft) -"cmL" = (/obj/machinery/door/window/eastright{name = "Engineering Reception Desk"; req_one_access_txt = "10;24"},/obj/machinery/light,/turf/simulated/floor,/area/hallway/primary/aft) -"cmM" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cmN" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/primary/aft) -"cmO" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-j2"; dir = 2},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cmP" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/hallway/primary/aft) -"cmQ" = (/obj/structure/closet/secure_closet/atmos_personal,/obj/item/weapon/tank/emergency_oxygen/engi,/turf/simulated/floor,/area/engine/locker_room) -"cmR" = (/obj/structure/closet/secure_closet/atmos_personal,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/item/weapon/tank/emergency_oxygen/engi,/turf/simulated/floor,/area/engine/locker_room) -"cmS" = (/turf/simulated/floor,/area/engine/locker_room) +"cmB" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor{dir = 4; icon_state = "loadingarea"},/area/engineering/foyer) +"cmC" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor,/area/engineering/foyer) +"cmD" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/requests_console{announcementConsole = 0; department = "Engineering"; departmentType = 4; name = "Engineering RC"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor,/area/engineering/foyer) +"cmE" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/computer/guestpass{pixel_y = -28},/turf/simulated/floor,/area/engineering/foyer) +"cmF" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor,/area/engineering/foyer) +"cmG" = (/obj/machinery/airlock_sensor/airlock_interior{id_tag = "eng_al_int_snsr"; master_tag = "engine_room_airlock"; pixel_y = 22; req_access = list(10)},/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cmH" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engineering/foyer) +"cmI" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{dir = 8; icon_state = "yellowcorner"},/area/engineering/foyer) +"cmJ" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/engineering/foyer) +"cmK" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-j2"; dir = 2},/turf/simulated/floor{dir = 2; icon_state = "yellowcorner"},/area/engineering/foyer) +"cmL" = (/obj/structure/closet/secure_closet/atmos_personal,/obj/item/weapon/tank/emergency_oxygen/engi,/turf/simulated/floor,/area/engineering/locker_room) +"cmM" = (/obj/structure/closet/secure_closet/atmos_personal,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/item/weapon/tank/emergency_oxygen/engi,/turf/simulated/floor,/area/engineering/locker_room) +"cmN" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/engineering/locker_room) +"cmO" = (/obj/structure/table,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor,/area/engineering/locker_room) +"cmP" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table,/obj/machinery/camera{c_tag = "Engineering Locker Room"; dir = 1; network = list("SS13")},/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor,/area/engineering/locker_room) +"cmQ" = (/obj/structure/cable,/obj/machinery/power/terminal{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/shuttle/constructionsite/station) +"cmR" = (/obj/machinery/camera{c_tag = "Medbay Operating Theatre 1"; dir = 8; network = list("SS13")},/obj/machinery/button/holosign{pixel_x = 24; pixel_y = 2},/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "whiteredcorner"},/area/medical/surgery) +"cmS" = (/obj/structure/bed/chair/comfy/black{dir = 4},/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/surgeryprep) "cmT" = (/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating/airless,/area/solar/starboard) "cmU" = (/obj/machinery/door/blast/regular{dir = 4; id = "disvent"; name = "Incinerator Vent"},/turf/simulated/floor/engine/vacuum,/area/maintenance/incinerator) "cmV" = (/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/hallway/secondary/entry/port) -"cmW" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 140; external_pressure_bound_default = 140; icon_state = "map_vent_out"; use_power = 1; pressure_checks = 0; pressure_checks_default = 0},/turf/simulated/floor/plating/airless,/area/maintenance/incinerator) -"cmX" = (/obj/machinery/atmospherics/pipe/cap/visible{color = "#ffcc00"},/turf/simulated/floor,/area/atmos) +"cmW" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/medical/surgeryprep) +"cmX" = (/obj/machinery/button/holosign{pixel_x = -24; pixel_y = 2},/obj/machinery/camera{c_tag = "Medbay Operating Theatre 2"; dir = 4; network = list("SS13")},/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor{dir = 1; icon_state = "whiteredcorner"},/area/medical/surgery2) "cmY" = (/obj/machinery/door/blast/regular{desc = "By gods, release the hounds!"; id = "xenobioout6"; name = "Containment Release"},/turf/simulated/floor/engine,/area/rnd/xenobiology) "cmZ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/solar/starboard) "cna" = (/obj/structure/cable/yellow,/turf/simulated/floor/plating/airless,/area/solar/starboard) "cnb" = (/obj/structure/table,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/item/stack/medical/advanced/bruise_pack,/obj/item/weapon/retractor,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "cnc" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "cnd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) -"cne" = (/obj/machinery/camera{c_tag = "Medbay Operating Theatre 1"; dir = 8; network = list("SS13")},/obj/machinery/holosign_switch{pixel_x = 24; pixel_y = 2},/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "whiteredcorner"},/area/medical/surgery) -"cnf" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/surgeryprep) -"cng" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/medical/surgeryprep) -"cnh" = (/obj/machinery/holosign_switch{pixel_x = -24; pixel_y = 2},/obj/machinery/camera{c_tag = "Medbay Operating Theatre 2"; dir = 4; network = list("SS13")},/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/floor{dir = 1; icon_state = "whiteredcorner"},/area/medical/surgery2) +"cne" = (/obj/structure/cable,/obj/machinery/power/smes/buildable/power_shuttle,/turf/simulated/floor/plating,/area/shuttle/constructionsite/station) +"cnf" = (/obj/machinery/computer/atmos_alert,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/constructionsite/station) +"cng" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/shuttle/constructionsite/station) +"cnh" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/shuttle/constructionsite/station) "cni" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) "cnj" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) "cnk" = (/obj/structure/table,/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/item/stack/medical/advanced/bruise_pack,/obj/item/weapon/retractor,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) "cnl" = (/obj/structure/sign/biohazard,/turf/simulated/wall/r_wall,/area/medical/virologyaccess) -"cnm" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Virology Access"; req_access_txt = "39"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/medical/virologyaccess) +"cnm" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/turf/simulated/wall/r_wall,/area/engineering/atmos) "cnn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/research_port) "cno" = (/obj/structure/sign/securearea{pixel_x = -32; pixel_y = 0},/obj/machinery/shower{icon_state = "shower"; dir = 4},/turf/simulated/floor{dir = 8; icon_state = "warnwhite"},/area/rnd/xenobiology) "cnp" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) @@ -6100,42 +6102,42 @@ "cnr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/xenobiology/xenoflora) "cns" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/xenobiology/xenoflora) "cnt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/xenobiology/xenoflora) -"cnu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/xenobiology/xenoflora) +"cnu" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/brigdoor{dir = 8; name = "Engine Waste"; req_one_access = list(10,24)},/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor/plating{icon_state = "platebot"},/area/engineering/engine_waste) "cnv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) -"cnw" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "solar_xeno_pump"; tag_exterior_door = "solar_xeno_outer"; frequency = 1379; id_tag = "solar_xeno_airlock"; tag_interior_door = "solar_xeno_inner"; pixel_x = 25; req_access_txt = "13"; tag_chamber_sensor = "solar_xeno_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_xeno_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "solar_xeno_pump"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/decal/warning_stripes,/turf/simulated/floor/plating,/area/maintenance/starboardsolar) +"cnw" = (/obj/machinery/door/window/brigdoor{dir = 8; name = "Engine Waste"; req_one_access = list(10,24)},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 9},/turf/simulated/floor/plating{icon_state = "platebot"},/area/engineering/engine_waste) "cnx" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/structure/lattice,/turf/space,/area/space) -"cny" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/turf/simulated/floor/plating,/area/engine/engine_room) -"cnz" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_x = 0; pixel_y = 32},/obj/structure/cable/cyan{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes/buildable{charge = 2e+006; RCon_tag = "Atmospherics"},/turf/simulated/floor/plating,/area/atmos) +"cny" = (/turf/simulated/wall/r_wall,/area/engineering/atmos) +"cnz" = (/turf/simulated/wall/r_wall,/area/engineering/atmos/monitoring) "cnA" = (/obj/machinery/light{dir = 8},/turf/simulated/floor,/area/construction) "cnB" = (/obj/item/device/flashlight,/turf/simulated/floor,/area/construction) "cnC" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor,/area/construction) "cnD" = (/turf/simulated/wall/r_wall,/area/construction) -"cnE" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/atmos{name = "Atmospherics Maintenance"; req_access_txt = "12;24"},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor,/area/atmos) -"cnF" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/atmos{name = "Atmospherics Maintenance"; req_access_txt = "12;24"},/obj/machinery/atmospherics/pipe/simple/visible/supply,/turf/simulated/floor,/area/atmos) -"cnG" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/turf/simulated/wall/r_wall,/area/hallway/primary/aft) -"cnH" = (/obj/machinery/door/airlock/maintenance{name = "Atmospherics Maintenance Access"; req_access_txt = "12;24"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor,/area/hallway/primary/aft) -"cnI" = (/obj/machinery/door/airlock/maintenance{name = "Engineering EVA Storage Maintainance"; req_access_txt = "12"; req_one_access_txt = "11;24"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hallway/primary/aft) -"cnJ" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Monitoring Room"; req_access_txt = "11"},/turf/simulated/floor,/area/hallway/primary/aft) -"cnK" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/hallway/primary/aft) -"cnL" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Hallway"; req_one_access_txt = "10;24"},/turf/simulated/floor,/area/hallway/primary/aft) -"cnM" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Hallway"; req_one_access_txt = "10;24"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/hallway/primary/aft) -"cnN" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Hallway"; req_one_access_txt = "10;24"},/turf/simulated/floor,/area/hallway/primary/aft) -"cnO" = (/turf/simulated/wall/r_wall,/area/engine/workshop) -"cnP" = (/obj/machinery/atmospherics/binary/pump/on{dir = 1},/turf/simulated/floor,/area/atmos) -"cnQ" = (/obj/machinery/atmospherics/binary/pump/on,/turf/simulated/floor,/area/atmos) -"cnR" = (/turf/simulated/wall/r_wall,/area/engine/storage_hard) +"cnE" = (/obj/machinery/door/window/brigdoor{dir = 8; name = "Engine Waste"; req_one_access = list(10,24)},/obj/structure/window/reinforced,/obj/machinery/atmospherics/binary/pump{dir = 8; name = "waste pump"},/turf/simulated/floor/plating{icon_state = "platebot"},/area/engineering/engine_waste) +"cnF" = (/obj/effect/decal/cleanable/blood/oil,/turf/simulated/floor,/area/engineering/workshop) +"cnG" = (/turf/simulated/wall/r_wall,/area/engineering/engineering_monitoring) +"cnH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engineering/engineering_monitoring) +"cnI" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/atmos{name = "Atmospherics Maintenance"; req_access = list(12,24)},/turf/simulated/floor,/area/engineering/atmos/storage) +"cnJ" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/engineering/engineering_monitoring) +"cnK" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor,/area/engineering/atmos) +"cnL" = (/obj/machinery/atmospherics/pipe/manifold/visible/red,/turf/simulated/floor,/area/engineering/atmos) +"cnM" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/engineering/workshop) +"cnN" = (/obj/machinery/atmospherics/pipe/manifold/visible/red{tag = "icon-map (NORTH)"; icon_state = "map"; dir = 1},/turf/simulated/floor,/area/engineering/atmos) +"cnO" = (/turf/simulated/wall/r_wall,/area/engineering/workshop) +"cnP" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"cnQ" = (/obj/machinery/atmospherics/pipe/simple/visible/green,/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"cnR" = (/turf/simulated/wall/r_wall,/area/engineering/locker_room) "cnS" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/maintenance/engineering) "cnT" = (/obj/structure/table,/obj/item/weapon/hemostat,/obj/machinery/light,/obj/item/weapon/cautery,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "cnU" = (/obj/structure/table,/obj/item/weapon/bonesetter,/obj/item/weapon/bonegel,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) -"cnV" = (/obj/structure/table,/obj/machinery/vending/wallmed1{pixel_y = -32},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) +"cnV" = (/obj/structure/table,/obj/machinery/vending/wallmed1{pixel_y = -32},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/random/medical,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "cnW" = (/obj/machinery/computer/med_data,/obj/machinery/light,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "cnX" = (/obj/structure/table,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/medical/surgeryprep) "cnY" = (/obj/machinery/computer/med_data,/obj/machinery/light,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) -"cnZ" = (/obj/structure/table,/obj/machinery/vending/wallmed1{pixel_y = -32},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) +"cnZ" = (/obj/structure/table,/obj/machinery/vending/wallmed1{pixel_y = -32},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/random/medical,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) "coa" = (/obj/structure/table,/obj/item/weapon/bonesetter,/obj/item/weapon/bonegel,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) "cob" = (/obj/structure/table,/obj/item/weapon/hemostat,/obj/machinery/light,/obj/item/weapon/cautery,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) "coc" = (/obj/machinery/light{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "bluecorner"},/area/medical/virologyaccess) -"cod" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/virologyaccess) +"cod" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/medical/virologyaccess) "coe" = (/obj/machinery/light{dir = 1},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{dir = 4; icon_state = "bluecorner"},/area/medical/virologyaccess) "cof" = (/obj/structure/disposalpipe/trunk{dir = 4},/obj/structure/disposaloutlet,/turf/simulated/floor/engine,/area/rnd/xenobiology) "cog" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/engine,/area/rnd/xenobiology) @@ -6143,105 +6145,105 @@ "coi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio3"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/rnd/xenobiology) "coj" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/obj/structure/window/reinforced,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/rnd/xenobiology) "cok" = (/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"col" = (/obj/structure/extinguisher_cabinet{pixel_x = 27; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"col" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) "com" = (/turf/simulated/wall,/area/rnd/xenobiology) -"con" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "xeno_airlock_control"; name = "Xenobiology Access Button"; pixel_x = 8; pixel_y = -28; req_access_txt = "55"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{dir = 10; icon_state = "warnwhite"},/area/rnd/xenobiology) -"coo" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/purple{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"cop" = (/obj/structure/closet/l3closet/scientist,/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor{dir = 6; icon_state = "warnwhite"},/area/rnd/xenobiology) -"coq" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/wall/r_wall,/area/rnd/xenobiology) -"cor" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio2"; name = "Containment Blast Doors"; opacity = 0},/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen"; req_access_txt = "55"},/turf/simulated/floor/engine,/area/rnd/xenobiology) +"con" = (/obj/machinery/camera{c_tag = "Xenobiology Module South"; dir = 4; network = list("SS13","Research"); pixel_x = 0},/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio1"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access = list(55)},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/xenobiology) +"coo" = (/obj/structure/closet/l3closet/scientist,/turf/simulated/floor{dir = 6; icon_state = "warnwhite"},/area/rnd/xenobiology) +"cop" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"coq" = (/obj/machinery/door/airlock/medical{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "virologyq_airlock_interior"; locked = 1; name = "Virology Quarantine Airlock"; req_access = list(39)},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cor" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "virology_inner"; locked = 1; name = "Engineering External Access"; req_access = list(13)},/turf/simulated/floor/plating,/area/maintenance/medbay) "cos" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) -"cot" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_xeno_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) -"cou" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/atmos) -"cov" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/atmos) -"cow" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/atmos) -"cox" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/plating,/area/atmos) -"coy" = (/obj/machinery/power/smes/buildable{charge = 1e+007; cur_coils = 4; input_attempt = 1; input_level = 500000; output_level = 500000; RCon_tag = "Engine Main"},/obj/structure/cable,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/engine/engine_smes) +"cot" = (/obj/machinery/door/airlock/maintenance{name = "Atmospherics Maintenance Access"; req_access = list(12,24)},/obj/structure/disposalpipe/segment,/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/engineering/atmos/storage) +"cou" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/engineering/atmos) +"cov" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/engineering/atmos) +"cow" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/engineering/atmos) +"cox" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/plating,/area/engineering/atmos) +"coy" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor/plating,/area/engineering/atmos) "coz" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/secondary/entry/port) -"coA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating,/area/atmos) -"coB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/atmos) -"coC" = (/turf/simulated/wall/r_wall,/area/atmos) -"coD" = (/obj/machinery/meter{frequency = 1443; id = "wloop_atm_meter"; name = "Waste Loop"},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor,/area/atmos) -"coE" = (/obj/machinery/meter{frequency = 1443; id = "dloop_atm_meter"; name = "Distribution Loop"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/visible/supply{dir = 8},/turf/simulated/floor,/area/atmos) -"coF" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/obj/machinery/atmospherics/pipe/simple/visible/supply{dir = 10},/turf/simulated/floor,/area/atmos) -"coG" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/meter,/obj/machinery/firealarm{pixel_y = 24},/turf/simulated/floor,/area/atmos) -"coH" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor,/area/atmos) -"coI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engine/atmos_monitoring) -"coJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/computer/power_monitor,/turf/simulated/floor{icon_state = "warning"},/area/engine/engine_monitoring) -"coK" = (/obj/machinery/firealarm{pixel_x = 32; pixel_y = 24},/turf/simulated/floor,/area/engine/atmos_monitoring) -"coL" = (/obj/machinery/computer/atmoscontrol,/turf/simulated/floor,/area/engine/atmos_monitoring) -"coM" = (/turf/simulated/wall/r_wall,/area/engine/engineering_monitoring) -"coN" = (/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/turf/simulated/floor,/area/engine/engineering_monitoring) -"coO" = (/obj/structure/table/reinforced,/turf/simulated/floor,/area/engine/engineering_monitoring) -"coP" = (/obj/machinery/computer/atmos_alert,/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor,/area/engine/engineering_monitoring) -"coQ" = (/turf/simulated/floor,/area/engine/hallway) -"coR" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/engine/hallway) -"coS" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/structure/sign/directions/medical{dir = 1; icon_state = "direction_med"; pixel_x = 30; pixel_y = 4; tag = "icon-direction_med (NORTH)"},/obj/structure/sign/directions/evac{dir = 8; icon_state = "direction_evac"; pixel_x = 30; pixel_y = -4; tag = "icon-direction_evac (WEST)"},/turf/simulated/floor,/area/engine/hallway) -"coT" = (/obj/machinery/vending/tool,/turf/simulated/floor,/area/engine/workshop) -"coU" = (/obj/machinery/vending/engivend,/turf/simulated/floor,/area/engine/workshop) -"coV" = (/obj/structure/closet/toolcloset,/obj/machinery/light{dir = 1},/obj/item/device/flashlight,/turf/simulated/floor,/area/engine/workshop) -"coW" = (/obj/structure/closet/toolcloset,/obj/item/device/flashlight,/turf/simulated/floor,/area/engine/workshop) -"coX" = (/turf/simulated/floor,/area/engine/workshop) -"coY" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engine/workshop) -"coZ" = (/obj/machinery/shield_gen/external,/turf/simulated/floor/plating,/area/engine/storage_hard) -"cpa" = (/obj/machinery/shield_gen,/obj/machinery/light{dir = 1},/turf/simulated/floor/plating,/area/engine/storage_hard) -"cpb" = (/obj/machinery/power/rad_collector,/turf/simulated/floor/plating,/area/engine/storage_hard) +"coA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 8},/turf/simulated/floor/plating,/area/engineering/atmos) +"coB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/plating,/area/engineering/atmos) +"coC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 8},/turf/simulated/floor/plating,/area/engineering/atmos) +"coD" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating,/area/engineering/atmos) +"coE" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/engineering/atmos) +"coF" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/plating,/area/engineering/atmos) +"coG" = (/obj/machinery/meter{frequency = 1443; id = "dloop_atm_meter"; name = "Distribution Loop"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/visible/supply{dir = 8},/turf/simulated/floor,/area/engineering/atmos) +"coH" = (/obj/machinery/meter{frequency = 1443; id = "wloop_atm_meter"; name = "Waste Loop"},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor,/area/engineering/atmos) +"coI" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/meter,/obj/machinery/firealarm{pixel_y = 24},/turf/simulated/floor,/area/engineering/atmos) +"coJ" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/obj/machinery/atmospherics/pipe/simple/visible/supply{dir = 10},/turf/simulated/floor,/area/engineering/atmos) +"coK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engineering/atmos/monitoring) +"coL" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor,/area/engineering/atmos) +"coM" = (/obj/machinery/firealarm{pixel_x = 32; pixel_y = 24},/turf/simulated/floor,/area/engineering/atmos/monitoring) +"coN" = (/obj/machinery/computer/general_air_control{frequency = 1443; level = 3; name = "Distribution and Waste Monitor"; sensors = list("mair_in_meter" = "Mixed Air In", "air_sensor" = "Mixed Air Supply Tank", "mair_out_meter" = "Mixed Air Out", "dloop_atm_meter" = "Distribution Loop", "wloop_atm_meter" = "Engine Waste")},/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/engineering/atmos/monitoring) +"coO" = (/obj/machinery/computer/atmoscontrol,/turf/simulated/floor,/area/engineering/atmos/monitoring) +"coP" = (/obj/structure/table/reinforced,/turf/simulated/floor,/area/engineering/engineering_monitoring) +"coQ" = (/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/turf/simulated/floor,/area/engineering/engineering_monitoring) +"coR" = (/obj/machinery/computer/atmos_alert,/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor,/area/engineering/engineering_monitoring) +"coS" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/engineering) +"coT" = (/turf/simulated/floor,/area/engineering) +"coU" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/structure/sign/directions/medical{dir = 1; icon_state = "direction_med"; pixel_x = 30; pixel_y = 4; tag = "icon-direction_med (NORTH)"},/obj/structure/sign/directions/evac{dir = 8; icon_state = "direction_evac"; pixel_x = 30; pixel_y = -4; tag = "icon-direction_evac (WEST)"},/turf/simulated/floor,/area/engineering) +"coV" = (/obj/machinery/vending/engivend,/turf/simulated/floor,/area/engineering/workshop) +"coW" = (/obj/machinery/vending/tool,/turf/simulated/floor,/area/engineering/workshop) +"coX" = (/obj/structure/closet/toolcloset,/obj/item/device/flashlight,/turf/simulated/floor,/area/engineering/workshop) +"coY" = (/obj/structure/closet/toolcloset,/obj/machinery/light{dir = 1},/obj/item/device/flashlight,/turf/simulated/floor,/area/engineering/workshop) +"coZ" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engineering/workshop) +"cpa" = (/turf/simulated/floor,/area/engineering/workshop) +"cpb" = (/obj/machinery/shield_gen/external,/turf/simulated/floor/plating,/area/engineering/storage) "cpc" = (/obj/machinery/status_display,/turf/simulated/wall,/area/medical/surgery) -"cpd" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre 1 Storage"; req_access_txt = "45"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) +"cpd" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_one_access = list(10,24)},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cpe" = (/obj/machinery/light{dir = 8},/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/obj/structure/closet/wardrobe/medic_white,/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/medical/surgeryprep) "cpf" = (/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/obj/structure/table,/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/camera{c_tag = "Medbay Surgery Prep"; dir = 8; network = list("SS13")},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/medical/surgeryprep) -"cpg" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre 2 Storage"; req_access_txt = "45"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) +"cpg" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "virology_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "virology_pump"; tag_exterior_door = "virology_outer"; frequency = 1379; id_tag = "virology_airlock"; tag_interior_door = "virology_inner"; pixel_x = 25; req_access = list(13); tag_chamber_sensor = "virology_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "virology_pump"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/maintenance/medbay) "cph" = (/obj/machinery/status_display,/turf/simulated/wall,/area/medical/surgery2) "cpi" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/medbay) -"cpj" = (/obj/structure/window/reinforced{dir = 1},/obj/item/stack/sheet/plasteel{amount = 10},/obj/item/stack/sheet/plasteel{amount = 10},/obj/item/stack/sheet/mineral/plastic{amount = 10},/obj/structure/table/reinforced,/turf/simulated/floor,/area/engine/workshop) -"cpk" = (/obj/structure/window/reinforced{dir = 1},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table/reinforced,/turf/simulated/floor,/area/engine/workshop) +"cpj" = (/turf/simulated/wall/r_wall,/area/engineering/storage) +"cpk" = (/obj/machinery/shield_gen,/obj/machinery/light{dir = 1},/turf/simulated/floor/plating,/area/engineering/storage) "cpl" = (/turf/simulated/floor/engine,/area/rnd/xenobiology) "cpm" = (/mob/living/carbon/slime,/turf/simulated/floor/engine,/area/rnd/xenobiology) -"cpn" = (/obj/structure/window/reinforced{dir = 1},/obj/item/stack/rods{amount = 50},/obj/item/weapon/airlock_electronics,/obj/item/weapon/airlock_electronics,/obj/item/weapon/cell/high,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table/reinforced,/turf/simulated/floor,/area/engine/workshop) -"cpo" = (/obj/machinery/door/window/northleft{dir = 4; name = "Containment Pen"; req_access_txt = "55"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/xenobiology) +"cpn" = (/obj/machinery/power/rad_collector,/turf/simulated/floor/plating,/area/engineering/storage) +"cpo" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "virologyq_airlock_control"; name = "Virology Quarantine Access Button"; pixel_x = -8; pixel_y = 28; req_access = list(39)},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cpp" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cpq" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"cpr" = (/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xeno_airlock_interior"; locked = 1; name = "Xenobiology Internal Airlock"; req_access_txt = "55"},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"cps" = (/obj/structure/window/reinforced{dir = 1},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/structure/table/reinforced,/turf/simulated/floor,/area/engine/workshop) -"cpt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/atmos) -"cpu" = (/turf/simulated/floor,/area/atmos) -"cpv" = (/obj/machinery/atmospherics/valve/digital/open{name = "Mixed Air Outlet Valve"},/turf/simulated/floor{dir = 9; icon_state = "arrival"},/area/atmos) -"cpw" = (/obj/machinery/computer/rcon,/turf/simulated/floor{icon_state = "warning"},/area/engine/engine_monitoring) -"cpx" = (/obj/machinery/computer/security/engineering{network = list("Engineering","Power Alarms","Atmosphere Alarms","Fire Alarms","Supermatter")},/turf/simulated/floor{icon_state = "warning"},/area/engine/engine_monitoring) -"cpy" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/atmospherics/binary/pump{dir = 8},/turf/simulated/floor/plating,/area/engine/engine_room) -"cpz" = (/obj/machinery/door_control{desc = "A remote control-switch for the engine control room blast doors."; id = "EngineEmitterPortWest"; name = "Engine Room Blast Doors"; pixel_x = 0; pixel_y = 25; req_access_txt = "10"},/obj/machinery/atmospherics/portables_connector{dir = 4},/turf/simulated/floor/plating{icon_state = "platebot"},/area/engine/engine_room) -"cpA" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable/yellow,/obj/machinery/power/sensor{name = "Powernet Sensor - Engine Output"; name_tag = "Engine Output"},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engine/engine_room) -"cpB" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan,/turf/simulated/floor/plating,/area/engine/engine_room) -"cpC" = (/obj/machinery/alarm{breach_detection = 0; dir = 2; frequency = 1439; name = "Engine Room Air Alarm"; pixel_y = 23},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 10},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engine/engine_room) -"cpD" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engine/engine_room) -"cpE" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/space,/area/space) -"cpF" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{external_pressure_bound = 140; external_pressure_bound_default = 140; icon_state = "map_vent_out"; pressure_checks = 0; pressure_checks_default = 0},/turf/simulated/floor/plating/airless,/area/atmos) +"cpr" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/glass_engineering{name = "Engineering Hallway"; req_one_access = list(10,24)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering) +"cps" = (/obj/machinery/door/blast/regular{density = 0; dir = 4; icon_state = "pdoor0"; id = "virologyquar"; name = "Virology Emergency Quarantine Blast Doors"; opacity = 0},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "delivery"},/area/medical/virologyaccess) +"cpt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engineering/atmos) +"cpu" = (/obj/machinery/atmospherics/valve/digital/open{name = "Mixed Air Outlet Valve"},/turf/simulated/floor{dir = 9; icon_state = "arrival"},/area/engineering/atmos) +"cpv" = (/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/engineering/atmos) +"cpw" = (/obj/machinery/atmospherics/valve/digital/open{name = "Mixed Air Inlet Valve"},/turf/simulated/floor{icon_state = "arrival"; dir = 5},/area/engineering/atmos) +"cpx" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1443; input_tag = "air_in"; name = "Mixed Air Supply Control"; output_tag = "air_out"; pressure_setting = 2000; sensors = list("air_sensor" = "Tank")},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/machinery/light{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "arrival"},/area/engineering/atmos) +"cpy" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/engineering/atmos) +"cpz" = (/obj/machinery/atmospherics/valve/digital/open{name = "Oxygen Outlet Valve"},/turf/simulated/floor{dir = 5; icon_state = "blue"},/area/engineering/atmos) +"cpA" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "o2_in"; name = "Oxygen Supply Control"; output_tag = "o2_out"; sensors = list("o2_sensor" = "Tank")},/obj/machinery/camera{c_tag = "Atmospherics North West"; dir = 2},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/machinery/light{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/engineering/atmos) +"cpB" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor{icon_state = "red"; dir = 9},/area/engineering/atmos) +"cpC" = (/obj/machinery/atmospherics/binary/pump,/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/engineering/atmos) +"cpD" = (/obj/machinery/atmospherics/valve/digital/open{name = "Nitrogen Outlet Valve"},/turf/simulated/floor{icon_state = "red"; dir = 5},/area/engineering/atmos) +"cpE" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{external_pressure_bound = 140; external_pressure_bound_default = 140; icon_state = "map_vent_out"; pressure_checks = 1; pressure_checks_default = 1; use_power = 1},/turf/simulated/floor/plating/airless,/area/engineering/atmos) +"cpF" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "n2_in"; name = "Nitrogen Supply Control"; output_tag = "n2_out"; sensors = list("n2_sensor" = "Tank")},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/engineering/atmos) "cpG" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/space,/area/space) -"cpH" = (/obj/structure/reagent_dispensers/fueltank,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = 25},/turf/simulated/floor,/area/atmos) +"cpH" = (/turf/simulated/floor,/area/engineering/atmos) "cpI" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/space,/area/space) -"cpJ" = (/obj/structure/table,/obj/item/device/t_scanner,/obj/item/device/multitool{pixel_x = 5},/obj/item/device/radio/headset/headset_eng,/obj/item/weapon/cartridge/atmos,/obj/item/weapon/cartridge/atmos,/obj/item/device/pipe_painter,/obj/machinery/requests_console{department = "Atmospherics"; departmentType = 4; name = "Atmos RC"; pixel_x = 0; pixel_y = 28},/turf/simulated/floor,/area/atmos) +"cpJ" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor,/area/engineering/atmos) "cpK" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/hallway/secondary/entry/aft) -"cpL" = (/obj/structure/table,/obj/item/weapon/wrench,/obj/machinery/camera{c_tag = "Atmospherics North East"; dir = 6},/obj/structure/sign/atmosplaque{pixel_x = 0; pixel_y = 32},/obj/machinery/cell_charger,/turf/simulated/floor,/area/atmos) -"cpM" = (/obj/structure/table,/obj/machinery/newscaster{pixel_y = 30},/obj/machinery/light{dir = 1},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/clothing/gloves/black,/obj/item/clothing/gloves/black,/obj/item/weapon/storage/belt/utility/atmostech,/obj/item/weapon/storage/belt/utility/atmostech,/turf/simulated/floor,/area/atmos) -"cpN" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor,/area/atmos) -"cpO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/universal,/turf/simulated/floor,/area/atmos) +"cpL" = (/obj/structure/reagent_dispensers/fueltank,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = 25},/turf/simulated/floor,/area/engineering/atmos) +"cpM" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/engineering/atmos) +"cpN" = (/obj/structure/table,/obj/item/device/t_scanner,/obj/item/device/multitool{pixel_x = 5},/obj/item/device/radio/headset/headset_eng,/obj/item/weapon/cartridge/atmos,/obj/item/weapon/cartridge/atmos,/obj/item/device/pipe_painter,/obj/machinery/requests_console{department = "Atmospherics"; departmentType = 4; name = "Atmos RC"; pixel_x = 0; pixel_y = 28},/turf/simulated/floor,/area/engineering/atmos) +"cpO" = (/obj/structure/dispenser,/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/engineering/atmos) "cpP" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/space,/area/space) -"cpQ" = (/obj/machinery/atmospherics/pipe/simple/visible/universal,/turf/simulated/floor,/area/atmos) +"cpQ" = (/obj/structure/table,/obj/item/weapon/wrench,/obj/machinery/camera{c_tag = "Atmospherics North East"; dir = 6},/obj/structure/sign/atmosplaque{pixel_x = 0; pixel_y = 32},/obj/machinery/cell_charger,/turf/simulated/floor,/area/engineering/atmos) "cpR" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/green,/turf/space,/area/space) "cpS" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/hallway/secondary/entry/port) -"cpT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engine/atmos_monitoring) -"cpU" = (/obj/machinery/computer/atmos_alert,/turf/simulated/floor,/area/engine/atmos_monitoring) -"cpV" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/engine/atmos_monitoring) -"cpW" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/engine/atmos_monitoring) -"cpX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/engine/engineering_monitoring) -"cpY" = (/obj/machinery/camera{c_tag = "Engineering Monitoring"; dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/engine/engineering_monitoring) -"cpZ" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Station Engineer"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/engine/engineering_monitoring) -"cqa" = (/obj/machinery/computer/security/engineering,/turf/simulated/floor{dir = 8; icon_state = "floorgrimecaution"},/area/engine/engineering_monitoring) -"cqb" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/status_display{pixel_y = 32},/turf/simulated/floor/plating,/area/engine/engineering_monitoring) -"cqc" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engine/hallway) -"cqd" = (/obj/structure/disposalpipe/segment,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor,/area/engine/hallway) -"cqe" = (/obj/structure/extinguisher_cabinet{pixel_x = 25},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engine/workshop) -"cqf" = (/obj/machinery/shield_capacitor,/turf/simulated/floor/plating,/area/engine/storage_hard) +"cpT" = (/obj/structure/table,/obj/item/stack/sheet/glass{amount = 50},/obj/item/clothing/head/welding{pixel_x = -5; pixel_y = 3},/obj/item/clothing/glasses/welding,/obj/structure/closet/fireaxecabinet{pixel_y = 32},/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/engineering/atmos) +"cpU" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"cpV" = (/obj/structure/table,/obj/machinery/newscaster{pixel_y = 30},/obj/machinery/light{dir = 1},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/clothing/gloves/black,/obj/item/clothing/gloves/black,/obj/item/weapon/storage/belt/utility/atmostech,/obj/item/weapon/storage/belt/utility/atmostech,/turf/simulated/floor,/area/engineering/atmos) +"cpW" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 1; sortType = "Atmospherics"; name = "Atmospherics"},/obj/machinery/atmospherics/pipe/simple/visible/universal,/turf/simulated/floor,/area/engineering/atmos) +"cpX" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/universal,/turf/simulated/floor,/area/engineering/atmos) +"cpY" = (/obj/machinery/atmospherics/binary/pump/on{dir = 1},/turf/simulated/floor,/area/engineering/atmos) +"cpZ" = (/obj/machinery/atmospherics/pipe/simple/visible/universal,/turf/simulated/floor,/area/engineering/atmos) +"cqa" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engineering/atmos/monitoring) +"cqb" = (/obj/machinery/atmospherics/binary/pump/on,/turf/simulated/floor,/area/engineering/atmos) +"cqc" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/engineering/atmos/monitoring) +"cqd" = (/obj/machinery/computer/atmos_alert,/turf/simulated/floor,/area/engineering/atmos/monitoring) +"cqe" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/engineering/engineering_monitoring) +"cqf" = (/obj/structure/bed/chair/office/dark{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/camera/autoname{dir = 8},/turf/simulated/floor,/area/engineering/atmos/monitoring) "cqg" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/engineering) "cqh" = (/obj/structure/closet/crate/freezer,/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery) "cqi" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery) @@ -6253,16 +6255,16 @@ "cqo" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery2) "cqp" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery2) "cqq" = (/obj/structure/closet/crate/freezer,/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery2) -"cqr" = (/obj/effect/decal/cleanable/blood/oil{amount = 0},/turf/simulated/floor/plating,/area/maintenance/medbay) -"cqs" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/light,/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "virologyquar"; name = "Virology Emergency Lockdown Control"; pixel_x = 0; pixel_y = -28; req_access_txt = "5"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "greencorner"},/area/medical/virologyaccess) -"cqt" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 10},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "green"},/area/medical/virologyaccess) +"cqr" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Hallway"; req_one_access = list(10,24)},/turf/simulated/floor,/area/engineering) +"cqs" = (/obj/machinery/embedded_controller/radio/airlock/access_controller{tag_exterior_door = "incinerator_airlock_exterior"; id_tag = "incinerator_access_control"; tag_interior_door = "incinerator_airlock_interior"; name = "Incinerator Access Console"; pixel_x = -6; pixel_y = -26; req_access = list(12)},/obj/machinery/button/ignition{id = "Incinerator"; pixel_x = 6; pixel_y = -24},/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor{dir = 2; icon_state = "warningcorner"; tag = "icon-warningcorner (WEST)"},/area/maintenance/incinerator) +"cqt" = (/obj/structure/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Station Engineer"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/engineering/engineering_monitoring) "cqu" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/light,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "greencorner"},/area/medical/virologyaccess) "cqv" = (/turf/simulated/wall/r_wall,/area/medical/virology) "cqw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/virology) "cqx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/virology) "cqy" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/virology) -"cqz" = (/obj/machinery/atmospherics/omni/mixer{active_power_usage = 7500; use_power = 1; tag_east = 1; tag_east_con = 0.79; tag_north = 1; tag_north_con = 0.21; tag_west = 2},/turf/simulated/floor,/area/atmos) -"cqA" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio3"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/rnd/xenobiology) +"cqz" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/camera/autoname{dir = 4},/turf/simulated/floor,/area/engineering/engineering_monitoring) +"cqA" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/machinery/meter,/obj/machinery/door_control{id = "disvent"; name = "Incinerator Vent Control"; pixel_x = 0; pixel_y = -24; req_one_access = list(12,5)},/turf/simulated/floor{dir = 1; icon_state = "warningcorner"; tag = "icon-warningcorner (WEST)"},/area/maintenance/incinerator) "cqB" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cqC" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 5},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cqD" = (/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_x = 0; pixel_y = 30},/obj/machinery/camera{c_tag = "Xenobiology Module North"; dir = 2; network = list("SS13","Research"); pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) @@ -6270,50 +6272,50 @@ "cqF" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/rnd/xenobiology) "cqG" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "whitegreencorner"},/area/rnd/xenobiology) "cqH" = (/obj/machinery/newscaster{pixel_y = 32},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"cqI" = (/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/machinery/power/smes/buildable{charge = 2e+006; RCon_tag = "Engine Core"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engine/engine_room) -"cqJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/atmos) -"cqK" = (/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/turf/simulated/floor,/area/atmos) +"cqI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/status_display{pixel_y = 32},/turf/simulated/floor/plating,/area/engineering/engineering_monitoring) +"cqJ" = (/obj/machinery/door/window/southright{dir = 1; name = "Containment Pen"; req_access = list(47)},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/rnd/xenobiology) +"cqK" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engineering) "cqL" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/obj/structure/lattice,/turf/space,/area/space) -"cqM" = (/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/atmos) +"cqM" = (/obj/structure/disposalpipe/segment,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor,/area/engineering) "cqN" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 9},/turf/space,/area/space) -"cqO" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "centcom_shuttle_dock_airlock"; name = "interior access button"; pixel_x = -30; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/simulated/floor,/area/hallway/secondary/entry/aft) -"cqP" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor,/area/atmos) -"cqQ" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 10},/turf/simulated/floor,/area/atmos) -"cqR" = (/obj/structure/stool/bed/chair{dir = 1},/obj/effect/landmark/start{name = "Atmospheric Technician"},/turf/simulated/floor,/area/atmos) -"cqS" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 6},/turf/simulated/floor,/area/atmos) +"cqO" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio5"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access = list(55)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/rnd/xenobiology) +"cqP" = (/obj/structure/extinguisher_cabinet{pixel_x = 25},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engineering/workshop) +"cqQ" = (/obj/machinery/shield_capacitor,/turf/simulated/floor/plating,/area/engineering/storage) +"cqR" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 10},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "green"},/area/medical/virologyaccess) +"cqS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engineering/atmos) "cqT" = (/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/security/prison) -"cqU" = (/obj/machinery/door/airlock/glass_atmos{name = "Atmospherics Monitoring Room"; req_access_txt = "24"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/hallway/primary/aft) -"cqV" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/obj/machinery/door/airlock/atmos{name = "Atmospherics Maintenance"; req_access_txt = "12;24"},/turf/simulated/floor,/area/atmos) -"cqW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 8},/turf/simulated/floor/plating,/area/atmos) -"cqX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cqY" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/turf/simulated/floor,/area/atmos) -"cqZ" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engine/drone_fabrication) -"cra" = (/obj/machinery/computer/general_air_control{frequency = 1441; name = "Tank Monitor"; sensors = list("n2_sensor" = "Nitrogen", "o2_sensor" = "Oxygen", "co2_sensor" = "Carbon Dioxide", "tox_sensor" = "Toxins", "n2o_sensor" = "Nitrous Oxide", "waste_sensor" = "Gas Mix Tank")},/turf/simulated/floor,/area/engine/atmos_monitoring) -"crb" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Atmospheric Technician"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/engine/atmos_monitoring) -"crc" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/atmos_monitoring) -"crd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engine/engineering_monitoring) -"cre" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/engine/engineering_monitoring) -"crf" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Station Engineer"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/engine/engineering_monitoring) -"crg" = (/obj/machinery/computer/station_alert,/turf/simulated/floor,/area/engine/engineering_monitoring) -"crh" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engine/engineering_monitoring) -"cri" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/engine/hallway) -"crj" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/engine/workshop) -"crk" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/engine/workshop) -"crl" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engine/workshop) -"crm" = (/obj/machinery/power/port_gen/pacman{anchored = 1},/turf/simulated/floor/plating,/area/engine/storage_hard) -"crn" = (/turf/simulated/floor/plating,/area/engine/storage_hard) -"cro" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/plating,/area/engine/storage_hard) -"crp" = (/obj/structure/closet/crate/solar,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/engine/storage_hard) +"cqU" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 8},/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) +"cqV" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) +"cqW" = (/obj/machinery/atmospherics/binary/pump{dir = 8},/turf/simulated/floor,/area/engineering/atmos) +"cqX" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor,/area/engineering/atmos) +"cqY" = (/obj/machinery/atmospherics/pipe/simple/visible/green,/turf/simulated/floor,/area/engineering/atmos) +"cqZ" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/turf/simulated/floor,/area/engineering/atmos) +"cra" = (/obj/structure/bed/chair{dir = 1},/obj/effect/landmark/start{name = "Atmospheric Technician"},/turf/simulated/floor,/area/engineering/atmos) +"crb" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor,/area/engineering/atmos) +"crc" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/turf/simulated/floor,/area/engineering/atmos) +"crd" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start{name = "Atmospheric Technician"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/engineering/atmos/monitoring) +"cre" = (/obj/machinery/computer/general_air_control{frequency = 1441; name = "Tank Monitor"; sensors = list("n2_sensor" = "Nitrogen", "o2_sensor" = "Oxygen", "co2_sensor" = "Carbon Dioxide", "tox_sensor" = "Toxins", "n2o_sensor" = "Nitrous Oxide", "waste_sensor" = "Gas Mix Tank")},/turf/simulated/floor,/area/engineering/atmos/monitoring) +"crf" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engineering/engineering_monitoring) +"crg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/atmos/monitoring) +"crh" = (/obj/structure/bed/chair/office/dark{dir = 4},/obj/effect/landmark/start{name = "Station Engineer"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/engineering/engineering_monitoring) +"cri" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/engineering/engineering_monitoring) +"crj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engineering/engineering_monitoring) +"crk" = (/obj/machinery/computer/station_alert,/turf/simulated/floor,/area/engineering/engineering_monitoring) +"crl" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/disposalpipe/segment,/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor,/area/engineering) +"crm" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/engineering/workshop) +"crn" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/engineering/workshop) +"cro" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engineering/workshop) +"crp" = (/obj/machinery/power/port_gen/pacman{anchored = 1},/turf/simulated/floor/plating,/area/engineering/storage) "crq" = (/obj/structure/closet,/obj/item/weapon/storage/backpack,/turf/simulated/floor/plating,/area/maintenance/engineering) "crr" = (/obj/machinery/light/small{dir = 8},/obj/structure/closet/crate/freezer,/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery) "crs" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery) "crt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery) "cru" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery) -"crv" = (/obj/machinery/door/airlock/medical{name = "Operating Theatre 1 Storage"; req_access_txt = "45"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgeryprep) +"crv" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio4"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access = list(55)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/rnd/xenobiology) "crw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/medical/surgeryprep) "crx" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/medical/surgeryprep) "cry" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "blue"; dir = 6},/area/medical/surgeryprep) -"crz" = (/obj/machinery/door/airlock/medical{name = "Operating Theatre 2 Storage"; req_access_txt = "45"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgeryprep) +"crz" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio6"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access = list(55)},/obj/machinery/door_control{desc = "A remote control-switch for a door to space."; id = "xenobioout6"; name = "Containment Release Switch"; pixel_x = 24; pixel_y = 4; req_access = list(55)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/rnd/xenobiology) "crA" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery2) "crB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery2) "crC" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery2) @@ -6322,266 +6324,266 @@ "crF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plating,/area/maintenance/medbay) "crG" = (/turf/simulated/wall,/area/maintenance/medbay) "crH" = (/obj/structure/sign/biohazard,/turf/simulated/wall/r_wall,/area/medical/virology) -"crI" = (/obj/machinery/door/airlock/medical{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "virology_airlock_exterior"; locked = 1; name = "Virology Exterior Airlock"; req_access_txt = "39"},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "virology_airlock_control"; name = "Virology Access Button"; pixel_x = -24; pixel_y = 0; req_access_txt = "39"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"crJ" = (/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/medical/virology) -"crK" = (/obj/machinery/light{dir = 1},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/medical/virology) -"crL" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/medical/virology) +"crI" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/plating,/area/engineering/storage) +"crJ" = (/turf/simulated/floor/plating,/area/engineering/storage) +"crK" = (/obj/structure/closet/crate/solar,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/engineering/storage) +"crL" = (/obj/machinery/door/airlock/maintenance{req_one_access = list(10,24)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/engineering) "crM" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/light{dir = 8},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/xenobiology) "crN" = (/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "crO" = (/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "crP" = (/obj/structure/lattice,/obj/structure/grille,/turf/space,/area/space) -"crQ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/visible/purple,/obj/machinery/meter{id = "wloop_atm_meter"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engine/engine_waste) -"crR" = (/obj/machinery/atmospherics/pipe/simple/visible/green,/turf/simulated/floor,/area/atmos) -"crS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/plating,/area/atmos) -"crT" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 8},/turf/simulated/floor/plating,/area/atmos) -"crU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/plating,/area/atmos) -"crV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"crW" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple{dir = 8},/turf/simulated/floor,/area/atmos) -"crX" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple{dir = 1},/turf/simulated/floor,/area/atmos) +"crQ" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/medical/virology) +"crR" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/structure/bed,/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/medical/virology) +"crS" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/medical/virology) +"crT" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 8},/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) +"crU" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"crV" = (/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"crW" = (/obj/machinery/atmospherics/pipe/simple/visible/green,/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"crX" = (/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor,/area/engineering/atmos) "crY" = (/obj/effect/decal/cleanable/cobweb2,/turf/simulated/floor/plating,/area/maintenance/engineering) -"crZ" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple,/turf/simulated/floor,/area/atmos) -"csa" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"csb" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/atmos{name = "Atmospherics Maintenance"; req_access_txt = "12;24"},/turf/simulated/floor,/area/atmos) -"csc" = (/obj/machinery/door/airlock/maintenance{name = "Drone Fabrication/Engine Waste Handling"; req_one_access_txt = "10;24"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"csd" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/cyan,/turf/simulated/floor,/area/atmos) -"cse" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/engine/engine_waste) -"csf" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engine/engine_waste) -"csg" = (/obj/machinery/camera/autoname{dir = 2; network = list("SS13","Supermatter","Atmospherics")},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/engine/engine_waste) -"csh" = (/obj/machinery/light/small{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engine/engine_waste) -"csi" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/engine/atmos_monitoring) -"csj" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/engineering_monitoring) -"csk" = (/obj/structure/table/reinforced,/obj/machinery/light,/obj/item/device/flashlight,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/engine/engineering_monitoring) +"crZ" = (/obj/machinery/atmospherics/binary/pump{dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"csa" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"csb" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 6},/turf/simulated/floor,/area/engineering/atmos) +"csc" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_one_access = list(10,24)},/turf/simulated/floor/plating,/area/engineering) +"csd" = (/obj/machinery/door/airlock/glass{autoclose = 0; frequency = 1379; heat_proof = 1; icon_state = "door_locked"; id_tag = "incinerator_airlock_interior"; locked = 1; name = "Mixing Room Interior Airlock"; req_access = list(12)},/turf/simulated/floor/plating,/area/maintenance/incinerator) +"cse" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "virology_outer"; locked = 1; name = "Engineering External Access"; req_access = list(10,13)},/turf/simulated/floor/plating,/area/maintenance/medbay) +"csf" = (/obj/machinery/door/airlock/medical{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "virologyq_airlock_exterior"; locked = 1; name = "Virology Quarantine Airlock"; req_access = list(39)},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "virologyq_airlock_control"; name = "Virology Quarantine Access Button"; pixel_x = -24; pixel_y = 0; req_access = list(39)},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"csg" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/engineering/atmos/monitoring) +"csh" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/obj/structure/sign/deathsposal{pixel_x = 32},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"csi" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/engineering/atmos/monitoring) +"csj" = (/obj/structure/table/reinforced,/obj/machinery/light,/obj/item/device/flashlight,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/engineering/engineering_monitoring) +"csk" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/engineering_monitoring) "csl" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio2"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/rnd/xenobiology) -"csm" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor,/area/engine/hallway) -"csn" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/engine/hallway) -"cso" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/engine/hallway) -"csp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engine/workshop) -"csq" = (/obj/structure/closet/secure_closet/engineering_welding,/obj/item/clothing/glasses/welding,/obj/item/clothing/glasses/welding,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engine/workshop) -"csr" = (/obj/structure/closet/secure_closet/engineering_welding,/obj/item/clothing/glasses/welding,/obj/item/clothing/glasses/welding,/turf/simulated/floor,/area/engine/workshop) -"css" = (/obj/structure/closet/secure_closet/engineering_electrical,/turf/simulated/floor,/area/engine/workshop) -"cst" = (/obj/structure/closet/secure_closet/engineering_electrical,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/workshop) -"csu" = (/obj/machinery/light_switch{pixel_x = 27},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engine/workshop) -"csv" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/engine/storage_hard) -"csw" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/engine/storage_hard) -"csx" = (/obj/structure/closet/crate,/obj/item/stack/sheet/mineral/phoron{amount = 25},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = 28},/turf/simulated/floor/plating,/area/engine/storage_hard) -"csy" = (/obj/machinery/computer/power_monitor,/turf/simulated/floor,/area/engine/engineering_monitoring) +"csm" = (/obj/machinery/computer/power_monitor,/turf/simulated/floor,/area/engineering/engineering_monitoring) +"csn" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/engineering) +"cso" = (/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor,/area/engineering) +"csp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engineering/workshop) +"csq" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/engineering) +"csr" = (/obj/structure/closet/secure_closet/engineering_welding,/obj/item/clothing/glasses/welding,/obj/item/clothing/glasses/welding,/turf/simulated/floor,/area/engineering/workshop) +"css" = (/obj/structure/closet/secure_closet/engineering_welding,/obj/item/clothing/glasses/welding,/obj/item/clothing/glasses/welding,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engineering/workshop) +"cst" = (/obj/structure/closet/secure_closet/engineering_electrical,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/workshop) +"csu" = (/obj/structure/closet/secure_closet/engineering_electrical,/turf/simulated/floor,/area/engineering/workshop) +"csv" = (/obj/machinery/light_switch{pixel_x = 27},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engineering/workshop) +"csw" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/engineering/storage) +"csx" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/engineering/storage) +"csy" = (/obj/structure/closet/crate,/obj/item/stack/sheet/mineral/phoron{amount = 25},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = 28},/turf/simulated/floor/plating,/area/engineering/storage) "csz" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery) "csA" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery) "csB" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery) "csC" = (/obj/structure/closet/secure_closet/medical2,/obj/machinery/light/small{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery) -"csD" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Pre-Op Prep Room Maintenance Access"; req_access_txt = "45"},/turf/simulated/floor/plating,/area/medical/surgeryprep) +"csD" = (/obj/machinery/door/window/southright{name = "Containment Pen"; req_access = list(47)},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio5"; name = "Containment Blast Doors"; opacity = 0},/turf/simulated/floor/engine,/area/rnd/xenobiology) "csE" = (/obj/structure/closet/secure_closet/medical2,/obj/machinery/light/small{dir = 8},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery2) "csF" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery2) "csG" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery2) "csH" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery2) "csI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/medbay) "csJ" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{dir = 9; icon_state = "warnwhite"},/area/medical/virology) -"csK" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"csK" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "csL" = (/obj/structure/closet/wardrobe/virology_white,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/camera/xray{c_tag = "Virology Access Aft"; dir = 2; network = list("SS13","Medical")},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor{icon_state = "warnwhite"; dir = 5},/area/medical/virology) -"csM" = (/obj/structure/sign/deathsposal,/turf/simulated/wall/r_wall,/area/medical/virology) -"csN" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"csO" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"csM" = (/obj/machinery/door/window/southright{name = "Containment Pen"; req_access = list(47)},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio4"; name = "Containment Blast Doors"; opacity = 0},/turf/simulated/floor/engine,/area/rnd/xenobiology) +"csN" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor,/area/engineering/atmos) +"csO" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor,/area/engineering/atmos) "csP" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"csQ" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Workshop"; req_access_txt = "0"; req_one_access_txt = "11;24"},/turf/simulated/floor,/area/engine/workshop) +"csQ" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor,/area/engineering/atmos) "csR" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/obj/structure/window/reinforced,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/xenobiology) "csS" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"csT" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Workshop"; req_access_txt = "0"; req_one_access_txt = "11;24"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/workshop) -"csU" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor,/area/atmos) -"csV" = (/obj/machinery/airlock_sensor/airlock_interior{id_tag = "eng_al_int_snsr"; master_tag = "engine_room_airlock"; pixel_y = 22; req_access_txt = "10"},/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/atmospherics/binary/pump{dir = 8},/turf/simulated/floor/plating,/area/engine/engine_room) -"csW" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"csX" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor,/area/atmos) -"csY" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/cyan{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/engine/engine_room) -"csZ" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/plating,/area/engine/engine_room) -"cta" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/plating,/area/engine/engine_room) -"ctb" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio1"; name = "Containment Blast Doors"; opacity = 0},/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen"; req_access_txt = "55"},/turf/simulated/floor/engine,/area/rnd/xenobiology) -"ctc" = (/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/engine/engine_room) -"ctd" = (/obj/machinery/door/airlock/maintenance{name = "Atmospherics Maintenance Access"; req_access_txt = "12;24"},/obj/structure/disposalpipe/segment,/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/atmos) -"cte" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engine/engine_waste) -"ctf" = (/obj/machinery/atmospherics/binary/pump{dir = 8},/turf/simulated/floor/plating,/area/engine/engine_waste) -"ctg" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor,/area/atmos) -"cth" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/atmos) -"cti" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/atmos) -"ctj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/atmos) -"ctk" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 6},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engine/engine_room) -"ctl" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Monitoring Room"; req_access_txt = "11"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/engineering_monitoring) -"ctm" = (/obj/machinery/camera{c_tag = "Engineering Hallway North"; dir = 4; network = list("SS13")},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/engine/hallway) -"ctn" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor,/area/engine/hallway) -"cto" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/engine/workshop) +"csT" = (/obj/machinery/atmospherics/omni/mixer{active_power_usage = 7500; use_power = 1; tag_east = 1; tag_east_con = 0.79; tag_north = 1; tag_north_con = 0.21; tag_west = 2},/turf/simulated/floor,/area/engineering/atmos) +"csU" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) +"csV" = (/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) +"csW" = (/obj/machinery/atmospherics/pipe/manifold/visible/green,/turf/simulated/floor,/area/engineering/atmos) +"csX" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"csY" = (/obj/machinery/door/window/southright{name = "Containment Pen"; req_access = list(47)},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio6"; name = "Containment Blast Doors"; opacity = 0},/turf/simulated/floor/engine,/area/rnd/xenobiology) +"csZ" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"cta" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) +"ctb" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/engi_shuttle) +"ctc" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor,/area/engineering/atmos) +"ctd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engineering/atmos/monitoring) +"cte" = (/obj/structure/disposalpipe/segment,/obj/machinery/pipedispenser/disposal,/obj/structure/window/reinforced,/turf/simulated/floor,/area/engineering/atmos) +"ctf" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "engineering_dock_airlock"; name = "interior access button"; pixel_x = -30; pixel_y = -25; req_one_access = list(13,11,24)},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/maintenance/engi_shuttle) +"ctg" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engineering/atmos/monitoring) +"cth" = (/obj/structure/table/rack{dir = 1},/obj/item/clothing/suit/fire/firefighter,/obj/item/weapon/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/weapon/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/clothing/glasses/meson,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) +"cti" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor,/area/engineering) +"ctj" = (/obj/machinery/camera{c_tag = "Engineering Hallway North"; dir = 4; network = list("SS13")},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/engineering) +"ctk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/engineering/workshop) +"ctl" = (/obj/structure/window/reinforced{dir = 1},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/structure/table/reinforced,/turf/simulated/floor,/area/engineering/workshop) +"ctm" = (/obj/structure/window/reinforced{dir = 1},/obj/item/stack/rods{amount = 50},/obj/item/weapon/airlock_electronics,/obj/item/weapon/airlock_electronics,/obj/item/weapon/cell/high,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table/reinforced,/turf/simulated/floor,/area/engineering/workshop) +"ctn" = (/obj/structure/window/reinforced{dir = 1},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table/reinforced,/turf/simulated/floor,/area/engineering/workshop) +"cto" = (/obj/structure/window/reinforced{dir = 1},/obj/item/stack/sheet/plasteel{amount = 10},/obj/item/stack/sheet/plasteel{amount = 10},/obj/item/stack/sheet/mineral/plastic{amount = 10},/obj/structure/table/reinforced,/turf/simulated/floor,/area/engineering/workshop) "ctp" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs"; name = "Operating Theatre Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgeryobs) "ctq" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs"; name = "Operating Theatre Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgeryobs) "ctr" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 2; icon_state = "shutter0"; id = "surgeryobs"; name = "Operating Theatre Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgeryobs) "cts" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"ctt" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/camera{c_tag = "Engineering Workshop"; dir = 8; network = list("SS13"); pixel_y = -23},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engine/workshop) -"ctu" = (/obj/machinery/light_switch{pixel_x = -27; pixel_y = 0},/obj/machinery/camera{c_tag = "Engineering Hard Storage"; dir = 4; network = list("SS13")},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/engine/storage_hard) +"ctt" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/camera{c_tag = "Engineering Workshop"; dir = 8; network = list("SS13"); pixel_y = -23},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engineering/workshop) +"ctu" = (/obj/machinery/light_switch{pixel_x = -27; pixel_y = 0},/obj/machinery/camera{c_tag = "Engineering Hard Storage"; dir = 4; network = list("SS13")},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/engineering/storage) "ctv" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/maintenance/engineering) "ctw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/engineering) -"ctx" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Operating Theatre 1 Maintenance Access"; req_access_txt = "45"},/turf/simulated/floor/plating,/area/medical/surgery) -"cty" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"ctx" = (/obj/machinery/door/airlock/maintenance{name = "Drone Fabrication"; req_one_access = list(10,24)},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cty" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "virology_airlock"; name = "exterior access button"; pixel_x = 20; pixel_y = 20; req_access = list(13)},/turf/simulated/floor/plating/airless,/area/maintenance/medbay) "ctz" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/medbay) "ctA" = (/obj/machinery/light/small{dir = 1},/obj/item/weapon/cigbutt,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/maintenance/medbay) -"ctB" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Operating Theatre 2 Maintenance Access"; req_access_txt = "45"},/turf/simulated/floor/plating,/area/medical/surgery2) +"ctB" = (/obj/machinery/door/airlock/maintenance_hatch{name = "SMES Access"; req_access = list(11)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/engine_smes) "ctC" = (/obj/machinery/shower{icon_state = "shower"; dir = 4},/obj/structure/sign/securearea{pixel_x = -32; pixel_y = 0},/turf/simulated/floor{dir = 8; icon_state = "warnwhite"},/area/medical/virology) "ctD" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "ctE" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/closet/l3closet/virology,/obj/item/clothing/mask/gas,/turf/simulated/floor{dir = 4; icon_state = "warnwhite"},/area/medical/virology) "ctF" = (/turf/simulated/wall,/area/medical/virology) "ctG" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/obj/structure/reagent_dispensers/virusfood{pixel_x = -30},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "ctH" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/item/device/radio/intercom{broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 26},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"ctI" = (/obj/machinery/smartfridge/secure/virology,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"ctI" = (/obj/machinery/door/airlock/maintenance_hatch{icon_state = "door_closed"; locked = 0; name = "Engine Access"; req_one_access = list(11,24)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/engine_airlock) "ctJ" = (/obj/machinery/disease2/incubator,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "ctK" = (/obj/machinery/light{dir = 1},/obj/machinery/computer/centrifuge,/obj/item/weapon/storage/secure/safe{pixel_x = 5; pixel_y = 29},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "ctL" = (/obj/machinery/disease2/isolator,/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "ctM" = (/obj/structure/closet/secure_closet/personal/patient,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "ctN" = (/obj/item/roller,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"ctO" = (/obj/machinery/camera{c_tag = "Virology Monkey Pen"; dir = 2},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/stool/bed/chair,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"ctO" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "ctP" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "ctQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "surgeryobs2"; name = "Operating Theatre Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgeryprep) "ctR" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"ctS" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"ctS" = (/obj/machinery/camera{c_tag = "Virology Monkey Pen"; dir = 2},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/bed/chair,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "ctT" = (/obj/structure/table,/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "ctU" = (/obj/structure/table,/obj/item/weapon/storage/box/syringes,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"ctV" = (/obj/structure/stool/bed/chair{dir = 8},/obj/effect/landmark/start{name = "Xenobiologist"},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"ctV" = (/obj/structure/bed/chair{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "ctW" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "ctX" = (/obj/machinery/power/solar{id = "starboardsolar"; name = "Starboard Solar Array"},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/starboard) "ctY" = (/turf/space,/area/syndicate_station/southwest) -"ctZ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engine/engine_room) -"cua" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 1},/turf/simulated/floor,/area/atmos) +"ctZ" = (/obj/structure/bed/chair{dir = 8},/obj/effect/landmark/start{name = "Xenobiologist"},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"cua" = (/obj/machinery/atmospherics/pipe/simple/visible/green,/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor,/area/engineering/atmos) "cub" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "surgeryobs"; name = "Operating Theatre Privacy Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/medical/surgery) -"cuc" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 4},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/engine/engine_room) -"cud" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "n2_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/atmos) -"cue" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/turf/simulated/floor,/area/atmos) -"cuf" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/engine/engine_room) -"cug" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 8},/turf/simulated/floor/plating,/area/engine/engine_room) -"cuh" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 9},/turf/simulated/floor,/area/atmos) -"cui" = (/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/atmos) -"cuj" = (/obj/machinery/door/airlock/hatch{icon_state = "door_locked"; id_tag = "engine_access_hatch"; locked = 1; req_access_txt = "10"},/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plating,/area/engine/engine_room) -"cuk" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_atmos{name = "Atmospherics"; req_access_txt = "24"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/atmos) -"cul" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/engine/hallway) -"cum" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor,/area/engine/hallway) -"cun" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/hallway) -"cuo" = (/obj/machinery/newscaster{pixel_y = 30},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/hallway) -"cup" = (/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 30},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/hallway) -"cuq" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/engine/hallway) -"cur" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 2; sortType = "Engineering"; name = "Engineering"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/hallway) -"cus" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 2; frequency = 1441; icon_state = "map_injector"; id = "n2_in"; use_power = 1},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/atmos) -"cut" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/engine/workshop) -"cuu" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/workshop) -"cuv" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/engine/workshop) -"cuw" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/engine/workshop) -"cux" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/engineering{name = "Engineering Hard Storage"; req_access_txt = "11"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/workshop) -"cuy" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engine/storage_hard) -"cuz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engine/storage_hard) -"cuA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plating,/area/engine/storage_hard) -"cuB" = (/obj/machinery/power/emitter,/turf/simulated/floor/plating,/area/engine/storage_hard) +"cuc" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/obj/machinery/atmospherics/binary/pump{dir = 1},/turf/simulated/floor,/area/engineering/atmos) +"cud" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor,/area/engineering/atmos) +"cue" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan,/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) +"cuf" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/engineering/atmos) +"cug" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/engineering/atmos) +"cuh" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/engineering) +"cui" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engine Monitoring Room"; req_access = list(11)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/engine_monitoring) +"cuj" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering) +"cuk" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor,/area/engineering) +"cul" = (/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 30},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering) +"cum" = (/obj/machinery/newscaster{pixel_y = 30},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering) +"cun" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/engineering) +"cuo" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "engineering_dock_inner"; locked = 1; name = "Engineering Dock Airlock"; req_access = list(13)},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) +"cup" = (/obj/structure/disposalpipe/sortjunction/flipped{dir = 2; sortType = "Engineering"; name = "Engineering"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering) +"cuq" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/workshop) +"cur" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/engineering/workshop) +"cus" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/engineering/workshop) +"cut" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/engineering/workshop) +"cuu" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engineering/storage) +"cuv" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "engineering_dock_inner"; locked = 1; name = "Engineering Dock Airlock"; req_access = list(13)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) +"cuw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plating,/area/engineering/storage) +"cux" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engineering/storage) +"cuy" = (/obj/machinery/power/emitter,/turf/simulated/floor/plating,/area/engineering/storage) +"cuz" = (/obj/machinery/atmospherics/pipe/manifold/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cuA" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cuB" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cuC" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/maintenance/engineering) "cuD" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plating,/area/maintenance/engineering) -"cuE" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"; pixel_x = 0; pixel_y = 32},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Engineering\\Medbay Maintenance"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/engineering) +"cuE" = (/obj/machinery/door/airlock/glass{autoclose = 0; frequency = 1379; heat_proof = 1; icon_state = "door_locked"; id_tag = "incinerator_airlock_exterior"; locked = 1; name = "Mixing Room Exterior Airlock"; req_access = list(12)},/turf/simulated/floor/plating,/area/maintenance/incinerator) "cuF" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/medbay) "cuG" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/sign/fire{pixel_y = -32},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/maintenance/medbay) "cuH" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/medbay) "cuI" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/maintenance/medbay) "cuJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/medbay) "cuK" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/medbay) -"cuL" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "virology_airlock_control"; name = "Virology Access Button"; pixel_x = 8; pixel_y = -28; req_access_txt = "39"},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 10; icon_state = "warnwhite"},/area/medical/virology) +"cuL" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "engineering_dock_pump"},/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "engineering_dock_airlock"; pixel_x = -25; pixel_y = 0; req_one_access = list(13,11,24); tag_airpump = "engineering_dock_pump"; tag_chamber_sensor = "engineering_dock_sensor"; tag_exterior_door = "engineering_dock_outer"; tag_interior_door = "engineering_dock_inner"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/maintenance/engi_shuttle) "cuM" = (/obj/machinery/atmospherics/pipe/manifold/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cuN" = (/obj/structure/closet/l3closet/virology,/obj/item/clothing/mask/gas,/turf/simulated/floor{dir = 6; icon_state = "warnwhite"},/area/medical/virology) "cuO" = (/obj/structure/table,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/item/weapon/folder/white,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cuP" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cuP" = (/obj/structure/bed/chair/office/dark{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cuQ" = (/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cuR" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cuR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cuS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/virology) "cuT" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/medical/virology) -"cuU" = (/obj/machinery/door/window/southright{dir = 1; name = "Virology Isolation Room One"; req_access_txt = "39"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/medical/virology) +"cuU" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/obj/machinery/light_switch{pixel_x = -27; pixel_y = 0},/obj/machinery/airlock_sensor/airlock_exterior{id_tag = "eng_al_ext_snsr"; layer = 3.3; master_tag = "engine_room_airlock"; pixel_y = -22; req_access = list(10)},/obj/structure/table,/obj/item/weapon/book/manual/supermatter_engine,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/engineering/engine_airlock) "cuV" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/virology) "cuW" = (/obj/structure/extinguisher_cabinet,/turf/simulated/wall/r_wall,/area/medical/virology) "cuX" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cuY" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio2"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/xenobiology) +"cuY" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "engineering_dock_pump"},/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "engineering_dock_sensor"; pixel_x = -25; pixel_y = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/maintenance/engi_shuttle) "cuZ" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"cva" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"cva" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cvb" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/item/clothing/gloves/latex,/obj/item/device/slime_scanner,/obj/item/device/slime_scanner,/obj/item/weapon/hand_labeler,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cvc" = (/obj/structure/table,/obj/machinery/reagentgrinder,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"cvd" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"cvd" = (/obj/structure/bed/chair{dir = 8},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cve" = (/obj/machinery/smartfridge/secure/extract,/turf/simulated/floor{dir = 2; icon_state = "whitecorner"},/area/rnd/xenobiology) "cvf" = (/obj/machinery/optable{name = "Xenobiology Operating Table"},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "whitehall"; dir = 2},/area/rnd/xenobiology) "cvg" = (/obj/machinery/computer/operating{name = "Xenobiology Operating Computer"},/turf/simulated/floor{dir = 8; icon_state = "whitecorner"},/area/rnd/xenobiology) -"cvh" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "o2_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/atmos) -"cvi" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 2; frequency = 1441; icon_state = "map_injector"; id = "o2_in"; use_power = 1},/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/atmos) -"cvj" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 2; frequency = 1443; icon_state = "map_injector"; id = "air_in"; use_power = 1},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/atmos) -"cvk" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1443; icon_state = "map_vent_in"; id_tag = "air_out"; internal_pressure_bound = 2000; internal_pressure_bound_default = 2000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/atmos) -"cvl" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio3"; name = "Containment Blast Doors"; opacity = 0},/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen"; req_access_txt = "55"},/turf/simulated/floor/engine,/area/rnd/xenobiology) +"cvh" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow,/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) +"cvi" = (/obj/machinery/atmospherics/unary/freezer{dir = 2; icon_state = "freezer"},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) +"cvj" = (/obj/machinery/constructable_frame/machine_frame,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) +"cvk" = (/obj/machinery/atmospherics/unary/heater{dir = 2; icon_state = "heater"},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) +"cvl" = (/obj/machinery/door/airlock/medical{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "virology_airlock_exterior"; locked = 1; name = "Virology Exterior Airlock"; req_access = list(39)},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "virology_airlock_control"; name = "Virology Access Button"; pixel_x = -24; pixel_y = 0; req_access = list(39)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cvm" = (/obj/machinery/door/blast/regular{density = 0; dir = 4; icon_state = "pdoor0"; id = "virologyquar"; name = "Virology Emergency Quarantine Blast Doors"; opacity = 0},/turf/simulated/floor{icon_state = "delivery"},/area/medical/virologyaccess) -"cvn" = (/obj/machinery/door/blast/regular{density = 0; dir = 4; icon_state = "pdoor0"; id = "virologyquar"; name = "Virology Emergency Quarantine Blast Doors"; opacity = 0},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "delivery"},/area/medical/virologyaccess) -"cvo" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/engine/engine_room) -"cvp" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor,/area/atmos) -"cvq" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "10;24"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/engine/engine_hallway) -"cvr" = (/obj/machinery/door/airlock/maintenance{name = "Drone Fabrication"; req_one_access_txt = "10;24"},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cvs" = (/obj/machinery/computer/general_air_control{frequency = 1443; level = 3; name = "Distribution and Waste Monitor"; sensors = list("mair_in_meter" = "Mixed Air In", "air_sensor" = "Mixed Air Supply Tank", "mair_out_meter" = "Mixed Air Out", "dloop_atm_meter" = "Distribution Loop", "wloop_atm_meter" = "Engine Waste")},/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/engine/atmos_monitoring) -"cvt" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "solar_xeno_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "10;13"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/solar/starboard) -"cvu" = (/obj/machinery/atmospherics/unary/freezer{dir = 2; icon_state = "freezer"},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) -"cvv" = (/obj/machinery/atmospherics/unary/heater{dir = 2; icon_state = "heater"},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) -"cvw" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor,/area/atmos) -"cvx" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/atmos) -"cvy" = (/obj/machinery/hologram/holopad,/obj/structure/disposalpipe/sortjunction/flipped{dir = 8; sortType = "Drone Fabrication"; name = "Drone Fabrication"},/turf/simulated/floor,/area/atmos) -"cvz" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Workshop"; req_access_txt = "0"; req_one_access_txt = "11;24"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engine/workshop) -"cvA" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_atmos{name = "Atmospherics"; req_access_txt = "24"},/turf/simulated/floor,/area/atmos) -"cvB" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/engine/hallway) -"cvC" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor,/area/engine/hallway) -"cvD" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/light,/turf/simulated/floor,/area/engine/hallway) -"cvE" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor,/area/engine/hallway) -"cvF" = (/obj/structure/disposalpipe/junction{dir = 8; icon_state = "pipe-j2"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/hallway) -"cvG" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor,/area/engine/hallway) -"cvH" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/engine/workshop) -"cvI" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/engine/workshop) -"cvJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engine/workshop) -"cvK" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/engineering{name = "Engineering Hard Storage"; req_access_txt = "11"},/turf/simulated/floor,/area/engine/workshop) -"cvL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engine/storage_hard) +"cvn" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"cvo" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor,/area/engineering/atmos) +"cvp" = (/obj/machinery/hologram/holopad,/obj/structure/disposalpipe/sortjunction/flipped{dir = 8; sortType = "Drone Fabrication"; name = "Drone Fabrication"},/turf/simulated/floor,/area/engineering/atmos) +"cvq" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/engineering) +"cvr" = (/obj/machinery/door/airlock/medical{name = "Operating Theatre 1 Storage"; req_access = list(45)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgeryprep) +"cvs" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/light,/turf/simulated/floor,/area/engineering) +"cvt" = (/obj/machinery/door/airlock/medical{name = "Operating Theatre 2 Storage"; req_access = list(45)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgeryprep) +"cvu" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor,/area/engineering) +"cvv" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor,/area/engineering) +"cvw" = (/obj/structure/disposalpipe/junction{dir = 8; icon_state = "pipe-j2"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering) +"cvx" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor,/area/engineering) +"cvy" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/engineering/workshop) +"cvz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engineering/workshop) +"cvA" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/engineering/workshop) +"cvB" = (/obj/machinery/atmospherics/pipe/simple/visible/red,/turf/simulated/floor,/area/engineering/atmos) +"cvC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engineering/storage) +"cvD" = (/obj/effect/decal/cleanable/blood/oil,/turf/simulated/floor/plating,/area/maintenance/medbay) +"cvE" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/purple{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cvF" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/hidden/purple{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "warnwhite"},/area/medical/virology) +"cvG" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "warnwhitecorner"},/area/medical/virology) +"cvH" = (/obj/machinery/atmospherics/pipe/manifold/hidden/purple{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cvI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/purple,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor{dir = 1; icon_state = "warnwhitecorner"},/area/medical/virology) +"cvJ" = (/obj/structure/bed/chair{dir = 8},/obj/effect/landmark/start{name = "Xenobiologist"},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"cvK" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor,/area/engineering/atmos) +"cvL" = (/obj/machinery/atmospherics/pipe/cap/visible{color = "#ffcc00"},/turf/simulated/floor,/area/engineering/atmos) "cvM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/engineering) "cvN" = (/turf/simulated/wall,/area/maintenance/incinerator) -"cvO" = (/obj/machinery/door/airlock/maintenance{name = "Incinerator Access"; req_access_txt = null; req_one_access_txt = "5;12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/maintenance/incinerator) +"cvO" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/light,/obj/machinery/door_control{desc = "A remote control-switch for shutters."; id = "virologyquar"; name = "Virology Emergency Lockdown Control"; pixel_x = 0; pixel_y = -28; req_access = list(5)},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "greencorner"},/area/medical/virologyaccess) "cvP" = (/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/turf/simulated/floor/plating,/area/maintenance/medbay) -"cvQ" = (/obj/machinery/door/airlock/medical{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "virology_airlock_interior"; locked = 1; name = "Virology Interior Airlock"; req_access_txt = "39"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cvQ" = (/obj/machinery/power/apc/super{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/cyan{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/engineering/atmos) "cvR" = (/obj/structure/table,/obj/machinery/light{dir = 8},/obj/machinery/camera{c_tag = "Virology Port"; dir = 4; network = list("SS13")},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/item/weapon/storage/box/gloves{pixel_x = 4; pixel_y = 4},/obj/item/weapon/storage/box/masks,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cvS" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cvT" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-j1"; dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cvU" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cvV" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cvW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cvX" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cvY" = (/obj/machinery/atmospherics/pipe/manifold/hidden/purple{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cvZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cwa" = (/obj/machinery/door/window/southright{dir = 4; name = "Primate Pen"; req_access_txt = "39"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/medical/virology) +"cvW" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/cyan{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/engineering/atmos) +"cvX" = (/turf/simulated/wall/r_wall,/area/engineering/atmos/storage) +"cvY" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor{dir = 8; icon_state = "yellow"},/area/engineering) +"cvZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 6; icon_state = "intact"; tag = "icon-intact-f (SOUTHEAST)"},/turf/simulated/wall/r_wall,/area/engineering/atmos/storage) +"cwa" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio3"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access = list(55)},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/rnd/xenobiology) "cwb" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cwc" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cwd" = (/obj/structure/closet/l3closet/scientist,/obj/machinery/light{dir = 8},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/xenobiology) "cwe" = (/obj/structure/table,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cwf" = (/obj/structure/table,/obj/item/stack/sheet/mineral/phoron{amount = 5; layer = 2.9},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"cwg" = (/obj/structure/stool/bed/chair{dir = 8},/obj/effect/landmark/start{name = "Xenobiologist"},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"cwg" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/engineering) "cwh" = (/turf/simulated/floor{icon_state = "whitehall"; dir = 4},/area/rnd/xenobiology) "cwi" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/floor{icon_state = "whitehall"; dir = 8},/area/rnd/xenobiology) "cwj" = (/obj/machinery/power/solar{id = "starboardsolar"; name = "Starboard Solar Array"},/obj/structure/cable/yellow,/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/starboard) -"cwk" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 140; external_pressure_bound_default = 140; icon_state = "map_vent_out"; use_power = 1; pressure_checks = 0; pressure_checks_default = 0},/turf/simulated/floor/plating/airless,/area/rnd/xenobiology) +"cwk" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/engineering) "cwl" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio3"; name = "Containment Blast Doors"; opacity = 0},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/rnd/xenobiology) -"cwm" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple,/obj/machinery/meter,/turf/simulated/floor/plating,/area/engine/engine_waste) +"cwm" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor,/area/engineering/workshop) "cwn" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating/airless,/area/solar/port) -"cwo" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 8},/turf/simulated/floor/plating,/area/engine/engine_room) -"cwp" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engine/engine_room) -"cwq" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 4},/obj/machinery/meter,/turf/simulated/floor/plating,/area/engine/engine_room) +"cwo" = (/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/turf/simulated/floor,/area/engineering/workshop) +"cwp" = (/obj/structure/reagent_dispensers/fueltank,/obj/machinery/newscaster{pixel_x = 28; pixel_y = 3},/turf/simulated/floor,/area/engineering/workshop) +"cwq" = (/obj/machinery/portable_atmospherics/canister/phoron,/turf/simulated/floor/plating,/area/engineering/storage) "cwr" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating/airless,/area/solar/port) -"cws" = (/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor,/area/atmos) -"cwt" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/cyan{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/atmos) -"cwu" = (/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/valve/digital/open{dir = 4},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engine/engine_room) -"cwv" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 6; icon_state = "intact"; tag = "icon-intact-f (SOUTHEAST)"},/turf/simulated/wall/r_wall,/area/atmos) -"cww" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor{dir = 8; icon_state = "yellow"},/area/engine/hallway) -"cwx" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/engine/hallway) -"cwy" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/engine/hallway) -"cwz" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor,/area/engine/workshop) -"cwA" = (/obj/effect/decal/cleanable/blood/oil/streak{amount = 0},/turf/simulated/floor,/area/engine/workshop) -"cwB" = (/obj/structure/reagent_dispensers/fueltank,/obj/machinery/newscaster{pixel_x = 28; pixel_y = 3},/turf/simulated/floor,/area/engine/workshop) -"cwC" = (/obj/machinery/portable_atmospherics/canister/phoron,/turf/simulated/floor/plating,/area/engine/storage_hard) -"cwD" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "EngineVent"; name = "Engine Core Vent"; p_open = 0},/turf/simulated/floor/engine,/area/engine/engine_room) -"cwE" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/plating,/area/engine/storage_hard) -"cwF" = (/obj/machinery/shieldwallgen,/turf/simulated/floor/plating,/area/engine/storage_hard) -"cwG" = (/obj/machinery/shieldgen,/turf/simulated/floor/plating,/area/engine/storage_hard) -"cwH" = (/obj/effect/decal/cleanable/blood/oil{amount = 0},/obj/effect/decal/remains/robot,/turf/simulated/floor/plating,/area/maintenance/engineering) +"cws" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/plating,/area/engineering/storage) +"cwt" = (/obj/machinery/shieldgen,/turf/simulated/floor/plating,/area/engineering/storage) +"cwu" = (/obj/machinery/shieldwallgen,/turf/simulated/floor/plating,/area/engineering/storage) +"cwv" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/purple,/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{dir = 1; icon_state = "green"},/area/medical/virology) +"cww" = (/obj/machinery/computer/security/engineering{network = list("Engineering","Engineering Outpost","Power Alarms","Atmosphere Alarms","Fire Alarms")},/turf/simulated/floor{dir = 8; icon_state = "floorgrimecaution"},/area/engineering/engineering_monitoring) +"cwx" = (/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "green"; dir = 4},/area/medical/virology) +"cwy" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cwz" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/medical/virology) +"cwA" = (/obj/structure/table,/obj/item/weapon/storage/lockbox/vials,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cwB" = (/obj/structure/table,/obj/item/weapon/storage/fancy/vials,/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cwC" = (/obj/machinery/atmospherics/pipe/manifold/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cwD" = (/obj/structure/table,/obj/item/weapon/storage/box/syringes{pixel_x = 4; pixel_y = 4},/obj/item/weapon/storage/box/beakers,/obj/item/weapon/reagent_containers/dropper,/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cwE" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/tvalve/bypass,/obj/structure/sign/securearea{desc = "A warning sign which reads 'SIPHON VALVE'."; name = "\improper SIPHON VALVE"; pixel_y = -32},/turf/simulated/floor/plating,/area/medical/virology) +"cwF" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warnwhite"},/area/medical/virology) +"cwG" = (/obj/machinery/camera{c_tag = "Virology Starboard"; dir = 8; network = list("RD"); pixel_y = -22},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cwH" = (/obj/machinery/door/window/southright{dir = 1; name = "Virology Isolation Room One"; req_access = list(39)},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/medical/virology) "cwI" = (/obj/machinery/atmospherics/pipe/tank/phoron{dir = 2; volume = 3200},/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cwJ" = (/obj/machinery/atmospherics/pipe/tank/oxygen{dir = 2; volume = 3200},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cwK" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) @@ -6592,18 +6594,18 @@ "cwP" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/maintenance/medbay) "cwQ" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/medbay) "cwR" = (/obj/structure/closet/l3closet/virology,/obj/item/clothing/mask/gas,/obj/machinery/embedded_controller/radio/airlock/access_controller{tag_exterior_door = "virology_airlock_exterior"; id_tag = "virology_airlock_control"; tag_interior_door = "virology_airlock_interior"; name = "Virology Access Console"; pixel_x = 8; pixel_y = 22},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "greencorner"},/area/medical/virology) -"cwS" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/purple,/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor{dir = 1; icon_state = "green"},/area/medical/virology) -"cwT" = (/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "green"; dir = 4},/area/medical/virology) -"cwU" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Virology Laboratory"; req_access_txt = "39"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "delivery"},/area/medical/virology) -"cwV" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/medical/virology) -"cwW" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cwX" = (/obj/structure/table,/obj/item/weapon/storage/fancy/vials,/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cwY" = (/obj/structure/table,/obj/item/weapon/storage/lockbox/vials,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cwZ" = (/obj/structure/table,/obj/item/weapon/storage/box/syringes{pixel_x = 4; pixel_y = 4},/obj/item/weapon/storage/box/beakers,/obj/item/weapon/reagent_containers/dropper,/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cxa" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/purple,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cxb" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cxc" = (/obj/machinery/atmospherics/pipe/manifold/hidden/purple,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cxd" = (/obj/machinery/camera{c_tag = "Virology Starboard"; dir = 8; network = list("RD"); pixel_y = -22},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cwS" = (/turf/simulated/floor{dir = 8; icon_state = "warnwhite"},/area/medical/virology) +"cwT" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio2"; name = "Containment Blast Doors"; opacity = 0},/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen"; req_access = list(55)},/turf/simulated/floor/engine,/area/rnd/xenobiology) +"cwU" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) +"cwV" = (/obj/machinery/door/window/northleft{dir = 4; name = "Containment Pen"; req_access = list(55)},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/xenobiology) +"cwW" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"cwX" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/yellow,/turf/simulated/floor,/area/engineering/atmos) +"cwY" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow,/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) +"cwZ" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) +"cxa" = (/obj/machinery/atmospherics/valve/digital{dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"cxb" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"cxc" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/turf/simulated/floor,/area/engineering/atmos/storage) +"cxd" = (/obj/machinery/smartfridge/secure/virology,/obj/structure/sign/deathsposal{pixel_y = 32},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cxe" = (/obj/structure/table,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cxf" = (/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating/airless,/area/solar/port) "cxg" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) @@ -6611,31 +6613,31 @@ "cxi" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cxj" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cxk" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"cxl" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = 0; pixel_y = -32; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor,/area/rnd/xenobiology) +"cxl" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/obj/machinery/portable_atmospherics/powered/pump,/turf/simulated/floor,/area/engineering/atmos/storage) "cxm" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/obj/structure/sign/deathsposal{pixel_x = 0; pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/rnd/xenobiology) "cxn" = (/obj/structure/table,/obj/item/weapon/circular_saw,/obj/item/weapon/scalpel{pixel_y = 12},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/rnd/xenobiology) -"cxo" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 6},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/engine/engine_room) -"cxp" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/yellow,/turf/simulated/floor,/area/atmos) -"cxq" = (/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/floor,/area/atmos) -"cxr" = (/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{tag = "icon-map (WEST)"; icon_state = "map"; dir = 8},/turf/simulated/wall/r_wall,/area/atmos) -"cxs" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "EngineRads"; layer = 3.3; name = "Engine Radiation Collector Access"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/engine/engine_room) -"cxt" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor,/area/atmos) -"cxu" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple,/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"cxv" = (/obj/machinery/atmospherics/pipe/simple/visible/green,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor,/area/atmos) -"cxw" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) +"cxo" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/obj/machinery/portable_atmospherics/powered/pump,/obj/machinery/light/small{dir = 1},/turf/simulated/floor,/area/engineering/atmos/storage) +"cxp" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow,/turf/simulated/wall/r_wall,/area/engineering/atmos/storage) +"cxq" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering) +"cxr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engineering/workshop) +"cxs" = (/obj/structure/table,/obj/item/weapon/crowbar,/obj/item/clothing/gloves/black,/obj/item/clothing/gloves/black,/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor,/area/engineering/workshop) +"cxt" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/engineering/workshop) +"cxu" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor,/area/engineering/workshop) +"cxv" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/floor/plating,/area/engineering/storage) +"cxw" = (/obj/structure/dispenser{oxygentanks = 0},/obj/machinery/light,/turf/simulated/floor/plating,/area/engineering/storage) "cxx" = (/turf/simulated/floor/plating/airless,/area/solar/port) "cxy" = (/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating/airless,/area/solar/port) "cxz" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating/airless,/area/solar/port) -"cxA" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/obj/machinery/portable_atmospherics/powered/pump,/obj/machinery/light/small{dir = 1},/turf/simulated/floor,/area/atmos) -"cxB" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/obj/machinery/portable_atmospherics/powered/pump,/turf/simulated/floor,/area/atmos) -"cxC" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/wall/r_wall,/area/atmos) -"cxD" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/hallway) -"cxE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engine/workshop) -"cxF" = (/obj/structure/table,/obj/item/weapon/crowbar,/obj/item/clothing/gloves/black,/obj/item/clothing/gloves/black,/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor,/area/engine/workshop) -"cxG" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/engine/workshop) -"cxH" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor,/area/engine/workshop) -"cxI" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/floor/plating,/area/engine/storage_hard) -"cxJ" = (/obj/structure/dispenser{oxygentanks = 0},/obj/machinery/light,/turf/simulated/floor/plating,/area/engine/storage_hard) +"cxA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor/plating,/area/medical/virology) +"cxB" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Operating Theatre 1 Maintenance Access"; req_access = list(45)},/turf/simulated/floor/plating,/area/medical/surgery) +"cxC" = (/obj/machinery/atmospherics/omni/filter{use_power = 1; tag_east = 1; tag_north = 3; tag_south = 6; tag_west = 2},/turf/simulated/floor,/area/engineering/atmos) +"cxD" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) +"cxE" = (/obj/machinery/atmospherics/omni/filter{use_power = 1; tag_east = 1; tag_north = 4; tag_south = 7; tag_west = 2},/turf/simulated/floor,/area/engineering/atmos) +"cxF" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Operating Theatre 2 Maintenance Access"; req_access = list(45)},/turf/simulated/floor/plating,/area/medical/surgery2) +"cxG" = (/obj/structure/closet/crate,/obj/item/weapon/circuitboard/smes,/obj/item/weapon/circuitboard/smes,/obj/item/weapon/smes_coil,/obj/item/weapon/smes_coil,/obj/item/weapon/smes_coil/super_capacity,/obj/item/weapon/smes_coil/super_capacity,/obj/item/weapon/smes_coil/super_io,/obj/item/weapon/smes_coil/super_io,/turf/simulated/floor/plating,/area/engineering/storage) +"cxH" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_atmos{name = "Atmospherics Monitoring Room"; req_access = list(24)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engineering/atmos/monitoring) +"cxI" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Monitoring Room"; req_access = list(11)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/engineering_monitoring) +"cxJ" = (/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor,/area/engineering/atmos) "cxK" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cxL" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cxM" = (/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) @@ -6643,106 +6645,106 @@ "cxO" = (/obj/machinery/atmospherics/binary/pump{dir = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cxP" = (/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = 28},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cxQ" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/maintenance/medbay) -"cxR" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "virology_airlock"; name = "interior access button"; pixel_x = -20; pixel_y = -20; req_access_txt = "10;13"},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/medbay) +"cxR" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/turf/simulated/floor,/area/engineering/atmos) "cxS" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/closet/secure_closet/personal/patient,/turf/simulated/floor{dir = 8; icon_state = "greencorner"},/area/medical/virology) "cxT" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "green"},/area/medical/virology) "cxU" = (/obj/machinery/embedded_controller/radio/airlock/access_controller{id_tag = "virologyq_airlock_control"; name = "Virology Quarantine Access Console"; pixel_x = -8; pixel_y = -22; tag_exterior_door = "virologyq_airlock_exterior"; tag_interior_door = "virologyq_airlock_interior"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "green"; dir = 4},/area/medical/virology) -"cxV" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Virology Laboratory"; req_access_txt = "39"},/turf/simulated/floor{icon_state = "delivery"},/area/medical/virology) +"cxV" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/red,/obj/machinery/meter,/turf/simulated/floor,/area/engineering/atmos) "cxW" = (/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/medical/virology) "cxX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cxY" = (/obj/structure/table,/obj/machinery/computer/med_data/laptop,/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cxZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/medical/virology) -"cya" = (/obj/machinery/door/window/southright{name = "Virology Isolation Room Two"; req_access_txt = "39"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/medical/virology) -"cyb" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/medical/virology) -"cyc" = (/obj/machinery/door/window/southright{name = "Virology Isolation Room Three"; req_access_txt = "39"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/medical/virology) +"cya" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Pre-Op Prep Room Maintenance Access"; req_access = list(45)},/turf/simulated/floor/plating,/area/medical/surgeryprep) +"cyb" = (/obj/machinery/atmospherics/binary/pump{dir = 1},/turf/simulated/floor,/area/engineering/atmos) +"cyc" = (/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor,/area/engineering/atmos) "cyd" = (/obj/machinery/power/tracker,/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating/airless,/area/solar/port) "cye" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cyf" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cyg" = (/obj/machinery/camera{c_tag = "Xenobiology South"; dir = 8; network = list("SS13","Research"); pixel_y = -22},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) -"cyh" = (/turf/space,/area/vox_station/southeast_solars) -"cyi" = (/obj/machinery/space_heater,/obj/machinery/light/small,/turf/simulated/floor,/area/atmos) -"cyj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/atmos) -"cyk" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow,/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"cyl" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor,/area/atmos) -"cym" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor,/area/atmos) -"cyn" = (/obj/machinery/atmospherics/binary/passive_gate,/turf/simulated/floor,/area/atmos) -"cyo" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"cyp" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; layer = 3.3; master_tag = "robotics_solar_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "13"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating/airless,/area/solar/port) -"cyq" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/green,/turf/simulated/floor,/area/atmos) -"cyr" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/purple{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/turf/simulated/floor,/area/atmos) -"cys" = (/obj/machinery/atmospherics/binary/pump{dir = 4},/turf/simulated/floor,/area/atmos) -"cyt" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/atmos) -"cyu" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/atmos) -"cyv" = (/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor,/area/atmos) -"cyw" = (/obj/machinery/atmospherics/binary/pump{dir = 1},/turf/simulated/floor,/area/atmos) -"cyx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/atmos) -"cyy" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/machinery/camera{c_tag = "Atmospherics South East"; dir = 1},/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/atmos) -"cyz" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/atmos) -"cyA" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/engine/engine_room) -"cyB" = (/obj/machinery/portable_atmospherics/canister/phoron,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) -"cyC" = (/obj/machinery/portable_atmospherics/canister/sleeping_agent,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) -"cyD" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/atmos) -"cyE" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/atmos) -"cyF" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/disposalpipe/segment,/obj/machinery/camera{c_tag = "Atmospherics Substation"; dir = 4},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/atmos) -"cyG" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/engine/hallway) -"cyH" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor,/area/engine/hallway) -"cyI" = (/obj/structure/table,/obj/item/weapon/storage/belt/utility,/obj/item/weapon/storage/belt/utility,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = 3},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor,/area/engine/workshop) -"cyJ" = (/obj/structure/stool/bed/chair,/obj/effect/landmark/start{name = "Station Engineer"},/turf/simulated/floor,/area/engine/workshop) -"cyK" = (/obj/effect/decal/cleanable/blood/oil{amount = 0},/turf/simulated/floor,/area/engine/workshop) -"cyL" = (/obj/machinery/constructable_frame/machine_frame,/turf/simulated/floor,/area/engine/workshop) +"cyh" = (/obj/machinery/computer/security/engineering{network = list("Engineering","Engineering Outpost","Power Alarms","Atmosphere Alarms","Fire Alarms","Atmospherics")},/turf/simulated/floor,/area/engineering/atmos/monitoring) +"cyi" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/machinery/camera{c_tag = "Atmospherics South East"; dir = 1},/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"cyj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor,/area/engineering/atmos) +"cyk" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/engineering/atmos) +"cyl" = (/turf/simulated/floor,/area/engineering/atmos/storage) +"cym" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/visible,/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"cyn" = (/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/floor,/area/engineering/atmos/storage) +"cyo" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor{icon_state = "red"; dir = 8},/area/engineering) +"cyp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"cyq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{tag = "icon-map (WEST)"; icon_state = "map"; dir = 8},/turf/simulated/wall/r_wall,/area/engineering/atmos/storage) +"cyr" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor,/area/engineering) +"cys" = (/obj/structure/table,/obj/item/weapon/storage/belt/utility,/obj/item/weapon/storage/belt/utility,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = 3},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor,/area/engineering/workshop) +"cyt" = (/obj/structure/bed/chair,/obj/effect/landmark/start{name = "Station Engineer"},/turf/simulated/floor,/area/engineering/workshop) +"cyu" = (/obj/machinery/constructable_frame/machine_frame,/turf/simulated/floor,/area/engineering/workshop) +"cyv" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/pipedispenser,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor,/area/engineering/atmos) +"cyw" = (/obj/structure/bed/chair/office/dark,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cyx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor/plating,/area/medical/virology) +"cyy" = (/obj/machinery/atmospherics/binary/passive_gate,/turf/simulated/floor,/area/engineering/atmos) +"cyz" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor,/area/engineering/atmos) +"cyA" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 9},/turf/simulated/floor,/area/engineering/atmos) +"cyB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engineering/atmos) +"cyC" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/turf/simulated/floor,/area/engineering/atmos) +"cyD" = (/obj/machinery/space_heater,/turf/simulated/floor,/area/engineering/atmos/storage) +"cyE" = (/obj/machinery/space_heater,/obj/machinery/light/small,/turf/simulated/floor,/area/engineering/atmos/storage) +"cyF" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/wall/r_wall,/area/engineering/atmos/storage) +"cyG" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_y = 5},/obj/item/weapon/storage/toolbox/mechanical{pixel_y = 5},/obj/item/weapon/storage/toolbox/electrical,/turf/simulated/floor,/area/engineering/workshop) +"cyH" = (/obj/structure/table,/obj/item/device/floor_painter,/obj/item/device/multitool{pixel_x = 5},/obj/item/device/t_scanner,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor,/area/engineering/workshop) +"cyI" = (/obj/structure/table,/obj/item/device/radio/off{pixel_y = 6},/obj/item/device/radio/off{pixel_x = 6; pixel_y = 4},/obj/item/device/radio/off{pixel_x = -6; pixel_y = 4},/obj/item/device/radio/off,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor,/area/engineering/workshop) +"cyJ" = (/obj/structure/table,/obj/machinery/light,/obj/item/weapon/wrench,/obj/item/device/flashlight,/obj/machinery/cell_charger,/turf/simulated/floor,/area/engineering/workshop) +"cyK" = (/obj/machinery/requests_console{announcementConsole = 0; department = "Engineering"; departmentType = 4; name = "Engineering RC"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor,/area/engineering/workshop) +"cyL" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cyM" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cyN" = (/obj/machinery/atmospherics/trinary/mixer,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cyO" = (/mob/living/simple_animal/mouse,/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) "cyP" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/structure/sign/deathsposal{pixel_x = 32},/turf/simulated/floor/plating,/area/maintenance/incinerator) "cyQ" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/wall,/area/maintenance/medbay) -"cyR" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "virology_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/medbay) -"cyS" = (/obj/machinery/door/airlock/medical{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "virologyq_airlock_interior"; locked = 1; name = "Virology Quarantine Airlock"; req_access_txt = "39"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cyR" = (/obj/machinery/door/airlock/medical{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "virology_airlock_interior"; locked = 1; name = "Virology Interior Airlock"; req_access = list(39)},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cyS" = (/obj/machinery/door/airlock/maintenance{name = "Incinerator Access"; req_one_access = list(5,12)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/maintenance/incinerator) "cyT" = (/obj/structure/table,/obj/item/device/antibody_scanner,/obj/machinery/requests_console{department = "Virology"; name = "Virology Requests Console"; pixel_x = -32},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cyU" = (/obj/structure/stool/bed/chair/office/dark,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cyU" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cyV" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 8},/obj/structure/disposalpipe/segment,/obj/item/device/radio{anchored = 1; broadcasting = 0; canhear_range = 7; frequency = 1487; icon = 'icons/obj/items.dmi'; icon_state = "red_phone"; listening = 1; name = "Virology Emergency Phone"; pixel_x = -6; pixel_y = 8},/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cyW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/medical/virology) -"cyX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/medical/virology) +"cyX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 9},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cyY" = (/obj/item/roller,/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cyZ" = (/obj/machinery/camera{c_tag = "Xenobiology Module South"; dir = 4; network = list("SS13","Research"); pixel_x = 0},/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio1"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/xenobiology) +"cyZ" = (/obj/machinery/door/window/southright{dir = 4; name = "Primate Pen"; req_access = list(39)},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/medical/virology) "cza" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "czb" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "czc" = (/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "czd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/xenobiology) -"cze" = (/obj/machinery/portable_atmospherics/canister/sleeping_agent,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) -"czf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/atmos) -"czg" = (/obj/machinery/atmospherics/valve/digital{name = "CO2 Outlet Valve"},/turf/simulated/floor{dir = 6; icon_state = "yellow"},/area/atmos) -"czh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/portable_atmospherics/canister/phoron,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) +"cze" = (/obj/machinery/light{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = -24},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/xenobiology) +"czf" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engineering/atmos) +"czg" = (/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/turf/simulated/floor,/area/engineering/atmos) +"czh" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 1},/turf/simulated/floor,/area/engineering/atmos) "czi" = (/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating/airless,/area/solar/port) -"czj" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1438; icon_state = "map_injector"; id = "cooling_in"; name = "Coolant Injector"; use_power = 1; pixel_y = 1; volume_rate = 700},/turf/simulated/floor/engine/nitrogen{dir = 1; icon_state = "warnplatecorner"; name = "plating"},/area/engine/engine_room) -"czk" = (/obj/machinery/atmospherics/valve/digital{name = "Phoron Outlet Valve"},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/atmos) -"czl" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "n2o_in"; name = "Nitrous Oxide Supply Control"; output_tag = "n2o_out"; sensors = list("n2o_sensor" = "Tank")},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/light,/turf/simulated/floor{dir = 7; icon_state = "escape"},/area/atmos) -"czm" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor{dir = 10; icon_state = "escape"},/area/atmos) -"czn" = (/obj/machinery/atmospherics/binary/pump{dir = 1},/obj/machinery/light,/turf/simulated/floor,/area/atmos) -"czo" = (/obj/machinery/atmospherics/valve/digital{name = "N2O Outlet Valve"},/turf/simulated/floor{icon_state = "escape"; dir = 6},/area/atmos) -"czp" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "tox_in"; name = "Phoron Supply Control"; output_tag = "tox_out"; sensors = list("tox_sensor" = "Tank")},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/light,/turf/simulated/floor{icon_state = "warning"},/area/atmos) -"czq" = (/obj/machinery/camera{c_tag = "Atmospherics South West"; dir = 1},/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/atmos) -"czr" = (/obj/machinery/atmospherics/valve/digital{name = "Gas Mix Outlet Valve"},/turf/simulated/floor{icon_state = "green"; dir = 6},/area/atmos) -"czs" = (/obj/machinery/light,/obj/machinery/atmospherics/binary/pump{dir = 1},/turf/simulated/floor,/area/atmos) -"czt" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/atmos) -"czu" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "waste_in"; name = "Gas Mix Tank Control"; output_tag = "waste_out"; sensors = list("waste_sensor" = "Tank")},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/light,/turf/simulated/floor{dir = 2; icon_state = "green"},/area/atmos) -"czv" = (/obj/machinery/atmospherics/valve/digital{name = "Gas Mix Inlet Valve"},/obj/machinery/camera{c_tag = "Atmospherics South"; dir = 1},/turf/simulated/floor{dir = 10; icon_state = "green"},/area/atmos) -"czw" = (/obj/machinery/light,/turf/simulated/floor,/area/atmos) -"czx" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/turf/simulated/floor,/area/atmos) -"czy" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "co2_in"; name = "Carbon Dioxide Supply Control"; output_tag = "co2_out"; sensors = list("co2_sensor" = "Tank")},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/light,/turf/simulated/floor{dir = 2; icon_state = "yellow"},/area/atmos) -"czz" = (/obj/machinery/atmospherics/unary/vent_pump/engine{dir = 1; external_pressure_bound = 100; external_pressure_bound_default = 0; frequency = 1438; icon_state = "map_vent_in"; id_tag = "cooling_out"; initialize_directions = 1; use_power = 1; pressure_checks = 1; pressure_checks_default = 1; pump_direction = 0},/turf/simulated/floor/engine/nitrogen{icon_state = "warnplatecorner"; name = "plating"},/area/engine/engine_room) -"czA" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor{dir = 10; icon_state = "yellow"},/area/atmos) -"czB" = (/obj/machinery/space_heater,/turf/simulated/floor,/area/atmos) +"czj" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/green,/turf/simulated/floor,/area/engineering/atmos) +"czk" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"czl" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/purple{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/turf/simulated/floor,/area/engineering/atmos) +"czm" = (/obj/machinery/portable_atmospherics/canister/phoron,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) +"czn" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) +"czo" = (/obj/machinery/portable_atmospherics/canister/sleeping_agent,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) +"czp" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) +"czq" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) +"czr" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) +"czs" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_x = 0; pixel_y = 32},/obj/structure/cable/cyan{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes/buildable{charge = 2e+006; RCon_tag = "Substation - Atmospherics"},/turf/simulated/floor/plating,/area/engineering/atmos/storage) +"czt" = (/obj/structure/disposalpipe/segment,/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/power/sensor{name = "Powernet Sensor - Atmospherics Subgrid"; name_tag = "Atmospherics Subgrid"},/obj/structure/cable/cyan{d2 = 4; icon_state = "0-4"},/obj/structure/cable/cyan,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/atmos/storage) +"czu" = (/turf/simulated/wall/r_wall,/area/engineering) +"czv" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Workshop"; req_one_access = list(11,24)},/turf/simulated/floor,/area/engineering/workshop) +"czw" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/bed/chair{dir = 4},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) +"czx" = (/obj/structure/bed/chair{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) +"czy" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/engineering{name = "Engineering Hard Storage"; req_access = list(11)},/turf/simulated/floor,/area/engineering/storage) +"czz" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating,/area/medical/virology) +"czA" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology) +"czB" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 10},/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology) "czC" = (/obj/structure/cable/yellow,/turf/simulated/floor/plating/airless,/area/solar/port) -"czD" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "EngineEmitterPort"; layer = 3.3; name = "Engine Blast Doors"},/turf/simulated/floor/plating,/area/engine/engine_room) -"czE" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_y = 5},/obj/item/weapon/storage/toolbox/mechanical{pixel_y = 5},/obj/item/weapon/storage/toolbox/electrical,/turf/simulated/floor,/area/engine/workshop) -"czF" = (/obj/structure/table,/obj/machinery/light,/obj/item/weapon/wrench,/obj/item/device/flashlight,/obj/machinery/cell_charger,/turf/simulated/floor,/area/engine/workshop) -"czG" = (/obj/structure/table,/obj/item/device/radio/off{pixel_y = 6},/obj/item/device/radio/off{pixel_x = 6; pixel_y = 4},/obj/item/device/radio/off{pixel_x = -6; pixel_y = 4},/obj/item/device/radio/off,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor,/area/engine/workshop) -"czH" = (/obj/machinery/requests_console{announcementConsole = 0; department = "Engineering"; departmentType = 4; name = "Engineering RC"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor,/area/engine/workshop) -"czI" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) +"czD" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology) +"czE" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engineering/atmos) +"czF" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/engineering/atmos) +"czG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/portable_atmospherics/canister/phoron,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) +"czH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/atmos) +"czI" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) "czJ" = (/obj/structure/table,/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) -"czK" = (/obj/structure/stool/bed/chair{dir = 8},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) +"czK" = (/obj/machinery/portable_atmospherics/canister/sleeping_agent,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) "czL" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/camera/autoname,/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) -"czM" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "10;24"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) +"czM" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_atmos{name = "Atmospherics"; req_access = list(24)},/turf/simulated/floor,/area/engineering/atmos) "czN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/engineering) "czO" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/engineering) "czP" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor{icon_state = "floorgrime"},/area/maintenance/incinerator) @@ -6751,19 +6753,19 @@ "czS" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/incinerator) "czT" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/incinerator) "czU" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/maintenance/medbay) -"czV" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "virology_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "virology_pump"; tag_exterior_door = "virology_outer"; frequency = 1379; id_tag = "virology_airlock"; tag_interior_door = "virology_inner"; pixel_x = 25; req_access_txt = "13"; tag_chamber_sensor = "virology_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "virology_pump"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/maintenance/medbay) +"czV" = (/obj/structure/sign/redcross{desc = "The Star of Life, a symbol of Medical Aid."; icon_state = "lifestar"; name = "Medbay"; pixel_x = 0; pixel_y = 32},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{name = "Engineering\\Medbay Maintenance"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/engineering) "czW" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"czX" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "virologyq_airlock_control"; name = "Virology Quarantine Access Button"; pixel_x = -8; pixel_y = 28; req_access_txt = "39"},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"czX" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "virology_airlock_control"; name = "Virology Access Button"; pixel_x = 8; pixel_y = -28; req_access = list(39)},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 10; icon_state = "warnwhite"},/area/medical/virology) "czY" = (/obj/structure/closet/crate/freezer,/obj/item/weapon/virusdish/random,/obj/item/weapon/virusdish/random,/obj/item/weapon/virusdish/random,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "czZ" = (/obj/machinery/computer/diseasesplicer,/obj/machinery/light,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cAa" = (/obj/machinery/disease2/diseaseanalyser,/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cAb" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cAc" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cAd" = (/obj/machinery/atmospherics/pipe/manifold/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cAd" = (/obj/machinery/portable_atmospherics/canister/air,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) "cAe" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cAf" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area/rnd/xenobiology) "cAg" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/rnd/xenobiology) -"cAh" = (/obj/machinery/light{dir = 8},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/xenobiology) +"cAh" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) "cAi" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cAj" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cAk" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) @@ -6775,34 +6777,34 @@ "cAq" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) "cAr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/rnd/xenobiology) "cAs" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/maintenance/engineering) -"cAt" = (/obj/machinery/power/apc/super{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/cyan{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/atmos) -"cAu" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cAv" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/atmos) -"cAw" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/atmos) -"cAx" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/atmos) -"cAy" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/atmos) -"cAz" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plating,/area/atmos) -"cAA" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/atmos) -"cAB" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/atmos) -"cAC" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) -"cAD" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) -"cAE" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) -"cAF" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) +"cAt" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/engineering/atmos) +"cAu" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/atmos/storage) +"cAv" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/disposalpipe/segment,/obj/machinery/camera{c_tag = "Atmospherics Substation"; dir = 4},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/engineering/atmos/storage) +"cAw" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering) +"cAx" = (/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio2"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access = list(55)},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/rnd/xenobiology) +"cAy" = (/obj/machinery/light{dir = 1},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/engineering) +"cAz" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = 25},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering) +"cAA" = (/obj/machinery/alarm{pixel_y = 22},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering) +"cAB" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/engineering) +"cAC" = (/obj/machinery/firealarm{pixel_y = 24},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering) +"cAD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engineering) +"cAE" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering) +"cAF" = (/obj/machinery/light{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor,/area/engineering) "cAG" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; layer = 3.1; master_tag = "incinerator_access_control"; name = "Incinerator airlock control"; pixel_x = 10; pixel_y = -22},/obj/structure/sign/fire{pixel_x = -32; pixel_y = 0},/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor/plating,/area/maintenance/incinerator) -"cAH" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor/plating,/area/atmos) -"cAI" = (/turf/simulated/wall/r_wall,/area/engine/hallway) -"cAJ" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Hallway"; req_one_access_txt = "10;24"},/turf/simulated/floor,/area/engine/hallway) -"cAK" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/glass_engineering{name = "Engineering Hallway"; req_one_access_txt = "10;24"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/hallway) -"cAL" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) -"cAM" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) +"cAH" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/engineering) +"cAI" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/obj/machinery/atmospherics/pipe/simple/visible/red,/turf/simulated/floor,/area/engineering/atmos) +"cAJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor/plating,/area/medical/virology) +"cAK" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor{dir = 10; icon_state = "yellow"},/area/engineering/atmos) +"cAL" = (/obj/machinery/light,/turf/simulated/floor,/area/engineering/atmos) +"cAM" = (/obj/machinery/atmospherics/valve/digital{name = "CO2 Outlet Valve"},/turf/simulated/floor{dir = 6; icon_state = "yellow"},/area/engineering/atmos) "cAN" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cAO" = (/turf/simulated/wall,/area/maintenance/engi_shuttle) "cAP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/engineering) "cAQ" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/incinerator) "cAR" = (/obj/structure/sign/nosmoking_2{pixel_x = 0; pixel_y = -30},/turf/simulated/floor/plating,/area/maintenance/incinerator) -"cAS" = (/obj/machinery/embedded_controller/radio/airlock/access_controller{tag_exterior_door = "incinerator_airlock_exterior"; id_tag = "incinerator_access_control"; tag_interior_door = "incinerator_airlock_interior"; name = "Incinerator Access Console"; pixel_x = -6; pixel_y = -26; req_access_txt = "12"},/obj/machinery/ignition_switch{id = "Incinerator"; pixel_x = 6; pixel_y = -24},/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor{dir = 2; icon_state = "warningcorner"; tag = "icon-warningcorner (WEST)"},/area/maintenance/incinerator) +"cAS" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "co2_in"; name = "Carbon Dioxide Supply Control"; output_tag = "co2_out"; sensors = list("co2_sensor" = "Tank")},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/light,/turf/simulated/floor{dir = 2; icon_state = "yellow"},/area/engineering/atmos) "cAT" = (/turf/simulated/floor{dir = 2; icon_state = "floorgrimecaution"},/area/maintenance/incinerator) -"cAU" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/machinery/meter,/obj/machinery/door_control{id = "disvent"; name = "Incinerator Vent Control"; pixel_x = 0; pixel_y = -24; req_access_txt = null; req_one_access_txt = "12;5"},/turf/simulated/floor{dir = 1; icon_state = "warningcorner"; tag = "icon-warningcorner (WEST)"},/area/maintenance/incinerator) +"cAU" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan,/turf/simulated/floor,/area/engineering/atmos) "cAV" = (/turf/simulated/floor/plating,/area/maintenance/incinerator) "cAW" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area/maintenance/incinerator) "cAX" = (/obj/structure/closet/emcloset,/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "virology_pump"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/maintenance/medbay) @@ -6813,45 +6815,48 @@ "cBc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/medical/virology) "cBd" = (/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology) "cBe" = (/obj/machinery/light,/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology) -"cBf" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology) -"cBg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/medical/virology) -"cBh" = (/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology) -"cBi" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology) -"cBj" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology) -"cBk" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating/airless,/area/space) +"cBf" = (/obj/machinery/camera{c_tag = "Atmospherics South West"; dir = 1},/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/engineering/atmos) +"cBg" = (/obj/machinery/light,/obj/machinery/atmospherics/binary/pump{dir = 1},/turf/simulated/floor,/area/engineering/atmos) +"cBh" = (/obj/machinery/atmospherics/valve/digital{name = "Phoron Outlet Valve"},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/engineering/atmos) +"cBi" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "tox_in"; name = "Phoron Supply Control"; output_tag = "tox_out"; sensors = list("tox_sensor" = "Tank")},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/light,/turf/simulated/floor{icon_state = "warning"},/area/engineering/atmos) +"cBj" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor{dir = 10; icon_state = "escape"},/area/engineering/atmos) +"cBk" = (/obj/machinery/atmospherics/binary/pump{dir = 1},/obj/machinery/light,/turf/simulated/floor,/area/engineering/atmos) "cBl" = (/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology) -"cBm" = (/obj/machinery/door/window/southright{dir = 1; name = "Containment Pen"; req_access_txt = "47"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/rnd/xenobiology) -"cBn" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio4"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/rnd/xenobiology) +"cBm" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_atmos{name = "Atmospherics"; req_access = list(24)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engineering/atmos) +"cBn" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Workshop"; req_one_access = list(11,24)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/workshop) "cBo" = (/obj/machinery/light,/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/rnd/xenobiology) "cBp" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/rnd/xenobiology) -"cBq" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio5"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/rnd/xenobiology) +"cBq" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/engineering{name = "Engineering Hard Storage"; req_access = list(11)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/storage) "cBr" = (/obj/machinery/light,/obj/structure/closet,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/rnd/xenobiology) -"cBs" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio6"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/machinery/door_control{desc = "A remote control-switch for a door to space."; id = "xenobioout6"; name = "Containment Release Switch"; pixel_x = 24; pixel_y = 4; req_access = "55"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/rnd/xenobiology) -"cBt" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/purple{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plating,/area/atmos) -"cBu" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/atmos) -"cBv" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/green,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/atmos) +"cBs" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio1"; name = "Containment Blast Doors"; opacity = 0},/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen"; req_access = list(55)},/turf/simulated/floor/engine,/area/rnd/xenobiology) +"cBt" = (/obj/machinery/atmospherics/valve/digital{name = "N2O Outlet Valve"},/turf/simulated/floor{icon_state = "escape"; dir = 6},/area/engineering/atmos) +"cBu" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "n2o_in"; name = "Nitrous Oxide Supply Control"; output_tag = "n2o_out"; sensors = list("n2o_sensor" = "Tank")},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/light,/turf/simulated/floor{dir = 7; icon_state = "escape"},/area/engineering/atmos) +"cBv" = (/obj/machinery/atmospherics/valve/digital{name = "Gas Mix Inlet Valve"},/obj/machinery/camera{c_tag = "Atmospherics South"; dir = 1},/turf/simulated/floor{dir = 10; icon_state = "green"},/area/engineering/atmos) "cBw" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "incinerator_access_control"; name = "Incinerator airlock control"; pixel_x = -8; pixel_y = 24},/obj/structure/sign/fire{pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/binary/pump{dir = 1},/turf/simulated/floor/plating,/area/maintenance/incinerator) -"cBz" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engine/engine_room) -"cBA" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/engine/engine_room) -"cBB" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) -"cBC" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) -"cBD" = (/obj/machinery/portable_atmospherics/canister/air,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) -"cBE" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) -"cBG" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/atmos) -"cBH" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow,/turf/simulated/floor/plating,/area/engine/engine_room) -"cBI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/engine_hallway) -"cBJ" = (/obj/machinery/light{dir = 1},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/engine/engine_hallway) -"cBK" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/engine_hallway) -"cBL" = (/obj/machinery/alarm{pixel_y = 22},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/engine_hallway) -"cBM" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = 25},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/engine_hallway) -"cBN" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/engine/engine_hallway) -"cBO" = (/obj/machinery/firealarm{pixel_y = 24},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/engine_hallway) -"cBP" = (/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 30},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/engine_hallway) -"cBQ" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/engine_hallway) -"cBR" = (/obj/machinery/light{dir = 1},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor,/area/engine/engine_hallway) -"cBS" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/engine_hallway) -"cBT" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/engine/engine_hallway) -"cBU" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "10;24"},/turf/simulated/floor/plating,/area/engine/engine_hallway) +"cBx" = (/obj/machinery/atmospherics/valve/digital{name = "Gas Mix Outlet Valve"},/turf/simulated/floor{icon_state = "green"; dir = 6},/area/engineering/atmos) +"cBy" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "waste_in"; name = "Gas Mix Tank Control"; output_tag = "waste_out"; sensors = list("waste_sensor" = "Tank")},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/light,/turf/simulated/floor{dir = 2; icon_state = "green"},/area/engineering/atmos) +"cBz" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/atmos) +"cBA" = (/turf/simulated/wall/r_wall,/area/engineering/drone_fabrication) +"cBB" = (/obj/machinery/door/window/southright{name = "Virology Isolation Room Three"; req_access = list(39)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/medical/virology) +"cBC" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/engineering) +"cBD" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering) +"cBE" = (/obj/machinery/camera{c_tag = "Engineering Hallway South West"; dir = 1; pixel_x = 22},/turf/simulated/floor,/area/engineering) +"cBF" = (/obj/machinery/camera{c_tag = "Engineering Hallway South East"; dir = 1},/turf/simulated/floor,/area/engineering) +"cBG" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/engineering) +"cBH" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/engineering) +"cBI" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/engineering) +"cBJ" = (/obj/structure/sign/securearea,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/wall/r_wall,/area/engineering) +"cBK" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating/airless,/area/space) +"cBL" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating/airless,/area/space) +"cBM" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating/airless,/area/maintenance/medbay) +"cBN" = (/obj/structure/bed,/obj/item/weapon/bedsheet/green,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cBO" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/turf/simulated/floor/plating/airless,/area/medical/virology) +"cBP" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating/airless,/area/medical/virology) +"cBQ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 140; external_pressure_bound_default = 140; icon_state = "map_vent_out"; pressure_checks = 1; pressure_checks_default = 1; use_power = 1},/turf/simulated/floor/plating/airless,/area/medical/virology) +"cBR" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/obj/structure/lattice,/turf/space,/area/space) +"cBS" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plating,/area/engineering/atmos) +"cBT" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/engineering/atmos) +"cBU" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/engineering/atmos) "cBV" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/engi_engine) "cBW" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cBX" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) @@ -6859,335 +6864,411 @@ "cBZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/maintenance/engineering) "cCa" = (/turf/simulated/wall/r_wall,/area/maintenance/incinerator) "cCb" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/wall/r_wall,/area/maintenance/incinerator) -"cCc" = (/obj/machinery/door/airlock/glass{autoclose = 0; frequency = 1379; heat_proof = 1; icon_state = "door_locked"; id_tag = "incinerator_airlock_interior"; locked = 1; name = "Mixing Room Interior Airlock"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/incinerator) +"cCc" = (/obj/machinery/door/window/southright{name = "Virology Isolation Room Two"; req_access = list(39)},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/medical/virology) "cCd" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/visible,/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/incinerator) -"cCe" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "virology_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/maintenance/medbay) -"cCf" = (/obj/machinery/door/airlock/medical{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "virologyq_airlock_exterior"; locked = 1; name = "Virology Quarantine Airlock"; req_access_txt = "39"},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "virologyq_airlock_control"; name = "Virology Quarantine Access Button"; pixel_x = -24; pixel_y = 0; req_access_txt = "39"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cCe" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Virology Laboratory"; req_access = list(39)},/turf/simulated/floor{icon_state = "delivery"},/area/medical/virology) +"cCf" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "virology_airlock"; name = "interior access button"; pixel_x = -20; pixel_y = -20; req_access = list(10,13)},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/medbay) "cCg" = (/obj/structure/table,/obj/item/weapon/storage/box/cups,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cCh" = (/obj/structure/reagent_dispensers/water_cooler,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cCi" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cCi" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/obj/machinery/door/airlock/atmos{name = "Atmospherics Maintenance"; req_access = list(12,24)},/turf/simulated/floor,/area/engineering/atmos/storage) "cCj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/virology) "cCk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/status_display,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/virology) "cCl" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 5},/turf/simulated/floor/plating/airless,/area/space) "cCm" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/virology) -"cCn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/status_display,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor/plating,/area/medical/virology) +"cCn" = (/obj/machinery/atmospherics/pipe/manifold/visible/red{tag = "icon-map (WEST)"; icon_state = "map"; dir = 8},/turf/simulated/floor,/area/engineering/atmos) "cCo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/virology) -"cCp" = (/obj/structure/grille,/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/wall/r_wall,/area/atmos) +"cCp" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engineering/atmos) "cCq" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/computer/reconstitutor/animal,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology) -"cCz" = (/turf/simulated/wall/r_wall,/area/engine/drone_fabrication) -"cCA" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engine/drone_fabrication) -"cCB" = (/turf/simulated/wall/r_wall,/area/engine/engine_hallway) -"cCC" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/engine/engine_hallway) -"cCD" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/engine_hallway) -"cCE" = (/turf/simulated/floor,/area/engine/engine_hallway) -"cCF" = (/obj/machinery/camera{c_tag = "Engineering Hallway South West"; dir = 1; pixel_x = 22},/turf/simulated/floor,/area/engine/engine_hallway) -"cCG" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/engine_hallway) -"cCH" = (/obj/machinery/camera{c_tag = "Engineering Hallway South East"; dir = 1},/turf/simulated/floor,/area/engine/engine_hallway) -"cCI" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/engine/engine_hallway) -"cCJ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/engine/engine_hallway) -"cCK" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/engine/engine_hallway) -"cCL" = (/obj/structure/sign/securearea,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/wall/r_wall,/area/engine/engine_hallway) -"cCN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/maintenance/engi_shuttle) -"cCO" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "engineering_dock_airlock"; name = "interior access button"; pixel_x = -30; pixel_y = -25; req_access_txt = "0"; req_one_access_txt = "13;11;24"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/engi_shuttle) +"cCr" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/engineering/atmos) +"cCs" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engineering/atmos) +"cCt" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engineering/atmos) +"cCu" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor/plating,/area/engineering/atmos) +"cCv" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engineering/atmos) +"cCw" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/green,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engineering/atmos) +"cCx" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/purple{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plating,/area/engineering/atmos) +"cCy" = (/obj/machinery/cryopod/robot/right,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cCz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cCA" = (/obj/machinery/computer/cryopod/robot{pixel_y = 30},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/drone_fabrication) +"cCB" = (/obj/machinery/light{dir = 1},/obj/effect/landmark{name = "JoinLateCyborg"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/engineering/drone_fabrication) +"cCC" = (/obj/machinery/ai_status_display{layer = 4; pixel_y = 32},/obj/machinery/light{dir = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/engineering/drone_fabrication) +"cCD" = (/obj/structure/bed/chair,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/drone_fabrication) +"cCE" = (/obj/machinery/recharge_station,/obj/machinery/light_switch{pixel_x = 0; pixel_y = 27},/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cCF" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cCG" = (/turf/simulated/wall/r_wall,/area/engineering/engine_smes) +"cCH" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/engineering/engine_smes) +"cCI" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = -7; pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = 7; pixel_y = -32},/turf/simulated/floor,/area/rnd/xenobiology) +"cCJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engineering/engine_monitoring) +"cCK" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 0; pixel_y = 0},/turf/simulated/wall/r_wall,/area/engineering/engine_monitoring) +"cCL" = (/obj/effect/decal/cleanable/blood/oil,/obj/effect/decal/remains/robot,/turf/simulated/floor/plating,/area/maintenance/engineering) +"cCM" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engineering/engine_monitoring) +"cCN" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_medical{name = "Virology Laboratory"; req_access = list(39)},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "delivery"},/area/medical/virology) +"cCO" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering EVA Storage"; req_one_access = list(11,24)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/engine_eva) "cCP" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air/airlock,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/maintenance/engi_shuttle) "cCQ" = (/obj/machinery/computer/shuttle_control/engineering,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cCR" = (/obj/machinery/atmospherics/valve,/turf/simulated/floor/plating,/area/maintenance/engineering) "cCS" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 6; icon_state = "intact"; tag = "icon-intact-f (SOUTHEAST)"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/engineering) "cCT" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating,/area/maintenance/engineering) -"cCW" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating/airless,/area/space) +"cCU" = (/turf/simulated/wall/r_wall,/area/engineering/engine_airlock) +"cCV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/engineering/engine_airlock) +"cCW" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/engineering{name = "Engineering EVA Storage"; req_access = list(12); req_one_access = list(11,24)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "floorgrime"},/area/engineering/engine_eva) "cCX" = (/turf/simulated/floor/plating/airless,/area/maintenance/medbay) -"cCY" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "virology_airlock"; name = "exterior access button"; pixel_x = 20; pixel_y = 20; req_access_txt = "13"},/turf/simulated/floor/plating/airless,/area/maintenance/medbay) -"cCZ" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/green,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cCY" = (/obj/machinery/door_control{id = "engineering_cubicle"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = -25; pixel_y = 8; specialfunctions = 4},/obj/structure/toilet{dir = 1},/obj/machinery/light/small{dir = 4},/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) +"cCZ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 140; external_pressure_bound_default = 140; icon_state = "map_vent_out"; pressure_checks = 1; pressure_checks_default = 1; use_power = 1},/turf/simulated/floor/plating/airless,/area/maintenance/incinerator) "cDa" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/camera{c_tag = "Virology Break/Access"; dir = 2; network = list("SS13")},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cDb" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cDc" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cDd" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cDe" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/virology) "cDf" = (/obj/structure/disposaloutlet,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/plating/airless,/area/space) +"cDg" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/obj/structure/sign/securearea{desc = "A warning sign which reads 'HOT EXHAUST'."; name = "\improper HOT EXHAUST"; pixel_x = -32},/turf/simulated/floor/plating/airless,/area/space) "cDh" = (/obj/machinery/clonepod,/turf/simulated/floor/engine,/area/rnd/xenobiology) "cDi" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/engine,/area/rnd/xenobiology) -"cDk" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "co2_sensor"},/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/atmos) -"cDn" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "tox_sensor"},/turf/simulated/floor/engine{carbon_dioxide = 0; name = "phoron floor"; nitrogen = 0; oxygen = 0; phoron = 70000},/area/atmos) -"cDq" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "n2o_sensor"},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) -"cDt" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "waste_sensor"; output = 63},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) -"cDv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cDw" = (/obj/machinery/cryopod/robot/right,/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cDx" = (/obj/machinery/light{dir = 1},/obj/effect/landmark{name = "JoinLateCyborg"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/engine/drone_fabrication) -"cDy" = (/obj/machinery/computer/cryopod/robot{pixel_y = 30},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engine/drone_fabrication) -"cDz" = (/obj/structure/stool/bed/chair,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engine/drone_fabrication) -"cDA" = (/obj/machinery/ai_status_display{layer = 4; pixel_y = 32},/obj/machinery/light{dir = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/engine/drone_fabrication) -"cDB" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cDC" = (/obj/machinery/recharge_station,/obj/machinery/light_switch{pixel_x = 0; pixel_y = 27},/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cDD" = (/turf/simulated/wall/r_wall,/area/engine/engine_smes) -"cDE" = (/obj/machinery/door/airlock/maintenance_hatch{name = "SMES Access"; req_access_txt = "11"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/engine_smes) -"cDF" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/engine/engine_smes) -"cDG" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 0; pixel_y = 0},/turf/simulated/wall/r_wall,/area/engine/engine_monitoring) -"cDH" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engine/engine_monitoring) -"cDI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/engine/engine_monitoring) -"cDJ" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engine Monitoring Room"; req_access_txt = "11"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/engine_monitoring) -"cDK" = (/turf/simulated/wall/r_wall,/area/engine/engine_airlock) -"cDL" = (/obj/machinery/door/airlock/maintenance_hatch{icon_state = "door_closed"; locked = 0; name = "Engine Access"; req_access_txt = "0"; req_one_access_txt = "11;24"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/engine_airlock) -"cDM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/engine/engine_airlock) -"cDN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) -"cDO" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "engineering_dock_inner"; locked = 1; name = "Engineering Dock Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) +"cDj" = (/obj/item/weapon/stool,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cDk" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cDl" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cDm" = (/obj/machinery/computer/drone_control,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cDn" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/drone_fabrication) +"cDo" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/drone_fabrication) +"cDp" = (/obj/machinery/computer/security/engineering{name = "Drone Monitoring Cameras"; network = list("Engineering")},/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cDq" = (/obj/machinery/recharge_station,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cDr" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = 25},/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = 3},/obj/item/device/multitool{pixel_x = 5},/obj/item/clothing/gloves/yellow,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/engineering/engine_smes) +"cDs" = (/obj/machinery/light_switch{pixel_x = 0; pixel_y = 27},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/engineering/engine_smes) +"cDt" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/engineering/engine_smes) +"cDu" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -2; pixel_y = 5},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cDv" = (/turf/simulated/wall/r_wall,/area/engineering/engine_monitoring) +"cDw" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/engine_monitoring) +"cDx" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cDy" = (/obj/structure/closet/radiation,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = 28},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cDz" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/obj/machinery/ai_status_display{layer = 4; pixel_y = 32},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cDA" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/engineering/engine_airlock) +"cDB" = (/obj/structure/closet/radiation,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/machinery/camera{c_tag = "Engine Room Airlock"; dir = 2; network = list("SS13","Supermatter")},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/engineering/engine_airlock) +"cDC" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/engine_airlock) +"cDD" = (/obj/structure/bed,/obj/item/weapon/bedsheet/green,/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cDE" = (/obj/item/weapon/stool,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cDF" = (/obj/structure/grille,/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/wall/r_wall,/area/engineering/atmos) +"cDG" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/yellow,/obj/machinery/meter,/turf/simulated/wall/r_wall,/area/engineering/atmos) +"cDH" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/green,/obj/machinery/meter,/turf/simulated/wall/r_wall,/area/engineering/atmos) +"cDI" = (/obj/structure/table,/obj/item/weapon/storage/box/matches,/obj/item/weapon/storage/fancy/cigarettes,/obj/machinery/light/small{dir = 8},/obj/item/weapon/deck,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cDJ" = (/obj/machinery/drone_fabricator,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cDK" = (/obj/effect/decal/remains/robot,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/drone_fabrication) +"cDL" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/drone_fabrication) +"cDM" = (/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cDN" = (/obj/structure/window/basic{dir = 4},/obj/machinery/shower{dir = 1},/obj/structure/curtain/open/shower{color = "#FFA500"; layer = 3.3},/obj/machinery/door/window/northleft{name = "Shower"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) +"cDO" = (/obj/structure/window/basic{dir = 8},/obj/machinery/shower{dir = 1},/obj/structure/curtain/open/shower{color = "#FFA500"; layer = 3.3},/obj/machinery/door/window/northright{name = "Shower"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash) "cDP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cDQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) "cDR" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor/plating,/area/maintenance/engineering) "cDS" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/hidden/cyan,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/maintenance/engineering) "cDT" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/engineering) -"cDU" = (/obj/machinery/door/airlock/glass{autoclose = 0; frequency = 1379; heat_proof = 1; icon_state = "door_locked"; id_tag = "incinerator_airlock_exterior"; locked = 1; name = "Mixing Room Exterior Airlock"; req_access_txt = "12"},/turf/simulated/floor/plating,/area/maintenance/incinerator) +"cDU" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Virology Access"; req_access = list(39)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "whitehall"; dir = 1},/area/medical/virologyaccess) "cDV" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cDW" = (/obj/structure/stool,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cDW" = (/obj/structure/disposalpipe/trunk{dir = 8},/obj/machinery/disposal,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) "cDX" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cDY" = (/obj/machinery/washing_machine,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cDZ" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/engine,/area/rnd/xenobiology) "cEa" = (/obj/machinery/light/small{dir = 8},/obj/structure/disposalpipe/segment,/turf/simulated/floor/engine,/area/rnd/xenobiology) -"cEb" = (/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/atmos) -"cEc" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/atmos) -"cEd" = (/turf/simulated/floor/engine{carbon_dioxide = 0; name = "phoron floor"; nitrogen = 0; oxygen = 0; phoron = 70000},/area/atmos) -"cEe" = (/obj/machinery/portable_atmospherics/canister/phoron,/turf/simulated/floor/engine{carbon_dioxide = 0; name = "phoron floor"; nitrogen = 0; oxygen = 0; phoron = 70000},/area/atmos) -"cEf" = (/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) -"cEg" = (/obj/machinery/portable_atmospherics/canister/sleeping_agent/roomfiller,/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) -"cEh" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) -"cEi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cEj" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cEk" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engine/drone_fabrication) -"cEl" = (/obj/machinery/computer/drone_control,/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cEm" = (/obj/machinery/computer/security/engineering{name = "Drone Monitoring Cameras"; network = list("Engineering")},/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cEn" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engine/drone_fabrication) -"cEo" = (/obj/machinery/recharge_station,/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cEp" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = 25},/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = 3},/obj/item/device/multitool{pixel_x = 5},/obj/item/clothing/gloves/yellow,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/engine/engine_smes) -"cEq" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/engine/engine_smes) -"cEr" = (/obj/machinery/light_switch{pixel_x = 0; pixel_y = 27},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/engine/engine_smes) -"cEs" = (/turf/simulated/wall/r_wall,/area/engine/engine_monitoring) -"cEt" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -2; pixel_y = 5},/turf/simulated/floor,/area/engine/engine_monitoring) -"cEu" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor,/area/engine/engine_monitoring) -"cEv" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/engine_monitoring) -"cEw" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/obj/machinery/ai_status_display{layer = 4; pixel_y = 32},/turf/simulated/floor,/area/engine/engine_monitoring) -"cEx" = (/obj/structure/closet/radiation,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = 28},/turf/simulated/floor,/area/engine/engine_monitoring) -"cEy" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/engine/engine_airlock) -"cEz" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/engine_airlock) -"cEA" = (/obj/structure/closet/radiation,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/machinery/camera{c_tag = "Engine Room Airlock"; dir = 2; network = list("SS13","Supermatter")},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/engine/engine_airlock) -"cEB" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "engineering_dock_pump"},/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "engineering_dock_airlock"; pixel_x = -25; pixel_y = 0; req_access_txt = "0"; req_one_access_txt = "13;11;24"; tag_airpump = "engineering_dock_pump"; tag_chamber_sensor = "engineering_dock_sensor"; tag_exterior_door = "engineering_dock_outer"; tag_interior_door = "engineering_dock_inner"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/maintenance/engi_shuttle) +"cEb" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cEc" = (/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = 3},/turf/simulated/floor,/area/engineering/engine_smes) +"cEd" = (/turf/simulated/floor,/area/engineering/engine_smes) +"cEe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engineering/engine_smes) +"cEf" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cEg" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/engine_monitoring) +"cEh" = (/turf/simulated/floor,/area/engineering/engine_monitoring) +"cEi" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cEj" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cEk" = (/obj/machinery/door/airlock/research{name = "Xenoflora Storage"; req_access = list(55)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"cEl" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor,/area/engineering/engine_airlock) +"cEm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/engineering/engine_airlock) +"cEn" = (/obj/structure/bed,/obj/item/weapon/bedsheet/green,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cEo" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1441; icon_state = "map_injector"; id = "co2_in"; use_power = 1; pixel_y = 1},/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/engineering/atmos) +"cEp" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "co2_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/engineering/atmos) +"cEq" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "co2_sensor"},/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/engineering/atmos) +"cEr" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1441; icon_state = "map_injector"; id = "tox_in"; use_power = 1; pixel_y = 1},/turf/simulated/floor/engine{carbon_dioxide = 0; name = "phoron floor"; nitrogen = 0; oxygen = 0; phoron = 70000},/area/engineering/atmos) +"cEs" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "tox_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{carbon_dioxide = 0; name = "phoron floor"; nitrogen = 0; oxygen = 0; phoron = 70000},/area/engineering/atmos) +"cEt" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "tox_sensor"},/turf/simulated/floor/engine{carbon_dioxide = 0; name = "phoron floor"; nitrogen = 0; oxygen = 0; phoron = 70000},/area/engineering/atmos) +"cEu" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1441; icon_state = "map_injector"; id = "n2o_in"; use_power = 1; pixel_y = 1},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/engineering/atmos) +"cEv" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "n2o_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/engineering/atmos) +"cEw" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "n2o_sensor"},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/engineering/atmos) +"cEx" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1441; icon_state = "map_injector"; id = "waste_in"; use_power = 1; pixel_y = 1},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/engineering/atmos) +"cEy" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "waste_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/engineering/atmos) +"cEz" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "waste_sensor"; output = 63},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/engineering/atmos) +"cEA" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cEB" = (/obj/machinery/door/airlock/research{name = "Xenoflora Research"; req_access = list(55)},/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology/xenoflora) "cEC" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/maintenance/engi_shuttle) "cED" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) +"cEE" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/drone_fabrication) "cEF" = (/turf/simulated/floor/engine/vacuum,/area/maintenance/incinerator) -"cEH" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/green,/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cEI" = (/obj/structure/stool,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cEG" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/toolbox/electrical,/obj/machinery/camera{c_tag = "Drone Fabrication"; dir = 8; network = list("SS13")},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cEH" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cEI" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/box/lights/mixed,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/engineering/engine_smes) "cEJ" = (/obj/structure/table,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cEK" = (/obj/machinery/computer/arcade,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cEL" = (/obj/structure/disposaloutlet{dir = 4},/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/engine,/area/rnd/xenobiology) -"cEM" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engine/engine_room) -"cEN" = (/obj/machinery/light/small,/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/atmos) -"cEO" = (/obj/machinery/light/small,/turf/simulated/floor/engine{carbon_dioxide = 0; name = "phoron floor"; nitrogen = 0; oxygen = 0; phoron = 70000},/area/atmos) -"cEP" = (/obj/machinery/light/small,/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos) -"cEQ" = (/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cER" = (/obj/effect/decal/remains/robot,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engine/drone_fabrication) -"cES" = (/obj/machinery/drone_fabricator,/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cET" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engine/engine_room) -"cEU" = (/obj/structure/disposalpipe/trunk{dir = 8},/obj/machinery/disposal,/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cEV" = (/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = 3},/turf/simulated/floor,/area/engine/engine_smes) -"cEW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engine/engine_smes) -"cEX" = (/turf/simulated/floor,/area/engine/engine_smes) -"cEY" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor,/area/engine/engine_monitoring) -"cEZ" = (/turf/simulated/floor,/area/engine/engine_monitoring) -"cFa" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/engine_monitoring) -"cFb" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engine/engine_monitoring) -"cFc" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/engine/engine_monitoring) -"cFd" = (/obj/machinery/light{dir = 8; icon_state = "tube1"; pixel_y = 0},/obj/machinery/light_switch{pixel_x = -27; pixel_y = 0},/obj/machinery/airlock_sensor/airlock_exterior{id_tag = "eng_al_ext_snsr"; layer = 3.3; master_tag = "engine_room_airlock"; pixel_y = -22; req_access_txt = "10"},/obj/structure/table,/obj/item/weapon/book/manual/supermatter_engine,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/engine/engine_airlock) -"cFe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/engine/engine_airlock) -"cFf" = (/obj/machinery/shower{icon_state = "shower"; dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor,/area/engine/engine_airlock) -"cFg" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "engineering_dock_pump"},/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "engineering_dock_sensor"; pixel_x = -25; pixel_y = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/maintenance/engi_shuttle) +"cEM" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/wall/r_wall,/area/engineering/engine_smes) +"cEN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/engineering/engine_smes) +"cEO" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engineering/engine_smes) +"cEP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cEQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) +"cER" = (/obj/machinery/hologram/holopad,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cES" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cET" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/newscaster{pixel_x = 28; pixel_y = 0},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cEU" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cEV" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/engineering/engine_airlock) +"cEW" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/wall/r_wall,/area/engineering/engine_monitoring) +"cEX" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/engineering/engine_airlock) +"cEY" = (/obj/structure/table,/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) +"cEZ" = (/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/engineering/atmos) +"cFa" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/engineering/atmos) +"cFb" = (/turf/simulated/floor/engine{carbon_dioxide = 0; name = "phoron floor"; nitrogen = 0; oxygen = 0; phoron = 70000},/area/engineering/atmos) +"cFc" = (/obj/machinery/portable_atmospherics/canister/phoron,/turf/simulated/floor/engine{carbon_dioxide = 0; name = "phoron floor"; nitrogen = 0; oxygen = 0; phoron = 70000},/area/engineering/atmos) +"cFd" = (/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/engineering/atmos) +"cFe" = (/obj/machinery/portable_atmospherics/canister/sleeping_agent/roomfiller,/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/engineering/atmos) +"cFf" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/engineering/atmos) +"cFg" = (/obj/machinery/light,/obj/structure/table,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engineering/break_room) "cFh" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/maintenance/engi_shuttle) "cFi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) -"cFk" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/obj/structure/sign/securearea{desc = "A warning sign which reads 'HOT EXHAUST'."; name = "\improper HOT EXHAUST"; pixel_x = -32},/turf/simulated/floor/plating/airless,/area/space) -"cFm" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/green,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) +"cFj" = (/obj/effect/landmark{name = "JoinLateCyborg"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/drone_fabrication) +"cFk" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cFl" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "warning"},/area/engineering/engine_smes) +"cFm" = (/obj/machinery/camera{c_tag = "SMES"; dir = 8; network = list("SS13","Supermatter")},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/engineering/engine_smes) "cFn" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cFo" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/closet/secure_closet/personal/patient,/obj/item/clothing/under/color/white,/obj/item/clothing/under/color/white,/obj/item/clothing/under/color/white,/obj/item/clothing/under/color/white,/obj/item/clothing/under/color/white,/obj/item/clothing/under/color/white,/obj/item/clothing/under/color/white,/obj/item/clothing/shoes/white,/obj/item/clothing/shoes/white,/obj/item/clothing/shoes/white,/obj/item/clothing/shoes/white,/obj/item/clothing/shoes/white,/obj/item/clothing/shoes/white,/obj/item/clothing/shoes/white,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cFq" = (/obj/structure/grille,/obj/structure/grille,/turf/simulated/wall/r_wall,/area/atmos) -"cFr" = (/obj/structure/table,/obj/item/weapon/storage/box/matches,/obj/item/weapon/storage/fancy/cigarettes,/obj/machinery/light/small{dir = 8},/obj/item/weapon/deck,/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cFs" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/engine/engine_room) -"cFt" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 8},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"cFu" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/toolbox/electrical,/obj/machinery/camera{c_tag = "Drone Fabrication"; dir = 8; network = list("SS13")},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cFv" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/wall/r_wall,/area/engine/engine_smes) -"cFw" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/table,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/box/lights/mixed,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/engine/engine_smes) -"cFx" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engine/engine_smes) -"cFy" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/engine/engine_smes) -"cFz" = (/obj/machinery/door/airlock/maintenance_hatch{name = "SMES Access"; req_access_txt = "11"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/engine/engine_monitoring) -"cFA" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/engine/engine_monitoring) -"cFB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/engine/engine_monitoring) -"cFC" = (/obj/machinery/hologram/holopad,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/engine/engine_monitoring) -"cFD" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engine/engine_monitoring) -"cFE" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/newscaster{pixel_x = 28; pixel_y = 0},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/engine/engine_monitoring) -"cFF" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/wall/r_wall,/area/engine/engine_monitoring) -"cFG" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/engine/engine_airlock) -"cFH" = (/obj/machinery/door/airlock/maintenance_hatch{frequency = 1379; icon_state = "door_closed"; id_tag = "engine_airlock_exterior"; locked = 0; name = "Engine Airlock Exterior"; req_access_txt = "10"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/engine/engine_airlock) -"cFI" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/engine/engine_airlock) +"cFp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/engineering/engine_smes) +"cFq" = (/obj/structure/table/reinforced,/obj/machinery/camera{c_tag = "Engine Monitoring Room"; dir = 4; network = list("SS13","Supermatter")},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cFr" = (/obj/item/clothing/shoes/magboots,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/void/engineering,/obj/machinery/door/window/southleft{name = "Engineering Hardsuits"; req_access = list(11)},/obj/structure/table/rack{dir = 8; layer = 2.6},/obj/item/clothing/suit/space/void/engineering,/turf/simulated/floor,/area/engineering/engine_eva) +"cFs" = (/obj/structure/bed/chair/office/dark,/obj/effect/landmark/start{name = "Station Engineer"},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cFt" = (/obj/structure/table/reinforced,/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor,/area/engineering/engine_monitoring) +"cFu" = (/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller{id_tag = "engine_room_airlock"; name = "Engine Room Airlock"; pixel_x = -24; tag_airpump = "engine_airlock_pump"; tag_chamber_sensor = "eng_al_c_snsr"; tag_exterior_door = "engine_airlock_exterior"; tag_exterior_sensor = "eng_al_ext_snsr"; tag_interior_door = "engine_airlock_interior"; tag_interior_sensor = "eng_al_int_snsr"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHEAST)"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/engineering/engine_airlock) +"cFv" = (/obj/structure/closet/emcloset,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/engineering/engine_airlock) +"cFw" = (/obj/machinery/atmospherics/binary/dp_vent_pump/high_volume{dir = 8; frequency = 1379; id = "engine_airlock_pump"},/turf/simulated/floor/plating,/area/engineering/engine_airlock) +"cFx" = (/obj/machinery/light/small,/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/engineering/atmos) +"cFy" = (/obj/machinery/light/small,/turf/simulated/floor/engine{carbon_dioxide = 0; name = "phoron floor"; nitrogen = 0; oxygen = 0; phoron = 70000},/area/engineering/atmos) +"cFz" = (/obj/machinery/light/small,/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/engineering/atmos) +"cFA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cFB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cFC" = (/obj/machinery/computer/drone_control,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/drone_fabrication) +"cFD" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/light,/obj/machinery/mecha_part_fabricator{output_dir = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/engineering/drone_fabrication) +"cFE" = (/obj/machinery/light,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/sensor{name = "Powernet Sensor - Master Grid"; name_tag = "Master"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/engineering/drone_fabrication) +"cFF" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/drone_fabrication) +"cFG" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/engineering/drone_fabrication) +"cFH" = (/obj/machinery/power/smes/buildable{charge = 1e+007; cur_coils = 4; input_attempt = 1; input_level = 500000; output_level = 500000; RCon_tag = "Engine - Main"},/obj/structure/cable,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/engineering/engine_smes) +"cFI" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "warning"},/area/engineering/engine_smes) "cFJ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall,/area/maintenance/engi_shuttle) -"cFK" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "engineering_dock_outer"; locked = 1; name = "Engineering Dock Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle) -"cFL" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "engineering_dock_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -8; req_access_txt = "0"; req_one_access_txt = "13;11;24"},/turf/space,/area/space) +"cFK" = (/obj/structure/table/rack{dir = 8; layer = 2.6},/obj/item/clothing/shoes/magboots,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/void/engineering,/obj/machinery/light{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/southleft{name = "Engineering Hardsuits"; req_access = list(11)},/obj/item/clothing/suit/space/void/engineering,/turf/simulated/floor,/area/engineering/engine_eva) +"cFL" = (/obj/machinery/door/airlock/engineering{name = "Aft Starboard Solar Access"; req_access = list(10)},/obj/machinery/atmospherics/pipe/simple/visible,/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) "cFM" = (/obj/effect/decal/cleanable/generic,/turf/simulated/floor/plating,/area/maintenance/engineering) "cFN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/engineering) "cFO" = (/obj/structure/sign/fire{pixel_y = 32},/obj/structure/lattice,/turf/space,/area/space) "cFP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/virology) "cFQ" = (/obj/machinery/vending/coffee,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) "cFR" = (/obj/machinery/vending/snack,/turf/simulated/floor{icon_state = "white"},/area/medical/virology) -"cFS" = (/obj/machinery/atmospherics/pipe/cap/visible{color = "#00ffff"; dir = 8},/turf/simulated/floor/plating,/area/engine/engine_room) -"cFT" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Aft Port Solar"},/turf/simulated/floor/plating,/area/maintenance/portsolar) -"cFU" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cFV" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"cFW" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "warning"},/area/engine/engine_smes) -"cFX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/engine/engine_smes) -"cFY" = (/obj/machinery/camera{c_tag = "SMES"; dir = 8; network = list("SS13","Supermatter")},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/engine/engine_smes) -"cFZ" = (/obj/structure/table/reinforced,/obj/machinery/camera{c_tag = "Engine Monitoring Room"; dir = 4; network = list("SS13","Supermatter")},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor,/area/engine/engine_monitoring) -"cGa" = (/obj/structure/stool/bed/chair/office/dark,/obj/effect/landmark/start{name = "Station Engineer"},/turf/simulated/floor,/area/engine/engine_monitoring) -"cGb" = (/obj/structure/table/reinforced,/obj/machinery/door_control{desc = "A remote control-switch for the engine control room blast doors."; id = "EngineBlast"; name = "Engine Room Blast Doors"; pixel_x = 0; pixel_y = -3; req_access_txt = "10"},/obj/machinery/door_control{desc = "A remote control-switch for the engine charging port."; id = "EngineEmitterPort"; name = "Engine Charging Port"; pixel_x = -6; pixel_y = 7; req_access_txt = "10"},/obj/machinery/door_control{desc = "A remote control-switch for the engine emitter."; id = "EngineEmitter"; name = "Engine Emitter"; normaldoorcontrol = 2; pixel_x = 6; pixel_y = 7; req_access_txt = "10"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/engine_monitoring) -"cGc" = (/obj/structure/table/reinforced,/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor,/area/engine/engine_monitoring) -"cGd" = (/obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller{id_tag = "engine_room_airlock"; name = "Engine Room Airlock"; pixel_x = -24; tag_airpump = "engine_airlock_pump"; tag_chamber_sensor = "eng_al_c_snsr"; tag_exterior_door = "engine_airlock_exterior"; tag_exterior_sensor = "eng_al_ext_snsr"; tag_interior_door = "engine_airlock_interior"; tag_interior_sensor = "eng_al_int_snsr"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHEAST)"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/engine/engine_airlock) -"cGe" = (/obj/machinery/atmospherics/binary/dp_vent_pump/high_volume{dir = 8; frequency = 1379; id = "engine_airlock_pump"},/turf/simulated/floor/plating,/area/engine/engine_airlock) -"cGf" = (/obj/structure/closet/emcloset,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/engine/engine_airlock) -"cGg" = (/turf/space,/area/shuttle/constructionsite/station) +"cFS" = (/obj/structure/reagent_dispensers/fueltank,/obj/effect/decal/cleanable/blood/oil,/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/maintenance/research_port) +"cFT" = (/obj/machinery/computer/general_air_control/supermatter_core{frequency = 1438; input_tag = "cooling_in"; name = "Engine Cooling Control"; output_tag = "cooling_out"; pressure_setting = 100; sensors = list("engine_sensor" = "Engine Core")},/turf/simulated/floor{icon_state = "warning"},/area/engineering/engine_monitoring) +"cFU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/computer/power_monitor,/turf/simulated/floor{icon_state = "warning"},/area/engineering/engine_monitoring) +"cFV" = (/obj/machinery/computer/rcon,/turf/simulated/floor{icon_state = "warning"},/area/engineering/engine_monitoring) +"cFW" = (/obj/machinery/computer/station_alert,/turf/simulated/floor{icon_state = "warning"},/area/engineering/engine_monitoring) +"cFX" = (/obj/machinery/computer/security/engineering{network = list("Engineering","Power Alarms","Atmosphere Alarms","Fire Alarms","Supermatter")},/turf/simulated/floor{icon_state = "warning"},/area/engineering/engine_monitoring) +"cFY" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "eng_al_c_snsr"; pixel_x = -25; pixel_y = 0},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/engineering/engine_airlock) +"cFZ" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/engineering/engine_airlock) +"cGa" = (/turf/simulated/floor/plating,/area/engineering/engine_airlock) +"cGb" = (/obj/structure/grille,/obj/structure/grille,/turf/simulated/wall/r_wall,/area/engineering/atmos) +"cGc" = (/turf/simulated/wall/r_wall,/area/engineering/engine_room) +"cGd" = (/obj/item/weapon/stool,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora) +"cGe" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/void/atmos,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/void/atmos,/obj/machinery/door/window/northright{name = "Atmospherics Hardsuits"; req_access = list(24)},/turf/simulated/floor,/area/engineering/engine_eva) +"cGf" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; dir = 4; icon_state = "pdoor0"; id = "EngineBlast"; name = "Engine Monitoring Room Blast Doors"; opacity = 0},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGg" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/void/atmos,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/void/atmos,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/northleft{name = "Atmospherics Hardsuits"; req_access = list(24)},/turf/simulated/floor,/area/engineering/engine_eva) +"cGh" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/regular{density = 0; dir = 4; icon_state = "pdoor0"; id = "EngineBlast"; name = "Engine Monitoring Room Blast Doors"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGi" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/regular{density = 0; dir = 4; icon_state = "pdoor0"; id = "EngineBlast"; name = "Engine Monitoring Room Blast Doors"; opacity = 0},/turf/simulated/floor/plating,/area/engineering/engine_room) "cGj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/engineering) -"cGk" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32; pixel_y = 0},/turf/space,/area/space) +"cGk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/regular{density = 0; dir = 4; icon_state = "pdoor0"; id = "EngineBlast"; name = "Engine Monitoring Room Blast Doors"; opacity = 0},/turf/simulated/floor/plating,/area/engineering/engine_room) "cGl" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/virology) -"cGm" = (/obj/machinery/atmospherics/binary/pump{dir = 8},/turf/simulated/floor,/area/atmos) -"cGn" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cGo" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engine/drone_fabrication) -"cGp" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/light,/obj/machinery/mecha_part_fabricator{output_dir = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/engine/drone_fabrication) -"cGq" = (/obj/machinery/computer/drone_control,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engine/drone_fabrication) -"cGr" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engine/drone_fabrication) -"cGs" = (/obj/machinery/light,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/sensor{name = "Powernet Sensor - Master Grid"; name_tag = "Master"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/engine/drone_fabrication) -"cGv" = (/obj/machinery/power/terminal{dir = 8},/obj/machinery/light,/obj/machinery/door_control{id = "engine_electrical_maintenance"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 5; pixel_y = -25; req_access_txt = "10"; specialfunctions = 4},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/engine/engine_smes) -"cGw" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "warning"},/area/engine/engine_smes) -"cGx" = (/obj/machinery/computer/general_air_control/supermatter_core{frequency = 1438; input_tag = "cooling_in"; name = "Engine Cooling Control"; output_tag = "cooling_out"; pressure_setting = 100; sensors = list("engine_sensor" = "Engine Core")},/turf/simulated/floor{icon_state = "warning"},/area/engine/engine_monitoring) -"cGB" = (/obj/machinery/computer/station_alert,/turf/simulated/floor{icon_state = "warning"},/area/engine/engine_monitoring) -"cGC" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "eng_al_c_snsr"; pixel_x = -25; pixel_y = 0},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/engine/engine_airlock) -"cGD" = (/turf/simulated/floor/plating,/area/engine/engine_airlock) -"cGE" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/engine/engine_airlock) +"cGm" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/engineering{name = "Construction Area"; req_access = list(32)},/turf/simulated/floor/plating,/area/construction) +"cGn" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/wall/r_wall,/area/engineering/engine_waste) +"cGo" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/engineering/engine_waste) +"cGp" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 10},/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/engineering/engine_waste) +"cGq" = (/obj/machinery/camera/autoname{dir = 2; network = list("SS13","Supermatter","Atmospherics")},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/engineering/engine_waste) +"cGr" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_waste) +"cGs" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 0; pixel_y = 0},/turf/simulated/wall/r_wall,/area/engineering/engine_room) +"cGt" = (/obj/machinery/light/small{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_waste) +"cGu" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/atmospherics/binary/pump{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGv" = (/obj/machinery/door/airlock/engineering{name = "Engineering Substation"; req_one_access = list(11,24)},/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/substation/engineering) +"cGw" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable/yellow,/obj/machinery/power/sensor{name = "Powernet Sensor - Engine Output"; name_tag = "Engine Output"},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/engine_room) +"cGx" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Locker Room"; req_one_access = list(11,24)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/engineering/locker_room) +"cGy" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) +"cGz" = (/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/machinery/power/smes/buildable{charge = 2e+006; input_attempt = 1; input_level = 100000; output_level = 200000; RCon_tag = "Engine - Core"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/engine_room) +"cGA" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/cyan{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGB" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGC" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGD" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGE" = (/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor/plating{icon_state = "platebotc"},/area/engineering/engine_room) "cGF" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall,/area/maintenance/engineering) "cGG" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/engineering) "cGH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/engineering) -"cGJ" = (/turf/simulated/wall/r_wall,/area/engine/engine_room) -"cGK" = (/obj/machinery/door/airlock/hatch{icon_state = "door_locked"; id_tag = "engine_electrical_maintenance"; locked = 1; name = "Electrical Maintenance"; req_access_txt = "10"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/engine/engine_room) -"cGP" = (/obj/machinery/door/airlock/maintenance_hatch{frequency = 1379; icon_state = "door_closed"; id_tag = "engine_airlock_interior"; locked = 0; name = "Engine Airlock Interior"; req_access_txt = "10"},/turf/simulated/floor/plating,/area/engine/engine_room) +"cGI" = (/obj/machinery/light_switch{pixel_x = 12; pixel_y = 25},/obj/machinery/power/apc/super{dir = 1; name = "north bump"; pixel_y = 24},/obj/structure/cable/cyan{d2 = 8; icon_state = "0-8"},/obj/machinery/power/sensor{name = "Powernet Sensor - Engine Power"; name_tag = "Engine Power"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGJ" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "solar_xeno_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access = list(10,13)},/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/starboardsolar) +"cGK" = (/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGL" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/space,/area/space) +"cGM" = (/obj/structure/grille,/obj/structure/grille,/turf/space,/area/space) +"cGN" = (/obj/machinery/atmospherics/binary/pump{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_waste) +"cGO" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/purple,/turf/simulated/floor/plating,/area/engineering/engine_waste) +"cGP" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_waste) "cGQ" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 6},/turf/space,/area/space) "cGR" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/space,/area/space) "cGS" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{dir = 8},/obj/structure/lattice,/obj/structure/grille,/turf/space,/area/space) -"cGT" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/wall/r_wall,/area/engine/engine_waste) -"cGU" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 10},/obj/effect/decal/cleanable/cobweb,/turf/simulated/floor/plating,/area/engine/engine_waste) -"cGV" = (/turf/simulated/floor/plating,/area/engine/engine_waste) -"cGY" = (/obj/machinery/atmospherics/valve/digital/open{name = "Mixed Air Inlet Valve"},/turf/simulated/floor{icon_state = "arrival"; dir = 5},/area/atmos) -"cGZ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 0; pixel_y = 0},/turf/simulated/wall/r_wall,/area/engine/engine_room) -"cHf" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engine/engine_room) -"cHg" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/engine/engine_room) -"cHh" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1443; input_tag = "air_in"; name = "Mixed Air Supply Control"; output_tag = "air_out"; pressure_setting = 2000; sensors = list("air_sensor" = "Tank")},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/machinery/light{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "arrival"},/area/atmos) -"cHi" = (/obj/machinery/light_switch{pixel_x = 12; pixel_y = 25},/obj/machinery/power/apc/super{dir = 1; name = "north bump"; pixel_y = 24},/obj/structure/cable/cyan{d2 = 8; icon_state = "0-8"},/obj/machinery/power/sensor{name = "Powernet Sensor - Engine Power"; name_tag = "Engine Power"},/turf/simulated/floor/plating,/area/engine/engine_room) -"cHj" = (/turf/simulated/floor/plating,/area/engine/engine_room) -"cHk" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/turf/simulated/floor/plating,/area/engine/engine_room) -"cHl" = (/obj/structure/table,/obj/item/stack/sheet/glass{amount = 50},/obj/item/clothing/head/welding{pixel_x = -5; pixel_y = 3},/obj/item/clothing/glasses/welding,/obj/structure/closet/fireaxecabinet{pixel_y = 32},/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/atmos) +"cGT" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_waste) +"cGU" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "EngineEmitterPortWest"; layer = 3.3; name = "Engine Waste Handling Access"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGV" = (/obj/machinery/door/window/northright{name = "Xenoflora Containment"; req_access = list(47)},/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora_storage) +"cGW" = (/obj/machinery/atmospherics/omni/filter{use_power = 0; tag_east = 1; tag_north = 0; tag_south = 4; tag_west = 2},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cGX" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 6},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) +"cGY" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/engine_room) +"cGZ" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/engineering/engine_room) +"cHa" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/engineering/engine_room) +"cHb" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/engine_room) +"cHc" = (/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHd" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHe" = (/obj/machinery/atmospherics/binary/pump,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHf" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHg" = (/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHh" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging,/turf/space,/area/space) +"cHi" = (/obj/machinery/atmospherics/unary/heat_exchanger{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/engineering/engine_waste) +"cHj" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/visible/purple{dir = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_waste) +"cHk" = (/obj/machinery/atmospherics/unary/heat_exchanger{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/engineering/engine_waste) +"cHl" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "xeno_airlock_control"; name = "Xenobiology Access Button"; pixel_x = -24; pixel_y = 0; req_access = list(55)},/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xeno_airlock_exterior"; locked = 1; name = "Xenobiology External Airlock"; req_access = list(55)},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"cHm" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) "cHn" = (/obj/machinery/power/solar{id = "portsolar"; name = "Port Solar Array"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/port) +"cHo" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) "cHp" = (/obj/machinery/power/solar{id = "portsolar"; name = "Port Solar Array"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/port) "cHq" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 5},/turf/space,/area/space) -"cHr" = (/obj/structure/dispenser,/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/atmos) -"cHs" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/atmos) -"cHt" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor/plating,/area/engine/engine_waste) -"cHu" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/binary/pump,/turf/simulated/floor,/area/atmos) -"cHv" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "n2_in"; name = "Nitrogen Supply Control"; output_tag = "n2_out"; sensors = list("n2_sensor" = "Tank")},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "red"; dir = 1},/area/atmos) -"cHz" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engine/engine_room) -"cHA" = (/obj/machinery/atmospherics/valve/digital/open{name = "Nitrogen Outlet Valve"},/turf/simulated/floor{icon_state = "red"; dir = 5},/area/atmos) -"cHB" = (/obj/machinery/atmospherics/binary/pump,/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/atmos) -"cHC" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor{icon_state = "red"; dir = 9},/area/atmos) -"cHD" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "o2_in"; name = "Oxygen Supply Control"; output_tag = "o2_out"; sensors = list("o2_sensor" = "Tank")},/obj/machinery/camera{c_tag = "Atmospherics North West"; dir = 2},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/machinery/light{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/atmos) -"cHE" = (/obj/machinery/atmospherics/valve/digital/open{name = "Oxygen Outlet Valve"},/turf/simulated/floor{dir = 5; icon_state = "blue"},/area/atmos) -"cHF" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/atmos) -"cHH" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_atmos{name = "Atmospherics Monitoring Room"; req_access_txt = "24"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/atmos) -"cHI" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor/plating{icon_state = "platebotc"},/area/engine/engine_room) +"cHr" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/visible/cyan{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHs" = (/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) +"cHt" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/engineering/engine_room) +"cHu" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 10},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/engineering/engine_room) +"cHv" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHw" = (/obj/machinery/atmospherics/valve/digital{dir = 4; name = "Emergency Cooling Valve 1"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHx" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHy" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_x = -32; pixel_y = 0},/turf/space,/area/space) +"cHz" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall,/area/space) +"cHA" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging,/turf/space,/area/space) +"cHB" = (/obj/machinery/atmospherics/unary/heat_exchanger{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/engineering/engine_waste) +"cHC" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple,/obj/machinery/meter,/turf/simulated/floor/plating,/area/engineering/engine_waste) +"cHD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/visible/purple,/obj/machinery/meter{id = "wloop_atm_meter"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_waste) +"cHE" = (/obj/machinery/atmospherics/unary/heat_exchanger{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/engineering/engine_waste) +"cHF" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "EngineEmitterPortWest"; layer = 3.3; name = "Engine Waste Handling Access"},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHG" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating,/area/maintenance/medbay) +"cHH" = (/obj/machinery/atmospherics/omni/filter{use_power = 0; tag_east = 1; tag_north = 4; tag_south = 0; tag_west = 2},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHI" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) +"cHJ" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor/plating,/area/engineering/engine_room) "cHK" = (/obj/item/stack/rods{amount = 10},/turf/space,/area/space) -"cHL" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/purple,/turf/simulated/floor/plating,/area/engine/engine_waste) -"cHM" = (/obj/machinery/atmospherics/unary/heat_exchanger{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/engine/engine_waste) -"cHN" = (/obj/machinery/atmospherics/unary/heat_exchanger{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/engine/engine_waste) -"cHP" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"cHQ" = (/obj/structure/disposalpipe/segment,/obj/machinery/pipedispenser/disposal,/obj/structure/window/reinforced,/turf/simulated/floor,/area/atmos) -"cHR" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/turf/simulated/floor,/area/atmos) -"cHS" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple{dir = 8},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"cHT" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor,/area/atmos) -"cHV" = (/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"cHW" = (/obj/machinery/atmospherics/pipe/manifold/visible/green,/turf/simulated/floor,/area/atmos) -"cHX" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/engine/atmos_monitoring) -"cHY" = (/obj/machinery/computer/security/engineering{network = list("Engineering","Power Alarms","Atmosphere Alarms","Fire Alarms","Atmospherics")},/turf/simulated/floor,/area/engine/atmos_monitoring) -"cHZ" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engine/engine_room) -"cIa" = (/obj/machinery/atmospherics/unary/freezer{dir = 8; icon_state = "freezer"; req_access_txt = "56"; set_temperature = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engine/engine_room) -"cIb" = (/obj/structure/lattice,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_x = -32; pixel_y = 0},/turf/space,/area/space) +"cHL" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHM" = (/obj/machinery/power/emitter{anchored = 1; id = "EngineEmitter"; state = 2},/obj/structure/cable/cyan,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHN" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_room) +"cHO" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) +"cHP" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHQ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHR" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 10},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHS" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 1},/obj/machinery/meter,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHT" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "EngineRadiatorViewport"; name = "Engine Radiator Viewport Shutter"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHV" = (/obj/machinery/atmospherics/binary/pump/high_power{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cHW" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/space,/area/space) +"cHX" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/structure/lattice,/turf/space,/area/space) +"cHY" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/space,/area/space) +"cHZ" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 5},/turf/space,/area/space) +"cIa" = (/turf/simulated/wall/r_wall,/area/engineering/engine_waste) +"cIb" = (/obj/machinery/light/small,/turf/simulated/floor/plating,/area/engineering/engine_waste) "cIc" = (/obj/item/stack/cable_coil,/turf/space,/area/space) -"cIe" = (/obj/machinery/atmospherics/unary/heat_exchanger{dir = 8},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/engine/engine_waste) -"cIf" = (/obj/machinery/atmospherics/unary/heat_exchanger{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/engine/engine_waste) -"cIg" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/pipedispenser,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 9},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor,/area/atmos) -"cIh" = (/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor,/area/atmos) -"cIi" = (/obj/machinery/atmospherics/pipe/manifold/visible/green{dir = 8},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"cIj" = (/obj/machinery/atmospherics/pipe/simple/visible/green,/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/atmos) -"cIk" = (/obj/machinery/constructable_frame/machine_frame,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/atmos) -"cIl" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow,/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"cIm" = (/obj/machinery/power/emitter{anchored = 1; id = "EngineEmitter"; state = 2},/obj/structure/cable/cyan,/turf/simulated/floor/plating,/area/engine/engine_room) -"cIn" = (/obj/machinery/atmospherics/pipe/simple/visible/green,/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor,/area/atmos) -"cIo" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor/plating,/area/engine/engine_room) -"cIp" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan,/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"cIq" = (/obj/machinery/atmospherics/unary/freezer{dir = 8; icon_state = "freezer"; req_access_txt = "56"; set_temperature = 1},/turf/simulated/floor/plating,/area/engine/engine_room) -"cIr" = (/turf/simulated/wall/r_wall,/area/engine/engine_waste) -"cIs" = (/obj/machinery/light/small,/turf/simulated/floor/plating,/area/engine/engine_waste) -"cIt" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/plating,/area/engine/engine_waste) -"cIu" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/engine/engine_waste) -"cIv" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/obj/machinery/atmospherics/binary/pump{dir = 1},/turf/simulated/floor,/area/atmos) -"cIw" = (/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/engine/engine_room) -"cIy" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engine/engine_room) -"cIz" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/atmos) -"cIA" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/obj/machinery/meter,/turf/simulated/floor,/area/atmos) -"cIB" = (/obj/machinery/atmospherics/valve/digital{dir = 4},/turf/simulated/floor,/area/atmos) -"cID" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/cyan{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/turf/simulated/floor,/area/atmos) -"cIE" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow,/turf/simulated/wall/r_wall,/area/atmos) +"cId" = (/turf/simulated/floor/plating,/area/engineering/engine_waste) +"cIe" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/engineering/engine_waste) +"cIf" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/plating,/area/engineering/engine_waste) +"cIg" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engineering/engine_waste) +"cIh" = (/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/engineering/engine_room) +"cIi" = (/obj/machinery/light,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) +"cIj" = (/turf/simulated/floor/plating{dir = 2; icon_state = "warnplatecorner"},/area/engineering/engine_room) +"cIk" = (/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) +"cIl" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/engineering/engine_room) +"cIm" = (/obj/effect/decal/cleanable/cobweb,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/medbay) +"cIn" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 6},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/engineering/engine_room) +"cIo" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIp" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 10},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/engineering/engine_room) +"cIq" = (/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/machinery/power/generator{anchored = 1; dir = 4},/obj/structure/cable/yellow,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIr" = (/obj/machinery/atmospherics/binary/circulator{anchored = 1; dir = 1},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIs" = (/obj/machinery/atmospherics/pipe/simple/visible/green,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIt" = (/obj/machinery/atmospherics/binary/circulator{anchored = 1},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "EngineRadiatorViewport"; name = "Engine Radiator Viewport Shutter"; opacity = 0},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIv" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 6},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIw" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/space,/area/space) +"cIx" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 6},/turf/space,/area/space) +"cIy" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIz" = (/obj/machinery/camera{c_tag = "Engineering Core West"; dir = 8; network = list("SS13","Supermatter")},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_room) +"cIA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{dir = 8; icon_state = "pdoor1"; id = "SupermatterPort"; layer = 3.3; name = "Reactor Blast Door"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIB" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering EVA Storage"; req_one_access = list(11,24)},/turf/simulated/floor,/area/engineering/engine_eva) +"cIC" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor{icon_state = "hydrofloor"},/area/rnd/xenobiology/xenoflora) +"cID" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIE" = (/obj/machinery/camera{c_tag = "Engineering Core East"; dir = 4; network = list("SS13","Supermatter")},/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 8},/obj/machinery/meter,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) +"cIF" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 9},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIG" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/green,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIH" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 5},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cII" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre 2"; req_access = list(45)},/turf/simulated/floor,/area/medical/surgeryprep) "cIJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/maintenance/portsolar) "cIK" = (/turf/simulated/wall/r_wall,/area/maintenance/portsolar) "cIL" = (/turf/simulated/wall/r_wall,/area/maintenance/engi_engine) -"cIM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance{name = "Engine Waste Handling"; req_one_access_txt = "10;24"},/turf/simulated/floor/plating,/area/maintenance/engi_engine) -"cIN" = (/obj/machinery/camera{c_tag = "Engineering Core West"; dir = 8; network = list("SS13","Supermatter")},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engine/engine_room) -"cIQ" = (/obj/machinery/door/airlock/hatch{icon_state = "door_locked"; id_tag = "engine_access_hatch"; locked = 1; req_access_txt = "10"},/obj/machinery/atmospherics/pipe/simple/visible/cyan,/turf/simulated/floor/plating,/area/engine/engine_room) -"cIR" = (/obj/machinery/camera{c_tag = "Engineering Core East"; dir = 4; network = list("SS13","Supermatter")},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engine/engine_room) -"cIS" = (/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/engine/engine_room) +"cIM" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre 1"; req_access = list(45)},/turf/simulated/floor,/area/medical/surgeryprep) +"cIN" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging,/obj/structure/lattice,/turf/space,/area/space) +"cIO" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Solar - Aft Port"},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"cIP" = (/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIQ" = (/obj/machinery/door/window/eastright{name = "Engineering Delivery"; req_one_access = list(11,24)},/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 6; icon_state = "intact"; tag = "icon-intact-f (SOUTHEAST)"},/turf/simulated/floor{icon_state = "delivery"},/area/engineering/foyer) +"cIR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "SupermatterPort"; layer = 3.3; name = "Reactor Blast Door"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cIS" = (/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engineering/engine_room) +"cIT" = (/obj/machinery/air_sensor{frequency = 1438; id_tag = "engine_sensor"; output = 63},/turf/simulated/floor/engine/nitrogen{icon_state = "warnplate"; name = "plating"},/area/engineering/engine_room) "cIU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/maintenance/portsolar) "cIV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/maintenance/portsolar) "cIW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/maintenance/portsolar) "cIX" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = -32; pixel_y = 0},/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/maintenance/portsolar) "cIY" = (/obj/machinery/power/terminal{dir = 4},/obj/machinery/light/small{dir = 1},/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"cIZ" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1438; icon_state = "map_injector"; id = "cooling_in"; name = "Coolant Injector"; pixel_y = 1; power_rating = 30000; use_power = 1; volume_rate = 700},/turf/simulated/floor/engine/nitrogen{icon_state = "warnplatecorner"; name = "plating"},/area/engineering/engine_room) "cJa" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/maintenance/portsolar) "cJb" = (/obj/structure/closet/wardrobe/black,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/maintenance/engi_engine) "cJc" = (/obj/structure/closet/crate,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/assembly/prox_sensor,/obj/item/device/flashlight,/turf/simulated/floor/plating,/area/maintenance/engi_engine) +"cJd" = (/obj/machinery/atmospherics/unary/vent_pump/engine{dir = 1; external_pressure_bound = 100; external_pressure_bound_default = 0; frequency = 1438; icon_state = "map_vent_in"; id_tag = "cooling_out"; initialize_directions = 1; use_power = 1; pressure_checks = 1; pressure_checks_default = 1; pump_direction = 0},/turf/simulated/floor/engine/nitrogen{dir = 1; icon_state = "warnplatecorner"; name = "plating"},/area/engineering/engine_room) "cJe" = (/turf/simulated/floor/plating,/area/maintenance/engi_engine) "cJf" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/maintenance/engi_engine) "cJg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/engi_engine) -"cJh" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/plating,/area/engine/engine_room) -"cJi" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engine/engine_room) -"cJk" = (/obj/machinery/power/rad_collector,/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/engine/engine_room) -"cJl" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/engine/engine_room) -"cJn" = (/obj/machinery/air_sensor{frequency = 1438; id_tag = "engine_sensor"; output = 63},/turf/simulated/floor/engine/nitrogen{icon_state = "warnplate"; name = "plating"},/area/engine/engine_room) -"cJp" = (/obj/machinery/power/rad_collector,/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/engine/engine_room) -"cJq" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engine/engine_room) -"cJr" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/plating,/area/engine/engine_room) -"cJz" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "robotics_solar_outer"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "10;13"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/portsolar) -"cJA" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "robotics_solar_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "robotics_solar_pump"; tag_exterior_door = "robotics_solar_outer"; frequency = 1379; id_tag = "robotics_solar_airlock"; tag_interior_door = "robotics_solar_inner"; layer = 3.3; pixel_x = 0; pixel_y = -25; req_access_txt = "13"; tag_chamber_sensor = "robotics_solar_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "robotics_solar_sensor"; layer = 3.3; pixel_x = 12; pixel_y = -25},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/decal/warning_stripes,/turf/simulated/floor/plating,/area/maintenance/portsolar) -"cJB" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "robotics_solar_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/portsolar) -"cJC" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; layer = 3.3; master_tag = "robotics_solar_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/portsolar) +"cJh" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJi" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) +"cJj" = (/obj/machinery/atmospherics/pipe/simple/visible/green{dir = 9; icon_state = "intact"; tag = "icon-intact (SOUTHEAST)"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJk" = (/obj/machinery/atmospherics/pipe/simple/visible/green{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJl" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJm" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/floor/plating{icon_state = "platebot"},/area/engineering/engine_room) +"cJn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "SupermatterPort"; layer = 3.3; name = "Reactor Blast Door"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJo" = (/obj/machinery/power/supermatter{layer = 4},/obj/machinery/mass_driver{id = "enginecore"},/turf/simulated/floor/engine/nitrogen{icon_state = "gcircuit"; name = "floor"},/area/engineering/engine_room) +"cJp" = (/turf/simulated/floor/engine/nitrogen{dir = 4; icon_state = "warnplate"; name = "plating"},/area/engineering/engine_room) +"cJq" = (/turf/simulated/floor/engine/nitrogen{dir = 8; icon_state = "warnplate"; name = "plating"},/area/engineering/engine_room) +"cJr" = (/obj/machinery/power/generator{anchored = 1; dir = 4},/obj/structure/cable/yellow,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJs" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "SupermatterPort"; layer = 3.3; name = "Reactor Blast Door"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJu" = (/turf/simulated/floor/engine/nitrogen,/area/engineering/engine_room) +"cJv" = (/obj/machinery/camera{c_tag = "Engineering Core South"; dir = 1; network = list("SS13","Supermatter")},/turf/simulated/floor/engine/nitrogen{dir = 8; icon_state = "warnplate"; name = "plating"},/area/engineering/engine_room) +"cJw" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJx" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engineering/engine_room) +"cJy" = (/obj/machinery/atmospherics/valve/digital{dir = 4; name = "Emergency Cooling Valve 2"},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJz" = (/obj/machinery/door/window/eastright{name = "Engineering Reception Desk"; req_one_access = list(10,24)},/obj/machinery/light,/turf/simulated/floor,/area/engineering/foyer) +"cJA" = (/obj/machinery/door/airlock/maintenance{req_one_access = list(10,24)},/obj/machinery/door/firedoor,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/substation/engineering) +"cJB" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Virology Access"; req_access = list(39)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/medical/virologyaccess) +"cJC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor/plating,/area/rnd/xenobiology/xenoflora) "cJD" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/portsolar) "cJE" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/maintenance/portsolar) -"cJF" = (/obj/machinery/door/airlock/engineering{name = "Aft Port Solar Access"; req_access_txt = "10"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"cJF" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "solar_xeno_pump"; tag_exterior_door = "solar_xeno_outer"; frequency = 1379; id_tag = "solar_xeno_airlock"; tag_interior_door = "solar_xeno_inner"; pixel_x = 25; req_access = list(13); tag_chamber_sensor = "solar_xeno_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "solar_xeno_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "solar_xeno_pump"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/decal/warning_stripes,/turf/simulated/floor/plating,/area/maintenance/starboardsolar) "cJG" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/engi_engine) "cJH" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/engi_engine) "cJI" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/engi_engine) "cJJ" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/engi_engine) "cJK" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/maintenance/engi_engine) -"cJL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/engine/engine_room) -"cJM" = (/turf/simulated/floor/engine/nitrogen{dir = 4; icon_state = "warnplate"; name = "plating"},/area/engine/engine_room) -"cJN" = (/obj/machinery/power/supermatter{layer = 4},/obj/machinery/mass_driver{id = "enginecore"},/turf/simulated/floor/engine/nitrogen{icon_state = "gcircuit"; name = "floor"},/area/engine/engine_room) -"cJO" = (/turf/simulated/floor/engine/nitrogen{dir = 8; icon_state = "warnplate"; name = "plating"},/area/engine/engine_room) -"cJP" = (/obj/machinery/door_control{id = "EngineVent"; name = "Engine Ventillatory Control"; pixel_x = 25; pixel_y = 0; req_access_txt = "10"},/turf/simulated/floor/plating,/area/engine/engine_room) +"cJL" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJM" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJN" = (/obj/machinery/atmospherics/pipe/manifold/visible/purple,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJO" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 9},/turf/simulated/floor/plating,/area/engineering/engine_room) +"cJP" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "EngineVent"; name = "Reactor Vent"; p_open = 0},/turf/simulated/floor/engine,/area/engineering/engine_room) +"cJQ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EJECTION/VENTING PORT'."; name = "\improper EJECTION/VENTING PORT"; pixel_y = 32},/turf/space,/area/space) "cJR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/maintenance/portsolar) "cJS" = (/obj/machinery/power/solar_control{id = "portsolar"; name = "Aft Port Solar Control"; track = 0},/obj/structure/cable/yellow,/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/maintenance/portsolar) "cJT" = (/turf/simulated/floor/plating,/area/maintenance/portsolar) @@ -7196,32 +7277,56 @@ "cJW" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/engi_engine) "cJX" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/engi_engine) "cJY" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor/plating,/area/maintenance/engi_engine) -"cJZ" = (/obj/machinery/door_control{desc = "A remote control-switch for opening the engines blast doors."; id = "EngineRads"; name = "Radiation Collector Access"; pixel_x = 0; pixel_y = -25; req_access_txt = "10"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/engine/engine_room) -"cKa" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/engine/engine_room) -"cKb" = (/turf/simulated/floor/engine/nitrogen,/area/engine/engine_room) -"cKc" = (/obj/machinery/camera{c_tag = "Engineering Core South"; dir = 1; network = list("SS13","Supermatter")},/turf/simulated/floor/engine/nitrogen{dir = 8; icon_state = "warnplate"; name = "plating"},/area/engine/engine_room) -"cKd" = (/obj/machinery/door_control{desc = "A remote control-switch for opening the engines blast doors."; id = "EngineRads"; name = "Radiation Collector Access"; pixel_x = 0; pixel_y = -25; req_access_txt = "10"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/engine/engine_room) +"cJZ" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/space,/area/space) +"cKa" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 5},/obj/structure/lattice,/turf/space,/area/space) +"cKb" = (/obj/effect/landmark{name = "carpspawn"},/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/structure/lattice,/turf/space,/area/space) +"cKc" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Locker Room"; req_one_access = list(11,24)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/locker_room) +"cKd" = (/obj/machinery/door/airlock/maintenance{name = "Engineering EVA Storage Maintainance"; req_access = list(12); req_one_access = list(11,24)},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/engineering/engine_eva) +"cKe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating,/area/maintenance/medbay) "cKf" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/maintenance/portsolar) "cKg" = (/turf/simulated/wall,/area/maintenance/engi_engine) "cKh" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/engi_engine) "cKi" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/engi_engine) "cKj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/engi_engine) +"cKk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/meter,/turf/simulated/floor/plating,/area/maintenance/medbay) "cKl" = (/turf/space,/area/syndicate_station/southeast) +"cKm" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre 1"; req_access = list(45)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/medical/surgeryprep) "cKn" = (/turf/space,/area/syndicate_station/south) -"cKo" = (/obj/structure/lattice,/obj/structure/grille,/obj/structure/lattice,/turf/space,/area/space) -"cKp" = (/obj/item/weapon/wrench,/turf/space,/area/space) -"cKq" = (/turf/space,/area/vox_station/southwest_solars) +"cKo" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre 2"; req_access = list(45)},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/medical/surgeryprep) +"cKp" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_xeno_inner"; locked = 1; name = "Engineering External Access"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) +"cKq" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "xenobio3"; name = "Containment Blast Doors"; opacity = 0},/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen"; req_access = list(55)},/turf/simulated/floor/engine,/area/rnd/xenobiology) "cKr" = (/obj/machinery/power/solar{id = "auxsolarnorth"; name = "Fore Solar Array"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/solar/fore) -"cKv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor/plating,/area/atmos) +"cKs" = (/obj/machinery/door/airlock/research{autoclose = 0; frequency = 1379; icon_state = "door_locked"; id_tag = "xeno_airlock_interior"; locked = 1; name = "Xenobiology Internal Airlock"; req_access = list(55)},/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"cKt" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre 2 Storage"; req_access = list(45)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2) +"cKu" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Operating Theatre 1 Storage"; req_access = list(45)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) +"cKv" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "solar_xeno_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access = list(10,13)},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/solar/starboard) +"cKw" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Hallway"; req_one_access = list(10,24)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engineering) +"cKx" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Hallway"; req_one_access = list(10,24)},/turf/simulated/floor,/area/engineering) +"cKy" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Workshop"; req_one_access = list(11,24)},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engineering/workshop) +"cKz" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/atmos{name = "Atmospherics Maintenance"; req_access = list(12,24)},/obj/machinery/atmospherics/pipe/simple/visible/supply,/turf/simulated/floor,/area/maintenance/atmos_control) "cKA" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/green,/turf/space,/area/space) "cKB" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/space,/area/space) -"cKU" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/engine/engine_room) -"cKV" = (/obj/machinery/door_control{desc = "A remote control-switch for the engine control room blast doors."; id = "EngineBlast"; name = "Engine Room Blast Doors"; pixel_x = 5; pixel_y = -25; req_access_txt = "10"},/obj/machinery/door_control{desc = "A remote control-switch for the engine charging port."; id = "EngineEmitterPort"; name = "Engine Charging Port"; pixel_x = -5; pixel_y = -25; req_access_txt = "10"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engine/engine_room) -"cKX" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/engine/engine_room) -"cKY" = (/obj/machinery/light,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engine/engine_room) -"cKZ" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engine/engine_room) -"cLa" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/engine/engine_waste) -"cLb" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engine/engine_room) +"cKC" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/atmos{name = "Atmospherics Maintenance"; req_access = list(12,24)},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor,/area/maintenance/atmos_control) +"cKD" = (/obj/machinery/door/airlock/maintenance{name = "Atmospherics Maintenance Access"; req_access = list(12,24)},/obj/machinery/atmospherics/pipe/simple/hidden/purple,/turf/simulated/floor,/area/engineering/atmos) +"cKE" = (/obj/machinery/door/airlock/glass_atmos{name = "Atmospherics Monitoring Room"; req_access = list(24)},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor,/area/engineering/atmos/monitoring) +"cKF" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Monitoring Room"; req_access = list(11)},/turf/simulated/floor,/area/engineering/engineering_monitoring) +"cKG" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 140; external_pressure_bound_default = 140; icon_state = "map_vent_out"; pressure_checks = 1; pressure_checks_default = 1; use_power = 1},/turf/simulated/floor/plating/airless,/area/space) +"cKH" = (/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology) +"cKI" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "xeno_airlock_control"; name = "Xenobiology Access Button"; pixel_x = 8; pixel_y = -28; req_access = list(55)},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{dir = 10; icon_state = "warnwhite"},/area/rnd/xenobiology) +"cKJ" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "solar_xeno_outer"; locked = 1; name = "Engineering External Access"; req_access = list(10,13)},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/starboardsolar) +"cKK" = (/turf/space,/area/skipjack_station/southwest_solars) +"cKL" = (/obj/machinery/door/airlock/engineering{name = "Aft Port Solar Access"; req_access = list(10)},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"cKM" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; layer = 3.3; master_tag = "robotics_solar_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/portsolar) +"cKN" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "robotics_solar_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "robotics_solar_pump"; tag_exterior_door = "robotics_solar_outer"; frequency = 1379; id_tag = "robotics_solar_airlock"; tag_interior_door = "robotics_solar_inner"; layer = 3.3; pixel_x = 0; pixel_y = -25; req_access = list(13); tag_chamber_sensor = "robotics_solar_sensor"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "robotics_solar_sensor"; layer = 3.3; pixel_x = 12; pixel_y = -25},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/decal/warning_stripes,/turf/simulated/floor/plating,/area/maintenance/portsolar) +"cKO" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "robotics_solar_inner"; locked = 1; name = "Engineering External Access"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"cKP" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; layer = 3.3; master_tag = "robotics_solar_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access = list(13)},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating/airless,/area/solar/port) +"cKQ" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "robotics_solar_outer"; locked = 1; name = "Engineering External Access"; req_access = list(10,13)},/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/maintenance/portsolar) +"cKR" = (/obj/machinery/door_control{id = "EngineVent"; name = "Reactor Ventillatory Control"; pixel_x = -25; pixel_y = 0; req_access = list(10)},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cKS" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance{name = "Engine Waste Handling"; req_one_access = list(10,24)},/turf/simulated/floor/plating,/area/maintenance/engi_engine) +"cKT" = (/obj/machinery/door_control{desc = "A remote control-switch for the engine radiator viewport shutters."; id = "EngineRadiatorViewport"; name = "Engine Radiator Viewport Shutters"; pixel_x = 25; pixel_y = 0; req_access = list(10)},/obj/machinery/atmospherics/pipe/manifold/visible/purple{dir = 4},/obj/machinery/meter,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cKU" = (/obj/machinery/door/airlock/hatch{icon_state = "door_locked"; id_tag = "engine_access_hatch"; locked = 1; req_access = list(10)},/obj/machinery/atmospherics/pipe/simple/visible/cyan,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cKV" = (/obj/machinery/door/airlock/hatch{icon_state = "door_locked"; id_tag = "engine_access_hatch"; locked = 1; req_access = list(10)},/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plating,/area/engineering/engine_room) +"cKW" = (/obj/machinery/door_control{desc = "A remote control-switch for the engine control room blast doors."; id = "EngineBlast"; name = "Engine Monitoring Room Blast Doors"; pixel_x = 5; pixel_y = -25; req_access = list(10)},/obj/machinery/door_control{desc = "A remote control-switch for the engine charging port."; id = "SupermatterPort"; name = "Reactor Blast Doors"; pixel_x = -5; pixel_y = -25; req_access = list(10)},/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engineering/engine_room) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -7274,7 +7379,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaaaaabaabaabaabaabaaaaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabgaabaabaabaabaabaaaaabaabaabaabaabaaaaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaaaaabaabaabaabaabaaaaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -7284,168 +7389,168 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaajaakaalaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaamaamaamaamaanaamaamaamaamaamaamaamaamaamaaaaaaaaaaaaaaaaaaaaaaajaaoaapaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqaaaaaaaafaaaaaaaaaaaaaaraapaasaataafaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauaaaaaaaaaaauaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaacKraawaavaaacKraawaavaaacKraawaavaafaafaamaaaaaaaaaaaaaaaaafaafaahaaxaataataaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayaayaayaayaayaayaayaayaayaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaamaaacKraazaavaaacKraazaavaaacKraazaavaafaafaafaafaaaaaaaaaaaaaaaaaaaafaaaaaaaafaaAaaBaaaaaaaaaaaaaaaaaaaaaaaaaaaaayaaCaaDaaEaaDaaEaaDaaFaayaayaaGaaHaayaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaauaaaaaaaauaaaaaaaauaauaauaauaauaauaauaaaaaaaauaaaaaaaauaaaaaaaaaaaaaaaaaaaaIaafcKraazaavaaacKraazaavaafcKraazaavaafaaaaaaaafaafaaJaaaaaaaaaaaaaafaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaKaaLaafaayaaMaaNaaNaaNaaNaaNaaOaaPaaQaaRaaSaayaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaauaauaauaauaaaaauaauaauaauaauaauaauaauaauaaaaauaauaauaauaaaaaaaaaaaaaaaaaaaafaaacKraazaavaafcKraazaavaaacKraazaavaaaaaaaaaaaaaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaaaTaaTaaTaaTaaTaaTaaTaafaaaaayaaUaaVaaEabkaaEaaVaaWaaXaaYaaZabaaayabbabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaauaauaauaauaaaaauaauaauaauaauaauaauaauaauaaaaauaauaauaauaaaaaaaaaaamaamaaIaafaaacKraazaavaafcKraazaavaaacKraazaavaafaaaaaaaacaaaaafaafabcabdabdabdabdabeabfaaaaaaaaTabgabgabhabgabgaaTaaaaafaayabiabjaaXabjaaXabjaaXaayablaaZabmaayabnaboaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaauaauaauaauaaaaauaauaauaauaauaauaauaauaauaaaaauaauaauaauaaaaaaaaaaamaaaaafaaaaafaafapsaafaafaafapsaafaaaaafapsaafaaaaaaaaaaaaaaaabqabrabsabtabuabvabwabxabfaafaaaaaTabyabzabAabBabCaaTaaaaaaabDabEabFabGabHaaEabFaaEabIabJabKabLappabNabOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaaaaadaadaadaadaadaaaaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaaaaIaafaqMaqbapTaqTaqTaqTaqTaqTaqTaqTaqTaqTaqTaqTaqTarBaqbaqbaryabWabXabYabZacaacbaccacdaaTaaTaaTaaTaaTaceacfacgaaTaaTachaciacjackaclacmacnacmacoackackackacpacqacracsactaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaaaaafaaLaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaaaaadaadaadaadaadaaaaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaaaamaaaaafaaaaafaafapjaafaaaaafapjaafaaaaafapjaafaaaaaaaaaaaaaaaabqabracvacwacxacyabdaczaaTaaTacBacAacDacCacEacFaaTaaTacGacHacIacJacKacLacMacNacOacPacQacQacRacSacracsabbabbabbabbabbabbaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaafaafaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaaaamaamaaIaafaafcKrapgaavaaacKrapgaavaaacKrapgaavaafaaaaaaaaaaaaaafaafacUabdabdabdabdacVaaTacWacXacXacXacXacEacXacYaoZadaacQadbadcaddadeacMadfacQacQacQacQadgadhackadiadjabbadkadladmabbaaLaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaaaaacKrapgaavaafcKrapgaavaaacKrapgaavaaaaaaaaaaafaaaaafaafaaaaaaaaaaaaabfacVaaTadnadoadpadradqadsadtaduaoZadaacQadvadcaddadwadxadyacQadzadzadzaddadAacradBadladCadladladladCaaLaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaIaafcKrapgaavaaacKrapgaavaaacKrapgaavaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaadDadEaaTadFacXacXacXacXacEacXadGaoZadaacQadvadHadIadJadKadLadMadNadNadNadOadPacradQadlabbadRadSadlabbaaLaaLaafaaaaafaaaaaLaafaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaIaafcKrapgaavaaacKrapgaavaafcKrapgaavaafaafaafaaaaafaafaaaaaaaaaaaaaaaadTadEaaTaaTadVadUadWadXacEadXaaTaaTadYacQadbacQaddadZaeaadyadMadNaebadNaecaedacradQaeeabbabbabbabbabbaaLaaaaaaaaaaaaaaaaaaaafaafaafaaaaaaaafaafaaLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaauaauaauaauaaaaaaaauaauaauaauaauaauaauaaaaaaaauaauaauaauaacaaaaaaaaaaaaaaaaaqaafcKrarDaavaaacKrarDaavaaacKrarDaavaafaaaaafaafaafaaaaaaaaaaaaaaaaaaadTaegaaTaaTaaTaaTaaTaaTaehaaTaaTaaTaeiaejaekaelaemaenaeoaepaeqaeraesaeraetaeuacradBaevabbaaaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaaaafaaaaaaaaaaafaafaafaaaaaaaafaafaaaaaaaafaafaaaaaaaaaaaaaaaaafaaaaewadEaexaeyaezaaTaeAaeBaeCaeDaeEaeFaeGaeHaeIaeHaddadZaeJaeKaeLaeLaeMaeLaeNaeOaePaeQaeRabbaeSaeSaeSaeSaeSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaaIaeTaamaamaamaamaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaafaafabfadEaeUaeVaeWaaTaeAaeAaeXaeYaeZaeFafaafbafcafdaddafeaffafgacQacQafhacQafiafjacrafkaflabbafmafnafoafoafpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfabfabfabfabfabfabfabfabfabfabfadEafqafrafsaaTaftafuafvafwafxafyafzafAafBafAafCafDadxafEafFacQafhacQafGafHafIafJafKafLadlafMafNafOafPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfafQafRafSabfafTafUafVafWafXafYafZafZafZafZafZafZagaagbagcagbaaTageagdagfaggaghaeFagiagjagkaglagmagnagoagpagqagragsagtaguagpagvagwagxabbadlagyafoafoagzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaabfagAagBafZafZafZafYafYafZagCagDagDagDagDagDagDagDagDagDagDarCaaTagFagGagHagIagJaeFagKagLagLagLaddagMagNagOagPagQagRagQagPagSagvagTadlabbabbaeSaeSaeSaeSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaaaaeaaeaaeaaeaaeaaaaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfagUagVagWagWagWagWagWagWagWagDagXagYagZagWahaahbahcahdaheahfahgahhahiahjahkahmahlahnahnahnahnaddahoahpahqahrahsahtahuahvahwagvahxahyaboaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahzaaaaaaaaaahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaaaaeaaeaaeaaeaaeaaaaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfafQafRahAabfahBadEagWahCahDahEahFahGahHagDagZahIahFahJahKahLahLahMahNahOahPacXacXacEacXahQahRahSacQacQacQaddahTahUahVahWahXahYahZaiaaibagvahxaicabOaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahzahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDaidaieaifabfaigadEagWaihaiiaijaikailaimagDagZahIainagWaioahLaipaiqahKahOairaisacXaitacXacXaiuacZahSacQacQaddaiwaixaiyagPagPaizagPagPaiAagvaiBaiCactaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahzaaaaaaahzaaaaaaahzahzahzahzahzahzahzaaaaaaahzaaaaaaahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaewagbagbaiDabfagbadEagWaiEaiFaiGaiHaiIahFagDaiJaiKaiLagWaiMaiNaiOaiOaiPaiQaiRaiSaiTacEaiUaiVaeFaiWaiXaiYaiZakNakfajcajdajeajfajgajhagPajiagvahxabbabbabbabbaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahzahzahzahzaaaahzahzahzahzahzahzahzahzahzaaaahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfajjabfabfajkajlagWagWajmagWagWajnagWagWagWajoagWagWajpajsajrantajtajuagWajvajwajxajyajqagWagWajzajAajBagWagWagWagpajCagpagpagpagpagpagvahxabbajDajEaboaaaaafaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahzahzahzahzaaaahzahzahzahzahzahzahzahzahzaaaahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfagBafYajFafYajGajHajIajJajKajLajMajNajOajPajQajRajSajTajUajVajWajXajUajYajWajWajZakaakaakbakcakdahOakeajbakgajzakhakiakjakkaklakmaknakoakpalaakZakqabOaaaaaaaaaaaaaaaaaaaaaaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaIaaIaamaamaaaaaaaaaaaaaaaaaaaaaaaaahzahzahzahzaaaahzahzahzahzahzahzahzahzahzaaaahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaamaamaaIaamaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfadEagWagWagWagWagWagWaksaktakuakvakwakxakyakzakAakBakCakDakEakFakwakGakwakwakHakIakJakKakLakMajaakOakPakJakQakRakSakTakUakVakWakXakYakoalIabbamsalbactaaaaaaaaaaafaaaaaaaaaaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaaaafaaaaaqaaaaaaaaaaaaaaaaaaaaaaaaahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaaaaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfadEagWalcaldalealfagWalgalhahLalialjagWacTacuacTagWabValnabUagWalpalqalralsagDaltalualvalwalxagWabTabSabSabRagWalBalCalDalEalFalGalHakoamtanQamuanQanQaaaaaaaafaafaaaaaaaaaaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafabQaafaaIaaaaaaaaaaaaaaaaaaaaaaaaahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafabMaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafabfadEabPalMalMalNalOalPalQalRahKalSaljagWalTalUalValWalXalYalZamaahKambahKamcamdameameamfamgamhamiamjamkamlammakoamnamoampamqalDalDamrakoadQanQamvawKamwaaaaaaaaLaaaaaaaaaaafaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaIaaIaaIaaIaaIaaaaaaaaaabpaaaaaaaaaaaIaaIaamaamaamaaaaaaahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaamaaIaaIaaaaaaaaaaoXaaaaaaaaaaaIaaIaamaamaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfadEagWamAamBamCamDagWamEalRaljamFamGagWamHamIamJalWamKamLamMamNamOamPamQamRamSamgamgamfamgamTaoWamVamWamXamYakoamZanaalDamqalDalDanbakoancandaneanfangaafaaLaafaafaaLaafaafaafakrakrakrakrakraaaaaaaaaaaaaaaaaaaaqaaaaaaaafaafaafaaaaaaaoYaafaafaaaaafaafaaaaaaaamaaaaaaahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaafaafaaaaaaaaaaoVaafaafaaaaafaafaaaaaaaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfankagWagWagWagWanlanmannanoanmanmanmanmanpaoPanpanraoQaojaoRanvaoSaoTaoUanzanAamgamgamfanBanCamianDanEamXanFanGanHanIanJanKanLanManNanGanOanPawLanRanSaaaaaaaafaaaaafaaLaafaacakrakrakrakrakraaaaaaaaaaaaaaaaaaaaIaafanTanTanTanTanTaafalJaafanTanTanTanTanTaafaaIaaaahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafanVanVanVanVanVaafalkaafanVanVanVanVanVaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanXanYanZaoaagDaobaocagWaodaoealKaogaohaoibqKaokaolaomaonaooaonaopaoqaoraonaoOaotamgamgaouaovaowamiaoxanEamXaoyanGaozaoAaoBaoCaoDaoEaoFanGaoGanQanQanQanQaoIaoJaoHaoLarPaaaaafaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaIaafanianjanjanjanjanualJansanqanqanqanqanwaafaaIaaaahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaIaafalzalyalyalyalyalAalkallaivaivaivaivagEaafaaIaaaaaaaaaaaaaaaaaaaacaaaaaaaaaanXanXapaapbagDalMapcapdapeapfaofaphapiaoMaonaonapkaplaonapmapnaoraonapoaonaoNapqapramgamfamgamTaosamYanEamXaptanGapuapvapwapxapyapzapAanGapBaoHapCapDapEapFapGaoHaoHapHaoHaoHaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaIaafapIapIapIapIapIaafalJaafapIapIapIapIapIaafaaIaaaaaaahzahzahzahzaaaaaaahzahzahzahzahzahzahzaaaaaaahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafapJapJapJapJapJaafalkaafapJapJapJapJapJaafaaIaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaapKapaapbagDapLapMagWalgapNalKapOapPapQapRaokapSanWapUapVapWapXapYapZaqaanUaqcaqdaovaqeaovaqfaqgaqhaqiaqjaqkanGaqlaqmapyaqnaqoaqpaqoaqqaqraqsapFaqtaquapFaqvaoHaqwaqxaqyaoHaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaamaaaaaaaaaaafaaaaaaaafalJaaaaaaaaaaafaaaaaaaaaaamaaaaaaaaaaaaaaaaaaaaaaaaahzahzahzahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaafaaaaaaaafalkaaaaaaaaaaafaaaaaaaaaaaqaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaqzaqAaqBagDagWagWagWaqCalRagWalWalWalWaqDaqEapkaqFaqGaqHaonaqIaqJaqKaqLanyaqNaqOaqPaqQaqRaqSanxaqUaqVaqWamVanGaqXaqYaqZaraarbarcardanGarearfapFaqtaqtapFargaoHarhariarjaoHaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaIaafanTanTanTanTanTaafalJaafanTanTanTanTanTaafaaIaaaaaaaaaaaaaaaaaaaaaaaaahzahzahzahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafanVanVanVanVanVaafalkaafanVanVanVanVanVaafaaIaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaqzarkaqBagDaobarlagWarmarnalKaogaroaoiaokarparqarrarsartaonarualWarvarwarxalLarzarAamUamzamyarEarFarGarHamjanGanGarIanGanGanGanGanGanGarJarKarLarMarMapFarNaoHaoHarOaoHaoHaaaaaaakrakrakraaaaaaaaaaaaaaaaaaaaaaaIaafanianjanjanjanjanualJansanqanqanqanqanwaafaaIaaaaaaaaaaaaaaaaaaaaaaaaahzahzahzahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaLamxaaLaaaaaaaaaaaaaaaaaaaaaaaIaafalzalyalyalyalyalAalkallaivaivaivaivagEaafaaIaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaqzarQaqBagDarRapcarSarTarUaefapharWaloaonaonarYarZasaasbaonascalWasdasealmasgasharAasiasjaskarEaoHaoHaoHaoHaoHaslasmasnasoasoaspaspasqasrassastastasuasvasvaswasxasyaszaqsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafapIapIapIapIapIaafalJaafapIapIapIapIapIaafaaIaaaaaaaaaaaaaaaaaaaaaaaaahzahzahzahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafasAasBasAaaaaaaaaaaaaaaaaaaaaaaaIaafapJapJapJapJapJaafalkaafapJapJapJapJapJaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasCarQapbagDapLapMagWasDasEalKapOasFaoiasGasGasHasIaonasJaonasKalWasLasMbgMasOasParAasQasRasSarEasTasUasUasVasWasVasXasYasZasZasZasZasZasZasZasZasZasmataatbatcaoKatdateatfaafatgathathatiathathatjaafaaaaaaaaaaamaaaaaaaaaaafaaaaaaaaaalJaaaaaaaaaaafaaaaaaaaaaamaaaaaaaaaaaaaaaaaaaaaaaaahzahzahzahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatkatlatmaaaatnatoatpaaaaafatqatratqaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaafaaaaaaaaaalkaaaaaaaaaaafaaaaaaaaaaamaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaanXatsattagDagDagDagWagWagWagWalWalWalWalWalWatuaonaoratvaqEatwalWalWalWatxatxatxarAatyatzatAarEatBasZasZasZasZatCatDatEatFatGatHatIatJatKatLatMatNatOatPatPatPatPatPatPatPatPatQatRatRatRatRatRatQatPaaaaaaaaaaaIaafanTanTanTanTanTaafalJaafanTanTanTanTanTaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaahzahzahzahzahzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatSatTatUatTatSatVatWatVatSaafatqatXatYaaaaaaaaaaaaaaaaaaaaaaaIaafanVanVanVanVanVaafalkaafanVanVanVanVanVaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafatZauaanYaubaucanXaafaafalWaudaueaufaugauhauiaonapnaonasJaqEaujaukaulaumaunauoauparAauqaurausarEatBasZaAfaySauvatCauxauyatFatGauzauAauBauCauDatMatNauEauFauGauHauIauJauwauLatPauMatRatRatRatRatRatQatPaafaaaaaaaamaafanianjanjanjanjanualJansanqanqanqanqanwaafaaIaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauNatTauOatTauNatVauPatVauNauQauRauSauTauUauUauVauQauQaafaaaaaIaafalzalyalyalyalyalAalkallaivaivaivaivagEaafaaIaaaaaaaaaaaaaaaaaaaaaaaaanXanXanXauWanXanXapbaucanXaaaaaaalWauXalWauYauZavaalWavbavcaonavdaveaveavfavgaveavhaviavjarAavkauravlarEatBasZawoavoawpatCawravqatFatGauzauAavravsavtatMatNavuavvauGauHauHauJavwavxavyavzatRatRatRatRatRavAatPatPatPaaaaamaaaapIapIapIapIapIaafalJaafapIapIapIapIapIaaaaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauNavBavCavDauNavEavFavGauNavHavIavJavKavLavMavNavOauQaaaaaaaaqaaaapJapJapJapJapJaafbeSaafapJapJapJapJapJaaaaaIaaaaaaaaaaaaaaaaaaaaaaaaavQavRavSavTavUavVavWavXanXaaaaaaalWalWalWavYavZawaalWawbawcawdaweawfawgaukawhawiautawkawlarAawmaurawnarEatBasZawXawUawYaxaaxbawZatFatFatFawsawtawuatFatFatNawvawwauGauHauHauJawxawyawzawAatRatRatRatRatRawBawCawDawEaaaaamaaaaafaaaaafaafaaaaaabepaaaaaaaafaaaaaaaafaaaaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauNawGawHawIauNawGawHawIauNawJavHavHavHavHavHavHavHasAaaaaaaaaIaaaaafaaaaafaafaaaaaabfxaaaaaaaafaaaaaaaafaaaaaIaafaaaaaaaafaafaaaaaaaafawPavRawQawRavUawSaucawTanXaafaaLcqTatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxarAawVaurawWarEatBasZauKaxjavmatCaxVavnaxdaxcaxfaxeaxhaxgaxhaxiaxkaxlaxmaxnaxoaxoaxnaxpaxqaxraxsatRatRatRatRatRaxsaxtaxuaxvaaaaamaamaaIaaaaaaaafaaaaaaabpaaaaafaafaafaafaaIaaIaaIaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaatSauNaxwaxxatSauNaxyaxxatSauNawMauNauNauNauNauNavHatqaaaaaaaaIaaIaaIaaaaaaaafaaaaxBaxCaxBaafaafaafaafaaIaaIaaIaafanXanXanXanXaxDaxEaxEaxFanXanXanXanXaxGaucaucanXaxHaxIanXanXaxJaxKaxLaxMaxMaxMaxMaxMaxMaxMaxMaxNaxMaxMaxMaxMaxMaxOaxPaxQaxRaxOavpasZaxSawjcfSatCaxVaxXaxXaxXaxZaxYayaaybaxXavqaydayeayfaygayhayhayhayiavxayjaykatRatRatRatRatRaykaylaxuaxvaaaaaaaaaaafaafaaaaafaaaaaabfyaaaaaaaafaaaaaaaafaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaynayoaypayoayqayoayrayoaysaytayvayvayvayvaywauNawNatqaaaaafaafaaaaaaaaaaaaaafaaaayyayzayAaafaaaaafaaaaaaaaaaaaaaaanXayBayCayDayCayCayCayCayEayCayCayFayGayDayHayIaxMaxMaxMaxMaxMaxMayJayKayLayLayLayLayMayLayLayNayLayMayLayLayLarAayOayPayQarEaAiasZcfSaycaxUatCayUayTayWayVayYayXayYayZayTazaazbazcazdazeazdazdazfazgazhaziazjatRatRatRatRatRazkazlazmaznaaaaaaaaaaaaaafaaaaafaaaazoazpazoaaaaafaaaaaaaafaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazqazrazsaztazuazvazwazxazyazwazzazAazwazwazBauNavHauRaafaafaaaaaaaaaaaaaaaaafazDazEazFazGazHaaaaafaaaaaaaaaaaaaaaanXazIanXazJazKazLazLazLazMazLazLazLazNazJazOazPazPazPazPazPazPazPazQazRayLazSazTazUazVazWazXazYazZaAaaAbazTaAcarAaAdayPayQarEaAiasZauuaAeauvatCaxWaxXaxXaxXaxXaAjaAkaAlaAmaAnaxkaAoaApaApaApaApaAqavxavxaAraAsatRatRatRatRatRaAtatPatPatPaafaafaafaafaafaafaafaaaaAuaAvaAuaaaaafaaaaaaaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafauNaAwaAxaAwaAyazsazsaAzaAwaAxaAwaAAaABaACaADauNavHauQauQaAEauUauUauUauUauVauQaAFaAGaAHaAIaAFanXanXaxHaAJaxIanXanXanXazIaAKazJaaaaafaaaaafaaaaafaaaaafaaaazJazOazPaALaAMaANaAOaAPazPazQaucayLaAQaAQaARaASaATaAUaAVaATaAWaAXazTaAcarAaAdayPaDdarEaAiasZawXaAgaAhaBbayRaBdaBeaBfaBgaBhaBiaBjaBjaBkaBjatPaBlaBmaBnaBoaBpaBqaBratPaBsatRatRatRatRatRaBtatPaafaaaaaaaaaaaaaafaafaaaaafaBuaBvaBwaBxaByaafaaaaaaaafaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaBzatSaBAawHaBBaBCaBDaBEaBFaBBawHaBGaBHaBIaBJaBKaBLavHavHavHavHavHavHavHavHaBOaBPaAFaBQaBRaBSaAFaBTaBUayCayCayCayCayCaBVaBWaBXazJaafaBYaBYaBYaBYaBYaBYaBYaafazJazOazPaBZaCaaCbaCcaBZazPazQaCdayLayLayLayLaCeaCfaCgaChaCfaCiaCjazTaCkarAaAdayPaClarEaJCasZaAZaAYaBaatCaxWavqatEaBjaBjaBjaBjaBjaCqaCraCsaBjatPatPatPatPaCtatPatPatPaBtatRatRatRatRatRaBtatPaaaaaaaaaaacaaaaafaaaaaaaaaaCvaCwaCxaCyaCvaafaaaaaaaafaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazqaAxaCzaCAaCAaCAaCAaCBaAxazqaaaaBIaCCaxzaBLaCEaCEaCEaCEaCEaCEaCEavHaCFaCGaAFaCHaCIaCJaAFaCKaCLaCKaCKaCKaCKaCKaCKaCKaCKaCMaaaaBYaCNaCOaCPaCQaCRaBYaaaazJazOazPaBZaCSaCTaCUaBZazPazQanXayLaCVaCWaARaCXaCYaCZaDaaDbaDcayLayLayLarAaAdayPayQarEaAiasZaxTaBcauvatCaDgavqatEaDhaDiaDjaDkaBjaCqaDlaCsaBjaDmaDnaDoaDpaDqaGwaDsaafaDtaDuaDuaDuaDuaDuaDvaafaaaaaaaaaaaaaaaaafaaaaaaaaaaCvaDzaDAaDBaCvaafaaaaaaaDCaDCaDCaDCaDCaDDaDEaDCaDCaDCaDCaDCaDCaDCaDFaDGaDGaDGaDHaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaaaaaaaDIaDJaDKaDJaDJaDLaDMaDJaDJaDKaDNaDOaBIaDPaxAaBLaDRaDSaDTaDUaDVaDWaCEavHaDXauQaAFaAFaDYaDZaCMaEaaEbaEcaEdaEeaEfaEgaEhaEiaEjaCMaafaBYaEkaElaEmaEnaEoaBYaafazJazOazPaEpaEqaEraEsaEtazPazQaEuayLazSazTaEvaEwaCfaExaEyaATaEzaEAaEBaEBarAaAdayPayQarEaAiaCmaCmaCmaCmaCmaEHaEIatEaEJaEKaEKaELaEMaEKaENaEOaBjaEPaEQaERaESaETaCnaDsaaaaafaaaaafaaaaafaaaaafaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaCvaEXaEYaEZaCvaFaaFbaDCaDCaFcaFdaFdaFdaFdaFdaFeaFfaFgaFgaFgaFgaFgaFgaFgaFhaFiaFjaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaDIaDNaDJaFkaFlaFlaFmaFnaFoaFpaFqaFlaFlaFraFsaFtaDPayuaBLaFvayxaBMazCaBMaBNaCDavHaFuaDQaFxaFwaFzaFyaFIaFJaFKaFLaFLaFLaFMaFLaFLaFNaFOaCMaaaaBYaFPaElaFQaEnaFRaBYaaaazJazOazPaFSaFTaFUaFTaFVazPazQaFWayLayLayLayLaFXaCfaCgazTaCfaFYaFZazTaGaarAaGbaGcaGdarEaAiaDeaDfaDraCoaDeaCpaGjaGkaGlaGmaBjaBjaBjaBjaBjaBjaGnaGoaGpaGqaDpaGraGsaDsaDsaDsaDsaDsaDsaDsaDsaDsaFaaFbaDsaDsaFaaGtaDsaDsaaaaaaaCvaCvaGxaGyaCvaGzaGAaGBaFdaGCaDCaDCaDCaDCaDCaGDaGEaGFaGFaGFaGFaGFaGFaGGaGGaGHaGGaGGaGGaGGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaFraGIaGJaGKaFlaGLaFlaGLaFlaGLaFlaGLaFlaGMaGNaGOaDPayuaBLaGPaFAaGRaGSaGTaGUaCEaFBaFDaFCaFCaFCbazaFEaFCaHcaFLaFLaFLaFLaFLaFLaFLaFNaHdaCMaafaBYaHeaHfaHgaHhaHiaBYaafazJazOazPaHjaHkaFUaHlaHmazPaHnaHoayLaHpazTaARaHqaATaHrazTaCfaFYaHsazTaHtarAaHuaHvaHwarEaGuaDyaEUaGvaDwaDxaEVaEWatEaHCaHDaBjaHEaBjaHFaBjaHGaBjaHHaGpaHIaDpaHJaHKaHLaHMaHMaHNaHOaHKaHKaHKaHKaHKaHPaHKaHKaHKaHQaHVaDsaDsaDsaDsaHRaHSaHTaHUaIaaIbaDCaDCaIcaDCaIdaIeaIfaIgaGFaIhaGFaIiaIjaIkaIlbinaInaIoaIpaIqaIraIsbjFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaIwaFlaFlaDKaFlaGLaFlaGLaIxaGLaIyaGLaFlaGMaGNaGOaDPaFFaIAaIAaFGaICaIDaICaIAaIAaIEaIFaFCaGQaFHaGWaGVaFCaIKaILaIMaFLaFLaINaFLaIOaIPaIKaCMaaaaBYaBYaIQaIRaIQaBYaBYaaaazJazOazPaISaITaIUaFTaIVazPaIWaIXayLaIYazTaIZaEwaCfaJaaEyaATaJbaJcazTaJdaJeaJfaJgaJhaMbaECaCuaCuaCuaCuaCuaJjaJkaJlaJmaJnaBjaJoaBjaJpaBjaJqaBjaJraGpaJsaJtaGsaGsaDqaJvaDsaDsaJwaDsaDsaJxaDsaGsaJyaGsaGsaGsaJzaHZaJBaJAaJAaJAaHXaHYaHWaHWaJGaJHaIgaJIaJJaJKaJLaJMaJNaIgaJOaJPaGFaJQaJRaJSaJTbinaJUaIoaJVaJWaGGaGGaGGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaFraJXaGJaGKaFlaGLaFlaGLaFlaGLaFlaGLaFlaGMaGNaGOaDPaGYaGXaHaaGZaHbaHbaIBaIzaIHaIGaIJaIIaJZaJYaKbaKaaFCaIKaKmaKnaKoaKpaIKaKqaKraKsaKtaKuaaaaafaaaaKvaKwaKvaaaaafaaaaKuazOazPaKxaKyaKzaKAaKBazPaKCaKDayLaKEazTaARaKFaKGaHrazTaKHaKIaKJaKKaKLaJeaEDaKNaKOaKPaEEaKRaaaaaaaJlaKSaKTaKUaJlaKVaJnaJnaJnaKWaJnaJnaJnaBjaDpaKXaDpaDpaDpaDpaKYaDpaKZaLaaLbaLcaLdaLeaLfaLgaLhaLfaLfaLfaLfaLfaLiaLfaLfaLfaLfaLfaLfaLfaLfaGraIgaLjaLkaLlaEFaLnaLoaIgaLpaLqaGFaLraLsaLtaJTaRraJUaIoaJVaIoaLvaLwaLxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaLyaLzaDJaFkaFlaFlaFlaLAaFlaFlaLBaFlaFlaFraLCaLDaDPaLEaLFaLGaLHaLGaLGaLGaLGaLGaLIaLJaFCaFCaFCaFCaFCaFCaLLaLMaLNaLOaLOaLOaLOaLPaLQaLRaKuaLSaLTaLTaLUaLVaLWaLTaLTaLXaKuaLYaKuaKuaLZaMaaLZaJeaJeaMbaMcaJeaJeaJeaJeaMdaMeaMfaMgaMhaMiaJeaJeaJeaJeaMjaKNaMkaMkaMlaMmaMnaMoaJlaMpaMqaMraJlaJlaJlaJlaJlaJlaJlaJlaBjaBjaMsaMtaMuaMvaMwaMxaMyaMzaKZaMAaMBaMCaMCaMDaLfaMEaMFaMGaMHaMIaMJaMKaMLaMMaMNaMHaMJaMIaMHaMOaLfaGraIgaMPaMQaMRaMSaMTaMUaIgaMVaMWaMXaMYaMZaNaaNbaGFaGGaNcaJVaIoaNdaNeaNfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaaaaaaaLyaDJaDKaDJaDJaDLaDMaDJaDJaDKaLzaNgaBIaNhaLEaNiaNjaNjaNkaNjaNlaIAaNmaNnaLJaNoaNpaNqaNraNsaNtaNraNuaNraNraNraNvaNraNraNwaNxaNyaNzaNAaNBaNzaNCaNzaNzaNzaNzaNDaNEaNFaNGaNraNHaNIaNJaNKaNLaNMaNLaNNaNOaNPaNQaNQaNRaNSaNTaNSaNUaNVaNWaEGaNYaNZaOaaObaOcaMkaMkaMkaOdaOeaOfaOgaOhaOiaOjaOkaOlaOmaOnaJlaOoaOpaOqaOraOsaOtaOuaOvaOwaOxaKZaOyaOzaOAaOAaOBaLfaOCaODaOEaOEaOEaOEaOFaOGaOHaOIaOJaOKaOKaOLaOMaLfaGraIgaONaOOaOPaOQaONaONaIgaORaOSaGFaOTaOUaOVaOWaGFaIoaIoaJVaIoaGGaGGaGGaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaOXaOYaOZaPaaPaaPaaPaaPbaOYaOXaaaaBIaPcaPdaPeaPfaPgaPhaPhaPiaIAaPjaNnaPkaPlaPmaPnaPoaPpaPqaPqaPraPsaPsaPsaPtaPuaPuaPvaPwaNIaPqaPqaPxaPyaPzaPAaPBaPBaPCaPBaPDaPyaPyaPyaPEaPFaPGaPHaMkaPIaPJaPJaPJaPJaPJaPJaPJaPJaPKaPJaPLaPMaPNaPOaPPaPQaPRaPSaPTaPJaPUaPJaPVaPWaPXaPWaPWaPWaPWaPWaPWaPYaPZaRsaQbaQbaQbaQcaQbaQbaQdaQeaQfaQgaKZaQhaMCaQiaQjaQkaLfaQlaQmaQnaQnaQnaQnaQnaQoaQpaQqaQraQnaQnaQsaQtaLfaGraIgaQuaONaONaQvaONaQwaIgaGFaGFaGFaGFaGFaGFaQxaGFaIoaIoaJVaIoaQyaQzaGGaaaaafaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaafaBIawqaBIaQBaQCaGOaQDaQEaQFaQGaGOaQCaQHaQIaBIaQJaLEaPeaQKaQLaPhaPhaPiaIAaQMaNnaLJaQNaNpaQOaQPaNraNraQQaQRaQSaQTaNraQUaQVaQWaQVaQXaQYaQVaQVaQZaQVaQVaRaaRbaQVaRcaQVaRdaNraNraNraReaPFaPGaPHaMkaRfaMkaRgaRgaRgaRgaRgaRgaRgaRgaRhaRiaRgaRjaRgaRgaRkaRgaRgaRgaRgaRlaRmaRnaRoaRoaRoaRoaRoaRoaRoaRpaRqaRpaJlaImawOawOawOawOawOaItaRuaRvaRwaKZaKZaKZaKZaKZaRxaLfaRyaQmaQnaRzaRAaRBaRCaRDaREaRFaQraRGaRHaRIaRJaLfaGraIgaRKaRKaRLaRMaRNaRNaROaIgaRPaRQaRRaGGaRSaRTaRUaRVaRVaRWaRXaGGaRYaGGaRZaRZaRZaSaaSbaScaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaGeaGgaGgaGiaGfaGhaSdaOYaLDaDPaHxaHxaSfaLDaOYaLDaHyaHAaHzaLEaSkaSlaSlaNkaSlaNlaIAaSmaNnaSnaIAaLKaLKaSoaLKaLKaLKaLKaLKaLKaSpaSqaLKaLKaLKaLKaLKaLKaSraSsaSraLKaStaLKaNraQPaSuaSvaSwaSxaNraSyaLKaMbaMbaMkaSzaKOaSAaMnaMnaSBaSBaSBaSBaSCaJeasfasNarVarXarXavParXarXarVasNawFaJeaSJaSKaSKaSKaSKaSLaSLaSMaSNaRqaRpaJlaSOaSPaSPaSPaSPaSPaSPaSQaSRaSSaSTaSUaSVaSWaSXaSYaKZaKZaSZaTaaTbaTcaTdaTeaTeaTeaTfaTgaTfaTeaTeaTeaTeaGraIgaThaONaRLaRMaONaONaTiaIgaTjaTkaTlaGGaIoaTmaTnaToaTpaTqaIoaTraTsaGGaTtaTuaRZaTvaTwaTxaafaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaKQaNXaLmaKMaQAaSgaSeaSiaShaSjaSiaTzaTyaTBaTAaTEaTCaTAaTFcozaTIaTJaTKaTLaTLaTLaTMaTLaTNaTOaIAaTPaTQaTRaTSaTTaTUaTVaTWaTXaTUaTYaTZaUaaUbaUcaUdaUeaUfaUgaUhaUeaUiaLKaLKaUjaLKaLKaLKaLKaUkaUlaLKaUmaMbaUnaSzaKOaUoaaaaaaaaaaaaaaaaaaaaaaUpaUqaUraUsaUtaUvaUuaUxaUwaUzaUyaVUaUpaaaaaaaaaaaaaaaaaaaaaaUAaSNaRqaUBaUCaUDaUEaUFaUFaUFaUFaUGaUHaUIaUFaUFaUFaUJaUKaULaUMaUNaUOaUPaUQaURaUSaUTaTfaUUaUVaUWaUXaUYaUZaVaaVbaTeaGraIgaVcaVcaRLaRMaVdaVdaVeaIgaIgaVfaIgaGGaVgaVhaViaViaViaVjaVkaGGaGGaGGaVlaVmaVnaVoaVpaVqaafaafaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaKQcmVaVrclfaDPaVsaVsaVtaVsaVsaVsaVDaVsaVsaVtaVsaVsaYEaWYaVuaVvaKdaKdaKdaKdaKdaVwaVxaVyaVzaIAaTQaTQaVAaTSaVBaTUaTUaTUaTUaTUaTYaVCaTUaTUaTUaUdaUeclraVEaVFaUeaUiaVGaVHaKeaKcaVKaUmaVLaVMaVNaVOaVPaVQaMkaSzaKOaUoaaaaaaaaaaaaaUpaUpaUpaUpaVRaVSaVTaXEaVVaVWaVXaXFaVZaWaaWbaUpaUpaUpaUpaaaaaaaaaaaaaUAaSNaRqaRpaWcaSSaWdaWeaWfaSSaWgaWhaWiaWjaWkaWlaWmaWnaQbaWoaWpaWqaWraWsaWtaWtaWuaWvaWwaWxaWyaWzaWAaWBaWCaWDaWEaTeaGraIgaThaONaRLaRMaONaONaONaWFaWGaONaWHaGGaWIaWJaToaToaToaTqaIoaYsaGGaQaaVoaLuaWQaVoaWRaWSaWTaWTaWUaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTGaGgaTHaGiaBIaBIaBIaWVaWWaWWaWWaWWaWWaWWaWWaWXaBIaBLcpSaWZaIAaXcaXbaXbaXbaYraXdaIAaIAaIAaIAaTQaXeaXfaTSaXgaTUaTUaXhaXiaXjaXkaXhaTUaTUaTUaXlaUeaXmaXnaXoaUeaUiaVGaXpaKfaXraXsaUmaXtaVPaXuaXvaXwaXxaMkaSzaKOaMmaSCaMbaXyaUpaUpaVYaXAaXzaXCaXDaXDaXEaXFaXGaXEaXFaXDaXDaXHaXIaXJaXBaUpaUpaXyaJlaXLaXMaSNaRqaRpaJlaXNaWdaXOaWfaSSaXPaXQaSSaXRaXSaWfaSSaXTaOtaXUaXVaUQaXWaXXaXYaXZaYaaYbaYcaYdaYeaYfaYgaWBaYhaWDaYiaTeaGraIgaYjaYjaRLaRMaYkaONaONaYlaONaYmaYnaGGaIoaYoaYpaToaYqaZkaZXaWLbaOaYGaWOaZcaVoaYvaYwaYxaYyaYzaYAaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaYVaaaaaaaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaafaYCaYDcpKaYFaWPaYHaYHaYIaYJaYKaYLaYMaYNaYOaYPaYQaYRaYSaTSaYTaTUaTUaXhaXjaYUbbTaXhaTUaTUaYWaUdaUeaUeaUeaUeaUeaUiaVGaVGaVGaVGaVGaUmaYYaXvaYZaXvaXvaXxaMkaSzaKOaNSaNSaZaaZbaWNaUpaZdaZeaZfaZgaZfaZfaZfaZfaZhaZfaZfaZfaZfaZfaZfaZiaZjaUpaWMaZbaZlaZmaZnaSNaRqaRpaWcaSSaSSaSSaSSaSSaXPaZoaSSaXRaZpaWfaSSaXTaOtaZqaXVaUQaZraZsaZtaZuaYaaZvaZwaYdaYeaYfaYgaWBaYhaZxaZyaZzaZAaZzaZzaZzaZBaZCaZDaZEaOOaZFaZGaZHaZIaGGaZJaZKaZLaToaZMaZLaIoaIoaXaaYtaVoaYuaVoaZNaZOaZPaZQaWTaZRaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaZSaZTaZUbjnaZWaSFaZYaZZbaababbacbadbaebafaYObagbahbaibajaTSbakbalbambanbaobapbaqbarbarbarbasbataTSbaubavbawbaxaKgbajbnZaKhbajbaCaUmbaDbaEbaFbaGbaHbaIaMkbaJbaKaMkbaLbaMbaNbcybaPbaQbaRbaQbaSbaTbaUbaVbaWbaXbaYbaZbbabbbbbcbaQbbdbbebbfbeobbhbbibbjbbkbblbbmbbnaJlaUDaWdbboaWfaSSbbpbbqbbrbbsaXOaWfaSSaXTbbtaULaXVbbubbvbbwaUQaUQaYabbxbbybbzbbAbbBaYgaWBbbCaWDbbDaZzbbEbbFbbFbbGbbHbbIaRLaRLaRLaRLaRLaRLaRLaGGbbJaYoaYpaToaYqaYpaIobbKaGGbbLaVoaYuaVoaZNbbMbbNbbOaafbbPaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBbbQbbRbbScqObbUaSFbaabaabaabaabaabbVbaabbWaYObbXbbYbaibbZbbZbbZbbZbcabbZbcbaTUbccbcdbcebcebcfbcgaTSaXebchbcibcjaKiaKjblcaKkbcobcobcpbcpbcpbcpbcpbcqaMbbcrbcsbctbcubcvbcwbcxbbgaUpbczbcAbcBbaBaUpaUpaUpaUpaUpbcDaUpaUpaUpbcCbcFbcGbczaUpbbgbcxbcHbcIbcJbcKbcLaRpaWcaSSaSSaSSaSSaSSaGpbcMaSSbcNaSSbcObcObcObcObcPbcQbcRbcSaUQaUQaUQbcTbcUaTebcVbcWbcXaYgaWBaYhaWDbcYaZzbcZbdabdbbdcbddbdebddbddbddbddbddbdfbdgbdhbdibdjbdkbdlbdmbdnbdobdpbdqbdraVoaYubdsaZNaVobdtbbOaafaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBbdubdvaZUbdwbdxaSFaYHbdybaababbdzbbVbaabdAaYObdBbdCbaibbZbdDbdEbdFbdGbbZbdHbdIbdJaTSbdKbdLbdMbdNaTSaXebdObdPbdPaKlbdPbdPbdPbdPbdRbdSbdSbdSbdTbdSbdUaMbbdVbdWbdXaJeaJeaJebdYbdYbdYbdZbeabdZbdYbebbebbebbebbebbecbebbebbebbedbedbeebedaUpaUpaUpaJiaJiaJibcKbcLaRpaJlbefbegaDmbehaSSbeibcMbejbekbelbcObcObembenaZzaZzaZzaSHaSGaSGaSGaZzaZzaZzbeqberbesbetaWBaYhaYhbeuaZzbevbewbexaZzbeybezbeAaZEbeBbeCbeDbeEaONaGGaIobeFbeGbeHbeFbeIaIoaIoaGGbeJaVoaYuaVoaZNbeKbeLbbOaafbeMaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBbeNbeObePbeQbeRaRtaYHbeTbeUaYHbdzbbVbeVbeWaYObeXbeYbaibbZbbZbbZbeZbfabbZbfbbdIbfcaTSbdKbdLbdMbfdaTSaXebdObdPbfebffbfgbfgbfhbdPbfibfjbfkbflbfmbfmbfmaMbaMkbcsbctaJebfnbfobfpbfqbfrbfsbftbfubdYbebbfvbfwaSEaSDbfzbfAbfBbebbedbfCbfDbfEbfFbfGbfHbfIbfJaJibfKbfLbfMaJlaZzaZzaZzaZzbfNbfObfPbfQaZzaZzbfRaZzaZzaZzaZzbfSbfTbfUbfVbfVbfVbfWbfXaZzbfYbfZbgabgbbgcbgcbgcbgdaZzbevbewbgeaZzaZzaZzaZzaZzaZzaZzaZzaZzaZzaZzbgfbggbghbgibgjbgfbggaZzaRZbgkaVoaYuaVoaZNaZObglbgmaWTaZRaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaabgnbgobgpbgqaZUbgrbgrbgrbgrbgrbgrbgsbgtbgraYOaYOaYOaYOaYObguaYOaYOaYObgvbgvbgwbbZbdDbgxbeZbgybbZbgzbgAbgzaTSbdKbdLbdMbfdaTSaXebdObdPbgBbgCbgDbfgbgDbdPbfibgEbgFbgGbgHbgIbgJaMbbgKbgLbctaWKbgNbgObgPbgQbgQbgRbgSbgTbdYbebbgUbgVbgWbgXbfvbgYbgZbebbedbhabhbbhcbhdbhebhfbhgbhhaJibhibhjaRpbhkbhlbhmbewbewbhnbewbhobewbewbewbewbhpbewbewbewbewbhqbewbewbewbewbewbewbhmbewbewbhrbhsbhsbhtbhsbhsbhubhvbewbhqbhwbhxbhpbewbhybewbewbewbhzbhAbhBbhCbewbhDbewbhEbewbewbhFbhGbhHaVoaYuaVobhIbhJbhKbhLbhMbhNaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaabhObhObhObhObhObhObhObhObhObhOaaaaafbhPaYDbhQbhRbhSbhTbhTbhTbhTbhTbhUbhVbhWbhXbhYbhZbgwbbZbbZbbZbiabfabbZaTSaTSaTSaTSbdKbibbicbidaTSbiebifbdPbigbihbiibgDbijbdPbfibikbgFbgGbgGbgGbilaMbbimaSzbctaSIbiobipbiqbirbisbitbiubivbdYbebbiwbixbiybiybiybgYbizbebbedbiAbiBbiCbiDbiEbiFbiGbiHaJibiIbiJbiKbiLbiMbiNbiObiObiPbiQbiRbiSbiSbiSbiTbiSbiSbiSbiSbiSbiUbiVbiVbiVbiWbiObiObiNbiObiObiXbiVbiVbiYbiSbiZbjabjbbiSbjcbiObiObiObiObiObiObiObiObiObiObiObiObiObjdbiTbjebiSbjfbjgbjhbjibjibjjbjkaZNaWRbjlaWTaWTaWUaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaabhObhObhObhObhObhObhObhObhObhObhOaZSaZTbjmbjnbjobgrbjpbjpbjqbjpbjpbjpbjrbajbajbajbajbaibbZbdDbjsbjtbgybbZbjubjvbjuaTSaTSaTSaTSbjwaTSbjxbdObdPbjybjzbgDbjAbjBbdPbfibfmbjCbgGbgGbgGbjDaMbbjEaSzbctcdNbjGbgObjHbjIbjJbjKbjLbjMbdYbjNbjObjPbiybjQbiybgVbjRbjSbedbjTbjUbjVbjWbjWbjWbjXbjYaJibjZbkabkbbkcbkdbkebbFbkfbkgbkhbkibkjbkkbklbkmbknbknbkobewbewbewbewbewbkpbkqbkrbewbksbktbkubkvbewbkpbkwbkxbkybhFbewbewbkzbewbewbkAbkBbewbkpbewbewbewbewbewbewbewbewbewbhqbewbewbhFbkCbkDbkEbkFbkGbkHbkIbkJaafaaaaafaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaabhObhObhObhObhObhObhObhObhObhObhObkKbkLbkMbkNbkObgrbkPbkQbkRbkRbkSbkTbkUbkVbkWbkWbkXbkYbbZbbZbbZbeZbkZbbZbajbajbajbajblaaXeaXeblbblcbldbleblfblgblhblibljblkbdPbllbfmblmbgGblnbgGbloblpblqaSzbctaJeblrblsbltblublvblwblxblybdYbebblzblAblCblBblDblAblEbebbedbedblFblGblHblIbiCblJblKaJiblLblMblNaJiblOblOblOblOblOblOaZzaZzblPblQbZNcdMblQblPaZzaZzaZzaZzaZzaZzaZzaZzaZzaZzblTaZzaZzaZzaZzaZzaZzaVIaZzbewbewblVblWblWblOblOblOblOblOblXblYblYblZblYbewblYblZbmablYbmbblObmcbmcbmcbmdaRZbmeaRZaRZaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaabhObhObhObhObhObhObhObhObhObhObhObdubdvbjmbjnbmfbgrbmgbjpbmhbmibjpbjpbjpaVAbmjbmkbmkbmlbbZbdDbmmbeZbmnbbZbmobmpbmqbmrbmsbmtbmtbmubmtbmtbmvbdPbmwbmxbfgbmybmzblfbmAbfmbmBbgGbgGbmCbmDbmEblqaSzbmFbmGbmGbmGbmGbmGbmGbmGbmHbmGbdYbebbmIbmJbmKbmLbmKbmMbmNbebbedbedbmObmPbmQbmRbiCbiGbmSaJibcKaRqaRpaJibmTbmUbmVbmWbmXbmYbmZbnabnbbncbndbnebncbnfbngbnhbnibnjbnkbnlbnmbnnbnobnpbnqbnrbnsbntbntbnubYfaVJblOblObZLblObZMbZMblObnzbnAbnBblObZtbZubZtblOblXblYbmbblObZnbZBbZnblObnGbnHbnIbnJbnKbnLbnMaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaabhObhObhObhObhObhObhObhObhObhOaaabnNbnObnPbeQbnQbgrbnRbjpbnSbnTbnUbnVbjpbnWbnXbnYbnZbmlbbZbbZbbZbbZbbZbbZboabobbocbodboebdPbdPbdPbdPbdPbdPbdPbWqbdPbdPbdPbogbdPbohboibojbgGbgGbgGbokblpblqaSzbolbmGbombonboobcEbvGbotbosbotaafbebboubovbowboxboybozboAbebaafbedboBboCboDboEbiCbiGboFaJiboGboHaRpbXHboJboKboLboMboNbYwboPboQboRboRboSboTboUboUboVboWboXboYboZbpabpbbnnbpcbpdbpebpfbpgbphbpfbpibYfaVJbpjbpkbplbpmbpnbpobppbpqbprbpqbpsbptbpubpvblOaZzbpwbpxblObpybpzbpAbpBbpCbpDbnIbpEbpFbpGbnMaaaaaaaaaaacaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaaaaaaaaaaaabgnbgobgpbgqbdvbpHbpHbpHbpIbpHbpJaZVbpKbpLbgrbpMbpNbpObpPbpQbpRbpSaYSaXeaXeaXebpTbkWbpUbkWbkWbkWbkWbpVbpWbpWbpXbpYbdPbpZbqabqbbqcbqdbqebqfbqgbqhbqibqjbqkbmAbqlbojbgGbgGbqmbfmaMbblqbqnbqoaJubqqbqrbqrbxqborbopbxsbotaafbebbebbebbebceebebbebbebbebaafbedbqzboCbqAbqBbqCbqDbqEaJibqFaRqaRpaJibqGbqHbqIbqJaJDbqLboPbqNboUboUboUboUboUboUbqObqPbqQboYbqRbqSbqTbnnbqUbqVbqWbpfbpgbphbpfbqXbYfaVJbpjbqYbqZbqZbrabrbbrcbrdbrdbrdbrebrdbrfbrgbrhbribrjbrkbnIbrlbpCbrmbrnbrobrpbnIbrqbpFbrrbnMaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaaaaaabrsbrtbrubrvbrwbrxbrxbrybrzbrAbgrcedbrCbpPbrDbjpbjpbjpbajbrEbrFbrGbrHbrGbrGbrGbrHbrGbajbajbdPbdPbdPbrIbdPbrJbrJbrJbrJbrJbrJbqfbrKbrLbrMbrNbrObrPbrQbrRbrSbrTbrUbrVbrWbrXbrYbrZaHBbsbbqvbsabsebscbotbosbotaafbsibsjbskbslbsmbsnbskbsobsiaafbedbspbsqbspbedbedbedbsraJibssaRqaRpbXHboJboKbstbsubsvbqLbswbqNbsxbsybszbsAbsBbsCbqObsDbnibsEbsFbsGbsHbnnbsIbqVbpebpfbpgbphbpfbpibYfaVJbpjbsJbsKbsLbsMbplbsNbsObsPbsQbsRbsSbsTbsUbrhbsVbsWbsXbnIbsYbsZbtabtbbtcbtdbnIbrqbpFbtebnMaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaaaaacaaaaaaaaaaaaaaaaaaaaabrsbtfbtgbthbtibtibtibtjbtibtibgrbtkbtlbtmbpPbjpaaaaaaaaaaafaafbtnbtnbtnbtnbtnbtnbtnaaaaaabtobtpbtqbtrbtsbrJbrJbrJbrJbrJbrJbttbtubtvbtwbtxbtybtzbtAbfmbfmbtBbfmbfmbtCbtDbtEbtFbmGbtHbmGbmGbmGbmGbmGbtIbmGaafbtJbtKbtLbtMbtNbtMbtLbtObtPaafbspbtQbtRbtSbtTbtUbspbtVaJlbtWbbmbtXaJibtYbmUbtZbuabubbucbudbuebufbugbuhbuibujbukbulbumbnibnnbunbuobupbnnbuqburbusbutbuubuubuvbuwbYfaXqbpjbuxbplbplbsMbuybuzbuAbuBbuCbuDbuEbuFbuGbrhbuHbuIbuJbnIbuKbuLbuMbtbbpCbuNbnIbpEbpFbuObnMaaaaaaaaaaaaaafbuPbuQbuRbuQbuRbuQbuSaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabuTbeObuUbuUbuVbpHbuWbgnbgobuXbuWbgrbuYbuZbvabvbbjpaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnaaaaaabvcbvdbrJbvebvfbvfbvfbvfbvfbvgbvhbvfbvibvjbvkbvlbvmbvnbvobfmbvpbgGbvqbvrbvsbvtbvubvvbmGbmGbmGbvxbvybvzbvAbvBbvwaafbvDbvIbvHbvJbvKbvMbvNbvObvLaafbspbvPbvQbxnbedbvRbspbvSaJlbvTbcLbvUaJibvVbvWbvXbvYbvZbuccdTcdUbwcbwdbwebwebwfbwgcdWcdVbwjbwkbwlbwmbwkbwkbwkbwkbwnbwkbwkaXKaXKaXKaXKaVJbpjbsJbsKbsLbwobwpbwqbwrbwsbwsbwsbsSbwtbwubwvbwwbwxbwybnIbwzbwAbwBbwCbpCbwDbnIbwEbwFbnMbnMaaaaaaaaaaaaaafbwGbwHbwIbwJbwJbwKbwGaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbwMbwNbwObwPbrJbwQbrJbwRbwRbwRbwSbwTbrKbrJbrJbrLbwUbwVbwWbwXbwYbwZbxabgGbgGbxbbxcbvtbvubxdbxebxfbUbbxhbxibxjbxkbxlbvwaafbxmbqtbskbxobxpbxobskbqxbxraafbspbqwbxtbxubedbxvbspbtVaJlbxwbcLaRpaJibxxbxybxzbxAbxBbxCbxDbxEbxCbxFbxGbxHbxFbwkbxIbxJbwkbwkbxKbxLbxMbxNbxObxPbxQbxRbxSaXKbayaYXaXKaVJbpjbxXbqZbqZbxYbxZbppbyabwsbwsbwsbsSbwtbybbwwbTPbUabTQbwwbyfbygbyhbyibpCbyjbnIbrqbykbnMaaaaaaaaaaaaaaaaafbylbymbwIbwJbwIbynbuRaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbyobypbyobyqbyrbwQbrJbrJbrJbysbrJbwTbrKbytbdPbdPbyubgGbrNbwXbyvbywbyxbyybyybyzbyAbyBbyCbyDbvsbyEbTNbyGbxkbyHbyIbyJbvwaafbxrbxrbyKbtLbyLbskbyMbxrbxraafbyNbyNbyNbyNbyNbyNbyNbyOaJibyPblMblNaJibyQbyRbyRbySbyTbxCbyUbyVbyWbyXbyYbyZbzabwmbzbbzcbzdbzebzfbzgbzgbzhbzibzgbzjbzkbckbaAbcmbclbdQbcnbzrbzsbztbzubzvbzwbppbzxbpqbpqbzybsSbwtbzzbzAbzBbzCbzDbzAbzEbzFbzGbzHbzIbwwbwwbzJbnMbnMbzKbzLbzLbzLbzMbzNbwGbwJbwIbwJbwJbzObwGaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaacaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbzPbzQbzPbzRbrJbwQbrJbzSbzSbzSbzSbwTbrKbzTbzUbdPbzVbgGbrNbwXbzWbzXbzYbgGblnbgGbzZbAabAbbAcbAdbyEbTMbAfbxkbxkbxkbAgbvwbAhbAhbAhbxrbAibxpbAibxrbAjbAjbAjbyNbAkbAlbAmbAnbAobApbAqaJibAraRqaRpaJibAsbAtbAubAvbAwbAxbAybAzbAAbABbACbADbAEbAFbAGbAHbAIbAJbAKbAIbALbAMbANbAObnvblUbsdbnwbsgbsfbaAbPObpjbAWbAXbAYbAZbAZbppbBabBbbBcbppbBdbBebBfbBgbBhbBibBjbBkbBlbBlbBmbBnbBobTHbBqbBrbBsbBtbTIbBvbBwbBwbBxbBybBzbuQbuRbBAbuRbuQbBBaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbBCbwNbBDbBEbrJbwQbrJbrJbrJbrJbrJbwTbrKbzTbBFbdPbBGbgGbBHbBIbgGbBJbgFbgGbgGbBKbvsbvtbAbbAcbAdbyEbvwbBLbBMbBNbBMbBObvwbBPbBQbBRbAhbxrbBSbxrbAjbBTbBUbBVbyNbBWbBXbBYbBZbCabCabCbbCcbAraRqaRpaJibCdbCebCebySbCfbxCbCgbChbxCbCibCjbCjbCkbwkbClbCmbwkbwkbwkbwkbwkbwkbCnbwkbwkbwmbCoaXKaXKaXKaXKbSwbpjbwwbzAbzAbzAbzAbzAbzAbzAbzAbzAbzIbCrbCsbCtbBhbCubCvbCwbCxbCxbCxbCybCzbSubCBbCCbCDbCEbTGbCGbCHbCGbCIbCJbzKbzLbzMbCKbzNbCLaaaaafaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbzPbzQbzPbCMbCNbCObrJbrJbrJbCNbrJbwTbrKbzTbCPbdPbCQbgGbrNbwXbgGbqlbCRbgGbgGbCSbxcbvtbAbbCTbxcbCUbvwbCVbCWbCXbCYbxlbvwbCZbDabDbbDcbDdbvFbvEbDgbDhbDibDjbyNbDkbDlbDlbDmbDnbDobDpaJibDqbDrbDsaJibDtbDubDvbDwbDxbDybDzbDAbyWbDBbDCbCjbDDbwmbDEbDFbwmbDGbDHbDIbDJbDKbDLbDMbCpbDNbDObDPbDQbDRbCpbVLbVMbDUbVAbDWbDXbDXbDYbDZbEabEbbEcbEdbEebEfbEabEgbEhbCvbEibEjbEkbwwbwwbwwbwwbwwbElbEmbEnbzKbzMbCJbEobEpbEqbErbEsbEtbEubEvaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbEwbExbEwbEybEzbEAbEAbEAbEAbEAbEBbECbEDbzTbEEbdPbEFbEGbEHbEIbEJbtzbEKbELbEMbfmbtCbENbAbbEObEPbyEbvwbEQbERbESbBMbETbvwbEUbEVbEWbAhbEXbvCbEYbAjbFabFbbFcbyNbFdbFebFfbFgbDnbDobFhaJibxwaRqaRpbVjbFjbFkbFlbFmbFnbFobFpbFqbxCbxFbxFbFrbxFbwkbFsbFtbFubFvbFwbFxbDJbFybDLbFzbFAbFBbDObFCbFDbFEbFFbVlbDXbVybVAbFJbDXbDXbFKbFLbFMbFLbFLbFNbFObFPbFQbFRbFSbCvbFTbFUbFVbFWbFXbFYbFZbGabGbbGcbGdaafaafbCJbGebGfbGgbGhbGibGjbGkbCJaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbGlbGmbGnbdPbdPbGobwNbwNbwNbGpbdPbdPbGqbGrbGsbdPbGtbGtbGtbGubGtbGvbGwbGxbGybGzbtCbvtbAbbGAbGBbtCbtGbtGbtGbtGbtGbGCbtGbtGbtGbtGbtGbtGbshbtGbtGbtGbtGbtGbtGbtGbtGaJiaJiaJiaJiaJiaJibxwaRqaRpbVjbGEbFkbGFbGGbGHbGIbGJbGKbGLbGMbGNbCjbGObGPbGQbGRbGSbGTbGUbGVbGWbGXbGYbGZbHabHbbHcbHdbHebHfbCpbUSbUfbwwbwwbwwbwwbwwbHibwwbwwbwwbzAbHjbzAbzAbHkbBhbCubCvbFTbHlbHmbHnbHobHpbHqbGabGbbGcbHraaaaaabCJbHsbHtbCJbBybCJbCJbBybCJaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabHuaafaaaaaaaaaaaabGtbHvbHwbHxbHybGvbHzbHAbHBbHCbtCbvtbAbbAcbAabHDbHEbHFbHGbHHbHIbHJbHKbHLbHMbHLbHNbHObqybHQbHRbAabHSbAabHTbAabzZbHUbHVbHWbHXbHYbHZbxwaRqbDsaJlbDtbUebUebUebDtbxCbIbbIcbIdbIebIfbIgbIhbIibIjbIkbwmbIlbImbInbDJbDLbIobIpbIqbIrbFDbIsbItbIubCpbIvbIwbIxbIybUdbIAbIBbICbIDbUcbIFbIGbIHbIIbIJbzAbIKbCubCvbILbIMbINbIObIPbIQbIRbGabGbbISbEnbEnbEnbCJbCJbCJbCJaaaaaaaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabGtbITbIUbIVbIWbIXbIYbIZbJabJbbtCbvtbJcbJdbJebJebJfbJgbJhbJibJjbJgbJfbJebJebJebJkbJlbqsbJnbJobJebJebJebJpbJgbJhbJqbJrbJsbJtbJubJtbJvbJwbvUaJlbJxbFlbFnbFnbJybDTbFpbJAbFibDVbxFbJDbCFbDSbDEbJGbwkbJHbJIbJJbDJbJKbJLbJMbJNbJObFDbJPbItbJObCpbJQbJRbIxbJSbJTbJUbJVbJWbJXbJYbIFbJZbKabKbbKbbzAbKcbKdbKebKfbKgbKhbKibKjbKjbKkbGabGbbKlbEnbKmbKobKnbEnaafaafaafaafaafaafaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbKpbKqbKqbKrbKsbKsbKtbKtbKtbKtbKuaafaafaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnaaaaaaaaaaaaaaaaaaaaaaaabKvbKwbKxbKwbKyaaaaaaaaabGtbGtbKzbKAbIVbKAbKBbKCbHBbKDbKEbtCbKFbvtbKGbKHbAabKIbAabzZbHHbKJbAabKKbKLbKMbKNbKObAcbAabKPbKQbHLbKRbHLbHLbKSbKTbKUbKVbKWbKXbcLbKYaRpaRpaRpaJlbKZbGFbLabLbbGFbFHbLdbLebFIbLgbLhbLibLjbHgbDEbIkbIabIzbHhbDJbDJbLobLobLobCpbLpbLqbLrbLsbLtbCpbLubLvbIxbLwbFGbLybLzbLAbLBbLCbIFbLDbLEbKbbKbbzAbBhbLFbCvbwwbLGbLHbLIbLJbLKbLLbGabLMbLNbLObLObLObLPbGdaaaaaaaaaaaaaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafbLQbLRbLSbLRbKsbKtbKtbLTbLUbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabLVbLWbLXbLYbLVbLZbMabMbbGtbMcbMdbMebMfbMgbMhbMibMjbMjbMkbtCbtCbtCbMlbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbMmbMnbMobtCbtCbtCbtCbtCbMpbtCaJlaJlaJlaJlbMqaJlaKSaMpbMraJlbMsbGFbGFbMtbMubMvbMwbMxbxCbMybMzbMAbMBbwkbMCbMDbMEbMFbMGbMHbMIbMJbMKbMLbItbJObFDbFDbMMbJObCpbMNbMObMObMObMObMObMObMObMObMObMObMPbMQbMRbMRbzAbMSbMTbMUbwwbMVbMVbMVbMWbMXbMYbMVbMVbMVbMVbMVbMZbNabNbaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymbNdbLRbLRbNebKtbKtbLTbLTbNfbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabKxbNgbNhbNgbKxbNibNjbNkbNlbNmbNnbKAbNobNpbGvbNqbNrbNsbNtbGvbNubNvbNwbNxaaaaaaaaaaaabNybNzbNAbNBbNDbNCbNEbNFbNGbNHbNIbNFbNJbNKbNLbNMbNNbNObNPbNQbNRbNSbNTbNUbNUbNUbNUbDtbNVbCAbCAbNXbDtbNYbNZbOabObbMzbOcbOdbOebOfbOgbOhbOibOjbOkbOlbOmbOnbMKbOobFDbFDbOpbJObJObOobCpbMNbMObOqbOrbOsbOtbOubOvbOwbOxbMObOybOzbOAbOAbzAbOBbOCbCvbzIbODbOEbOFbOGbOHbOIbOJbOKbOLbOMbMVbEnbONbEnbOObOObOObOObOOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabOPbKtbNdbKtbKtbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabLVbNgbNgbNgbOQbORbKAbOSbOTbOUbKAbKAbOVbOWbGvbGvbGvbGvbGvbGvbOXbOYbOZbPaaaabPbbPcbPcbPdbPebPfbPgbPhbPfbPibNFbPjbPkbPlbNFbPmbPnbPobPpbPqbPrbPsbPtbPtbNSbPubPvbPwbPxbPybDtbMsbPzbGFbGFbPAbPBbDzbPCbxCbPDbPEbPFbPGbwkbPHbPIbwkbPJbPKbPLbPMbPNbMKbCpbCpbCpbCpbCpbCpbCpbCpbPObMObPPbQYbPRbOsbOsbOsbOsbPSbMObPTbLEbPUbPUbzAbBhbPVbPWbPXbPYbPYbPYbPYbPZbQabQabQbbQcbQdbMVbQebQfbQgbOObQhbQibQjbQkaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbKsbKtbQlbQmbQmbLTbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabKxbNhbNhbNhbKxbQnbQobQpbQqbQrbKAbKAbQsbQtbQubQvbQvbQvbQvbQvbQvbQwbQxbQyaaabQzbQAbQBbQCbQDbPfbQEbQGbQFbQHbNFbQIbQJbQKbNFbQLbQMbQNbQObQPbQQbQRbPtbQSbPxbQTbNUbPxbPxbQUbDtbKZbQVbLabLbbGFbJCbQXbLebRCbQZbRabRbbRcbRGbDEbIkbSpbPJbPLbPLbPMbRfbMKbRgbRhbRibRjbRkbRlbRmbRnbPObMObOsbOsbRobOsbOsbOsbOsbRpbMObRqbLEbRrbRrbzAbRsbRtbRubRvbRwbRxbRybRybRzbRAbRybRybRybRBbRebRDbREbRFbRdbRHbRIbRJbRKaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabKtbKtbRLbLTbLTbLTbLTbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaabLVbRMbRNbRObLVbRPbMabMbbGtbGtbRQbRQbRQbGtbGtbNxbRRbRRbRSbRSbRSbRSbNwbQyaaabRTbRUbRVbRWbRXbRYbRZbSabSbbSbbScbSdbSebSfbNFbPtbPtbPtbPtbPtbSgbPtbPtbShbSibSjbNUbPxbSkbSlbDtbJxbQVbGFbSmbSnbJCbSobJAbJBbSqbSrbSsbStbJzbFsbSvbIEbSxbSybSzbSAbSBbMKbSCbSDbSEbRjbSFbSGbSHbRnbPObMObMObMObRobOsbOsbOsbMObMObMObSIbSJbRrbRrbzAbSKbSLbCvbzIbSMbSNbSObSPbSQbSRbSSbQabSTbSUbMVbSVbQfbSWbOObSXbSYbSZbTaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbKtbLTbLTbLTbLTbLTbLTbTbbLTbTcbLTbLTbLTbLTbLTbKtbKtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTdbKwbTebKwbTfbTgaafaaaaaabGtbThbTibTjbGtaaabNxbTkbTlbTmbTnbTnbTnbTobQyaaabQzbTpbTqbTrbTsbPfbTtbTvbTubTwbNFbTxbTybTzbTAbTBbTBbTBbTCbTCbTDbTEbULbPxbPxbTFbNUbNUbNUbNUbDtbDtbLkbLfbLcbDtbTJbTKbTLbJFbJEbTJbTObLlbLmbTRbTSbTJbMKbMKbMKbMKbMKbMKbTTbTUbTVbRjbTWbTXbTYbRnbPObMObTZbQWbPQbLxbLnbNWbNcbTZbUgbUhbUibIIbIJbzAbIKbSLbUjbwwbMVbMVbMVbMVbMVbUkbMVbUlbQabUmbMVbUnbUobUnbOObUpbUqbUrbOOaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabKtbUsbUsbUsbUsbUsbUsbUtbLTbUubUsbTcbLTbLTbLTbLTbKtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbUvbNxbNxbNxbNxbRSbUwbNwbUxaaabUybPcbPcbUzbUAbPfbPfbUBbPfbUCbNFbUDbUEbUFbNFbUGbUGbUGbUGbUGbUGbUGbUGbUHbUIbUJbUKbUKbUMbNUbDtbUNbUObUPbUQbURbwabUTbUUbUVbUWbUXbUTbUYbUZbVabVbbVcbVdbVebVfbVgbVhbVibwbbVkbwbbRjboObVmboObRnbPObMObVnbxUbVpbVqbVrbVsbVtbVubUgbzAbVvbzAbzAbVwbCxbSLbCxbVxaafbnxbVzbrBbVBbVCbVBbVDbVEbVFbMVbVGbVHbVIbOObVJbVKbVKbwhaaLaaLaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwibLRbLRbLRbLRbLRbLRbLRbVNbLUbLTbLTbLTbLTbVObLUbKuaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabVPbVQbVQbVRbVSbNxbVTbRSbVUbNxaaaaaaaaaaaabNybVVbVWbVXbVZbVYbPfbNFbWabWbbNIbNFbUGbWcbWdbWebWfbWgbWhbUGbWibWibWibWibWibTFbWjbWkbWlbWmbWnbWobWpbxgbWrbWsbWtbWubWtbWvbWtbWwbWxbWybWzbWAbWBbWAbWCbWDbWEbWFbWGbWHbWIbWJbWKbWLbWMbxVbMObxWbzmbzlbWSbWTbWUbWSbWSbWVbWWbWXbWYbWZbCxbCxbSLbCxbFTaafbnxbXabXbbXcbXdbXebXfbXgbXhbMVbXibVHbXjbOObOObOObOObOOaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabKtbQmbQmbQmbQmbQmbQmbXkbLTbQlbQmbXlbLTbLTbLTbLTbKtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabXmbXnbXobXpbRSbXqbXrbRSbXsbNxaaKaaaaaaaaabNybNybNybNybNybNybNFbNFbUDbUEbXtbNFbNFbXubXvbXwbXwbXvbXxbUGbXybXzbXzbXAbWibXBbDtbDtbXCbXDbXEbXFbXGblRbXIbXJbXKbXLbXMbXNbXObXPbXQbXRbXSbXTbXUbznbzpbzobAPbzqbARbAQbATbASbAVbAUbYfbYgbIwbYhbVobCqbWObWNbWPbYmbYnbYobYpbYqbYrbYsbYtbYrbYubYvbILaafbnxbXablSbVBbYxbVBbYybYzbYAbMVbXjbVHbYBbYCbUnaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbKtbLTbLTbLTbLTbLTbLTbTbbLTbXlbLTbLTbLTbLTbLTbKtbKtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYDbVQbVQbVRbYEbYFbYGbNxbYHbNxbYIbYJbYKbYIbYIbYLbYMbYNbYObYPbYQbYRbYSbYTbYUbYVbYWbXvbYXbYYbYZbZabZbbZcbZdbZebZfbZgbWibZhbNSbZibZjbZkbZlbZlbZmbnEbZobZpbTJbTJbZqbZrbTJbTJbZsbnCbnybVibZvbWQbZxbZybZzbZybZAbnDbZCbnDbZAbWRbYfbMNbIwbZEbXWbXVbXVbZIbZJbZKbMObMObwwbwwbwwbwwbwwboIbnFbofbwwbMVbMVbMVbMVbMVbUkbMVbMVbMVbMVbMVbZObZPbZQbZRbUnaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabKtbKtbRLbLTbLTbLTbLTbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaambZSaamaamaamaamaamaaaaaaaaaaaaaaaaaaaafaafaaabZTbZUbZUbZUbZVbZUbZUbZWbZXbYIbZYbZZbYIcaacabcaccadcaecafcagcahcaicajcakcalcambXvbYXcancaobZacapbUGcaqcaqcaqcaqcaqcarbNSbDtcascatcaucavcawcaxcaycazbTJcaAcaBcaCcaDcaEcaFcaGcaHcaIbZxbWQcaJbZycaKcaLbZAcaMcaNcaObZAbXXbYfbPObIwbXYbYabXZbXYbXYbIwbIwbIwcaRcaScaTcaUcaVbwwbwwcaWbwwbwwcaXcaYcaZcbabXjcbbbXjbXjcbccbdcbecbfcbgcbhbUnbUnbUnaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbKsbKtbUubUsbUsbLTbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafcbicbjcbkcblcbmcbncbocbpcbqbYIcbrcbsbYIbYIcbtcbucbvcbwcbxcbycbzbYSbYTbYUcbAcbBbXvbXvcbCcbDbXvcbEbUGcbFcbGcaqcbHcaqbTFcbIcbIcbIcbIcbIcbIcbIbTJcbJcbKbTJcbLcbMcbNcbOcaEcbPcbQcbRcaIbZxbWQbZxbZycbScbTbZAcbUcbVcbWbZAbXXbYfbYbbYdbYcbYibYebYjbYcchBbYkbYlcktbZDbZwbZFcktccrbZGbZHccqccrccscctcctcctcctccucctcctcctcctcctccvccwccxccycczbUnbUnbUnbUnaaaaafaaaaaaaaaaahaahaahaafaaaaaaaafaaaaaaaafaaaaaabOPbKtbNdbKtbKtbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafccAccAcbkccBccCcbnccDccEccFbYIccGccHccIccJccKccLccMccNccOccPccQccRbTyccSccTccUccVccWccXccYccZcdacdbcdccddaJEcdfcaqbTFcbIcdgcdhcdicdjcdkcdlcdmcdncdocdpcdqcdrcdscdtcaEcducdvcdwcaIbZxbWQbZxbZycdxcdybZAcdzcdAcdBbZAcaPbYfbYfcaQbYccbYcbXcbZbYcchBccacjfcdLcdLbyFbBucdLcdOcdPcdQcdRcdOcdSbBpbyebydcdScdScdScdSbAebyebydcdScdSbXjcdXcdYcdZceacebcecbxTbycbycbycbycbycbycbycbycbycbycbycbycbycbycbycbyccefcegcegcehbKtbKtbLTbLTceibLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacejcejcejcejcejcejcejcekcelcemcemcemcemcemcenceocepcepcepceqcerbYSbYTbYUcesbYWcetceucevcewcexceybUGcezaJFboqaJFcaqbTFcbIceDceEceEceEceFceGbTJceHceIbTJcbLcbNceJcbOcaEceKceLceMcaIbZxbWQceNbZyceOcePbZAbZAbZAbZAbZAccbceRbYfcaQbYcccdcccbYcbYcchBccecjfcdLceZcfacfbcfccdOcfdcfecffcdOcfgcfhcfhcfhcficfjcfkcflcfmcfncfocfpcdScfqcfrcfsbUnbUnbUnbUnaaaaafaaaaaaaaaaahaahaahaafaaaaaaaafaaaaaaaafaafaafcftcfucfvbNebKsbKtbKtbLTbLUbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafaafaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafcejcfwcfxcfycfzcfAcejcfBcfCcfDcfEcfFcfGcfHcfHcamcfIcfIcfJcfKcbzbYSbYTbYUcfLcamcfMcfNcfOcfPcfQcfRbUGaJFaJFcaqceBcaqbTFcbIcfVcfWcfWcfWcfXcbIcfYcfZcgacfYcgbcgccgdcgecaEcgfceLcggcaIcghccfcgjbZycgkcglbZycgmbLvbVicgnccgcchbYfccjcciccicckcclcclcclcclccmcdLcgxcgycgycgzcgActsctyctscgDcgEcgFcgGcgGcgHcgIcgIcgJcgKcgLcgLcgMcdScgNcgOcgPcgNaaaaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafcgQbKqbKqbKrbKsbKsbKtbKtbKtbKtbKuaafaafaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaafaafcgRcgRcgRcgRcgRcgRcgRcgRcgRcgRcgRcgRcgRaaaaaacgScgTcgTcgTcgUcgVcejcgWcgXcgYcgZchachbchcchdchechfchgchhchichjchkchlchmchnbNFbUGbUGbUGbUGbUGbUGbUGbEZbGDcaqbDfcaqbTFcbIcbIctpctqctrcbIcbIchrchschtcfYcaEcaEcaEcaEcaEcaIchuchvcaIchwccnchwbZychychzbZychAchBbVichCbVichDbYfccobYfbYfccpcdCcdCcdCcdDbYfcdLchIchJchJchKchLchMchNchOchPchQchRchSchTchUchVchWcgIcgIcgIchXchYcdSchZciacgtcgNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacgRciccidciccgRciecifciecgRcigcihcigcgRaaaaaaciicgTcgTcgUcgUcijcejcikcilcemcimcinciocipciqcirbQJbQJcisbQJcbzbYScitbYUciucivciwcixciycixcixceTceUceUciAciAciAciAbTFciGciHciIciIciJciKciLciMciXciOciPciQciRciSciSciTciUcaIcaIcaIciVcdEckqbZybZybZybZychBchBbViciYbViciZbYfccobYfaaaaaaaaaaaaaaaaaaaaacdLcjgcjhcjhcjicjjcjkcjlcjmcjncjocjpcjqcgIcgIcjrcjscgIcjtcgIchXcjucdScjvcjwcjxcgNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacgRciccjyciccgRciecjzciecgRcigcjAcigcgRaaaaaaciicgTcgUcgUcgUcjBcjCcjDcjEcemcjFcjGcjHchHchGcivcjKcjLcjMcjNcbzbYScjOchmcjPcjQcjRcjScjScjSbJmbHPcjScjSceCcdeceAciAbTFciGckaciIckbckcckdcubckfckgckhctQckjckkcklciSckmciUcknckockpclicdFcdHcdGcdIcdIcdJcdIcdKbVibVibVibVibYfccobYfaaaaaaaaaaaaaaaaaaaaacdLckCckDckDckDckEcdOckFcdOckGckHckIckJckJckKckLckLckMckJckJckNckOcdSckPckQckRcgNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacgRcvkckTcvjcgRcvickWcvhcgRcusckZcudcgRaaaaafciiclbcgTcgUcgUcgUcejclccldcleclecnIclecleclecleclgbQJclhcltcbzcljclkcllclmclncgicgocgocgocgrcmScmScgpciAcgucgqclwclxciGclyciIclzclAclBclCclDclEclFclGclHclIclJciSclKciUclLclMclNclOclPclQclNclRclSclTbYfceQcdIcdIcdIcdIcdIceSbYfaaaaaaaaaaaaaaaaaaaaacdLcmacmbcmccmdcdOcmecmfcmgcdScmhcmicmicmicmjcmkcmlcmmcmicmicmicmncdScmocmpcmqcmraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaafaafcgRcmscmtcmucgRcCpcmtcmwcgRcCpcmtcmwcgRaaaaafcmzcgTcgTcgUcgUcmAcejcmBcmCcmDcmEcmFcmGcmHcmHcmIcmJcmHcmKcmLcbzcmMcmNcmOcmPcivcmQcmQcmRcmSceYceXceWceWciAcibceVcfUcqgciGcnbciIcnccndcneciGcnfciNcngcfYcnhcnicnjciScnkciUclLclMclNcnlcnmcnlclNaaaaaaaaabYfbYfbYfcnnclSclSclTbYfbYfaaaaaaaaaaaacdOcdOcdOcdOcdOcdOcdOcdOcdOcnocnpcnqcdScdScnrcnscntcdScdScdScdScnucnscntcdScdScnvcnwcnvaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabZSaafaafaafaaaaafcnxaafcnxaafcKBaafcKAaafcKBaafcKAaafaafaaacejcnAcnBcgUcgUcnCcnDcnEcnFclecnGcnHcleclecqUcleclecnJcivclecnKcnLcnMcnNcnKclecnOcnOcnOcsQcvzcnOcnRcnRcgscgscgscgscnSciGcnTcnUcnccnVcnWciGcnfciNcnXciUcnYcnZcnjcoacobciUclLclMclNcoccodcoeclNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaacdOcofcogcohcwlcojcokcolcomconcoocopcoqcwkaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaafcoscotcosaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaafcoucovcowcoxcowcovcKvcoxcqWcrScKvcoAcrTcrUcoBcoCcoCcoCcoCcoCcoCcoCcoCcoDcoEcoFcoGcoHcoIcvscoKcoLcoMcoNcoOcoPcoMcoQcoRcoScnOcoTcoUcoVcoWcoXcoYcnOcoZcoZcpacpbcpbcnRbTFciGciGcpccpdciGciGciGcpeciNcpfciUciUciUcpgcphciUciUclLcpiclNcvmcvncvmclNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaafaafcdOcplcpmcplcvlcpocppcpqcomcomcprcomcdOcdOaaaaaaaaaaafaafaaaaacaaaaaaaaaaaaaafaaacvtaaaaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaaaaaaaaaafcptcuicpvcHhcGYcuicHFcHDcHEcHBcHCcHvcHAcHucpucHscpHcHrcpJcHlcpLcpMcpNcpOcjZcpQcnPcnQcpTcpUcpVcpWcpXcpYcpZcqacqbcoQcqccqdcnOcoXcoXcoXcoXcoXcqecnOcqfcqfcqfcpbcpbcnRbTFcrYciGcqhcqicqjcqkciGcqlciNcqmciUcqncqocqpcqqciUcqrclLcpiclNcqscqtcquclNaaaaaaaaaaaaaaaaaacqvcqwcqxcqycqvaafaaaaaaaaaaaacdOcplcplcplcoicqAcqBcqCcqDcqEcqFcqGcqHcdOaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaaacmZaaaaafaafaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaafcqJcpucFtcGmcFVcpucymcpucrRczxcymcpucrRczxcpucpucpucpucpucqRcpucpucpucnQckzcnPcqYcymcpTcracrbcrccrdcrecrfcrgcrhcoQcqccricnOcrjcoXcoXcrkcoXcrlcnOcrmcrncrocrncrpcnRbTFcrqciGcrrcrscrtcrucrvcrwcrxcrycrzcrAcrBcrCcrDciUcrEcrFcrGcrHcqvcrIcqvcrHaaaaaaaafaaaaaaaaacqvcrJcrKcrLcqvaafaafaaaaaaaaacdOcomcomcomcomcrMcppcrNcrNcrNcnpcrNcrOcdOaaaaaaaaaaaaaaacrPcrPcrPbZSaafaafaafaafcnaaafaafaafaafaafaaqcrPcrPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaafaafcptcpucqYcpucqYcpucymcpucIicqMcyucqMcIjcqMcqMcyscIhcpucpucqScqPcqPcqPcrZckAcsdcsdcIgcpTcHYcHXcsicoMcsjcskcsycoMcsmcsncsocspcsqcsrcsscstcoXcsucnOcsvcrncswcrncsxcnRbTFcizciGcszcsAcsBcsCciGcfYcsDcfYciUcsEcsFcsGcsHciUcsIcrGcrGcqvcsJcsKcsLcqvcqvcqvcsMcqvcqvcqvcqvcsNcsOcsPcqvcqvcqvcrHaaaaaacdOcofcogcohcslcsRcqBcrNcrNcrNcnpcrNcsScdOaaaaaaaaaaaaaaacrPaaaaafaaaaafaaaaaaaaackxaaaaafaafaaaaaaaaaaaacrPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafaafaaaaaacptcpucqYcpucsUcsXcHTcsWcqzcHVcyucqMcHWcqMcqMcyscHRcpucpucHScGmcHPckBckBclvcqYcqYcHQctictjcHHcoCcoMctlcoMcoMcoMctmctncsoctocpncpscpjcpkcoXcttcnOctucrncswcrnbDecnRctvctwciGciGctxciGciGciGciBctzctAciUciUciUctBciUciUcsIcrGaaacqvctCctDctEctFctGctHctIctJctKctLcqvctMctDctNcqvctOctPcqvaafaafcdOcplcplcplcorcpoctRctSctTctUctVcrNctWcdOcdOcdOcdOaaaaaacrPaaactXctXctXctXctXaafckxaafctXctXctXctXctXaaacrPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacptcpucsUcsXcsXcsXcHTcsXcsXcsXcHTcsXcsXcsXcsXcsXcIncsXcsXcHTcsXcIvcsXcsXcsXcIpctgcthcuicpucIzcukculcumcuncuocupcuncuqcurcsTcutcuucuucuvcuucuwcuxcuycuzcuAcuBcuBcnRcuCcuDcuEcuFcuFcuGcuHcuIcuJcuJcuJcuJcuJcuJcuJcuJcuKcrFcrGaaactFcuLcuMcuNctFcuOcuPcuQcuQcuRcuQcuScuTcuUcuVcuWcuXcuQcqvaaaaaacdOcplcplcplcslcuYcuZcvacvbcvccvdcrNcrNcvecvfcvgcdOaafaafcrPaafckVckSckSckSckSckyckxckwckvckvckvckvckUaafcrPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacptcpucpucpucpucpucymcpucpucpucymcpucpucpucpucpucrRcpucpucymcpucIlcpucpucvucvvcIkcvwcvxcvycvxcvAcvBcvCcvDcvEcvBcvBcvFcvGcsQcvHcoXcvIcvJcoXcoXcvKcrncrncvLcuBcuBcnRbPxcAscvNcvNcvNcvNcvOcvNcvNcvNcvNclMcvPcrGcrGcrGcrGcrGcrGaaactFctFcvQctFctFcvRcvScvTcvUcvVcvWcvVcvXcvYcvZcwacwbcwccqvaaaaaacdOcomcomcomcomcwdcppcvacwecwfcwgcrNcrNcwhcrNcwicdOaaaaaacrPaafcwjcwjcwjcwjcwjaaackxaaacwjcwjcwjcwjcwjaafcrPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaabZSaaaaaaaaaaaacptcpucpucpucpucpucymcpucpucpucymcpucpucpucpucpucrRcpucpucymcpucvpcpucpucvpcvpcmXcpucpucwtcAtcoCcoCcoCcoCcwvcwwcoQcwxcwycspcwzcoXcwAcvJcoXcwBcnOcwCcrncwEcwFcwGcnRcwHcvMcvNcwIcwJcwKcwLcwMcwNcwOcvNcwPcwQcrGaaaaaaaaaaaaaaaaaacqvcwRcwScwTcwUcwVcwWcwXcwYcwZcxacvZcxbcxccxdcuWcqvcxecqvaaaaaacdOcofcogcohckXcsRcuZcxgcxhcxhcxicxjcxkcxlcxmcxncdOaaaaaacrPaaaaafaaaaafaafaafaaackxaaaaafaaaaafaaaaafaaacrPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacptcpucpucpucpucpucyocpucpucpucyocpucpucpucpucpucrRcpucpucrWcGmcxpcuecuecxpcykcxpcIBcIAcIDcuecqVcuecxAcxBcIEcwwcoQcxDcoQcxEcxFcoXcoXcxGcoXcxHcnOcxIcxIcxJcwFcwGcnRbPxcvMcvNcxKcxLcxMcxNcxOcxNcxPcvNcxQcxRcrGaaaaaaaaaaaaaaaaaacqvcxScxTcxUcxVcxWcxXcxYcxZcuTcyacuScybcuTcyccuVcqvcqvcqvaaaaaacdOcplcpmcplctbcpocppcrNcrNcyecyfcrNcygcomcomcomcdOaaaaaacrPaaactXctXctXctXctXaafckxaafctXctXctXctXctXaafcrPaaaaaaaaaaaaaaaaaaaaaaaacyhaaaaaaaaacyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafaaaaaaaaacptcpucqScqPcqPcxwckucqPcxwcqPckscxwcqPcqPcqPcqPcxvcqPcrXcxucqQcvpcpucpucyvcwscywcxtcyycyzcpucsbcpucxqcxqcxrcyGcoQcxDcyHcnOcyIcoXcyJcoXcyKcyLcnOcnRcnRcnRcnRcnRcnRbPxcvMcvNcyMcyNcxLcyOcxLcxNcyPcvNcyQcyRcrGaaaaaaaaaaaaaaaaaacqvcuVcySctFctFcyTcyUcyVcyWctMctDctNcyXctMctDcyYcqvaaaaaaaaaaaacdOcplcplcplckXcyZczacrNcrNcrNcyfcrNczbcrNczccrNczdaafaafcrPaafckVckSckSckSckSckyckxckwckvckvckvckvckUaafcrPaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafaaaaaaaaacptcpucymcpucpucpucyocpucpucpucyocpucpucpucpucpucrRcpucywcpucyncvpcpucpucylcykcuhcyjcoCctdcoCcoCcpucyiczBcxCcyGcoQcxDcoQcnOckYczEczFczGczHcoXcnOczIczJczJczKczLczMczNczOcvNcxNczPczQcxNczRczSczTcvNczUczVcrGaaaaaaaaaaaaaaaaaacqvczWcuMczXcuVczYczZcAactFcAbcAccsPcyXczWcAdcAecqvaaaaaaaaaaaackEcdOcAfcAgcAgcAhcAicAjcAkcAlcAmcAncAocApcAqcokcAraaaaaacrPaafcwjcwjcwjcwjcwjaaackxaafcwjcwjcwjcwjcwjaaacrPaaacyhaaaaaacyhaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaacyhaaaaaacyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaacyxcpucymcpucqKcqMcyucqMcuacqMcyucqMcuacqMcqMcqMcyqcytcyqcyscyrcuhcyBcyCcACcADcAEcAFcoCclacnzcoCcoCcoCcoCcoCcAIcAJcAKcAJcnOcnOcnOcnOcnOcnOcnOcnOcALczJczJcAMcANcAObPxcAPcvNcAQcARcAScATcAUcAVcAWcvNcAXcAYcrGaaaaaaaaaaaaaaaaaacqvcuQcAZcAectFcBacBbcBcctFcBdcBecBfcBgcBhcBicBjcqvaafaafaaaaaaaaaaaabquaaacdOcBlcBmcBncBocBpcBmcBqcBrcBpcBmcBscdOaaaaaabZSaaaaafaaaaafaaaaafaaackxaaaaafaaaaafaafaafaafcrPaaacyhcyhcyhcyhaaacyhcyhcyhcyhcyhcyhcyhcyhcyhaaacyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabZSaaaaaaaaaaaaaamaaaaaaaaacyDcpucymcpucywcwscymcpucywcwscymcpucywcwscpucpucyvcpucywcwscyEczfczhczecBBcBCcBDcBEcoCcyFcBGcvqcBIcBJcBKcBLcBMcBKcBNcBKcBOcBPcBQcBRcBScBScBTcBUcBVcBWcBWcBXcBYcAObPxcBZcvNcvNcCacCbcCccCbcCacCdcvNcrGcCecrGaaaaaaaaaaaaaaaaaacqvctFcCfcuVctFcCgcChcCictFcCjcCkcqycgvcCmcCncCocrHaaaaaaaaaaaaaaaaaacgwaafcdOcCqcluclUcomclsclpclqcomcloclVclWcdOaaaaaacrPaaactXctXctXctXctXaafckxaafctXctXctXctXctXaafcrPaaacyhcyhcyhcyhaaacyhcyhcyhcyhcyhcyhcyhcyhcyhaaacyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaafaafaafaafaamaafaafaafcyDczwczAczyczgczsczqczpczkcznczmczlczoczscpuczwczvczuczrczncztcoCcoCcoCcCzcCzcCzcCzcCzcvrcCzcCBcCCcCDcCEcCFcCEcCEcCGcCEcCEcCHcCEcCDcCIcCJcCKcCLciCcCNcCOcCPcCQcAObPwcCRcCScCTcCacAGcAVcBwcCacCWaafcCXcCYcCXaaaaaaaaaaaaaaaaaacqvcCZctDcuQcDacDbcuQcDccDdcDeaafaaachxchFchEclXaaaaaaaaaaacaaaaaaaaaaaaaaacdOcDhcplcplcomcDicplcplcomcDicplcplcdOaafaafcrPaafckVckSckSckSckSckyckxckwckvckvckvckvckUaafcrPaaacyhcyhcyhcyhaaacyhcyhcyhcyhcyhcyhcyhcyhcyhaaacyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPcpFaaaaaaaaaaamaaaaaaaaacAzcAvcAwcAxcAycABcAAcAHcAycABcAAcAHcAycABcBucBucBvcAHcAycABcBtcoCaaacDvcDwcDxcDycDzcDAcAucDCcDDcDDcDEcDFcDGcDHcDIcDJcDHcDIcDGcDKcDLcDMcDKcCBcCBcAOcDNcDOcDPcDQcAObNUcDRcDScDTcCacCbcDUcCbcCacCWaafaaaaafaaaaaaaaaaaaaaaaaaaaacqvcCZcDVcDWcDXcDXcDWcsPcDYcqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdOcDZcplcplcomcEacplcplcomcEacplcplcdOaaaaaacrPaafcwjcwjcwjcwjcwjaaackxaaacwjcwjcwjcwjcwjaaacrPaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPcClcqLcqLcqLcpEcpIcpIcpIcqLcpIcpPcpIcpGcpIcpPcpIcpGcpIcpPcpIcpGcpIcqLcpIcpRcpIcpGcpIcqNaafaaacEicEjcEkcElcEmcEncAucEocDDcEpcEqcErcEscEtcEucEvcEwcExcEscEycEzcEAcDKaaaaafcAOcEBcECcEDaafaaabNUbPxbPxbSkcCaclZcEFclYcCacCWaafaafaaaaaaaaaaaaaaaaaaaaaaaacqvcEHcuXcEIcEJcEJcEIcuQcEKcqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdOcplcplcplcomcELcplcplcomcELcplcplcdOaacaaacrPaaaaaaaafaafaafaaaaaacmTaafaaaaaaaafaafaaaaaacrPaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaafaafaaaaaaaaqaaaaaaaaaaafcgRcCpcmtcmvcgRcCpcmtcmvcgRcCpcmtcmxcgRaaacgRcmycmtcmxcgRaaaaafaaacEicEQcERcEScEQcCAcDBcEUcDDcEVcEWcEXcEscEYcEZcFacFbcFccEscFdcFecFfcDKaaaaaacAOcFgcFhcFiaaaaaabNUbPxbPxbNUcCacmUcmUcmUcCacFkcmWaaaaaaaaaaaaaaaaaaaaaaaaaaacqvcFmcFncuQcuQcuQcuQcuQcFocqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaackEcdOcdOcdOcdOcdOcdOcdOcdOcmYcmYcmYckEaaaaaacrPcrPcrPcrPcrPaaaaaaaaacmZaaaaaaaaacrPcrPcrPbZScrPaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaaaaafaafaaaaamaaaaaaaaaaafcgRcgCcDkcgBcgRcjbcDncjacgRciWcDqchqcgRaafcgRchpcDtchocgRaaaaafaaacEicFrcEkcEQcEQcqZcqXcFucFvcFwcFxcFycFzcFAcFBcFCcFDcFEcFFcFGcFHcFIcDKaafaaacFJcDNcFKcAOcFLaaabNUcFMbPxcFNcFOaafaafaafaaacBkaafaafaaaaaaaaaaaaaaaaaaaaaaaacrHcqvcqvcFPcFQcEIcEIcEIcFRcFPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqpbqpbqpaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaafcfTaafcrPaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaamaaaaaaaafaafcgRcEbcEccEbcgRcEdcEecEdcgRcEfcEgcEfcgRaaacgRcEfcEfcEhcgRaaaaafaaacEicFUcEkcEScEQcEncrVcEocDDcFWcFXcFYcEscFZcGacGbcGacGccEscGdcGecGfcDKaaLcGgcGgcGgcGgcGgcGgcGgbNUciEciDcGjaafaaaaaaaafcGkcDfaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGlcEJcEJcEJcEJcEJcGlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaaaaafaaacrPaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaafaamaaaaafaafaaacgRcEbcENcEbcgRcEdcEOcEdcgRcEfcEPcEfcgRaafcgRcEfcEfcEfcgRaafaafaafcGncGocGpcGqcGrcGscsacEocDDcoycGvcGwcEscGxcpwcoJcpxcGBcEscGCcGDcGEcDKaaacGgcGgcGgcGgcGgcGgcGgcGFcGGcGHbNUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqvcCmcqxcqxcqxcCocqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPcrPcrPcrPcrPaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbZSaaaaaacgRcgRcgRcgRcgRcgRcgRcgRcgRcgRcgRcgRcgRaaacFqcgRcgRcgRcgRaaaaaaaaaaaacCzcCzcCzcCzcCzcsccGJcGJcGJcGJcGKcGJcjIcjdcjecjdcjccGJcGJcGPcGJcGJcGJcGgcGgcGgcGgcGgcGgcGgaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaacyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafcrPaaaaaaaafaafaaaaafaafaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaafaaacGQcGRcGRcGRcGScGTcGUcsecsfcsgcshcGZcpzcpycpCcpAcqIcHfcsZcsYctacHgcHicHjcHkcsVcHIcGJcGgcGgcGgcGgcGgcGgcGgaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafcHncjVcHpaaacHncjVcHpaaacHncjVcHpaafaafaaaaafaafaafaafaafcHqcGRcGRcGRcGScGTcHLctfcHtctecjTcjUctkcjJcucctZcHzcIwcHjctccHjcHjcHjcHjcugcHZcIacGJcGgcGgcGgcGgcGgcGgcGgaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaacHncjWcHpaaacHncjWcHpaaacHncjWcHpaafaafaaaaafaaaaaacHKaafcGQcGRcGRcGRcGScGTcHLcHMcHNcjXcjYcjUcwpcwocwqcufcHjcHjcxocwucyAcHjcHjcHjcugcHZcIqcGJcIbaafaaIaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcHncjWcHpaaacHncjWcHpaafcHncjWcHpaafaaaaaaaafaafcIcaaaaafcHqcGRcGRcGRcGScGTcwmcIecIfcrQckickrcBzckecBHcBAcnycnycpDcImcEMcIocIocIocpBcHZcFScGJaaaaaaaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaacHncjWcHpaafcHncjWcHpaaacHncjWcHpaaaaaaaaaaaaaafaafaaaaafaaaaaaaaaaaaaafcIrcGVcIscItcIucLacGZcIwcHjcFscETcKYcLbcvocIycKUcKVcKYcKZcKXcHZcFScGJaaaaaaaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaaIaafaaacHncjWcHpaafcHncjWcHpaaacHncjWcHpaafaaaaaaaaaaaaaafaafcIJcIKcIKcIKcIKcILcILcILcILcILcIMcILcGJcHjcHjcINcGJcGJcGJcujczDcIQcGJcGJcGJcIRcIScHzcGJaafaaabZSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyhcyhcyhcyhcyhaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaaaaafaafczCaafaafaafczCaafaaaaafczCaafaaaaaaaaaaaaaaacIUcIVcIWcIXcIYcFTcJacJbcJcciFcJecJfcJgcJecGJcJhcHjcJicxscJkcJlczzcJnczjcJlcJpcxscJqcHjcJrcGJaaaaaaaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcydcxzcxycxxcxxcxxcxxcxxcxxcxxcxxcxxcxxcxxczicxzcxzcxzcypcJzcJAcJBcJCcJDcJEcJFcJGcJHcJHcJHcJIcJJcJKcGJcHjcHjcJicxscJkcJLcJMcJNcJOcJLcJpcxscJqcHjcJPcGJaaaaaaaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaactYctYctYctYctYaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaaaaafaafcxfaafaaaaafcxfaafaaaaafcxfaafaaaaaaaaaaaaaaacIUcIVcJRcJScJTcJUcIKcJVcJWcJecJecJXcJXcJYcGJcHjcHjcJZcxscJkcKacJMcKbcKccKacJpcxscKdcHjcHjcGJaaaaaaaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaactYctYctYctYctYaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaaIaafaafcHncwrcHpaaacHncwrcHpaaacHncwrcHpaafaaaaaaaaaaaaaafaafcKfcIKcIKcIKcIKcKgcKhcKicKicKjcKgcKgcGJcGJcGZcGJcGJcGJcGJcGJcwDcGJcGJcGJcGJcGJcGZcGJcGJaafaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHncwrcHpaafcHncwrcHpaaacHncwrcHpaaaaaaaaaaafaaaaafaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaafaaaaaaaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcHncwrcHpaaacHncwrcHpaaacHncwrcHpaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaaaaLaaaaafaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcHncwrcHpaaacHncwrcHpaafcHncwrcHpaafaafaafaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaIaaIbZSbZSaaIaaIaaaaaaaaaaaIaaIaaIaaIaaIaaIaaIaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaauaaaaaaaauaaaaaaaaaaauaaaaaaaaaaaaaaaaauaaaaaaaaaaauaaaaaaaauaaaaaaaaaaaaaaaaamaaacKraawaavaaacKraawaavaaacKraawaavaafaafaamaaaaaaaaaaaaaaaaafaafaahaaxaataataaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayaayaayaayaayaayaayaayaayaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaauaauaauaauaaaaaaaaaaauaauaauaauaauaauaauaaaaaaaaaaauaauaauaauaaaaaaaaaaacaaaaamaaacKraazaavaaacKraazaavaaacKraazaavaafaafaafaafaaaaaaaaaaaaaaaaaaaafaaaaaaaafaaAaaBaaaaaaaaaaaaaaaaaaaaaaaaaaaaayaaCaaDaaEaaDaaEaaDaaFaayaayaaGaaHaayaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaauaauaauaauaaaaaaaauaauaauaauaauaauaauaauaauaaaaaaaauaauaauaauaaaaaaaaaaaaaaaaaIaafcKraazaavaaacKraazaavaafcKraazaavaafaaaaaaaafaafaaJaaaaaaaaaaaaaafaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaKaaLaafaayaaMaaNaaNaaNaaNaaNaaOaaPaaQaaRaaSaayaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaauaauaauaauaaaaaaaauaauaauaauaauaauaauaauaauaaaaaaaauaauaauaauaaaaaaaaaaaaaaaaafaaacKraazaavaafcKraazaavaaacKraazaavaaaaaaaaaaaaaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaabhabhabhabhabhabhabhaafaaaaayaaUaaVaofaaVaaEaaVaaWaaXaaYaaZabaaayabbabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaamaamaaIaafaaacKraazaavaafcKraazaavaaacKraazaavaafaaaaaaaacaaaaafaafabcabdabdabdabdabeabfaaaaaaabhabvabvaojabvabvabhaaaaafaayabiabjaaXabjaaXabjaaXaayablaaZaosaayabnaboaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaamaaaaafaaaaafaafapsaafaafaafapsaafaaaaafapsaafaaaaaaaaaaaaaaaabqabrabsabtabuabzabwabxabfaafaaaabhabBabAaceabCacfabhaaaaaaabDabEabFabGabHaaEabFaaEabIabJabKabLamxabNabOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaaaaadaadaadaadaadaaaaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaIaafaqMaqbapTaqTaqTaqTaqTaqTaqTaqTaqTaqTaqTaqTaqTarBaqbaqbaoeamMamHamWamUacaacbamyacdaaTaaTaaTabhabhacgankacAabhabhachaciacjackaclacmacnacmacoackackackanPacqacracsactaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaaaaafaaLaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaaaaadaadaadaadaadaaaaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaamaaaaafaaaaafaafapjaafaaaaafapjaafaaaaafapjaafaaaaaaaaaaaaaaaabqabracvacwacxacyabdaczaaTaaTalPalxamtalZacEacFaaTaaTacGacHacIadnacKacLacMacNacOacPacQacQacRacSacracsabbabbabbabbabbabbaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaafaafaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaamaamaaIaafaafcKrapgaavaaacKrapgaavaaacKrapgaavaafaaaaaaaaaaaaaafaafacUabdabdabdabdacVaaTamuacXacXacXacXacEacXacYaoZadaacQadbadcaddadeacMadqacQacQacQacQadgadhackadiadjabbadkadladmabbaaLaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaacKrapgaavaafcKrapgaavaaacKrapgaavaaaaaaaaaaafaaaaafaafaaaaaaaaaaaaabfacVaaTalnadoadpadFadzadsadtaduaoZadaacQadvadcaddadwadxadyacQadMadMadMaddadAacradBadlalaadladladlalaaaLaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaaaaaaaIaafcKrapgaavaaacKrapgaavaaacKrapgaavaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaadDadEaaTalqacXacXacXacXacEacXalvaoZadaacQadvadHadIadJalradLadUadNadNadNadVadPacradQadlabbadRadSadlabbaaLaaLaafaaaaafaaaaaLaafaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaaaaaaaIaafcKrapgaavaaacKrapgaavaafcKrapgaavaafaafaafaaaaafaafaaaaaaaaaaaaaaaadTadEaaTaaTarSarPadWadXacEadXaaTaaTasnacQadbacQaddadZaeaadyadUadNaebadNaetaedacradQaeeabbabbabbabbabbaaLaaaaaaaaaaaaaaaaaaaafaafaafaaaaaaaafaafaaLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaqaafcKrarDaavaaacKrarDaavaaacKrarDaavaafaaaaafaafaafaaaaaaaaaaaaaaaaaaadTaegaaTaaTaaTaaTaaTaaTasOaaTaaTaaTaeiaejaekaelaemaenasBaepaeMaeraesaerafAaeuacradBaevabbaaaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaaaafaaaaaaaaaaafaafaafaaaaaaaafaafaaaaaaaafaafaaaaaaaaaaaaaaaaafaaaaewadEaexaeyarzaaTaeAaeBaeCaeDaeEaeFaeGaeHaeIaeHaddadZaeJaeKaeLaeLafBaeLaeNaeOarCaeQaeRabbaeSaeSaeSaeSaeSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauabgaaaaaaaaaaaaaaaaaaaaaaaaaamaamaaIaeTaamaamaamaamaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaafaafabfadEaeUaeVaeWaaTaeAaeAaeXaeYaeZaeFafaafbafcafdaddarOaffafgacQacQafhacQafiafjacrafkaflabbafmafnafoafoafpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaacaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfabfabfabfabfabfabfabfabfabfabfadEafqafrafsaaTaftafuafvafwafxappafzafNafOafNafCafDadxafEafFacQafhacQafGapdaqqafJafKaqJadlapHaghaqgafPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfafQafRafSabfafTafUafVafWafXafYafZafZafZafZafZafZagaagbagcagbaaTageagdagfarvarnaeFagiagjagkaglagmagnagoagpagqagrarjagtaguagpagvagwaryabbadlagyafoafoagzaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaabgaauaauaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaabfagAagBafZafZafZafYafYafZagCagDagDagDagDagDagDagDagDagDagDaoGaaTagFagGaoCagIagJaeFahNagLagLagLaddagMagNagOagPagQagRagQagPagSagvagTadlabbabbaeSaeSaeSaeSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaaaaeaaeaaeaaeaaeaaaaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauaauaauaauaauaauaauaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfagUagVagWagWagWagWagWagWagWagDagXagYagZagWahaahbahcahdaheahfahgahhahiahjahkahmahlahnahnahnahnaddahoahpahqahrahsahQahuahvahwagvahxahyaboaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkaaaaaaabkaaaaaaaaaabkaaaaaaaaaaaaaaaabkaaaaaaaaaabkaaaaaaabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaaaaeaaeaaeaaeaaeaaaaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfafQafRahAabfahBadEagWahCahDahEahFahGahHagDagZahIahFaezahKahLahLahMaiiahOaePacXacXacEacXaikaeoahSacQacQacQaddahTahUahVahWaeqahYahZaiaaibagvahxaicabOaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkabkabkabkaaaaaaaaaabkabkabkabkabkabkabkaaaaaaaaaabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaeaaeaaeaaeaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadDaidaieaifabfaigadEagWaihaimaijaipailaisagDagZahIainagWaioahLaizaiqahKahOairaiFacXaitacXacXaiuacZahSacQacQaddaiwaixaiyagPagPajeagPagPaiAagvaiBaiCactaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkabkabkabkaaaaaaabkabkabkabkabkabkabkabkabkaaaaaaabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaewagbagbaiDabfagbadEagWaiEakfaiGaiHaiIahFagDaiJaiKaiLagWaiMaiNaiOaiOaiPaiQaiRaiSaiTacEaiUaiVaeFaiWaiXaiYaiZakNakEajcajdakVajfajgajhagPajiagvahxabbabbabbabbaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaIaaIaamaamaaaaaaaaaaaaaaaaaaaaaaaaabkabkabkabkaaaaaaabkabkabkabkabkabkabkabkabkaaaaaaabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfadrabfabfajkajlagWagWadGagWagWadCagWagWagWadOagWagWajpajsadKantaecajuagWajvajwadYajyajqagWagWajzaehaefagWagWagWagpajCagpagpagpagpagpagvahxabbajDajEaboaaaaafaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaaaafaaaaaqaaaaaaaaaaaaaaaaaaaaaaaaabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfagBafYajFafYajGajHadfajJajKajLajMajNajOajPajQajRajSajTajUajVajWajXajUajYajWajWajZakaakaakbakcakdahOakeajbakgajzakhakiakjakkaklakmaknakoakpacWakZakqabOaaaaaaaaaaaaaaaaaaaaaaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafabQaafaaIaaaaaaaaaaaaaaaaaaaaaaaaabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaamaamaaIaamaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfadEagWagWagWagWagWagWaksaktakuakvakwakxakyakzacDakBakCakDakXakFakwakGakwakwakHakIakJakKakLakMajaakOakPakJakQacJakSakTakUalbakWalCakYakoalIabbalOamaactaaaaaaaaaaafaaaaaaaaaaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaIaaIaaIaaIaaaaaaaaaabpaaaaaaaaaaaIaaIaamaamaamaaaaaaabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaaaaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfadEagWalcaldalealfagWalgalhahLalialjagWacTacCacTagWabVacBabUagWalpacpacualsagDaltaluaccalwabZagWabTabSabSabRagWalBamcalDalEalFalGalHakoabXanQabYanQanQaaaaaaaafaafaaaaaaaaaaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqaaaaaaaafaafaafaaaaaaaoYaafaafaaaaafaafaaaaaaaamaaaaaaabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafabMaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafabfadEabyalMalMalNamsabmalQalRahKalSaljagWalTalUalValWalXalYabWabPahKambahKamNamdameameamfamgamhamiamjamkamlammakoamnamoampamqalDalDamrakoadQanQamvawKamwaaaaaaaaLaaaaaaaaaaafaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafanTanTanTanTanTaafalJaafanTanTanTanTanTaafaaIaaaaaaabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaamaaIaaIaaaaaaaaaaoXaaaaaaaaaaaIaaIaamaamaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfadEagWamAamBamCamDagWamEalRaljamFamGagWamRamIamJalWamKamLakAakRamOamPamQanaamSamgamgamfamgamTaoWamVanfamXanhakoamZanWalDamqalDalDanbakoancandaneaocangaafaaLaafaafaaLaafaafaafakrakrakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafanianjanjanjanjanualJansanqanqanqanqanwaafaaIaaaaaaabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaafaafaaaaaaaaaaoVaafaafaaaaafaafaaaaaaaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfajBagWagWagWagWanlanmannanoanmanmanmanmanpaoPanpanraoQajAaoRanvaoSaoTaoUanzanAamgamgamfanBanCamianDanEamXanFanGanHanIanJanKanLanManNanGanOajIapqanRanSaaaaaaaafaaaaafaaLaafaacakrakrakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafapIapIapIapIapIaafalJaafapIapIapIapIapIaafaaIaaaabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafanVanVanVanVanVaafalkaafanVanVanVanVanVaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanXanYanZaoaagDaobapDagWaodajoalKaogaohaoibqKaokaolaomaonaooaonaopaoqaoraonaoOaotamgamgaouaovaowamiaoxanEamXaoyanGaozaoAaoBajraoDaoEaoFanGajxanQanQanQanQaoIaoJaoHaoLajtaaaaafaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaafaaaaaaaafalJaaaaaaaaaaafaaaaaaaaaaamaaaabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaIaafalzalyalyalyalyalAalkallaivaivaivaivagEaafaaIaaaaaaaaaaaaaaaaaaaacaaaaaaaaaanXanXapaapbagDalMapcajjapeapfahXaphapiaoMaonaonapkaplaonapmapnaoraonapoaonaoNapEapramgamfamgamTajmamYanEamXaptanGapuapvapwapxapyapzapAanGapBaoHapCapLapGapFapPaoHaoHajnaoHaoHaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafanTanTanTanTanTaafalJaafanTanTanTanTanTaafaaIaaaaaaabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafapJapJapJapJapJaafalkaafapJapJapJapJapJaafaaIaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaapKapaapbagDapUapMagWalgapNalKapOapVapQapRaokapSaqmaqcaqpapWapXapYapZaqaanUaqNaqdaovaqeaovaqfahPaqhaqiaqjaqkanGaqlaqWapyaqnaqoarlaqoahRaqraqsapFaqtaquapFaqvaoHaqwaqxaqyaoHaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafanianjanjanjanjanualJansanqanqanqanqanwaafaaIaaaaaaaaaaaaaaaaaaabkabkabkabkabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaafaaaaaaaafalkaaaaaaaaaaafaaaaaaaaaaaqaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaqzaqAaqBagDagWagWagWaqCalRagWalWalWalWaqDaqEapkaqFaqGaqHaonaqIahzaqKaqLanyarMaqOaqPaqQaqRaqSanxaqUaqVarQamVanGaqXaqYaqZaraarbarcardanGarearfapFaqtaqtapFargaoHarhariahJaoHaaaakrakrakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafapIapIapIapIapIaafalJaafapIapIapIapIapIaafaaIaaaaaaaaaaaaabgaaaabkabkabkabkabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafanVanVanVanVanVaafalkaafanVanVanVanVanVaafaaIaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaqzarkaqBagDaobarZagWarmaggalKaogaroaoiaokarparqarrarsartaonarualWagxarwarxalLagsarAagKamzagHarEarFarGarHamjanGanGarIanGanGanGanGanGanGarJarKarLasaasaapFarNaoHaoHahtaoHaoHaaaaaaakrakrakraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaafaaaaaaaaaalJaaaaaaaaaaafaaaaaaaaaaamaaaaaaaaaaaaaaaaaaabkabkabkabkabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaLafLaaLaaaaaaaaaaaaaaaaaaaaaaaIaafalzalyalyalyalyalAalkallaivaivaivaivagEaafaaIaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaqzasbaqBagDarRapcafyarTarUafeapharWaloaonaonarYasFasyasMaonascalWasdasealmasgasharAasiasjaskarEaoHaoHaoHaoHaoHaslafIafHasoasoaspaspasqasrassastastasuasvasvaswasxafMaszaqsaaaaafaafaafaaaaaaaafaafaafaafaaaaaaaafaafaafaaaaaaaaaaaaaaIaafanTanTanTanTanTaafalJaafanTanTanTanTanTaafaaIaaaaaaaaaaaaaaaaaaabkabkabkabkabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafasAaSZasAaaaaaaaaaaaaaaaaaaaaaaaIaafapJapJapJapJapJaafalkaafapJapJapJapJapJaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasCasbapbagDapUapMagWasDasEalKapOasPaoiasGasGasHasIaonasJaonasKalWasLatgaSHathatiarAasQasRasSarEasTasUasUasVaRxasVaSoaStasZasZasZasZasZasZasZasZasZasmataatbatcaoKatdateatfaaaaafatPatratjatjatjatjatQatjatjatjatjatUaafaaaaaaaaaaaaaamaafanianjanjanjanjanualJansanqanqanqanqanwaafaaIaaaaaaaaaaaaaaaaaaaaaaaaabkabkabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatkatlatmaaaatnatoatpaaaaafatqatWatqaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaafaaaaaaaaaalkaaaaaaaaaaafaaaaaaaaaaamaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaanXatsattagDagDagDagWagWagWagWalWalWalWalWalWatuaonaoratvaqEatwalWalWalWatxatxatxarAatyatzatAarEatBasZasZasZasZatCatDatEatFatGatHatIatJatKatLatMatNatOatPatPatPatPatPatPatPatPatPatPatRatRatRatRatRatRatRatRatRatRaumaafaaaaaaaaaaaaaamaaaapIapIapIapIapIaafalJaafapIapIapIapIapIaaaaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaabkabkabkabkabkabkabkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatSatTaUjatTatSatVaUlatVatSaafatqaVfatYaaaaaaaaaaaaaaaaaaaaaaaIaafanVanVanVanVanVaafalkaafanVanVanVanVanVaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafatZauaanYaubaucanXaafaafalWaudaueaufaugauhaTPaonapnaonasJaqEaujaukaulauvaunauKauparAauqaurausarEatBasZauLaySauMatCauxauyatFatGauzauAauBauCauDatMatNauEauFauGauHauIauHauJauwauOauPaxsatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaamaaaaafaaaaafaafaaaaaabepaaaaaaaafaaaaaaaafaaaaaIaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauNatTavmatTauNatVavyatVauNauQauRaVIauTauUauUauVauQauQaafaaaaaIaafalzalyalyalyalyalAalkallaivaivaivaivagEaafaaIaaaaaaaaaaaaaaaaaaaaaaaaanXanXanXauWanXanXapbaucanXaaaaaaalWauXalWauYauZavaalWavbavzaonavdaveaveavfavgaveavhaviavjarAavkauravlarEatBasZavAavoavJatCawravqatFatGauzauAavravsavtatMatNavuavvauGauHauHauHauJavwavQawfavVatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaamaamaaIaaaaaaaafaaaaaaabpaaaaafaafaafaafaaIaaIaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauNavBaLiavDauNavEaLeavGauNavHavIaKYavKavLavMavNavOauQaaaaaaaaqaaaapJapJapJapJapJaafbeSaafapJapJapJapJapJaaaaaIaaaaaaaaaaaaaaaaaaaaaaaaaLmaLkavSaMcaMwaLYavWavXanXaaaaaaalWalWalWavYavZawaalWawbawcawdaweawpawgaukawhawxautawyawlarAawmauraMEarEatBasZawzawUawYaxaaxbawZatFatFatFawsawtawuatFatFatNawvawwauGauHauHauHauJawAavxawfaykatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaaaaafaafaaaaafaaaaaaaKXaaaaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauNawGawHawIauNawGawHawIauNawJavHavHavHavHavHavHavHasAaaaaaaaaIaaaaafaaaaafaafaaaaaaaOpaaaaaaaafaaaaaaaafaaaaaIaafaaaaaaaafaafaaaaaaaafawPaLkawQawRaMwawSaucawTanXaafaaLcqTatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxarAawVaurawWarEatBasZawBaxjawCatCaxVavnaxdaxcaxfaxeaxhaxgaxhaxiaxkaxlaxmaxnaxoaxoaxoaxnaxmavxawEawDatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaaaaaaaafaafaafaaaazoaMXazoaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaatSauNaQcaxxatSauNaOsaxxatSauNaOHauNauNauNauNauNavHatqaaaaaaaaIaaIaaIaaaaaaaafaaaaxBaQxaxBaafaafaafaafaaIaaIaaIaafanXanXanXanXaxDaxEaxEaxFanXanXanXanXaxGaucaucanXaxHaxIanXanXaxJaxKaxLaxMaxMaxMaxMaxMaxMaxMaxMaxNaxMaxMaxMaxMaxMaQdaxPaxQaxRaQdavpasZaxSawjcfSatCaxVaxXaxXaxXaxZaxYayaawLaxXavqaydayeayfaygayhayhayhayhawXavxawEawDatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaAuaOqaAuaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaynayoaypayoayqayoayrayoaysaytayvayvayvayvaywauNawNatqaaaaafaafaaaaaaaaaaaaaafaaaayyaRrayAaafaaaaafaaaaaaaaaaaaaaaanXayBayCayDayCayCayCayCayEayCayCayFayGayDayHayIaxMaxMaxMaxMaxMaxMayJayKayLayLayLayLayMayLayLaQAayLayMayLayLayLarAayOayPayQarEaAiasZcfSaycaxUatCayUayTayWaxpayYayXayYaxqayTazaazbazcazdazeazdazdazfaxraxuaxtaxTaxvatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaaaaaaaaaaafaafaBuaBvaQyaBxaByaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazqazrazsaztazuazvazwazxazyazwazzazAazwazwbhJauNavHauRaafaafaaaaaaaaaaaaaaaaafazDazEbguazGazHaaaaafaaaaaaaaaaaaaaaanXazIanXazJazKazLazLazLazMazLazLazLazNazJazOazPazPazPazPazPazPazPazQazRayLazSazTbgMazVazWazXazYazZaAabheazTaAcarAaAdayPayQarEaAiasZaybaAeauMatCaxWaxXaxXaxXaxXayiayjaAlaAmaAnaxkaAoaylaApaApaApaAqayVatPayZatPatPatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaCvaCwbhKaCyaCvaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafauNaAwaAxaAwaAyazsazsaAzaAwaAxaAwaAAaABaACaADauNavHauQauQaAEauUauUauUauUauVauQaAFaAGbhLaAIaAFanXanXaxHaAJaxIanXanXanXazIaAKazJaaaaafaaaaafaaaaafaaaaafaaaazJazOazPaALaAMaANaAOaAPazPazQaucayLaAQaAQaARaASaATaAUaAVaATaAWaAXazTaAcarAaAdayPaDdarEaAiasZawzaAgaAhaBbayRaBdaBeazhaBgaBhaBiaBjaBjbhNaBjatPaBlaBmaBnaBoaBpaBraxvaziazkazjatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaacaaaaaaaafaaaaCvazlaDAaDBaCvaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaBzatSaBAawHaBBaBCaBDaBEaBFaBBawHaBGaBHaBIaBJaBKaBLavHavHavHavHavHavHavHavHaBOaBPaAFazmaBRaBSaAFaBTaBUayCayCayCayCayCaBVaBWaBXazJaafaBYaBYaBYaBYaBYaBYaBYaafazJazOazPaBZaCaaCbaCcaBZazPazQaCdayLayLayLayLaCeaCfaCgaChaCfaCiaCjazTaCkarAaAdayPaClarEaJCasZaznaAYazCatCaxWavqatEaBjaBjaBjaBjaBjaCqaCraCsaBjatPatPatPatPbhSatPatPaAfaAkaAjatRatRatRatRatRatRatRatRatRatRaumaafaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaCvaEXaEYaAraCvaaaaaaaaaaafaafaaaaaaaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazqaAxaCzaCAaCAaCAaCAaCBaAxazqaaaaBIaCCaxzaBLaCEaCEaCEaCEaCEaCEaCEavHaCFaCGaAFaCHaCIaAsaAFaCKbitaCKaCKaCKaCKaCKaCKaCKaCKaCMaaaaBYaCNaCOaCPaCQaCRaBYaaaazJazOazPaBZaCSaCTaCUaBZazPazQanXayLaCVaCWaARaCXaCYaCZaDaaDbbiqayLayLayLarAaAdayPayQarEaAiasZaAtaBcauMatCaDgavqatEaDhaDiaDjaDkaBjaCqaDlaCsaBjaDmaDnaDoaDpaDqaGwaDsatPatPatPaAZatjatjatjatjaBaatjatjatjatjaBfaafaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaCvaCvbiDaGyaCvaDCaDDaDEaDCaDCaDCaDCaDCaDCaDCaDFaDGaDGaDGaDHaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaaaaaaaDIaDJaDKaDJaDJaDLaDMaDJaDJaDKaDNaDOaBIaDPaxAaBLaDRaDSaDTaDUaDVaDWaCEavHaDXauQaAFaAFaWoaDZaCMaEaaEbaEcaEdaEeaEfaEgaEhaEiaEjaCMaafaBYaEkaElaEmaEnaEoaBYaafazJazOazPaEpaEqaEraEsaEtazPazQaEuayLazSazTaWwaEwaCfaExaEyaATaEzaEAaEBaEBarAaAdayPayQarEaAiaCmaCmaCmaCmaCmaEHaEIatEaEJaEKaEKaELaWFaEKaENaEOaBjaEPaEQaERaXIaETaCnaDsaaaaafaafaafaaaaaaaafaafaafaafaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaaaaDCaBsaBqaDCaBtaCpaBQaFdaFdaFdaFdaFeaFfaFgaFgaFgaFgaFgaFgaFgaFhaFiaFjaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaDIaDNaDJaFkaFlaFlaFmaFnaFoaFpaFqaFlaFlaFraFsaFtaDPayuaBLaFvayxaBMaCxaBMaBNaYqavHaFuaXXaFxaCJaFzaDraYwaFJaFKaFLaFLaFLaDtaFLaFLaFNaFOaCMaaaaBYaDuaElaFQaEnaFRaBYaaaazJazOazPaFSaFTaFUaFTaFVazPazQaFWayLayLayLayLaFXaCfaCgazTaCfaFYaYAazTaGaarAaGbaGcaGdarEaAiaDeaYyaDvaCoaDeaEVaDzaYxaGlaGmaBjaBjaBjaBjaBjaBjaGnaGoaGpaGqaDpaYVbaNaDsaDsaDsaDsaDsaDsaDsaDsaDsaFaaFbaDsaDsaFaaGtaDsaDsaaaaaaaDCaDCaDCaDCaDCaEZaEWaFdaFcaFwaDCaDCaDCaDCaDCaGDaGEaGFaGFaGFaGFaGFaGFaGGaGGbaPaGGaGGaGGaGGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaFraGIaFyaGKaFlaFMaFlaFMaFlaFMaFlaFMaFlaGMaGNaGOaDPayuaBLaGPaFAaGRaGSaGTaGUaCEaFBaFDaFCaFCaFCbazbbhaFCaHcaFLaFLaFLaFLaFLaFLaFLaFNaHdaCMaafaBYaHeaHfaHgaHhaHiaBYaafazJazOazPaHjaFPaFUaHlaHmazPaHnaHoayLaHpazTaARaHqaATaHrazTaCfaFYaHsazTaHtarAaHuaHvaHwarEaGubbfaEUaGvaDwbaYaGzaGjatEaHCaHDaBjaHEaBjaHFaBjaHGaBjaHHaGpbcTaDpbcabcPaHLaHMaHMaHNaHOaHKaHKaHKaHKaHKaHPaHKaHKaHKaHQaHVaDsaDsaDsaDCaGBaGAaGCaGCaGLaGJaDCaDCbbPaDCaIdaIeaIfaIgaGFbbQaGFaIiaIjaIkaIlbinbbRaIoaIpaIqbbSaIsbjFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaIwaFlaFlaDKaFlaFMaFlaFMaIxaFMaIyaFMaFlaGMaGNaGOaDPaFFaIAaIAbeaaICbdQaICaIAaIAaIEaIFaFCaGQaFHaGWaHkaFCaIKaILaIMaFLaFLaHRaFLaIOaIPaIKaCMaaaaBYaBYaIQaHSaIQaBYaBYaaaazJazOazPaISaITaIUaFTaIVazPaIWaIXayLaIYazTbeMaEwaCfaJaaEyaATaJbaJcazTaJdaJeaJfaJgaJhaMbbeeaCuaCuaCuaCuaCuaHUaHTaJlaJmaJnaBjaJoaBjaJpaBjaJqaBjaJraGpbfyaJtaGsaGsaDqaJvaDsaDsbeNaDsaDsaJxaDsaGsaJyaGsaGsaGsaJzaHZaHXaHWaIabfxaIraIbaIbaIbaIRaINaIgaJIaJJaJjaJkaJMaJNaIgaJOaJPaGFaJQaJAaJSaJTbinaJUaIoaJVaJBaGGaGGaGGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaFraJXaFyaGKaFlaFMaFlaFMaFlaFMaFlaFMaFlaGMaGNaGOaDPaGYaGXaHaaGZaHbaHbaIBaIzaIHaIGaIJaAbaJZaJYaJGaKaaFCaIKaKmaKnaKoaKpaIKaKqaKraKsaKtaKuaaaaafaaaaKvaKwaKvaaaaafaaaaKuazOazPaKxaKyaKzaKAaKBazPaKCaKDayLaKEazTaARaKFaKGaHrazTaKHaKIaKJaKKaKLaJeaEDaKNaKOaKPaEEaKRaaaaaaaJlaKSaJKazUaJlaKVaJnaJnaJnaKWaJnaJnaJnaBjaDpazFaDpaDpaDpaDpazBaDpaKZaLaaLbaLcaLdazpaLfaLgaLhaLfaLfaLfaLfaLfazgaLfaLfaLfaLfaLfaLfaLfaLfaJLaIgaLjaJRaLlaEFaJWaLoaIgaLpaKbaGFaLraLsaLtaJTayNaJUaIoaJVaIoaKTaLwaLxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaLyaLzaDJaFkaFlaFlaFlaLAaFlaFlaLBaFlaFlaFraLCaLDaDPaLEaLFaLGaLHaLGaLGaLGaLGaLGaLIaLJaFCaFCaFCaFCaFCaFCaLLaLMaLNaLOaLOaLOaLOaLPaLQaLRaKuaLSaLTaLTaLUaLVaLWaLTaLTaLXaKuayzaKuaKuaLZaMaaLZaJeaJeaMbaxyaJeaJeaJeaJeaMdaMeaxCaxOaMhaMiaJeaJeaJeaJeaMjaKNaMkaMkaMlaMmaMnaMoaJlaMpaLqaLnaJlaJlaJlaJlaJlaJlaJlaJlaBjaBjaMsaMtaMuaMvawMaLvaMyaMfaKZaMAaMBaMCaMCaMDaLfaxwaMFaMGaMHaMIaMJaMKaMLaMMaMNaMHaMJaMIaMHaMOaLfaJLaIgaMPaMgaMRaMSaMqaMUaIgaMVaMWawoaMYaMraNaaNbaGFaGGaNcaJVaIoaMxaNeaNfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaaaaaaaLyaDJaDKaDJaDJaDLaDMaDJaDJaDKaLzaNgaBIaNhaLEaNiaMzaMzaNkaMzaNlaIAaNmaNnaLJaNoaNpaNqaNraNsaNtaNraNuaNraNraNraNvaNraNraNwaNxaNyaNzaNAaNBaNzaNCaNzaNzaNzaNzaNDaNEaNFaNGaNraNHaNIaNJaNKaNLaNMaNLaNNaNOaNPaNQaNQaNRaNSaNTaNSaNUaNVaNWaEGaNYaNZaOaaObaOcaMkaMkaMkaOdaOeaMTaMQaOhaOiaOjaOkaOlaOmaOnaJlaOoaCLaCDaOraOtaOtaOuaMZaOwaNdaKZaOyaOzaOAaOAaOBaLfaOCaODaOEaOEaOEaOEaOFaOGaCtaOIaOJaOKaOKaOLaOMaLfaJLaIgaONaOOaNjaOfaONaONaIgaORaOSaGFaOTaOUaOVaOWaGFaIoaIoaJVaIoaGGaGGaGGaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaOXaOYaOZaPaaPaaPaaPaaPbaOYaOXaaaaBIaPcaPdaPeaOvaOgaPhaPhaOxaIAaPjaNnaPkaPlaPmaPnaPoaPpaPqaPqaPraPsaPsaPsaPtaPuaPuaPvaPwaNIaPqaPqaPxaPyaPzaPAaPBaPBaPCaPBaPDaPyaPyaPyaPEaPFaPGaPHaMkaPIaPJaPJaPJaPJaPJaPJaPJaPJaPKaPJaPLaPMaPNaPOaPPaPQaPRaPSaPTaPJaPUaPJaPVaPWaPXaPWaPWaPWaPWaPWaPWaPYaPZaRsaQbaQbaQbaAHaQbaQbaAvaQeaQfaQgaKZaQhaMCaQiaQjaQkaLfaQlaQmaQnaQnaQnaQnaQnaQoaQpaOPaQraQnaQnaQsaQtaLfaJLaIgaQuaONaONaQvaONaQwaIgaGFaGFaGFaGFaGFaGFaBwaGFaIoaIoaJVaIoaBkaOQaGGaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaafaBIawqaBIaQBaQCaGOaQDaQEaQFaQGaGOaQCaQHaQIaBIaQJaLEaPeaPfaQLaPhaPhaOxaIAaQMaNnaLJaQNaNpaQOaQPaNraNraQQaQRaQSaQTaNraQUaQVaQWaQVaQXaQYaQVaQVaQZaQVaQVaRaaRbaQVaRcaQVaRdaNraNraNraReaPFaPGaPHaMkaRfaMkaRgaRgaRgaRgaRgaRgaRgaRgaRhaRiaRgaRjaRgaRgaRkaRgaRgaRgaRgaRlaRmaRnaRoaRoaRoaRoaRoaRoaRoaRpaRqaRpaJlaImawOawOawOawOawOaItaRuaRvaRwaKZaKZaKZaKZaKZatXaLfaRyaQmaQnaRzaRAaRBaPgaRDaREaRFaQraRGaRHaRIaRJaLfaJLaIgaRKaRKaRLaRMaRNaRNaROaIgaRPaRQaRRaGGaRSaRTaRUaRVaRVaRWaRXaGGaRYaGGaRZaRZaRZaSaaSbaScaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaGeaGgaGgaGiaGfaGhaSdaOYaLDaDPaHxaHxaSfaLDaOYaLDaHyaHAaHzaLEaSkaPiaPiaNkaPiaNlaIAaSmaNnaSnaIAaLKaLKasXaLKaLKaLKaLKaLKaLKaSpaSqaLKaLKaLKaLKaLKaLKaSraSsaSraLKasYaLKaNraQPaSuaSvaSwaSxaNraSyaLKaMbaMbaMkaSzaKOaSAaMnaMnaSBaSBaSBaSBaSCaJeasfasNarVarXarXavParXarXarVasNawFaJeaSJaSKaSKaSKaSKaSLaSLaSMaSNaRqaRpaJlaQqaQaaQaaQaaQaaQaaQaaSQaSRaSSaSTaSUaSVaSWaSXaSYaKZaKZasWaTaaTbaTcaTdaTeaTeaTeaTfaTgaTfaTeaTeaTeaTeaJLaIgaThaONaRLaRMaONaONaTiaIgaTjaQzaTlaGGaIoaTmaTnaToaTpaTqaIoaTraQKaGGaTtaTuaRZaTvaTwaTxaafaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDauSaNXavTavUawiaSgaSeaSiaShaSjaSiaTzaTyaTBaTAaTEaTCaTAaTFcozaTIaTJaTKaTLaTLaTLaTMaTLaTNaTOaIAavRaTQaTRaTSaTTaTUaTVaTWaTXaTUaTYaTZaUaaUbaUcaUdaUeaUfaUgaUhaUeaUiaLKaLKawnaLKaLKaLKaLKaUkawkaLKaUmaMbaUnaSzaKOaUoaaaaaaaaaaaaaaaaaaaaaaUpaUqaUraUsaUtaUvaUuaUxaUwaUzaUyaVUaUpaaaaaaaaaaaaaaaaaaaaaaUAaSNaRqaUBaUCaUDaUEaUFaUFaUFaUFaUGaUHaUIaUFaUFaUFaUJaUKaULaUMaUNaUOaUPaUQaURaUSaUTaTfaUUaUVaRCaUXaUYaUZaVaaVbaTeaJLaIgaVcaVcaRLaRMaVdaVdaVeaIgaIgavFaIgaGGaVgaVhaViaViaViaVjaVkaGGaGGaGGaVlaVmaVnaVoaVpaVqaafaafaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDauScmVaVravCaDPaVsaVsaVtaVsaVsaVsaVDaVsaVsaVtaVsaVsaYEaWYaVuaVvaKdaKdaKdaKdaKdaVwaVxaVyaVzaIAaTQaTQaVAaTSaVBaTUaTUaTUaTUaTUaTYaVCaTUaTUaTUaUdaUeclraVEaVFaUeaUiaVGaVHaKeaKcaVKaUmaVLaVMaVNaVOaVPaVQaMkaSzaKOaUoaaaaaaaaaaaaaUpaUpaUpaUpaVRaSlaVTaXEaVVaSDaVXaXFaVZaSOaWbaUpaUpaUpaUpaaaaaaaaaaaaaUAaSNaRqaRpaWcaSSaSPaWeaTkaSSaTsaUWaWiaVSaWkaVWaWmaWnaQbauiaWpaWqaWraWsaWtaWtaWuaWvauoaWaaWyaWdaWAaWBaWCaWDaWEaTeaJLaIgaThaONaRLaRMaONaONaONauuaWGaONaWHaGGaWIaWJaToaToaToaTqaIoaYsaGGaWfaVoaLuaWQaVoaWRaWSaWTaWTaWUaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTGaGgaTHaGiaBIaBIaBIaWVaWWaWWaWWaWWaWWaWWaWWaWXaBIaBLcpSaWZaIAaXcaXbaXbaXbaYraXdaIAaIAaIAaIAaTQaXeaXfaTSaXgaTUaTUaWgaXiaXjaXkaWgaTUaTUaTUaXlaUeaXmaXnaXoaUeaUiaVGaXpaKfaXraXsaUmaXtaVPaXuaXvaXwaXxaMkaSzaKOaMmaSCaMbaXyaUpaUpaVYaXAaXzaXCaXDaXDaXEaXFaXGaXEaXFaXDaXDaXHaGxaXJaXBaUpaUpaXyaJlaXLaXMaSNaRqaRpaJlaXNaSPaXOaTkaSSaXPaXQaSSaWhaXSaTkaSSaXTaOtaXUaXVaUQaXWaHYaXYaXZaYaaYbaYcaYdaYeaWjaYgaWBaYhaWDaYiaTeaJLaIgaYjaYjaRLaRMaWlaONaONaYlaONaWzaWxaGGaIoaXRaXhaToaYfaYkaZXaWLbaOaYmaWOaZcaVoaYvaHIaGVaGHaYzaHJaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaGkaaaaaaaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaafaYCaYDcpKaYFaWPaYHaYHaYIaYJaYKaYLaYMaYNaYOaYPaYQaYRaYSaTSaYTaTUaTUaWgaXjaYUbbTaWgaTUaTUaYWaUdaUeaUeaUeaUeaUeaUiaVGaVGaVGaVGaVGaUmaYYaXvaYZaXvaXvaXxaMkaSzaKOaNSaNSaZaaZbaWNaUpaZdaYnaZfaZgaZfaZfaZfaZfaZhaZfaZfaZfaZfaZfaZfaYoaZjaUpaWMaZbaZlaZmaZnaSNaRqaRpaWcaSSaSSaSSaSSaSSaXPaZoaSSaWhaZpaTkaSSaXTaOtaZqaXVaUQaZraZsaZtaZuaYaaYpaZwaYdaYeaWjaYgaWBaYhaZxaZyaZzaGraZzaZzaZzaZBaZCaZDaYtaOOaZFaZGaZHaZIaGGaZJaYXaYGaToaZeaYGaIoaIoaXaaZiaVoaYuaVoaZNaZOaZPaZQaWTaZRaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaZSaZTaZUbjnaZWaSFaZYaZkbaaaZvbacbadbaebafaYObagbahbaibajaTSbakbalbambanbaobapbaqbarbarbarbasbataTSbaubavbawbaxaKgbajbnZaKhbajbaCaUmbaDbaEbaFbaGbaHbaIaMkbaJbaKaMkbaLbaMaJHbcyaKjbaQbaRbaQbaSbaTbaUbaVbaWbaXaKlbaZbbabbbbbcbaQbbdbbeaKQbeoaKMbbibbjbbkbblbbmbbnaJlaUDaSPbboaTkaSSaZAaZEbbraZKaXOaTkaSSaXTbbtaULaXVbbubbvbbwaUQaUQaYabbxbbybbzbbAbbBaYgaWBbbCaWDbbDaZzaZLbbFbbFbbGbbHbbIaRLaRLaRLaRLaRLaRLaRLaGGbbJaXRaXhaToaYfaXhaIobbKaGGbbLaVoaYuaVoaZNbbMbbNbbOaafaKUaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaIIaIZaIDaInbbUaSFbaabaabaabaabaabbVbaabbWaYObbXbbYbaibbZbbZbbZbbZaIhbbZbcbaTUbccbcdbcebcebcfbcgaTSaXebchbcibcjaKiaIcblcaKkbcobcobcpbcpbcpbcpbcpbcqaMbbcrbcsbctbcubcvbcwbcxbbgaUpbczbcAbcBbaBaUpaUpaUpaUpaUpbcDaUpaUpaUpbcCbcFbcGbczaUpbbgbcxbcHbcIbcJbcKbcLaRpaWcaSSaSSaSSaSSaSSaGpbcMaSSbcNaSSbcObcObcObcOaJwbcQbcRbcSaUQaUQaUQaJsbcUaTeaZMbcWbcXaYgaWBaYhaWDbcYaZzaZZbdabdbbdcbddbdebddbddbddbddbddbdfbdgbdhbdibdjbdkbdlbdmbdnbdobdpbdqbdraVoaYubdsaZNaVobdtbbOaafaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBbdubdvaZUbdwbdxaSFaYHbabbaaaZvbdzbbVbaabdAaYObbpbdCbaibbZbdDbdEbdFbdGbbZbdHbdIbdJaTSbdKbdLbdMbdNaTSaXebdObdPbdPaDQbdPbdPbdPbdPbdRbdSbdSbdSbdTbdSbdUaMbbdVbdWbdXaJeaJeaJebdYbdYbdYbdZaDxbdZbdYbebbebbebbebbebbecbebbebbebbedbedaDybedaUpaUpaUpaJiaJiaJibcKbcLaRpaJlbefbegaDmbehaSSbeibcMbejbekbelbcObcObembenaZzaZzaZzaDYaSGaSGaSGaZzaZzaZzbeqberbesbetaWBaYhaYhbeuaZzbevbewbbqaZzbeybbsbeAaYtbeBbbEbeDbcmaONaGGaIobeFbeGbeHbeFbeIaIoaIoaGGbeJaVoaYuaVoaZNbeKbeLbbOaafaEvaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaYBaDfbeObePbeQbeRaRtaYHbeTbeUaDcbdzbbVbeVbeWaYObeXbeYbaibbZbbZbbZbeZbfabbZbfbbdIbfcaTSbdKbdLbdMbfdaTSaXebdObdPbfebffbfgbfgbfhbdPbfibcVbfkbflbfmbfmbfmaMbaMkbcsbctaJebfnbfobfpbfqbfrbfsbftbfubdYbebbfvbfwaSEbcZbfzbfAbdybebbedbfCbfDbfEbfFbfGbfHbfIbfJaJibfKbfLbfMaJlaZzaZzaZzaZzbfNbfObfPbfQaZzaZzbfRaZzaZzaZzaZzbfSbfTbfUbfVbfVbfVbfWbfXaZzbfYbfZbgabgbbgcbgcbgcbgdaZzbevbewbdBaZzaZzaZzaZzaZzaZzaZzaZzaZzaZzaZzbgfbggbghbgibgjbgfbggaZzaRZbgkaVoaYuaVoaZNaZObglbgmaWTaZRaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaabgnbgobgpbgqaZUbgrbgrbgrbgrbgrbgrbgsbgtbgraYOaYOaYOaYOaYOaEMaYOaYOaYObgvbgvbgwbbZbdDbgxbeZbgybbZbgzbgAbgzaTSbdKbdLbdMbfdaTSaXebdObdPbgBbgCbgDbfgbgDbdPbfibgEbgFbgGbgHbgIbgJaMbbgKbgLbctaWKbgNbgObgPbexbexbgRbgSbgTbdYbebbgUbgVbgWbgXbfvbgYbezbebbedbhabhbbhcbeCaESbeEbhgbhhaJibhibhjaRpbhkbhlbhmbewbewbhnbewbhobewbewbewbewbhpbewbewbewbewbhqbewbewbewbewbewbewbhmbewbewbhrbhsbhsbhtbhsbhsbhubhvbewbhqbhwbhxbhpbewbhybewbewbewbhzbhAbhBbhCbewbhDbewbhEbewbewbhFbhGbhHaVoaYuaVobhIaFZaFIaFGbhMaFEaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaabhObhObhObhObhObhObhObhObhObhOaaaaafbhPaYDbhQbhRaECbhTbhTbhTbhTbhTbhUbhVbhWbhXbhYbhZbgwbbZbbZbbZbiabfabbZaTSaTSaTSaTSbdKbibbicbidaTSbiebifbdPbigbihbiibgDbijbdPbfibikbgFbgGbgGbgGbilaMbbimaSzbctaSIbiobipbfjbirbisbfBbiubivbdYbebbiwbixbiybiybiybgYbgebebbedbiAbiBbiCbgQbiEbgZbiGbiHaJibiIbiJbiKbiLbiMbiNbiObiObiPbiQbiRbiSbiSbiSbiTbiSbiSbiSbiSbiSbiUbiVbiVbiVbiWbiObiObiNbiObiObiXbiVbiVbiYbiSbiZbjabjbbiSbjcbiObiObiObiObiObiObiObiObiObiObiObiObiObjdbiTbjebiSbjfbjgbjhbjibjibjjbjkaZNaWRbjlaWTaWTaWUaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaabhObhObhObhObhObhObhObhObhObhObhOaZSaZTbjmbjnbjobgrbjpbjpbZCbjpbjpbjpbjrbajbajbajbajbaibbZbdDbjsbjtbgybbZbjubjvbjuaTSaTSaTSaTSbZLaTSbjxbdObdPbjybjzbgDbjAbjBbdPbfibfmbjCbgGbgGbgGbjDaMbbjEaSzbctcdNcbjbgObhdbjIbjJbhfbjLbjMbdYbjNcaWbjPbiycaxbiybgVcacbjSbedbjTbjUbizbjWbjWbjWbjXbjYaJibjZbkabkbbkcbkdbkebbFbkfbkgbkhbkibkjbkkbklbkmbknbknbkobewbewbewbewbewbkpbkqbkrbewbksbktbkubkvbewbkpbkwbkxbkybhFbewbewbkzbewbewbkAbkBbewbkpbewbewbewbewbewbewbewbewbewbhqbewbewbhFbkCbkDbkEbkFbkGcbkbkIbkJaafaaaaafaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaabhObhObhObhObhObhObhObhObhObhObhObYabXwbZcbZibkObgrbkPbkQbkRbkRbkSbkTbkUbYobYwbYwbYHbYTbbZbbZbbZbeZbkZbbZbajbajbajbajblaaXeaXeblbblcbldbleblfblgblhblibljblkbdPbllbfmblmbgGblnbgGbloblpblqaSzbctaJeblrblsbltblublvblwblxblybdYbebblzblAbZrbZsblDblAbiFbebbedbedblFblGblHblIbiCblJblKaJiblLblMblNaJiblOblOblOblOblOblOaZzaZzblPblQbZNcdMblQblPaZzaZzaZzaZzaZzaZzaZzaZzaZzaZzbZuaZzaZzaZzaZzaZzaZzbZzaZzbewbewblVblWbjHblOblOblOblOblOblXblYblYblZblYbewblYblZbmablYbmbblObmcbmcbmcbZBaRZbmeaRZaRZaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaabhObhObhObhObhObhObhObhObhObhObhObdubdvbjmbjnbmfbgrbmgbjpbmhbmibjpbjpbjpbWkbmjbmkbmkbUwbbZbdDbmmbeZbmnbbZbmobmpbmqbmrbmsbmtbmtbmubmtbmtbmvbdPbmwbXcbfgbmybmzblfbmAbfmbmBbgGbgGbjKbmDbWVblqaSzbmFbmGbmGbmGbmGbmGbmGbmGbWMbmGbdYbebbmIbmJbmKbmLbmKbmMbjQbebbedbedbmObWmbmQbmRbiCbiGbmSaJibcKaRqaRpaJibmTbXqbmVbmWbmXbmYbmZbnablBbjVbndbnebjVblEbmCbnhbnibnjbmPbmNbnmbnnbnobnpbnqbnrbnsbntbntbnubYfaVJblOblObXpblObZMbZMblObnzbnAbnBblObZtbXebZtblOblXblYbmbblObZnbXfbZnblObnGbnHbnIbnJbnKbnLbnMaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaabhObhObhObhObhObhObhObhObhObhOaaabUobnObnPbeQbnQbgrbnRbjpbURbnTbnUbnVbjpbUPbUqbnYbnZbUwbbZbbZbbZbbZbbZbbZboabobbocbodboebdPbdPbdPbdPbdPbdPbdPbWqbdPbdPbdPbogbdPbohbVmbojbgGbgGbgGbokblpblqaSzbVkbmGbombonbncbcEbvGbotbosbotaafbebboubovbowboxboybozbnfbebaafbedboBboCboDboEbiCbiGboFaJiboGboHaRpbXHboJbngboLboMbnkbWhboPboQboRboRboSboTboUboUboVbnlboXboYboZbpabpbbnnbpcbpdbpebpfbpgbphbpfbpibYfaVJbpjbpkbplbpmbpnbnybppbnCbnDbpqbpsbptboobVyblOaZzbVvbpxblObpyboqbpAbpBbpCbpDbnIbpEbpFbpGbnMaaaaaaaaaaacaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaaaaaaaaaaaabgnbgobgpbgqbdvbpHbpHbpHbpIbpHbpJaZVbpKcfBbgrbpMbpNboAbpPbpQbpRcfHcfJcfUcfUcfUcgmbkWbpUbkWbkWbkWbkWbpVbpWbpWbpXbpYbdPbpZbqabqbbqcbqdbqebqfcfibqhbqibqjbqkbmAbqlbojbgGbgGbqmbfmaMbblqbqnbqoaJubqqbqrbqrbxqborcfubxsbotaafbebbebbebbebcfjbebbebbebbebaafbedbqzboCbqAcfmbqCbqDbqEaJibqFaRqaRpaJibqGbqHbqIbqJaJDbqLboPbqNboUboUboUboUboUboUbqObqPcgCboYbqRbqSboNbnnbqUbqVbqWbpfbpgbphbpfbqXbYfaVJbpjbqYbqZbqZbrabrbcgObrdbrdbrdbrebrdbrfboObrhbribrjbrkbnIbrlbpCbrmbrnbrocgDbnIbrqbpFbrrbnMaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaaaaaabrsbrtcefcescembrxbrxbrybrzbrAbgrcedbrCbpPbrDbjpbjpbjpbajbrEbrFbrGbrHbrGbrGbrGbrHbrGbajbajbdPbdPbdPcdpbdPbrJbrJbrJbrJbrJbrJbqfbrKbrLbrMbrNbrOcdFbrQbrRbrSbrTbrUbrVbrWbrXbrYbrZaHBbsbbqvbsabsebscbotbosbotaafbsicdYbskbslbsmbsnbskcdZbsiaafbedbspcecbspbedbedbedcebaJibssaRqaRpbXHboJbngbstbsuceCbqLbswbqNbsxceHbszbsAceKbsCbqObsDbnibsEbsFbsGceIbnnbsIbqVbpebpfbpgbphbpfbpibYfaVJbpjbsJbsKbsLbsMbplbsNbsObsPbsQbsRbsSbsTbsUbrhbsVbsWbsXbnIbsYbsZbtabtbbtcbtdbnIbrqbpFbtebnMaaaaaaaaaaaaaafaafaafaafaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaaaaacaaaaaaaaaaaaaaaaaaaaabrsbtfbtgccJbtibtibtibtjbtibtibgrbtkbtlbtmbpPbjpaaaaaaaaaaafaafbtnbtnbtnbtnbtnbtnbtnaaaaaabtobtpbtqbtrbtsbrJbrJbrJbrJbrJbrJbttbtuccubtwbtxbtybtzbtAbfmbfmccFbfmbfmbtCbtDbtEbtFbmGbtHbmGbmGbmGbmGbmGccrbmGaafbtJbtKbtLbtMbtNbtMbtLbtObtPaafbspbtQbtRbtSccqbtUbspbtVaJlbtWbbmbtXaJibtYbXqbtZbuabubbucbudbuebufccRbuhcdmbprbukbulbumbnibnnbunbpubupbnnbuqburbusbutbuubuubuvbuwbYfaXqbpjbuxbplbplbsMbuybuzbuAbpvbuCbuDbuEbuFbuGbrhbuHbuIbuJbnIbuKbuLbuMbtbbpCbuNbnIbpEbpFbuObnMaaaaaaaaaaaaaafbuPbuQbuRbuQbuRbuQbuSaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacbnbeOcbocbobuVbpHbuWbgnbgobuXbuWbgrbuYbuZbvabvbbjpaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnaaaaaabvcbvdbrJbvebvfbvfbvfbvfbvfbvgbvhbvfbvicblbvkbvlbvmbvnbvobfmbvpbgGbvqbpzbvsbvtbvubvvbmGbmGbmGbvxbvybvzbvAbvBbvwaafbpObvIbvHbvJbvKbvMbvNbvObpOaafbspbqMbvQbxnbedbvRbspbvSaJlbvTbcLbvUaJibvVbvWbvXbvYcbBbuccdTcdUcbtbwdbwebwebwfccncdWcdVbwjbwkcccbwmbwkbwkbwkbwkcbObwkbwkaXKaXKaXKaXKaVJbpjbsJbsKbsLbwobwpbwqbwrbwsbwsbwsbsSbwtbqTbwvbwwcbrbwybnIbwzbwAbwBbwCbpCbwDbnIbwEbwFbnMbnMaaaaaaaaaaaaaafbwGbwHbrgbwJbwJbwKbwGaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbwMbwNbwObwPbrJbwQbrJbwRbwRbwRbwSbwTbrKbrJbrJbrLbwUbwVbwWbwXbrpbPvbxabgGbgGbugbxcbvtbvubxdbxebxfbPzbujbxibxjbxkbxlbvwaafbxmbqtbskbxobxpbxobskbqxbxraafbspbqwbuobuBbedbPBbspbtVaJlbxwbcLaRpaJibxxbxybxzbxAbxBbxCbORbxEbxCbxFbxGbOTbxFbwkbOUbxJbwkbwkbxKbxLbxMbxNbxObxPbxQbxRbxSaXKbaybvraXKaVJbpjbxXbqZbqZbxYbxZbppbyabwsbwsbwsbsSbwtbybbwwbvDbUabTQbwwbyfbygbyhbyibpCbvLbnIbrqbykbnMaaaaaaaaaaaaaaaaafbylbymbrgbwJbrgbynbuRaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbONbypbONbyqbyrbwQbrJbrJbrJbysbrJbwTbrKbytbdPbdPbyubgGbrNbwXbyvbywbyxbyybyybyzbyAbyBbyCbyDbvsbyEbvPbyGbxkbyHbyIbyJbvwaafbxrbxrbyKbtLbyLbskbyMbxrbxraafbyNbyNbyNbyNbyNbyNbyNbOQaJibyPblMblNaJibwbbyRbyRbySbyTbxCbNVbyVbyWbyXbyYbyZbzabwmbzbbzcbzdbzebzfbzgbzgbzhbzibzgbzjbzkbckbaAbwubclbOfbcnbOibzsbztbzubzvbzwbppbzxbpqbpqbzybsSbwtbzzbzAbzBbzCbzDbzAbzEbzFbzGbObbzIbwwbwwbOdbnMbnMbzKbzLbzLbzLbzMbzNbwGbwJbrgbwJbwJbOkbwGaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaacaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbNQbzQbNQbzRbrJbwQbrJbzSbzSbzSbzSbwTbrKbzTbzUbdPbzVbgGbrNbwXbzWbzXbzYbgGblnbgGbzZbAabAbbAcbAdbyEbwIbAfbxkbxkbxkbAgbvwbAhbAhbAhbxrbAibxpbAibxrbAjbAjbAjbyNbAkbAlbAmbAnbAobApbAqaJibAraRqaRpaJibxbbwYbxhbAvbAwbMlbAybAzbMhbABbACbADbAEbMpbAGbAHbAIbAJbAKbAIbxtbAMbANbAObnvblUbsdbMqbsgbsfbaAbPObpjbxubxUbAYbAZbAZbppbBabBbbBcbppbBdbBebBfbBgbBhbBibBjbBkbBlbBlbBmbBnbBobTHbLYbBrbBsbNdbTIbBvbBwbBwbBxbBybBzbuQbuRbNkbuRbuQbBBaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbBCbwNbBDbLxbrJbwQbrJbrJbrJbrJbrJbwTbrKbzTbBFbdPbBGbgGbBHbBIbgGbLnbgFbgGbgGbyjbvsbvtbAbbAcbAdbyEbvwbBLbBMbBNbBMbBObvwbBPbBQbBRbAhbxrbLabxrbAjbyQbBUbBVbyNbBWbzmbBYbBZbCabCabCbbKfbAraRqaRpaJibAsbCebCebySbCfbxCbCgbChbxCbCibCjbCjbCkbwkbClbCmbwkbwkbwkbwkbwkbwkbIvbwkbwkbwmbIoaXKaXKaXKaXKbHmbpjbwwbzAbzAbzAbzAbzAbzAbzAbzAbzAbzIbHjbCsbCtbBhbCubCvbCwbCxbCxbCxbCybCzbHlbCBbCCbCDbIUbTGbCGbCHbCGbAtbCJbzKbzLbzMbJDbzNbJVaaaaafaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbNQbzQbNQbCMbCNbCObrJbrJbrJbCNbrJbwTbrKbzTbCPbdPbCQbgGbrNbwXbgGbqlbCRbgGbgGbAubxcbvtbAbbCTbxcbCUbvwbCVbALbCXbAWbxlbvwbCZbDabDbbTObDdbvFbvEbUbbDhbDibDjbyNbDkbDlbDlbDmbDnbDobDpaJibDqbDrbDsaJibDtbSFbDvbSVbDxbDybDzbDAbyWbDBbBKbCjbDDbwmbDEbDFbwmbDGbDHbDIbDJbDKbDLbDMbCpbDNbDObBTbDQbDRbCpbVLbVMbDUbVAbDWbDXbCxbDYbDZbEabEbbEcbEdbEebEfbEabEgbEhbCvbEibEjbEkbwwbwwbwwbwwbwwbTAbTgbEnbzKbzMbCJbEobEpbCAbSwbSubCIbEubEvaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbSrbExbSrbEybEzbEAbEAbEAbEAbEAbEBbECbEDbzTbEEbdPbEFbEGbEHbEIbEJbtzbEKbELbEMbfmbtCbENbAbbEObEPbyEbvwbEQbERbESbBMbETbvwbEUbEVbEWbAhbEXbvCbEYbAjbFabFbbFcbyNbFdbFebFfbFgbDnbDobFhaJibxwaRqaRpbVjbFjbFkbFlbFmbFnbFobFpbFqbxCbxFbxFbRWbxFbwkbFsbFtbFubFvbFwbFxbDJbFybDLbFzbFAbFBbDObFCbFDbFEbSfbVlbDXbSgbVAbFJbDXbDXbFKbFLbFMbFLbFLbFNbFObFPbFQbFRbFSbCvbFTbFUbScbFWbFXbFYbFZbGabGbbGcbGdaafaafbCJbGebGfbGgbGhbGibGjbRBbCJaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnbGlbGmbGnbdPbdPbGobwNbwNbwNbGpbdPbdPbGqbGrbGsbdPbGtbGtbGtbRAbGtbGvbGwbGxbGybGzbtCbvtbAbbGAbGBbtCbtGbtGbtGbtGbtGbRybtGbtGbtGbtGbtGbtGbRzbtGbtGbtGbtGbtGbtGbtGbtGaJiaJiaJiaJiaJiaJibxwaRqaRpbVjbRebFkbCSbGGbCWbGIbGJbGKbGLbGMbGNbCjbGObGPbGQbGRbGSbGTbGUbGVbRxbGXbGYbGZbRvbHbbHcbHdbHebHfbCpbUSbUfbwwbwwbwwbwwbwwbRabwwbwwbwwbzAbQubzAbzAbHkbBhbCubCvbFTbRdbCYbHnbHobHpbHqbGabGbbGcbHraaaaaabCJbHsbHtbCJbBybCJbCJbBybCJaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabHuaafaaaaaaaaaaaabGtbHvbHwbHxbHybGvbHzbDebHBbHCbtCbvtbAbbAcbAabHDbHEbHFbHGbHHbHIbHJbHKbHLbHMbHLbHNbHObqybHQbHRbAabHSbAabHTbAabzZbHUbHVbHWbHXbHYbHZbxwaRqbDsaJlbDtbDubDtbDCbDPbxCbIbbIcbIdbIebIfbIgbIhbIibIjbIkbwmbIlbImbInbDJbDTbElbIpbIqbIrbFDbIsbItbIubCpbPXbIwbIxbIybUdbIAbIBbICbIDbUcbIFbIGbIHbIIbIJbzAbIKbCubCvbILbIMbINbIObIPbIQbIRbGabGbbISbEnbEnbEnbCJbCJbCJbCJaaaaaaaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnbtnbtnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabGtbITbEmbIVbIWbIXbIYbIZbJabJbbtCbvtbJcbJdbJebJebJfbJgbJhbJibJjbJgbJfbJebJebJebJkbJlbqsbJnbJobJebJebJebJpbJgbJhbJqbJrbJsbJtbJubJtbJvbJwbvUaJlbEtbEqbFHbGFbzObGHbDzbHAbFibDVbxFbzPbCFbDSbDEbJGbwkbJHbJIbJJbDJbJKbJLbJMbJNbJObFDbJPbItbJObCpbJQbJRbIxbJSbJTbJUbzJbJWbHPbJYbIFbJZbKabKbbKbbzAbKcbKdbKebzHbKgbKhbKibKjbKjbKkbGabGbbKlbEnbKmbKobKnbEnaafaafaafaafaafaafaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbKpbKqbKqbKrbKsbKsbKtbKtbKtbKtbKuaafaafaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtnbtnbtnbtnbtnaaaaaaaaaaaaaaaaaaaaaaaabKvbKwbKxbKwbKyaaaaaaaaabGtbGtbKzbKAbIVbKAbKBbKCbHBbKDbKEbtCbKFbvtbKGbKHbAabKIbAabzZbHHbKJbAabKKbKLbKMbKNbKObAcbAabKPbKQbHLbKRbHLbHLbKSbKTbKUbKVbKWbKXbcLbKYaRpaRpaRpaJlbAebGFbGFbFlbJmbAxbJybJxbFIbLgbLhbLibLjbHgbDEbIkbIabIzbHhbDJbDJbLobLobLobCpbLpbLqbLrbLsbLtbCpbLubLvbIxbLwbFGbLybLzbLAbLBbLCbIFbJCbLEbKbbKbbzAbRsbLFbCvbwwbLGbLHbLIbLJbLKbLLbGabLMbLNbLObLObLObLPbGdaaaaaaaaaaaaaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafbLQbLRbLSbLRbKsbKtbKtbLTbLUbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabLVbLWbLXbwxbLVbLZbMabMbbGtbMcbMdbMebMfbMgbwnbMibMjbMjbMkbtCbtCbtCbxDbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbtCbMmbMnbMobtCbtCbtCbtCbtCbwZbtCaJlaJlaJlaJlbxvaJlaKSaMpbMraJlbKZbJXbxHbGFbLdbxCbDzbLDbxCbMybMzbMAbMBbwkbMCbMDbMEbMFbMGbMHbMIbMJbMKbMLbItbJObFDbFDbMMbJObCpbMNbMObMObMObMObMObMObMObMObMObMObMPbMQbMRbMRbzAbMSbMTbMUbwwbMVbMVbMVbMWbMXbMYbMVbMVbMVbMVbMVbMZbNabNbaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymaymbsBbLRbLRbNebKtbKtbLTbLTbNfbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabKxbNgbMsbNgbKxbNibNjbxIbNlbNmbNnbKAbNobNpbGvbNqbNrbNsbNtbGvbNubNvbNwbNxaaaaaaaaaaaabNybNzbNAbNBbNDbNCbNEbNFbNGbNHbNIbNFbNJbNKbNLbNMbNNbNObNPbxTbNRbNSbNTbNUbNUbNUbNUbDtbDtbDtbDtbMtbMtbxCbNZbOabyobMzbMvbMubOebyUbOgbOhbyObOjbMxbMwbOmbNhbMKbOobFDbFDbNXbJObJObOobCpbMNbMObOqbOrbOsbOtbOubOvbOwbOxbMObOybOzbOAbOAbzAbOBbOCbCvbzIbODbOEbOFbOGbOHbOIbOJbOKbOLbOMbMVbEnbzrbEnbOObOObOObOObOOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabOPbKtbsBbKtbKtbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabLVbNgbNgbNgbDgbDfbKAbOSbDcbCLbKAbKAbOVbOWbGvbGvbGvbGvbGvbGvbOXbOYbOZbPaaaabPbbPcbPcbPdbPebPfbPgbPhbPfbPibNFbPjbPkbPlbNFbPmbNYbPobPpbPqbPrbPsbPtbPtbNSbPubCKbPwbPxbPybDtbOcbLbbEsbGFbGFbErbDzbPCbxCbPDbPEbPFbPGbwkbPHbPIbwkbOlbPKbPLbOnbPNbMKbCpbCpbCpbCpbCpbCpbCpbCpbPObMObPPbQYbPRbOsbOsbOsbOsbPSbMObPTbLEbPUbPUbzAbBhbPVbPWbDwbPYbPYbPYbPYbPZbQabQabQbbQcbQdbMVbQebQfbQgbOObQhbOpbPnbQkaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbKsbKtbQlbQmbQmbLTbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabKxbMsbMsbMsbKxbQnbQobQpbQqbQrbKAbKAbQsbQtbEwbQvbQvbQvbQvbQvbQvbQwbQxbQyaaabQzbQAbQBbQCbQDbPfbQEbQGbQFbPfbNFbQIbQJbQKbNFbQLbQMbQNbQObQPbQQbQRbPtbQSbPxbQTbNUbPxbPxbQUbDtbHibGFbQVbGFbGFbPAbDzbLebRCbQZbPJbHabRcbRGbDEbIkbSpbOlbPLbPLbOnbRfbMKbRgbRhbPMbRjbRkbRlbQibRnbPObMObOsbOsbRobOsbOsbOsbOsbRpbMObRqbLEbRrbRrbzAbRsbRtbRubGWbRwbFVbGkbGkbGubGCbGkbGDbGEbFFbFrbRDbREbRFbEZbRHbRIbQjbRKaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabKtbKtbRLbLTbLTbLTbLTbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLbwLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaabLVbRMbRNbRObLVbRPbMabMbbGtbGtbRQbRQbRQbGtbGtbNxbRRbRRbRSbRSbRSbRSbNwbQyaaabRTbRUbRVbAFbRXbRYbRZbSabSbbSbbAXbSdbSebQHbNFbPtbPtbPtbPtbPtbAAbPtbPtbShbSibSjbNUbPxbSkbSlbDtbQXbLbbQVbSmbBAbPAbSobJAbJBbSqbRbbSsbStbJzbFsbSvbIEbSxbRmbRibSAbSBbMKbRJbSDbBtbRjbSnbSGbBJbRnbPObMObMObMObRobOsbOsbOsbMObMObMObSIbSJbRrbRrbzAbSKbSLbCvbzIbSMbSNbSObSPbSQbSRbSSbBEbQabSybMVbBqbQfbSWbOObSXbSYbSzbTaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbKtbLTbLTbLTbLTbLTbLTbTbbLTbTcbLTbLTbLTbLTbLTbKtbKtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabTdbKwbTebKwbTfbBSaafaaaaaabGtbThbTibTjbGtaaabNxbTkbTlbTmbTnbTnbTnbTobQyaaabQzbTpbTqbTrbTsbPfbTtbTvbTubTwbNFbSCbTybTzbBXbTBbTBbTBbTCbTCbTDbTEbULbPxbPxbTFbNUbNUbNUbNUbDtbDtbLfbLkbLcbDtbTJbTKbTLbJFbJEbTJbCnbLlbLmbTRbTSbTJbMKbMKbMKbMKbMKbMKbTTbTUbTVbRjbTWbTXbTYbRnbPObMObTZbQWbPQbCrbCobNWbNcbTZbUgbUhbUibIIbIJbzAbIKbSLbUjbwwbMVbMVbMVbMVbMVbUkbMVbCEbSEbVFbMVbUnbCcbUnbOObUpbCdbUrbOOaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabKtbUsbUsbUsbUsbUsbUsbUtbLTbUubUsbTcbLTbLTbLTbLTbKtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbUvbNxbNxbNxbNxbRSbmEbNwbUxaaabUybPcbPcbUzbUAbPfbPfbUBbPfbSHbNFbUDbSTbSUbNFbSZbSZbSZbSZbSZbSZbSZbSZbUHbUIbUJbUKbUKbUMbNUbDtbUNbTxbTMbUQbmlbwabUTbUUbTNbUWbTPbUTbUYbUZbVabVbbVcbUebVdbVebVgbVhbVibUlbmxbUmbRjbUCblCbUCbRnbPObMObVnbUFbVpbVqbVrbVsbVtbVubUgbzAblTbzAbzAbVwbCxbSLbCxbVxaafbnxbVzblSbVBbUGbVBbmdbUObUVbMVbVGbVHbVIbOObVJbVKbVKbwhaaLaaLaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwibLRbLRbLRbLRbLRbLRbLRbVNbLUbLTbLTbLTbLTbVObLUbKuaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabVPbVQbVQbVRbVSbNxbVTbRSbVUbNxaaaaaaaaaaaabNybVVbVWbVXbVZbVYbPfbNFbWabWbbNIbNFbSZbUXbVCbVfbVEbVDbWcbSZcaqcaqcaqcaqcaqbTFbWjbnWbWlbWdbWebWobWpbxgbWrbWsbWtbWubWtbWvbWtbWwbWxbWybWzbWAbWBbWAbWCbWDbWEbWFbWGbWfbWIbWgbWKbWLbnwbxVbMObxWbnNbzlbWSbWTbWibWSbWSbnSbWWbWXbWYbWZbCxbCxbSLbCxbFTaafbnxbXabXbbmHbXdbmUbnbbXgbXhbMVbXibVHbXjbOObOObOObOObOOaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabKtbQmbQmbQmbQmbQmbQmbXkbLTbQlbQmbXlbLTbLTbLTbLTbKtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabXmbjGbWnbjObRSbjRbXrbRSbXsbNxaaKaaaaaaaaabNybNybNybNybNybNybNybNFbUDbUEbXtbNFbSZbWHbWRbWJbWJbWRbWUbSZbXobXnbXnbXucaqbXBbDtbDtbXCbXDbXEbXFbXGblRbXIbXJbXKbXLbXMbXNbXObXPbXQbXRbXSbXTbXUbznbzpbzobAPbzqbARbAQbATbASbAVbAUbYfbYgbIwbYhbVobCqbWObWNbWPbYmbYnbjqbYpbYqbYrbYsbYtbYrbYubYvbILaafbnxbXabrBbVBbXvbVBbjwbYzbYAbMVbXjbVHbYBbYCbUnaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbKtbLTbLTbLTbLTbLTbLTbTbbLTbXlbLTbLTbLTbLTbLTbKtbKtaafaaaaaaaaaaaaabgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabYDbVQbVQbVRbYEbYFbYGbNxbkYbNxbYIbYJbYKbYIbYIbYLbYMbYNbYObYPbXybXxbXAbXzbYjbYebYxbWRbYQbYybYSbYRbYUbkXbYWbYVbYYbYXcaqbZhbNSbkMbZjbZkbZlbZlbZmbnEbZobZpbTJbTJbZqbkNbTJbTJbkHbYZbZabVibZvbWQbZxbZybkLbZybZAbZbbkKbZbbZAbkVbYfbMNbIwbZEbXWbXVbZdbZIbZJbZKbMObMObwwbwwbwwbwwbwwboIbnFbofbwwbMVbMVbMVbMVbMVbZebMVbMVbMVbMVbMVbZObZPbZQbZRbUnaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaabKtbKtbRLbLTbLTbLTbLTbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaambZSaamaamaamaamaamaaaaaaaaaaaaaaaaaaaafaafaaabZfbZgbZgbZgbZHbZgbZgbZUbZTbYIbZYbZZbYIbZVcabbZWcadbZXcafbsycaacagcaecaicahcajbWRbYQcakcalbYRcambSZcaqcaqcaqcaqcaqcarbNSbDtcascatcaocancawbsvcaycazbTJcapcaBcaCcaDcaEcaFcaGcaHcaIbZxbWQcaubZycaKcaLbZAcaMcaNcaObZAbXXbYfbPObIwbXYbsqbXZbXYbXYbIwbIwbIwcaRcaScaTcaUcaVbwwbwwbsrbwwbwwcaXcaYcavcaJcaAcbbcaZcbacbccbdcbecbfcbgcbhbUnbUnbUnaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbKsbKtbUubUsbUsbLTbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabgaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafcbibwlbpScbmbwgbpTbvZcbqcbpbYIbvjcbsbYIbYIbwccbucbvcbwcbxcbzcbybXAbXzbYjcbAbuUbWRbWRcbCcbDbWRcbEbSZcbFcbGcaqcbHcaqbTFcbIcbIcbIcbIcbIcbIcbIbTJcbJcbKbTJcbLcbMcbNbrucaEcbPcbQcbRcaIbZxbWQcbUbZycbScbTbZAcbWcbVbuTbZAccsbYfbYbbYdbYcbYiccAccBbYcbuibYkbYlcktbZDbZwbZFcktbtIbZGccDccCbtTccEccQccPbsHbthbtvbthbthbtBcctcctccvccwccxccycczbUnbUnbUnbUnaaaaafaaaaaaaaaaahaahaahaafaaaaaaaafaaaaaaaafaaaaaabOPbKtbsBbKtbKtbLTbLTbLTbLTbLTbLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafccSccSbpSccUccTbpTccVccXccWbYIccGccHccIbqgccKccLccMccNccOccZccYcdbcdacdycdebqBcdBceecdQcelcekcenbqQcdccddaJEcdfcaqbTFcbIcdgcdhcdicdjcdkcdlbpwcdncdobpocdqcdrcdscdtcaEcducdvcdwcaIbZxbWQceobZycdxcepbZAcdzcdAceqbZAcaPbYfbYfcaQbYccbYcbXcbZbYcchBccacjfcdLcdLbyFbBucdLcdOcdPcercdRcdOcdSbBpbyebydcdScdScdScdSbpLbyebydcdScdSbXjcdXboKbopceabnXbolboibycbycbycbycbycbycbycbycbycbycbycbycbycbycbycbycboWcegcegcehbKtbKtbLTbLTceibLTbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacejcejcejcejcejcejcejceucetbYIbYIbYIbYIbYIbYJcewcevcevcevceycexbXAbXzbYjceEbYxceSceUceTceXceWceYbSZcezaJFcfaaJFcaqbTFcbIceDcfccfccfcceFceGbTJbrwbrvbTJcbLcbNceJbrucaEbrcceLceMcaIbZxbWQceNbZyceOcePbZAbZAbZAbZAbZAccbceRbYfcaQbYcccdbsobYcbYcchBccecjfcdLceZcfbcfbcfecdOcfdbsjcffcdOcfgcfhcfhcfhbshbrIcfkcflbrPcfncfocfpcdScfqcfrcfsbUnbUnbUnbUnaaaaafaaaaaaaaaaahaahaahaafaaaaaaaafaaaaaaaafaafaafcftcfCcfvbNebKsbKtbKtbLTbLUbLTbKtbKtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafaafaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafcejcfwcfxcfycfzcfAcejcfEcfDcfGcfFcfIcFKcFrcFrcfLcfKcfKcfMcfNcbybXAbXzbYjcfOcajcfPcfRcfQcggcFgcgibSZaJFaJFcaqceBcaqbTFcbIcfVcfWcfWcfWcfXcbIcfYcfZcgacfYcgbcgccgdcgecaEcgfceLcgocaIcghccfcgjbZycgkcglbZycFSbLvbVicgnccgcchbYfccjcciccicckcclcclcclcclccmcdLcgpcgycgycgzcgActscgtcgrcgxcgucgGcgGcgGcgBcgIcgIcgJcGdcgLcgEcgMcdScgNcFLcgPcgNaaaaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafcgQbKqbKqbKrbKsbKsbKtbKtbKtbKtbKuaafaafaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaafaafcgFcgFcgFcgFcgFcgFcgFcgFcgFcgFcgFcgFcgFaaaaaacgScgTcgTcgTcgUcgVcejcgKcgHcCWcgRcgYcgXchacgZcCOchbchechdchgchfchichhchkchjbSZbSZbSZbSZbSZbSZbSZbSZcDNcDOcaqcCYcaqbTFcbIcbIctpctqctrcbIcbIchrchschtcfYcaEcaEcaEcaEcaEcaIchlchmcaIchwcDUchwbZychychnbZychAchBbVichCbVichDbYfccobYfbYfccpcdCcdCcdCcdDbYfcdLchIchJchJchKcEkchMchpchOcEBchQckLckLckLckLcEYchvckLcEQckLchEchFcdSchZciachGcgNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacgFchHchLchHcgFchNchPchNcgFchRchSchRcgFaaaaaaciicgTcgTcgUcgUcijcejchUchTchWchVchYchXcidciccIBcieciecigciecbybXAcihbYjcikcimcilciocinciocipcirciqciqciAciAciAciAbTFciGciHciIciIciJciKcIMciMciXciOcIIciQciRciSciSciTciUcaIcaIcaIciVcdEckqbZybZybZybZychBchBbViciYbViciZbYfccobYfaaaaaaaaaaaaaaaaaaaaacdLcjgcisciucitcjjcjkcivcjmcjncjociwcjocjocixcjrcjscgIcICcgIciWcjucdScjacjwcjxcgNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacgFchHcjbchHcgFchNcjcchNcgFchRcjdchRcgFaaaaaaciicgTcgUcgUcgUcjBcGmcjhcjechWcjicjpcjlcGgcGecjzcjycjDcjAcjEcbybXAcjFchkcjGcGxcjHcjJcjJcjJcjKcjMcjLcjNcGvcjOceAciAbTFciGckaciIckbckcckdcubckfckgckhctQckjckkcklciSckmciUcImcHGckpcjQcjPcdHcdGcdIcdIcdJcdIcdKbVibVibVibVibYfccobYfaaaaaaaaaaaaaaaaaaaaacdLcGVcjRcjTcjSckEcdOcHlcdOckGckHcjXcjUcjUcjYcgIcgIckecjZcjUckickOcdSckPcGJckRcgNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacgFckrckuckscgFckzckBckAcgFckDckJckIcgFaaaaafciiclbcgTcgUcgUcgUcejckMckKchWchWcKdchWchWchWchWckTcieckWckYcbyclackZcldclccKccleclhclhclhclicljcljclkciAcllcgqclwclxciGclyciIclzclAclBcKmclDclEclFcKoclHclIclJciSclKciUcKecKkclNclnclmclQclNclRclSclTbYfceQcdIcdIcdIcdIcdIcltbYfaaaaaaaaaaaaaaaaaaaaacdLcmacmbcmccmdcdOcmecmfcmgcdScmhcmicmicmiclvcmkcmlclPclOcmicmicmncdScmocKpcmqcmraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaafaafcgFclXcmmcmjcgFcmscmmcmtcgFcmscmmcmtcgFaaaaafcmzcgTcgTcgUcgUcmAcejcmvcmucmxcIQcmBcmycmCcmCcmEcmDcmCcmFcJzcbycmIcmHcmKcmJcimcmLcmLcmMcljcmNcmPcmOcmOciAcibceVcJAcqgciGcnbciIcnccndcmRciGcmSciNcmWcfYcmXcnicnjciScnkciUclLclMclNcnlcJBcnlclNaaaaaaaaabYfbYfbYfcnnclSclSclTbYfbYfaaaaaaaaaaaacdOcdOcdOcdOcdOcdOcdOcdOcdOcnocnpcnqcdScdScnrcnscntcdScdScdScdScJCcnscntcdScdScnvcJFcnvaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabZSaafaafaafaaaaafcnxaafcnxaafcKBaafcKAaafcKBaafcKAaafaafaaacejcnAcnBcgUcgUcnCcnDcKCcKzcnycnmcKDcnzcnzcKEcnzcnGcKFcnHcnGcnJcqrcKwcKxcnMcnOcnOcnOcnOczvcKycnRcnRcnRcgscgscgscgscnSciGcnTcnUcnccnVcnWciGcmSciNcnXciUcnYcnZcnjcoacobciUclLclMclNcoccodcoeclNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaacdOcofcogcohcwlcojcokcKHcomcKIcopcoocdOaaLaafaafaafaafaaaaaaaaacKGaaaaaaaaaaafcoscKJcosaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaafcoucowcovcoxcovcowcoycoxcoAcoBcoycoDcoCcoFcoEcnycnycnycnycnycnycnycnycoHcoGcoJcoIcoLcoKcoNcoMcoOcnGcoQcoPcoRcnGcoTcoScoUcnOcoWcoVcoYcoXcpacoZcpjcpbcpbcpkcpncpncpjbTFciGciGcpccKuciGciGciGcpeciNcpfciUciUciUcKtcphciUciUclLcpiclNcvmcpscvmclNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaafaafcdOcplcpmcplcKqcwVcppcpqcomcomcKscomcdOcdOaaaaaaaaaaafaafaaaaacaaaaaaaaaaaaaafaaacKvaaaaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaaaaaaaaaafcptcpvcpucpxcpwcpvcpycpAcpzcpCcpBcpFcpDcpJcpHcpMcpLcpOcpNcpTcpQcpVcpUcpXcpWcpZcpYcqbcqacqdcqccqfcqecqzcqtcwwcqIcoTcqKcqMcnOcpacpacpacpacpacqPcpjcqQcqQcqQcpncpncpjbTFcrYciGcqhcqicqjcqkciGcqlciNcqmciUcqncqocqpcqqciUcvDclLcpiclNcvOcqRcquclNaaaaaaaaaaaaaaaaaacqvcqwcqxcqycqvaafaaaaaaaaaaaacdOcplcplcplcoicwacqBcqCcqDcqEcqFcqGcqHcdOaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaaacmZaaaaafaafaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaafcqScpHcqUcqWcqVcpHcqXcpHcqYcqZcqXcpHcqYcqZcpHcpHcpHcpHcpHcracpHcpHcpHcqbcrbcpYcrccvBcqacrecrdcrgcrfcricrhcrkcrjcoTcqKcrlcnOcrmcpacpacrncpacrocpjcrpcrJcrIcrJcrKcpjbTFcrqciGcrrcrscrtcrucvrcrwcrxcrycvtcrAcrBcrCcrDciUcrEcrFcrGcrHcqvcvlcqvcrHaaaaaaaafaaaaaaaaacqvcrQcrScrRcqvaafaafaaaaaaaaacdOcomcomcomcomcrMcppcrNcrNcrNcnpcrNcrOcdOaaaaaaaaaaaaaaacrPcrPcrPbZSaafaafaafaafcnaaafaafaafaafaafaaqcrPcrPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaafaafcptcpHcrccpHcrccpHcqXcpHcrTcrVcrUcrVcrWcrVcrVcrZcrXcpHcpHcyCcnPcnPcnPcnLcymcypcypcyvcqacyhcsgcsicnGcskcsjcsmcnGcsocsncsqcspcsscsrcsucstcpacsvcpjcswcrJcsxcrJcsycpjbTFcizciGcszcsAcsBcsCciGcfYcyacfYciUcsEcsFcsGcsHciUcsIcrGcrGcqvcsJcsKcsLcqvcqvcqvcqvcqvcqvcqvcqvctMctDctNcqvcqvcqvcrHaaaaaacdOcofcogcohcslcsRcqBcrNcrNcrNcnpcrNcsScdOaaaaaaaaaaaaaaacrPaaaaafaaaaafaaaaaaaaackxaaaaafaafaaaaaaaaaaaacrPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafaafaaaaaacptcpHcrccpHcsNcsQcsOcsUcsTcsVcrUcrVcsWcrVcrVcrZcsXcxRcrZcxVcqWctacsZcsZctccrccrcctectdctgcxHcnzcnGcxIcnGcnGcnGctjcticsqctkctmctlctoctncpacttcpjctucrJcsxcrJcxGcpjctvctwciGciGcxBciGciGciGciBctzctAciUciUciUcxFciUciUcsIcrGaaacqvctCctOctEctFctGctHcxdctJctKctLcqvcuVcwHcuVcqvctSctPcqvaafaafcdOcplcplcplcwTcwVctRctVctTctUctZcrNctWcdOcdOcdOcdOaaaaaacrPaaactXctXctXctXctXaafckxaafctXctXctXctXctXaaacrPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacptcpHcsNcsQcsQcsQcsOcsQcsQcsQcsOcsQcsQcsQcsQcsQcuacAUcsQcAIcsQcuccsQcsQcsQcuecudcufcpvcpHcugcBmcuhcukcujcumculcujcuncupcBncurcuqcuqcuscuqcutcBqcuucuxcuwcuycuycpjcuCcuDczVcuFcuFcuGcuHcuIcuJcuJcuJcuJcuJcuJcuJcuJcuKcrFcrGaaactFczXcuzcuNctFcuOcuAcuQcuQcuPcuBcuQcuQcuRcuQcuVcuXcuQcqvaaaaaacdOcplcplcplcslcAxcuZcvacvbcvccvdcrNcrNcvecvfcvgcdOaafaafcrPaafckVckSckSckSckSckyckxckwckvckvckvckvckUaafcrPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacptcpHcpHcpHcpHcpHcqXcpHcpHcpHcqXcpHcpHcpHcpHcpHcqYcpHcpHcvBcpHcvhcpHcpHcvicvkcvjcvocvncvpcvnczMcvqcvucvscvvcvqcvqcvwcvxczvcvycpacvAcvzcpacpaczycrJcrJcvCcuycuycpjbPxcAscvNcvNcvNcvNcyScvNcvNcvNcvNclMcvPcrGcrGcrGcrGcrGcrGaaactFctFcyRctFctFcvRcvScvTcvUcvVcvEcvGcvFcvIcvHcyZcwbcwccqvaaaaaacdOcomcomcomcomcwdcppcvacwecwfcvJcrNcrNcwhcrNcwicdOaaaaaacrPaafcwjcwjcwjcwjcwjaaackxaaacwjcwjcwjcwjcwjaafcrPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaabZSaaaaaaaaaaaacptcpHcpHcpHcpHcpHcqXcpHcpHcpHcqXcpHcpHcpHcpHcpHcqYcpHcpHcvBcpHcvKcpHcpHcvKcvKcvLcpHcpHcvWcvQcvXcvXcvXcvXcvZcvYcoTcwgcwkcspcwmcpacwocvzcpacwpcpjcwqcrJcwscwucwtcpjcCLcvMcvNcwIcwJcwKcwLcwMcwNcwOcvNcwPcwQcrGaaaaaaaaaaaaaaaaaacqvcwRcwvcwxcCNcwzcwycwBcwAcwDcwCcwFcwEcwScwGcuWcuQcxecqvaaaaaacdOcofcogcohckXcsRcuZcxgcxhcxhcxicxjcxkcCIcxmcxncdOaaaaaacrPaaaaafaaaaafaafaafaaackxaaaaafaaaaafaaaaafaaacrPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaaacptcpHcpHcpHcpHcpHcwUcpHcpHcpHcwUcpHcpHcpHcpHcpHcqYcpHcpHcCncqWcwXcwWcwWcwXcwYcwXcxacwZcxbcwWcCicxccxocxlcxpcvYcoTcxqcoTcxrcxscpacpacxtcpacxucpjcxvcxvcxwcwucwtcpjbPxcvMcvNcxKcxLcxMcxNcxOcxNcxPcvNcxQcCfcrGaaaaaaaaaaaaaaaaaacqvcxScxTcxUcCecxWcxXcxYcxZcuTcCccuScxAcuTcBBcqvcqvcqvcqvaaaaaacdOcplcpmcplcBscwVcppcrNcrNcyecyfcrNcygcomcomcomcdOaaaaaacrPaaactXctXctXctXctXaafckxaafctXctXctXctXctXaafcrPaaacgWaaaaaacgWaaaaaaaaacgWaaaaaaaaaaaaaaacgWaaaaaaaaacgWaaaaaacgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafaaaaaaaaacptcpHcsbcsacsacxDcxCcnPcolcnPcxEcolcnPcnPcnPcnPcnQcnPcnNcnLcnKcvKcpHcpHcxJcyccybcyjcyicykcpHcnIcylcyncyncyqcyocoTcxqcyrcnOcyscpacytcpacnFcyucpjcpjcpjcpjcpjcpjcpjbPxcvMcvNcyMcyNcxLcyOcxLcxNcyPcvNcyQcorcrGaaaaaaaaaaaaaaaaaacqvcuVcoqctFctFcyTcywcyVcyWctMctDctNcyxctMcuRcyYcqvaaaaaaaaaaaacdOcplcplcplckXconczacrNcrNcrNcyfcrNczbcrNczccrNczdaafaafcrPaafckVckSckSckSckSckyckxckwckvckvckvckvckUaafcrPaaacgWcgWcgWcgWaaaaaaaaacgWcgWcgWcgWcgWcgWcgWaaaaaaaaacgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafaaaaaaaaacptcpHcqXcpHcpHcpHcwUcpHcpHcpHcwUcpHcpHcpHcpHcpHcqYcpHcybcpHcyycvKcpHcpHcyzcwYcyAcyBcvXcotcvXcvXcylcyEcyDcyFcyocoTcxqcoTcnOcyHcyGcyJcyIcyKcpacnOcyLczJczJcyUczLcpdczNczOcvNcxNczPczQcxNczRczSczTcvNczUcpgcrGaaaaaaaaaaaaaaaaaacqvczWcuMcpocuVczYczZcAactFcAbcAccsPcyxczWcyXcAecqvaaaaaaaaaaaackEcdOcAfcAgcAgczecAicAjcAkcAlcAmcAncAocApcAqcokcAraaaaaacrPaafcwjcwjcwjcwjcwjaaackxaafcwjcwjcwjcwjcwjaaacrPaaacgWcgWcgWcgWaaaaaacgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaacgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaIaaaaaaczfcpHcqXcpHczgcrVcrUcrVczhcrVcrUcrVczhcrVcrVcrVczjczkczjcrZczlcyAczmczocznczqczpczrcvXcztczscvXcvXcvXcvXcvXczucqrcprcqrcnOcnOcnOcnOcnOcnOcnOcnOczwczJczJczxcANcAObPxcAPcvNcAQcARcqscATcqAcAVcAWcvNcAXcAYcrGaaaaaaaaaaaaaaaaaacqvcuQcAZcAectFcBacBbcBcctFcBdcBeczAczzczBcBeczDcqvaafaafaaaaaaaaaaaabquaaacdOcBlcqJcrvcBocBpcqJcqOcBrcBpcqJcrzcdOaaaaaabZSaaaaafaaaaafaaaaafaaackxaaaaafaaaaafaafaafaafcrPaaacgWcgWcgWcgWaaaaaacgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaacgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabZSaaaaaaaaaaaIaaaaaaczEcpHcqXcpHcybcyccqXcpHcybcyccqXcpHcybcyccpHcpHcxJcpHcybcycczFczHczGczKczIcAhcAdcAtcvXcAvcAucrLcAwcAycujcAAcAzcujcABcujcACculcADcAFcAEcAEcAHcsccBVcBWcBWcBXcBYcAObPxcBZcvNcvNcCacCbcsdcCbcCacCdcvNcrGcsecrGaaaaaaaaaaaaaaaaaacqvctFcsfcuVctFcCgcChcshctFcCjcCkcqycgvcAJcCkcCocrHaaaaaaaaaaaaaaaaaacgwaafcdOcCqcsMclUcomclscsDclqcomclocsYclWcdOaaaaaacrPaaactXctXctXctXctXaafckxaafctXctXctXctXctXaafcrPaaacgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaafaafaafaaIaafaafczEcALcAKcAScAMcBgcBfcBicBhcBkcBjcBucBtcBgcpHcALcBvcBycBxcBkcBzcnycnycnycnycnycnycnycnyctxcBAczucBCcBDcoTcBEcoTcoTcxqcoTcoTcBFcoTcBDcBGcBIcBHcBJcthctfctbcCPcCQcAObPwcCRcCScCTcCacAGcAVcBwcCacBLcBKcBMctycCXaaaaaaaaaaaaaaaaaacqvcBNctDcuQcDacDbcuQcDccDdcDeaafaaachxcBPcBOcBQaaaaaaaaaaacaaaaaaaaaaaaaaacdOcDhcplcplcomcDicplcplcomcDicplcplcdOaafaafcrPaafckVckSckSckSckSckyckxckwckvckvckvckvckUaafcrPaaacgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPcpEaaaaaaaaIaaaaaacBScBUcBTcCrcCpcCtcCscCucCpcCtcCscCucCpcCtcCvcCvcCwcCucCpcCtcCxcnyaaacCzcCycCBcCAcCDcCCcCFcCEcCGcCGctBcCHcCKcCJcCMcuicCJcCMcCKcCUctIcCVcCUczuczucAOcuvcuocDPcDQcAObNUcDRcDScDTcCacCbcuEcCbcCacDgcCZcDfaafaaaaaaaaaaaaaaaaaaaaacqvcBNcDVcDjcDXcDXcDjcsPcDYcqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdOcDZcplcplcomcEacplcplcomcEacplcplcdOaaaaaacrPaafcwjcwjcwjcwjcwjaaackxaaacwjcwjcwjcwjcwjaaacrPaaacgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPcClcqLcpIcBRcpIcpIcqLcpIcpPcpIcpGcpIcpPcpIcpGcpIcpPcpIcpGcpIcqLcpIcpRcpIcpGcpIcqNaafaaacDlcDkcDncDmcDpcDocCFcDqcCGcDrcDtcDscDvcDucDxcDwcDzcDycDvcDAcDCcDBcCUaaaaafcAOcuLcECcEDaafaaabNUbPxbPxbSkcCaclZcEFclYcCaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqvcDDcuXcDEcEJcEJcDEcuQcEKcqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacdOcplcplcplcomcELcplcplcomcELcplcplcdOaacaaacrPaaaaaaaafaafaafaaaaaacmTaafaaaaaaaafaafaaaaaacrPaaacgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaabgaaaaaaaaaaaaaaaaaaaaacrPaafaafaaaaaqaaaaaaaafcgFcmscmmcDFcgFcmscmmcDFcgFcmscmmcDGcgFaaacgFcDHcmmcDGcgFaaaaafaaacDlcDIcDKcDJcDMcDLcEbcDWcCGcEccEecEdcDvcEfcEhcEgcEjcEicDvcuUcEmcElcCUaaaaaacAOcuYcFhcFiaaaaaabNUbPxbPxbNUcCacmUcmUcmUcCaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqvcEncFncuQcuQcuQcuQcuQcFocqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaackEcdOcdOcdOcdOcdOcdOcdOcdOcmYcmYcmYckEaaaaaacrPcrPcrPcrPcrPaaaaaaaaacmZaaaaaaaaacrPcrPcrPbZScrPaaacgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaaaaafaafaaIaaaaaaaafcgFcEocEqcEpcgFcErcEtcEscgFcEucEwcEvcgFaafcgFcExcEzcEycgFaaaaafaaacDlcEAcDncDMcDMcEEcEHcEGcEMcEIcEOcENchccEPcEScERcEUcETcEWcEVchzcEXcCUaafaaacFJchqchocAOchuaaabNUcFMbPxcFNcFOaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrHcqvcqvcFPcFQcDEcDEcDEcFRcFPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqpbqpbqpaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaafcfTaafcrPaaaaaaaaaaaaaaaaaaaaacgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaIaaaaafaafcgFcEZcFacEZcgFcFbcFccFbcgFcFdcFecFdcgFaaacgFcFdcFdcFfcgFaaaaafaaacDlcCycFjcDJcDMcDocFkcDqcCGcFlcFpcFmcDvcFqcFscjqcFscFtcDvcFucFwcFvcCUaaLciPciyciLciCciyciycifbNUciEciDcGjaafaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGlcEJcEJcEJcEJcEJcGlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaaaaafaaacrPaaaaaaaaaaaaaaaaaacgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaIaafaafaaacgFcEZcFxcEZcgFcFbcFycFbcgFcFdcFzcFdcgFaafcgFcFdcFdcFdcgFaafaafaafcFBcFAcFDcFCcFFcFEcFGcDqcCGcFHcjvcFIcDvcFTcFVcFUcFXcFWcDvcFYcGacFZcCUaaacjIcjCckocknckFckCcjtcGFcGGcGHbNUaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacqvcCmcqxcqxcqxcCocqvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPcrPcrPcrPcrPaaaaaaaaaaaaaaaaaacgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabZSaaaaaacgFcgFcgFcgFcgFcgFcgFcgFcgFcgFcgFcgFcgFaaacGbcgFcgFcgFcgFaaaaaaaaaaaacBAcBAcBAcBAcBAclCcGccGccGccGcclGcGccGfcGicGhcGicGkcGccGcclucGccGccGccjIcjCclpclgclfckQckNaafaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrPaaaaaaaafaafaaaaafaafaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaafaaacGQcGRcGRcGRcGScGncGpcGocGrcGqcGtcGscmwcGucmpcGwcGzcGycGBcGAcGDcGCcGIcGEcGKcmGcGEcGccjIcjCcnecmQclfcnfclVaafaaacGQcGLcGQcGLcGQcGLaafcGMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaafcHncjVcHpaaacHncjVcHpaaacHncjVcHpaafaafaaaaafaafaafaafaafcHqcGRcGRcGRcGScGncGOcGNcGTcGPcnucGUcGXcGWcGZcGYcHbcHacHdcHccHdcHdcHdcHecHdcHfcHgcGccnhciyciyciyciyciycngaafaafcHhcHhcHhcHhcHhcHhaafcGMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaabgaaacgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaacHncjWcHpaaacHncjWcHpaaacHncjWcHpaafaafaaaaafaaaaaacHKaafcGQcGRcGRcGRcGScGncGOcHicHkcHjcnwcGUcHocHmcHrcGKcGKcGKcHtcHscHucGKcGKcHmcHwcHvcHxcGccGccGccHyaaaaaaaaaaaacHzaaacHAcHAcHAcHAcHAcHAaafcGMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcHncjWcHpaaacHncjWcHpaafcHncjWcHpaafaaaaaaaafaafcIcaaaaafcHqcGRcGRcGRcGScGncHCcHBcHEcHDcnEcHFcHIcHHcHLcHJcHJcHJcHNcHMcHOcHJcHJcHPcHRcHQcHTcHScHVcHUcHXcHWcHWcHWcHWcHWcHWcHYcHZcHYcHZcHYcHhaafcGMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaacHncjWcHpaafcHncjWcHpaaacHncjWcHpaaaaaaaaaaaaaafaafaaaaafaaaaaaaaaaaaaafcIacIdcIbcIfcIecIgcGscIhcGKcGKcGKcIjcIicIlcIkcIncKWcIpcIocIrcIqcItcIscIvcIucHXcIwcIxcIwcIxcIwcIxcIwcIxcIwcIxcIwcHhaafcGMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgWcgWcgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaaIaafaaacHncjWcHpaafcHncjWcHpaaacHncjWcHpaafaaaaaaaaaaaaaafaafcIJcIKcIKcIKcIKcILcILcILcILcILcKScILcGccIycGKcGKcGKcIzcGccKUcIAcKVcGccIEcIDcIFcHQcIHcIGcKTcGcaaacHAcHAcHAcHAcINcHAcHAcHAcHAcHAcHAcHAaafcGMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacgWcgWcgWcgWcgWcgWcgWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaaaaafaafczCaafaafaafczCaafaaaaafczCaafaaaaaaaaaaaaaaacIUcIVcIWcIXcIYcIOcJacJbcJcciFcJecJfcJgcJecGccKRcIPcGKcGKcIScIRcIZcITcJdcIRcJicJhcHRcHQcJkcJjcJlcGcaafcHhcHhcHhcHhcHhcHhcHhcHhcHhcHhcHhcHhaafaanaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcydcxzcxycxxcxxcxxcxxcxxcxxcxxcxxcxxcxxcxxczicxzcxzcxzcKPcKQcKNcKOcKMcJDcJEcKLcJGcJHcJHcJHcJIcJJcJKcGccJmcJmcGKcGKcIScJncJpcJocJqcJncJicGKcIrcJrcItcGKcJscGcaafcHhcHhcHhcHhcHhcHhcHhcHhcHhcHhcHhcHhaafcGMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaactYctYctYctYctYaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaaaaafaaaaafaafcxfaafaaaaafcxfaafaaaaafcxfaafaaaaaaaaaaaaaaacIUcIVcJRcJScJTcJUcIKcJVcJWcJecJecJXcJXcJYcGccJmcJmcGKcGKcIScJtcJpcJucJvcJtcJxcJwcJLcJycJNcJMcJOcGcaaacHAcHAcHAcHAcINcHAcHAcHAcHAcHAcHAcHAaafaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaactYctYctYctYctYaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaaIaafaafcHncwrcHpaaacHncwrcHpaaacHncwrcHpaafaaaaaaaaaaaaaafaafcKfcIKcIKcIKcIKcKgcKhcKicKicKjcKgcKgcGccGccGscGccGccGccGccGccJPcGccGccGccGccGccGscGccGccGccGcaafcHhcHhcHhcHhcHhcHhcHhcHhcHhcHhcHhcHhaafaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaactYctYctYctYctYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacHncwrcHpaafcHncwrcHpaaacHncwrcHpaaaaaaaaaaafaaaaafaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaaacJQaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaacHqcJZcHqcJZcKacJZcHqcJZcHqcJZcHqcJZaafaamaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcHncwrcHpaaacHncwrcHpaaacHncwrcHpaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaLaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaafcHncwrcHpaaacHncwrcHpaafcHncwrcHpaafaafaafaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaIaaIbZSbZSaaIaaIaaaaaaaaaaaIaaIaaIaaIaaIaaqaaIaaIaaIaaIaaIaaIaaIaaIcKbaaIaaIaaIaaIaaqaaIaaIaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqaafcHncwncHpaaacHncwncHpaaacHncwncHpaafaaIaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaaaaafaaaaaaaaaaafaafaafaaaaaaaafaafaaaaaIaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaaIaamaamaaqaaIaaIaaIaaIaamaaIaaIaamcKoaafaaaaaaaaaaaaaaacKpaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaacHKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqaaaaaaaaacKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqaaaaaacKqaaaaaacKqcKqcKqcKqcKqcKqcKqaaaaaacKqaaaaaacKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqaaacKqcKqcKqcKqcKqcKqcKqcKqcKqaaacKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqaaacKqcKqcKqcKqcKqcKqcKqcKqcKqaaacKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqaaacKqcKqcKqcKqcKqcKqcKqcKqcKqaaacKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqaaaaaacKqcKqcKqcKqcKqcKqcKqaaaaaacKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKqcKqcKqcKqcKqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlaaacKlcKlcKlcKlcKlaaacKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaamaamaaIaamaamaaqaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaacHKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKaaaaaacKKaaaaaaaaacKKaaaaaaaaaaaaaaacKKaaaaaaaaacKKaaaaaacKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKaaaaaaaaacKKcKKcKKcKKcKKcKKcKKaaaaaaaaacKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaacKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabgcKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaacKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKKcKKcKKcKKcKKcKKcKKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlaaacKlcKlcKlcKlcKlaaacKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlaaacKlcKlcKlcKlcKlaaacKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaacKlcKlcKlcKlcKlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKncKnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/maps/exodus-2.dmm b/maps/exodus-2.dmm index 28724abc1a..4a6468a5a0 100644 --- a/maps/exodus-2.dmm +++ b/maps/exodus-2.dmm @@ -94,44 +94,44 @@ "bP" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/engie,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/engie,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "bQ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/holofloor{icon_state = "asteroid"; dir = 2},/area/holodeck/source_picnicarea) "bR" = (/turf/simulated/floor/holofloor{icon_state = "wood"; dir = 4},/turf/simulated/floor/holofloor{icon_state = "siding1"; dir = 2},/area/holodeck/source_theatre) -"bS" = (/turf/simulated/floor/holofloor{icon_state = "rampbottom"; dir = 2},/area/holodeck/source_theatre) +"bS" = (/turf/space,/area/shuttle/escape/transit) "bT" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/blue,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/blue,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) -"bU" = (/turf/simulated/floor/holofloor/grass,/obj/structure/flora/ausbushes/grassybush,/turf/simulated/floor/holofloor{icon_state = "wood_siding5"; dir = 2},/area/holodeck/source_picnicarea) +"bU" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; tiles = 0},/turf/space/transit/north/shuttlespace_ns13,/area/space) "bV" = (/obj/effect/decal/cleanable/dirt,/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "asteroid"; dir = 2},/area/holodeck/source_picnicarea) -"bW" = (/obj/effect/decal/cleanable/dirt,/obj/structure/table/holotable/wood,/turf/simulated/floor/holofloor{icon_state = "asteroid"; dir = 2},/area/holodeck/source_picnicarea) -"bX" = (/turf/simulated/floor/holofloor/grass,/obj/structure/flora/ausbushes/grassybush,/turf/simulated/floor/holofloor{icon_state = "wood_siding9"; dir = 2},/area/holodeck/source_picnicarea) +"bW" = (/turf/simulated/floor/holofloor/space,/area/holodeck/source_space) +"bX" = (/obj/effect/landmark{name = "Holocarp Spawn Random"},/turf/simulated/floor/holofloor/space,/area/holodeck/source_space) "bY" = (/turf/simulated/floor/holofloor{icon_state = "wood"; dir = 4},/area/holodeck/source_theatre) "bZ" = (/turf/simulated/floor/holofloor{icon_state = "carpet6-2"; dir = 4},/area/holodeck/source_theatre) -"ca" = (/turf/simulated/floor/holofloor{icon_state = "carpet14-10"; dir = 4},/area/holodeck/source_theatre) +"ca" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet15-15"; dir = 4},/area/holodeck/source_meetinghall) "cb" = (/turf/simulated/floor/holofloor{icon_state = "carpet10-8"; dir = 4},/area/holodeck/source_theatre) "cc" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns8,/area/space) "cd" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 8; name = "thrower_escapeshuttletop(left)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns10,/area/space) -"ce" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 8; name = "thrower_escapeshuttletop(left)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns5,/area/space) +"ce" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet7-3"; dir = 4},/area/holodeck/source_meetinghall) "cf" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 4; name = "thrower_escapeshuttletop(right)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns7,/area/space) "cg" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 4; name = "thrower_escapeshuttletop(right)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns11,/area/space) "ch" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns4,/area/space) "ci" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) -"cj" = (/turf/simulated/floor/holofloor/grass,/obj/structure/flora/ausbushes/grassybush,/turf/simulated/floor/holofloor{icon_state = "wood_siding6"; dir = 2},/area/holodeck/source_picnicarea) -"ck" = (/turf/simulated/floor/holofloor/grass,/obj/structure/flora/ausbushes/grassybush,/turf/simulated/floor/holofloor{icon_state = "wood_siding10"; dir = 2},/area/holodeck/source_picnicarea) -"cl" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet7-3"; dir = 4},/area/holodeck/source_theatre) +"cj" = (/turf/simulated/floor/holofloor{icon_state = "cult"; dir = 2},/area/holodeck/source_meetinghall) +"ck" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet11-12"; dir = 4},/area/holodeck/source_meetinghall) +"cl" = (/obj/structure/holostool,/obj/structure/window/reinforced/holowindow{dir = 4},/turf/simulated/floor/holofloor{dir = 5; icon_state = "vault"},/area/holodeck/source_basketball) "cm" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet15-15"; dir = 4},/area/holodeck/source_theatre) -"cn" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet11-12"; dir = 4},/area/holodeck/source_theatre) +"cn" = (/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_basketball) "co" = (/turf/simulated/floor/holofloor{dir = 8; icon_state = "green"},/area/holodeck/source_emptycourt) "cp" = (/turf/simulated/floor/holofloor{dir = 4; icon_state = "green"},/area/holodeck/source_emptycourt) "cq" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns12,/area/space) -"cr" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 8; name = "thrower_escapeshuttletop(left)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns7,/area/space) -"cs" = (/turf/space/transit/north/shuttlespace_ns9,/area/shuttle/escape/transit) -"ct" = (/turf/space/transit/north/shuttlespace_ns4,/area/shuttle/escape/transit) -"cu" = (/turf/space/transit/north/shuttlespace_ns6,/area/shuttle/escape/transit) -"cv" = (/turf/space/transit/north/shuttlespace_ns10,/area/shuttle/escape/transit) +"cr" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{dir = 5; icon_state = "vault"},/area/holodeck/source_basketball) +"cs" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{dir = 5; icon_state = "vault"},/area/holodeck/source_thunderdomecourt) +"ct" = (/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_thunderdomecourt) +"cu" = (/obj/structure/holostool,/obj/structure/window/reinforced/holowindow{dir = 4},/turf/simulated/floor/holofloor{dir = 5; icon_state = "vault"},/area/holodeck/source_thunderdomecourt) +"cv" = (/turf/simulated/floor/holofloor{dir = 6; icon_state = "green"},/area/holodeck/source_boxingcourt) "cw" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 4; name = "thrower_escapeshuttletop(right)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns3,/area/space) "cx" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns14,/area/space) -"cy" = (/turf/simulated/floor/holofloor{icon_state = "carpet2-0"; dir = 4},/area/holodeck/source_theatre) +"cy" = (/obj/structure/window/reinforced/holowindow{dir = 8},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_boxingcourt) "cz" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns11,/area/space) -"cA" = (/turf/space/transit/north/shuttlespace_ns8,/area/shuttle/escape/transit) -"cB" = (/turf/space/transit/north/shuttlespace_ns3,/area/shuttle/escape/transit) -"cC" = (/turf/space/transit/north/shuttlespace_ns5,/area/shuttle/escape/transit) -"cD" = (/turf/space/transit/north/shuttlespace_ns2,/area/shuttle/escape/transit) +"cA" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_boxingcourt) +"cB" = (/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_boxingcourt) +"cC" = (/obj/structure/window/reinforced/holowindow{dir = 4},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_boxingcourt) +"cD" = (/turf/space/transit/east/shuttlespace_ew1,/area/shuttle/escape_pod3/transit) "cE" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns13,/area/space) "cF" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; name = "thrower_leftnostop"},/turf/space/transit/east/shuttlespace_ew4,/area/space) "cG" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; name = "thrower_leftnostop"},/turf/space/transit/east/shuttlespace_ew13,/area/space) @@ -141,57 +141,57 @@ "cK" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; name = "thrower_leftnostop"},/turf/space/transit/east/shuttlespace_ew9,/area/space) "cL" = (/turf/simulated/floor/holofloor/grass,/obj/structure/flora/ausbushes/brflowers,/turf/simulated/floor/holofloor{icon_state = "wood_siding1"; dir = 2},/area/holodeck/source_picnicarea) "cM" = (/turf/simulated/floor/holofloor/grass,/obj/structure/flora/ausbushes/ywflowers,/turf/simulated/floor/holofloor{icon_state = "wood_siding1"; dir = 2},/area/holodeck/source_picnicarea) -"cN" = (/turf/simulated/floor/holofloor{icon_state = "carpet3-0"; dir = 4},/area/holodeck/source_theatre) +"cN" = (/turf/simulated/floor/holofloor{icon_state = "bluefull"},/area/holodeck/source_boxingcourt) "cO" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns5,/area/space) -"cP" = (/turf/space/transit/north/shuttlespace_ns11,/area/shuttle/escape/transit) -"cQ" = (/turf/space/transit/north/shuttlespace_ns13,/area/shuttle/escape/transit) -"cR" = (/turf/space/transit/north/shuttlespace_ns7,/area/shuttle/escape/transit) -"cS" = (/turf/space/transit/north/shuttlespace_ns14,/area/shuttle/escape/transit) +"cP" = (/obj/structure/window/reinforced/holowindow/disappearing{dir = 1},/turf/simulated/floor/holofloor,/area/holodeck/source_thunderdomecourt) +"cQ" = (/obj/structure/window/reinforced/holowindow/disappearing{dir = 1},/turf/simulated/floor/holofloor{dir = 4; icon_state = "green"},/area/holodeck/source_thunderdomecourt) +"cR" = (/obj/structure/window/reinforced/holowindow/disappearing{dir = 1},/turf/simulated/floor/holofloor{dir = 8; icon_state = "green"},/area/holodeck/source_thunderdomecourt) +"cS" = (/turf/space/transit/east/shuttlespace_ew15,/area/shuttle/escape_pod3/transit) "cT" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns10,/area/space) "cU" = (/turf/space/transit/east/shuttlespace_ew7,/area/shuttle/escape_pod5/transit) -"cV" = (/turf/space/transit/east/shuttlespace_ew8,/area/shuttle/escape_pod5/transit) -"cW" = (/turf/space/transit/east/shuttlespace_ew9,/area/shuttle/escape_pod5/transit) -"cX" = (/turf/space/transit/east/shuttlespace_ew10,/area/shuttle/escape_pod5/transit) +"cV" = (/obj/structure/window/reinforced/holowindow/disappearing,/turf/simulated/floor/holofloor{dir = 8; icon_state = "red"},/area/holodeck/source_thunderdomecourt) +"cW" = (/obj/structure/window/reinforced/holowindow/disappearing,/turf/simulated/floor/holofloor,/area/holodeck/source_thunderdomecourt) +"cX" = (/obj/item/weapon/inflatable_duck,/turf/simulated/floor/beach/sand{tag = "icon-desert"; icon_state = "desert"},/area/holodeck/source_beach) "cY" = (/obj/effect/step_trigger/thrower{direction = 1; name = "thrower_throwup"; nostop = 0; tiles = 0},/turf/space/transit/east/shuttlespace_ew14,/area/space) -"cZ" = (/turf/simulated/floor/holofloor{icon_state = "asteroid"; dir = 2},/turf/simulated/floor/holofloor{icon_state = "asteroid6"; dir = 2},/area/centcom/specops) -"da" = (/turf/space/transit/north/shuttlespace_ns12,/area/shuttle/escape/transit) +"cZ" = (/turf/space/transit/north/shuttlespace_ns14,/area/skipjack_station/transit) +"da" = (/obj/structure/window/reinforced/holowindow/disappearing,/turf/simulated/floor/holofloor{dir = 4; icon_state = "red"},/area/holodeck/source_thunderdomecourt) "db" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 4; name = "thrower_escapeshuttletop(right)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns9,/area/space) "dc" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns15,/area/space) "dd" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; name = "thrower_leftnostop"},/turf/space/transit/east/shuttlespace_ew11,/area/space) -"de" = (/turf/space/transit/east/shuttlespace_ew2,/area/shuttle/escape_pod5/transit) -"df" = (/turf/space/transit/east/shuttlespace_ew3,/area/shuttle/escape_pod5/transit) +"de" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet14-10"; dir = 4},/area/holodeck/source_meetinghall) +"df" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet6-2"; dir = 4},/area/holodeck/source_meetinghall) "dg" = (/turf/space/transit/east/shuttlespace_ew4,/area/shuttle/escape_pod5/transit) "dh" = (/turf/space/transit/east/shuttlespace_ew5,/area/shuttle/escape_pod5/transit) "di" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; stopper = 0; tiles = 0},/turf/space/transit/east/shuttlespace_ew1,/area/space) "dj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_mothership) -"dk" = (/turf/simulated/floor/holofloor{icon_state = "carpet1-0"; dir = 4},/area/holodeck/source_theatre) -"dl" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet5-1"; dir = 4},/area/holodeck/source_theatre) +"dk" = (/obj/item/weapon/beach_ball/holoball,/turf/simulated/floor/holofloor{dir = 2; icon_state = "red"},/area/holodeck/source_basketball) +"dl" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet10-8"; dir = 4},/area/holodeck/source_meetinghall) "dm" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet13-5"; dir = 4},/area/holodeck/source_theatre) -"dn" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet9-4"; dir = 4},/area/holodeck/source_theatre) +"dn" = (/turf/space/transit/east/shuttlespace_ew14,/area/shuttle/escape_pod3/transit) "do" = (/turf/simulated/floor/holofloor{dir = 10; icon_state = "green"},/area/holodeck/source_emptycourt) "dp" = (/turf/simulated/floor/holofloor{dir = 2; icon_state = "green"},/area/holodeck/source_emptycourt) "dq" = (/turf/simulated/floor/holofloor{dir = 6; icon_state = "green"},/area/holodeck/source_emptycourt) -"dr" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 8; name = "thrower_escapeshuttletop(left)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns3,/area/space) -"ds" = (/turf/space/transit/north/shuttlespace_ns1,/area/shuttle/escape/transit) +"dr" = (/turf/simulated/floor/holofloor{dir = 9; icon_state = "red"},/area/holodeck/source_boxingcourt) +"ds" = (/obj/item/weapon/beach_ball,/turf/simulated/floor/beach/sand{tag = "icon-desert0"; icon_state = "desert0"},/area/holodeck/source_beach) "dt" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 4; name = "thrower_escapeshuttletop(right)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns14,/area/space) "du" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns3,/area/space) -"dv" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; name = "thrower_leftnostop"},/turf/space/transit/east/shuttlespace_ew5,/area/space) +"dv" = (/turf/simulated/floor/holofloor{icon_state = "grimy"; dir = 2},/turf/simulated/floor/holofloor{icon_state = "siding1"; dir = 2},/area/holodeck/source_meetinghall) "dw" = (/turf/space/transit/east/shuttlespace_ew14,/area/shuttle/escape_pod5/transit) "dx" = (/turf/space/transit/east/shuttlespace_ew15,/area/shuttle/escape_pod5/transit) "dy" = (/turf/space/transit/east/shuttlespace_ew1,/area/shuttle/escape_pod5/transit) "dz" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; stopper = 0; tiles = 0},/turf/space/transit/east/shuttlespace_ew10,/area/space) -"dA" = (/turf/unsimulated/wall{icon_state = "iron3"},/area/space) +"dA" = (/turf/simulated/floor/holofloor{icon_state = "rampbottom"; dir = 2},/turf/simulated/floor/holofloor{icon_state = "siding1"; dir = 2},/area/holodeck/source_meetinghall) "dB" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/wall{icon_state = "iron12"},/area/space) "dC" = (/turf/unsimulated/wall,/area/space) "dD" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/unsimulated/wall{icon_state = "iron12"},/area/space) "dE" = (/turf/unsimulated/wall{icon_state = "iron11"},/area/space) -"dF" = (/turf/space/transit/north/shuttlespace_ns15,/area/shuttle/escape/transit) +"dF" = (/obj/structure/table/holotable,/obj/item/clothing/gloves/boxing/hologlove{icon_state = "boxinggreen"; item_state = "boxinggreen"},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_boxingcourt) "dG" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns2,/area/space) "dH" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; name = "thrower_leftnostop"},/turf/space/transit/east/shuttlespace_ew10,/area/space) "dI" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; name = "thrower_leftnostop"},/turf/space/transit/east/shuttlespace_ew12,/area/space) -"dJ" = (/turf/simulated/floor/holofloor{icon_state = "1"; dir = 5},/area/holodeck/source_space) -"dK" = (/turf/simulated/floor/holofloor{icon_state = "17"; dir = 5},/area/holodeck/source_space) -"dL" = (/turf/simulated/floor/holofloor{icon_state = "22"; dir = 5},/area/holodeck/source_space) +"dJ" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet13-5"; dir = 4},/area/holodeck/source_meetinghall) +"dK" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet5-1"; dir = 4},/area/holodeck/source_meetinghall) +"dL" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet9-4"; dir = 4},/area/holodeck/source_meetinghall) "dM" = (/turf/simulated/floor/holofloor{icon_state = "snow"},/area/holodeck/source_snowfield) "dN" = (/turf/simulated/floor/holofloor{icon_state = "grimy"; dir = 2},/area/holodeck/source_meetinghall) "dO" = (/turf/simulated/floor/holofloor{dir = 9; icon_state = "red"},/area/holodeck/source_basketball) @@ -204,9 +204,9 @@ "dV" = (/obj/structure/table/holotable,/obj/machinery/readybutton{pixel_y = 0},/turf/simulated/floor/holofloor{dir = 9; icon_state = "red"},/area/holodeck/source_thunderdomecourt) "dW" = (/obj/structure/table/holotable,/obj/item/clothing/head/helmet/thunderdome,/obj/item/clothing/suit/armor/tdome/red,/obj/item/clothing/under/color/red,/obj/item/weapon/holo/esword/red,/turf/simulated/floor/holofloor{dir = 1; icon_state = "red"},/area/holodeck/source_thunderdomecourt) "dX" = (/obj/structure/table/holotable,/turf/simulated/floor/holofloor{dir = 5; icon_state = "red"},/area/holodeck/source_thunderdomecourt) -"dY" = (/obj/structure/table/holotable,/obj/item/clothing/gloves/boxing/hologlove,/turf/simulated/floor/holofloor{dir = 9; icon_state = "red"},/area/holodeck/source_boxingcourt) +"dY" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; tiles = 0},/turf/space/transit/north/shuttlespace_ns12,/area/space) "dZ" = (/turf/simulated/floor/holofloor{dir = 1; icon_state = "red"},/area/holodeck/source_boxingcourt) -"ea" = (/obj/structure/table/holotable,/obj/item/clothing/gloves/boxing/hologlove,/turf/simulated/floor/holofloor{dir = 5; icon_state = "red"},/area/holodeck/source_boxingcourt) +"ea" = (/obj/structure/window/reinforced/holowindow{dir = 1},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_boxingcourt) "eb" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns1,/area/space) "ec" = (/obj/structure/flora/grass/both,/turf/simulated/floor/holofloor{icon_state = "snow"},/area/holodeck/source_snowfield) "ed" = (/turf/simulated/floor/holofloor{icon_state = "carpet4-0"; dir = 4},/area/holodeck/source_meetinghall) @@ -218,15 +218,15 @@ "ej" = (/obj/effect/overlay/palmtree_r,/turf/simulated/floor/beach/sand{tag = "icon-desert"; icon_state = "desert"},/area/holodeck/source_beach) "ek" = (/turf/simulated/floor/beach/sand{tag = "icon-desert3"; icon_state = "desert3"},/area/holodeck/source_beach) "el" = (/obj/effect/overlay/palmtree_l,/obj/effect/overlay/coconut,/turf/simulated/floor/beach/sand{tag = "icon-desert0"; icon_state = "desert0"},/area/holodeck/source_beach) -"em" = (/obj/item/weapon/beach_ball,/turf/simulated/floor/beach/sand{tag = "icon-desert"; icon_state = "desert"},/area/holodeck/source_beach) +"em" = (/obj/machinery/door/window/holowindoor{dir = 1; name = "Green Corner"},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_boxingcourt) "en" = (/turf/simulated/floor/holofloor{dir = 8; icon_state = "red"},/area/holodeck/source_thunderdomecourt) "eo" = (/turf/simulated/floor/holofloor,/area/holodeck/source_thunderdomecourt) "ep" = (/turf/simulated/floor/holofloor{dir = 4; icon_state = "red"},/area/holodeck/source_thunderdomecourt) "eq" = (/turf/simulated/floor/holofloor{dir = 8; icon_state = "red"},/area/holodeck/source_boxingcourt) "er" = (/turf/simulated/floor/holofloor,/area/holodeck/source_boxingcourt) -"es" = (/turf/simulated/floor/holofloor{dir = 4; icon_state = "red"},/area/holodeck/source_boxingcourt) +"es" = (/obj/machinery/door/window/holowindoor{base_state = "right"; icon_state = "right"; name = "Green Team"},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_thunderdomecourt) "et" = (/obj/structure/flora/tree/pine,/turf/simulated/floor/holofloor{icon_state = "snow"},/area/holodeck/source_snowfield) -"eu" = (/obj/structure/table/holotable/wood,/turf/simulated/floor/holofloor{icon_state = "grimy"; dir = 2},/area/holodeck/source_meetinghall) +"eu" = (/obj/machinery/door/window/holowindoor{base_state = "right"; icon_state = "right"; name = "Green Team"},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_basketball) "ev" = (/turf/simulated/floor/holofloor{dir = 1; icon_state = "red"},/area/holodeck/source_basketball) "ew" = (/obj/item/clothing/glasses/sunglasses,/turf/simulated/floor/beach/sand{tag = "icon-desert0"; icon_state = "desert0"},/area/holodeck/source_beach) "ex" = (/turf/space/transit/east/shuttlespace_ew7,/area/shuttle/escape_pod3/transit) @@ -236,38 +236,38 @@ "eB" = (/turf/space/transit/east/shuttlespace_ew2,/area/shuttle/escape_pod3/transit) "eC" = (/turf/space/transit/east/shuttlespace_ew3,/area/shuttle/escape_pod3/transit) "eD" = (/turf/space/transit/east/shuttlespace_ew4,/area/shuttle/escape_pod3/transit) -"eE" = (/turf/space/transit/east/shuttlespace_ew5,/area/shuttle/escape_pod3/transit) +"eE" = (/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/turf/space/transit/north/shuttlespace_ns10,/area/space) "eF" = (/obj/structure/flora/grass/green,/turf/simulated/floor/holofloor{icon_state = "snow"},/area/holodeck/source_snowfield) -"eG" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet6-0"; dir = 4},/area/holodeck/source_meetinghall) -"eH" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet14-0"; dir = 4},/area/holodeck/source_meetinghall) -"eI" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet10-0"; dir = 4},/area/holodeck/source_meetinghall) +"eG" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; name = "thrower_leftnostop"},/turf/space/transit/east/shuttlespace_ew5,/area/space) +"eH" = (/turf/space/transit/east/shuttlespace_ew5,/area/shuttle/escape_pod3/transit) +"eI" = (/turf/space/transit/north/shuttlespace_ns14,/area/shuttle/escape/transit) "eJ" = (/turf/simulated/floor/holofloor{dir = 10; icon_state = "red"},/area/holodeck/source_basketball) "eK" = (/turf/simulated/floor/holofloor{dir = 2; icon_state = "red"},/area/holodeck/source_basketball) "eL" = (/turf/simulated/floor/holofloor{dir = 6; icon_state = "red"},/area/holodeck/source_basketball) -"eM" = (/obj/item/weapon/inflatable_duck,/turf/simulated/floor/beach/sand{tag = "icon-desert1"; icon_state = "desert1"},/area/holodeck/source_beach) -"eN" = (/obj/structure/holowindow,/turf/simulated/floor/holofloor{dir = 8; icon_state = "red"},/area/holodeck/source_thunderdomecourt) -"eO" = (/obj/structure/holowindow,/turf/simulated/floor/holofloor,/area/holodeck/source_thunderdomecourt) -"eP" = (/obj/structure/holowindow,/turf/simulated/floor/holofloor{dir = 4; icon_state = "red"},/area/holodeck/source_thunderdomecourt) -"eQ" = (/turf/space/transit/east/shuttlespace_ew14,/area/shuttle/escape_pod3/transit) -"eR" = (/turf/space/transit/east/shuttlespace_ew15,/area/shuttle/escape_pod3/transit) -"eS" = (/turf/space/transit/east/shuttlespace_ew1,/area/shuttle/escape_pod3/transit) +"eM" = (/turf/space/transit/north/shuttlespace_ns3,/area/shuttle/escape/transit) +"eN" = (/turf/space/transit/north/shuttlespace_ns7,/area/shuttle/escape/transit) +"eO" = (/turf/space/transit/north/shuttlespace_ns11,/area/shuttle/escape/transit) +"eP" = (/obj/structure/holostool,/obj/structure/window/reinforced/holowindow{dir = 4},/turf/simulated/floor/holofloor{dir = 5; icon_state = "vault"},/area/holodeck/source_emptycourt) +"eQ" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{dir = 5; icon_state = "vault"},/area/holodeck/source_emptycourt) +"eR" = (/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_emptycourt) +"eS" = (/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_courtroom) "eT" = (/obj/structure/flora/tree/dead,/turf/simulated/floor/holofloor{icon_state = "snow"},/area/holodeck/source_snowfield) -"eU" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet7-0"; dir = 4},/area/holodeck/source_meetinghall) -"eV" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet15-0"; dir = 4},/area/holodeck/source_meetinghall) -"eW" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet11-0"; dir = 4},/area/holodeck/source_meetinghall) +"eU" = (/obj/structure/window/reinforced/holowindow{dir = 4},/obj/structure/flora/pottedplant{tag = "icon-plant-10"; icon_state = "plant-10"},/turf/simulated/floor/holofloor{icon_state = "grimy"; dir = 2},/area/holodeck/source_courtroom) +"eV" = (/turf/simulated/floor/holofloor{icon_state = "grimy"; dir = 2},/area/holodeck/source_courtroom) +"eW" = (/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_courtroom) "eX" = (/turf/simulated/floor/holofloor{dir = 9; icon_state = "green"},/area/holodeck/source_basketball) "eY" = (/turf/simulated/floor/holofloor{dir = 1; icon_state = "green"},/area/holodeck/source_basketball) "eZ" = (/turf/simulated/floor/holofloor{dir = 5; icon_state = "green"},/area/holodeck/source_basketball) "fa" = (/turf/simulated/floor/beach/sand{tag = "icon-beachcorner"; icon_state = "beachcorner"; dir = 2},/area/holodeck/source_beach) "fb" = (/turf/simulated/floor/beach/sand{tag = "icon-beach"; icon_state = "beach"},/area/holodeck/source_beach) "fc" = (/turf/simulated/floor/beach/sand{tag = "icon-beachcorner (NORTH)"; icon_state = "beachcorner"; dir = 1},/area/holodeck/source_beach) -"fd" = (/obj/structure/holowindow{dir = 1},/turf/simulated/floor/holofloor{dir = 8; icon_state = "green"},/area/holodeck/source_thunderdomecourt) -"fe" = (/obj/structure/holowindow{dir = 1},/turf/simulated/floor/holofloor,/area/holodeck/source_thunderdomecourt) -"ff" = (/obj/structure/holowindow{dir = 1},/turf/simulated/floor/holofloor{dir = 4; icon_state = "green"},/area/holodeck/source_thunderdomecourt) -"fg" = (/turf/simulated/floor/holofloor{dir = 8; icon_state = "green"},/area/holodeck/source_boxingcourt) +"fd" = (/obj/machinery/door/window/holowindoor,/turf/simulated/floor/holofloor{icon_state = "grimy"; dir = 2},/area/holodeck/source_courtroom) +"fe" = (/turf/simulated/floor/holofloor{icon_state = "rampbottom"; dir = 2},/turf/simulated/floor/holofloor{icon_state = "siding1"; dir = 2},/area/holodeck/source_theatre) +"ff" = (/obj/structure/window/reinforced/holowindow{dir = 4},/turf/simulated/floor/holofloor{icon_state = "grimy"; dir = 2},/area/holodeck/source_courtroom) +"fg" = (/turf/simulated/floor/holofloor{icon_state = "carpet14-10"; dir = 4},/area/holodeck/source_courtroom) "fh" = (/turf/simulated/floor/holofloor{dir = 4; icon_state = "green"},/area/holodeck/source_boxingcourt) "fi" = (/turf/simulated/floor/holofloor{dir = 8; icon_state = "green"},/area/holodeck/source_basketball) -"fj" = (/obj/item/weapon/beach_ball/holoball,/turf/simulated/floor/holofloor,/area/holodeck/source_basketball) +"fj" = (/turf/simulated/floor/holofloor{icon_state = "carpet6-2"; dir = 4},/area/holodeck/source_courtroom) "fk" = (/turf/simulated/floor/holofloor{dir = 4; icon_state = "green"},/area/holodeck/source_basketball) "fl" = (/turf/simulated/floor/beach/sand{tag = "icon-beach (SOUTHEAST)"; icon_state = "beach"; dir = 6},/area/holodeck/source_beach) "fm" = (/turf/simulated/floor/beach/sand{tag = "icon-seashallow"; icon_state = "seashallow"; dir = 2},/area/holodeck/source_beach) @@ -277,18 +277,18 @@ "fq" = (/obj/structure/flora/grass/brown,/turf/simulated/floor/holofloor{icon_state = "snow"},/area/holodeck/source_snowfield) "fr" = (/turf/simulated/floor/holofloor{dir = 2; icon_state = "green"},/area/holodeck/source_basketball) "fs" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns9,/area/space) -"ft" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet5-0"; dir = 4},/area/holodeck/source_meetinghall) -"fu" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet13-0"; dir = 4},/area/holodeck/source_meetinghall) -"fv" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet9-0"; dir = 4},/area/holodeck/source_meetinghall) +"ft" = (/obj/structure/window/reinforced/holowindow{dir = 8},/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor{icon_state = "carpet7-3"; dir = 4},/area/holodeck/source_courtroom) +"fu" = (/turf/simulated/floor/holofloor{icon_state = "carpet10-8"; dir = 4},/area/holodeck/source_courtroom) +"fv" = (/obj/structure/bed/chair/holochair{dir = 8},/turf/simulated/floor/holofloor{icon_state = "carpet11-12"; dir = 4},/area/holodeck/source_courtroom) "fw" = (/turf/simulated/floor/holofloor{dir = 10; icon_state = "green"},/area/holodeck/source_basketball) "fx" = (/obj/structure/holohoop{dir = 1},/turf/simulated/floor/holofloor{dir = 2; icon_state = "green"},/area/holodeck/source_basketball) "fy" = (/turf/simulated/floor/holofloor{dir = 6; icon_state = "green"},/area/holodeck/source_basketball) "fz" = (/obj/structure/table/holotable,/turf/simulated/floor/holofloor{dir = 10; icon_state = "green"},/area/holodeck/source_thunderdomecourt) "fA" = (/obj/structure/table/holotable,/obj/item/clothing/head/helmet/thunderdome,/obj/item/clothing/suit/armor/tdome/green,/obj/item/clothing/under/color/green,/obj/item/weapon/holo/esword/green,/turf/simulated/floor/holofloor{dir = 2; icon_state = "green"},/area/holodeck/source_thunderdomecourt) "fB" = (/obj/structure/table/holotable,/obj/machinery/readybutton{pixel_y = 0},/turf/simulated/floor/holofloor{dir = 6; icon_state = "green"},/area/holodeck/source_thunderdomecourt) -"fC" = (/obj/structure/table/holotable,/obj/item/clothing/gloves/boxing/hologlove{icon_state = "boxinggreen"; item_state = "boxinggreen"},/turf/simulated/floor/holofloor{dir = 10; icon_state = "green"},/area/holodeck/source_boxingcourt) +"fC" = (/obj/structure/bed/chair/holochair{dir = 8},/turf/simulated/floor/holofloor{icon_state = "carpet15-15"; dir = 4},/area/holodeck/source_courtroom) "fD" = (/turf/simulated/floor/holofloor{dir = 2; icon_state = "green"},/area/holodeck/source_boxingcourt) -"fE" = (/obj/structure/table/holotable,/obj/item/clothing/gloves/boxing/hologlove{icon_state = "boxinggreen"; item_state = "boxinggreen"},/turf/simulated/floor/holofloor{dir = 6; icon_state = "green"},/area/holodeck/source_boxingcourt) +"fE" = (/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor{icon_state = "asteroid"; dir = 2},/area/holodeck/source_picnicarea) "fF" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; stopper = 0; tiles = 0},/turf/space/transit/north/shuttlespace_ns7,/area/space) "fG" = (/turf/unsimulated/wall{icon_state = "iron5"},/area/space) "fH" = (/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/wall{icon_state = "iron12"},/area/space) @@ -314,7 +314,7 @@ "gb" = (/mob/living/silicon/decoy{icon_state = "ai-malf"; name = "GLaDOS"},/turf/unsimulated/floor{icon_state = "whiteshiny"},/area/syndicate_mothership/control) "gc" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; freerange = 1; frequency = 1213; listening = 1; name = "Syndicate Ops Intercom"; pixel_y = 0; subspace_transmission = 1; syndie = 1},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "circuit"},/area/syndicate_mothership) "gd" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns7,/area/space) -"ge" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 8; name = "thrower_escapeshuttletop(left)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns11,/area/space) +"ge" = (/turf/simulated/floor/holofloor/grass,/obj/structure/flora/ausbushes/ywflowers,/turf/simulated/floor/holofloor{dir = 4; icon_state = "wood_siding8"},/area/holodeck/source_picnicarea) "gf" = (/turf/space/transit/north/shuttlespace_ns6,/area/syndicate_station/transit) "gg" = (/turf/space/transit/north/shuttlespace_ns8,/area/syndicate_station/transit) "gh" = (/turf/space/transit/north/shuttlespace_ns3,/area/syndicate_station/transit) @@ -323,9 +323,9 @@ "gk" = (/turf/space/transit/north/shuttlespace_ns2,/area/syndicate_station/transit) "gl" = (/turf/space/transit/north/shuttlespace_ns13,/area/syndicate_station/transit) "gm" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns6,/area/space) -"gn" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) +"gn" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) "go" = (/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) -"gp" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) +"gp" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) "gq" = (/turf/space/transit/north/shuttlespace_ns11,/area/syndicate_station/transit) "gr" = (/turf/space/transit/north/shuttlespace_ns7,/area/syndicate_station/transit) "gs" = (/turf/space/transit/north/shuttlespace_ns14,/area/syndicate_station/transit) @@ -348,42 +348,42 @@ "gJ" = (/turf/space/transit/north/shuttlespace_ns15,/area/syndicate_station/transit) "gK" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns4,/area/space) "gL" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns9,/area/space) -"gM" = (/turf/space/transit/north/shuttlespace_ns14,/area/vox_station/transit) -"gN" = (/turf/space/transit/north/shuttlespace_ns9,/area/vox_station/transit) +"gM" = (/turf/space/transit/north/shuttlespace_ns9,/area/skipjack_station/transit) +"gN" = (/turf/space/transit/north/shuttlespace_ns13,/area/skipjack_station/transit) "gO" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns14,/area/space) "gP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/syndicate_mothership/elite_squad) "gQ" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns3,/area/space) "gR" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns8,/area/space) "gS" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns13,/area/space) -"gT" = (/turf/space/transit/north/shuttlespace_ns13,/area/vox_station/transit) -"gU" = (/turf/space/transit/north/shuttlespace_ns4,/area/vox_station/transit) -"gV" = (/turf/space/transit/north/shuttlespace_ns8,/area/vox_station/transit) +"gT" = (/turf/space/transit/north/shuttlespace_ns4,/area/skipjack_station/transit) +"gU" = (/turf/space/transit/north/shuttlespace_ns8,/area/skipjack_station/transit) +"gV" = (/obj/machinery/door/airlock/external{name = "Shuttle Airlock"; req_access = list(150)},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "syndicate_elite"; name = "Side Hull Door"; opacity = 0},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) "gW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_mothership) "gX" = (/turf/unsimulated/floor{name = "plating"},/area/syndicate_mothership/elite_squad) -"gY" = (/obj/machinery/door/airlock/external{req_access_txt = "150"},/turf/unsimulated/floor{name = "plating"},/area/syndicate_mothership/elite_squad) +"gY" = (/obj/machinery/door/airlock/external{req_access = list(150)},/turf/unsimulated/floor{name = "plating"},/area/syndicate_mothership/elite_squad) "gZ" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns2,/area/space) -"ha" = (/turf/space/transit/north/shuttlespace_ns7,/area/vox_station/transit) +"ha" = (/turf/space/transit/north/shuttlespace_ns12,/area/skipjack_station/transit) "hb" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns12,/area/space) -"hc" = (/turf/space/transit/north/shuttlespace_ns12,/area/vox_station/transit) -"hd" = (/turf/space/transit/north/shuttlespace_ns3,/area/vox_station/transit) +"hc" = (/turf/space/transit/north/shuttlespace_ns7,/area/skipjack_station/transit) +"hd" = (/turf/space/transit/north/shuttlespace_ns3,/area/skipjack_station/transit) "he" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_mothership) "hf" = (/turf/space,/area/shuttle/escape_pod1/centcom) "hg" = (/turf/space,/area/shuttle/escape_pod2/centcom) "hh" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns1,/area/space) -"hi" = (/turf/space/transit/north/shuttlespace_ns6,/area/vox_station/transit) -"hj" = (/turf/space/transit/north/shuttlespace_ns11,/area/vox_station/transit) -"hk" = (/turf/space/transit/north/shuttlespace_ns2,/area/vox_station/transit) +"hi" = (/obj/machinery/door/airlock/glass_security{name = "Airlock"; req_access = list(150)},/obj/machinery/door/blast/regular{id = "syndicate_elite_mech_room"; name = "Mech Room Door"},/turf/unsimulated/floor{icon_state = "floor4"},/area/syndicate_mothership/elite_squad) +"hj" = (/turf/space/transit/north/shuttlespace_ns11,/area/skipjack_station/transit) +"hk" = (/turf/space/transit/north/shuttlespace_ns6,/area/skipjack_station/transit) "hl" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/turf/space/transit/north/shuttlespace_ns11,/area/space) "hm" = (/obj/machinery/computer/pod{id = "syndicate_elite"; name = "Hull Door Control"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) "hn" = (/obj/machinery/computer/syndicate_elite_shuttle,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) "ho" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 4; name = "thrower_escapeshuttletop(right)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns15,/area/space) -"hp" = (/turf/space/transit/north/shuttlespace_ns5,/area/vox_station/transit) -"hq" = (/turf/space/transit/north/shuttlespace_ns10,/area/vox_station/transit) -"hr" = (/turf/space/transit/north/shuttlespace_ns1,/area/vox_station/transit) +"hp" = (/turf/space/transit/north/shuttlespace_ns2,/area/skipjack_station/transit) +"hq" = (/turf/space/transit/north/shuttlespace_ns10,/area/skipjack_station/transit) +"hr" = (/turf/space/transit/north/shuttlespace_ns5,/area/skipjack_station/transit) "hs" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/shuttle/syndicate_elite/mothership) -"ht" = (/obj/machinery/door/airlock/external{name = "Shuttle Airlock"; req_access_txt = "150"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "syndicate_elite"; name = "Side Hull Door"; opacity = 0},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/syndicate_elite/mothership) +"ht" = (/turf/space/transit/north/shuttlespace_ns1,/area/skipjack_station/transit) "hu" = (/turf/space,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/syndicate_elite/mothership) -"hv" = (/turf/space/transit/north/shuttlespace_ns15,/area/vox_station/transit) +"hv" = (/obj/machinery/door/airlock/external{name = "Shuttle Airlock"; req_access = list(150)},/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "syndicate_elite"; name = "Front Hull Door"; opacity = 1},/turf/simulated/shuttle/plating,/area/shuttle/syndicate_elite/mothership) "hw" = (/turf/simulated/floor/plating/airless,/area/shuttle/syndicate_elite/mothership) "hx" = (/turf/simulated/shuttle/wall{icon_state = "swall_s6"; dir = 2},/area/centcom/evac) "hy" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 1},/turf/space,/area/centcom/evac) @@ -396,19 +396,19 @@ "hF" = (/obj/structure/window/reinforced,/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 1},/turf/simulated/floor/plating/airless,/area/centcom/evac) "hG" = (/turf/simulated/shuttle/wall{icon_state = "swall7"; dir = 2},/area/centcom/evac) "hH" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/centcom/evac) -"hI" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_1_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock"; req_access_txt = "13"},/turf/unsimulated/floor,/area/centcom/evac) -"hJ" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_2_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock"; req_access_txt = "13"},/turf/unsimulated/floor,/area/centcom/evac) +"hI" = (/turf/space/transit/north/shuttlespace_ns15,/area/skipjack_station/transit) +"hJ" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_1_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock"; req_access = list(13)},/turf/unsimulated/floor,/area/centcom/evac) "hK" = (/turf/simulated/shuttle/wall{icon_state = "swall11"; dir = 2},/area/centcom/evac) "hL" = (/obj/machinery/portable_atmospherics/powered/pump,/turf/simulated/shuttle/plating,/area/centcom/evac) "hM" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/shuttle/plating,/area/centcom/evac) "hN" = (/turf/simulated/shuttle/plating,/turf/simulated/shuttle/wall{icon_state = "swall_f6"; dir = 2},/area/centcom/evac) "hO" = (/turf/simulated/shuttle/wall{dir = 2; icon_state = "swall_floor_f9"},/area/centcom/evac) "hP" = (/obj/structure/closet/emcloset,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) -"hQ" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_1_recovery"; pixel_x = 25; pixel_y = 30; req_access_txt = "0"; req_one_access_txt = "13"; tag_door = "escape_pod_1_recovery_hatch"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor2"},/area/centcom/evac) +"hQ" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_2_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock"; req_access = list(13)},/turf/unsimulated/floor,/area/centcom/evac) "hR" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/toxin{pixel_x = -2; pixel_y = 4},/obj/item/weapon/storage/firstaid/toxin,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "hS" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/fire{pixel_x = -2; pixel_y = 4},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "hT" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 0},/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) -"hU" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_2_recovery"; pixel_x = -25; pixel_y = 30; req_access_txt = "0"; req_one_access_txt = "13"; tag_door = "escape_pod_2_recovery_hatch"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor2"},/area/centcom/evac) +"hU" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_1_recovery"; pixel_x = 25; pixel_y = 30; req_one_access = list(13); tag_door = "escape_pod_1_recovery_hatch"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor2"},/area/centcom/evac) "hV" = (/turf/simulated/shuttle/wall{dir = 2; icon_state = "swall_floor_f5"},/area/centcom/evac) "hW" = (/turf/simulated/shuttle/plating,/turf/simulated/shuttle/wall{dir = 3; icon_state = "swall_f10"; layer = 2},/area/centcom/evac) "hX" = (/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/shuttle/plating,/area/centcom/evac) @@ -424,11 +424,11 @@ "ih" = (/turf/unsimulated/wall,/area/syndicate_mothership) "ii" = (/turf/simulated/shuttle/plating,/area/centcom/evac) "ij" = (/turf/simulated/shuttle/wall{icon_state = "swall1"; dir = 2},/area/centcom/evac) -"ik" = (/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = -30; pixel_y = 0; req_access_txt = "0"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) +"ik" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_2_recovery"; pixel_x = -25; pixel_y = 30; req_one_access = list(13); tag_door = "escape_pod_2_recovery_hatch"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor2"},/area/centcom/evac) "il" = (/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "im" = (/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor2"},/area/centcom/evac) -"in" = (/obj/structure/stool,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) -"io" = (/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = 30; pixel_y = 0; req_access_txt = "0"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) +"in" = (/obj/item/weapon/stool,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) +"io" = (/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = -30; pixel_y = 0},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "ip" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; tiles = 0},/turf/space/transit/north/shuttlespace_ns8,/area/space) "iq" = (/turf/space/transit/north/shuttlespace_ns12,/area/shuttle/escape_pod1/transit) "ir" = (/turf/space/transit/north/shuttlespace_ns7,/area/shuttle/escape_pod1/transit) @@ -445,7 +445,7 @@ "iC" = (/obj/structure/flora/tree/pine,/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/area/syndicate_mothership) "iD" = (/obj/structure/flora/grass/both,/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/area/syndicate_mothership) "iE" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/centcom/evac) -"iF" = (/obj/machinery/door/airlock/maintenance_hatch{req_access_txt = "101"},/turf/simulated/shuttle/plating,/area/centcom/evac) +"iF" = (/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = 30; pixel_y = 0},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "iG" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/centcom/evac) "iH" = (/turf/space/transit/north/shuttlespace_ns11,/area/shuttle/escape_pod1/transit) "iI" = (/turf/space/transit/north/shuttlespace_ns6,/area/shuttle/escape_pod1/transit) @@ -456,9 +456,9 @@ "iN" = (/turf/space/transit/north/shuttlespace_ns13,/area/shuttle/escape_pod2/transit) "iO" = (/turf/space/transit/north/shuttlespace_ns10,/area/shuttle/escape_pod2/transit) "iP" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; tiles = 0},/turf/space/transit/north/shuttlespace_ns6,/area/space) -"iQ" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 8; name = "thrower_escapeshuttletop(left)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns12,/area/space) +"iQ" = (/obj/structure/holostool,/turf/simulated/floor/holofloor{icon_state = "carpet14-10"; dir = 4},/area/holodeck/source_theatre) "iR" = (/obj/machinery/vending/cigarette,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) -"iS" = (/obj/structure/stool/bed/chair,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) +"iS" = (/obj/structure/bed/chair,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "iT" = (/obj/machinery/vending/cola,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "iU" = (/turf/space/transit/north/shuttlespace_ns10,/area/shuttle/escape_pod1/transit) "iV" = (/turf/space/transit/north/shuttlespace_ns5,/area/shuttle/escape_pod1/transit) @@ -468,8 +468,8 @@ "iZ" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; tiles = 0},/turf/space/transit/north/shuttlespace_ns5,/area/space) "ja" = (/obj/structure/flora/bush,/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/area/syndicate_mothership) "jb" = (/obj/structure/table,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) -"jc" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) -"jd" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) +"jc" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) +"jd" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "je" = (/obj/machinery/vending/snack,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "jf" = (/turf/space/transit/north/shuttlespace_ns4,/area/shuttle/escape_pod1/transit) "jg" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; tiles = 0},/turf/space/transit/north/shuttlespace_ns1,/area/space) @@ -478,16 +478,16 @@ "jj" = (/turf/space,/area/shuttle/escape_pod5/centcom) "jk" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "jl" = (/turf/space,/area/shuttle/escape_pod3/centcom) -"jm" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_5_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock"; req_access_txt = "13"},/turf/unsimulated/floor,/area/centcom/evac) -"jn" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_5_recovery"; pixel_x = -25; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13"; tag_door = "escape_pod_5_recovery_hatch"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor2"},/area/centcom/evac) -"jo" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) -"jp" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_3_recovery"; pixel_x = 25; pixel_y = -25; req_access_txt = "0"; req_one_access_txt = "13"; tag_door = "escape_pod_3_recovery_hatch"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor2"},/area/centcom/evac) -"jq" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_3_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock"; req_access_txt = "13"},/turf/unsimulated/floor,/area/centcom/evac) +"jm" = (/obj/machinery/door/airlock/maintenance_hatch{req_access = list(101)},/turf/simulated/shuttle/plating,/area/centcom/evac) +"jn" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_5_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock"; req_access = list(13)},/turf/unsimulated/floor,/area/centcom/evac) +"jo" = (/obj/structure/bed/chair{dir = 1},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) +"jp" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_5_recovery"; pixel_x = -25; pixel_y = 25; req_one_access = list(13); tag_door = "escape_pod_5_recovery_hatch"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor2"},/area/centcom/evac) +"jq" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_3_recovery_hatch"; locked = 1; name = "Recovery Shuttle Dock"; req_access = list(13)},/turf/unsimulated/floor,/area/centcom/evac) "jr" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"},/area/syndicate_mothership) "js" = (/obj/machinery/vending/coffee,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "jt" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/syndicate_mothership) -"ju" = (/obj/machinery/door/airlock/glass_security{name = "Airlock"; req_access_txt = "150"},/obj/machinery/door/blast/regular{id = "syndicate_elite_mech_room"; name = "Mech Room Door"},/turf/unsimulated/floor{icon_state = "floor4"},/area/syndicate_mothership/elite_squad) -"jv" = (/obj/machinery/door/airlock/external{name = "Shuttle Airlock"; req_access_txt = "150"},/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "syndicate_elite"; name = "Front Hull Door"; opacity = 1},/turf/simulated/shuttle/plating,/area/shuttle/syndicate_elite/mothership) +"ju" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_pod_3_recovery"; pixel_x = 25; pixel_y = -25; req_one_access = list(13); tag_door = "escape_pod_3_recovery_hatch"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor2"},/area/centcom/evac) +"jv" = (/obj/machinery/computer/shuttle_control/multi/syndicate,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "jw" = (/obj/machinery/door/blast/regular{id = "smindicate"; name = "Outer Airlock"},/turf/simulated/shuttle/plating,/area/syndicate_mothership) "jx" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/syndicate_mothership) "jy" = (/turf/simulated/shuttle/wall{dir = 2; icon_state = "swallc1"},/area/centcom/evac) @@ -495,8 +495,8 @@ "jA" = (/obj/structure/table,/obj/machinery/microwave,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "jB" = (/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "jC" = (/obj/machinery/computer/security/nuclear,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) -"jD" = (/obj/machinery/computer/shuttle_control/multi/syndicate{req_access_txt = "0"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) -"jE" = (/obj/structure/table,/obj/machinery/door_control{id = "syndieshutters"; name = "remote shutter control"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"jD" = (/obj/structure/table,/obj/machinery/door_control{id = "syndieshutters"; name = "remote shutter control"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"jE" = (/obj/machinery/door/airlock/hatch{name = "Infirmary"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/centcom/evac) "jF" = (/obj/structure/computerframe,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "jG" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) "jH" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/obj/structure/flora/grass/both,/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"},/area/syndicate_mothership) @@ -506,7 +506,7 @@ "jL" = (/obj/structure/window/shuttle{icon_state = "window2"},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/centcom/evac) "jM" = (/obj/structure/grille,/obj/structure/window/shuttle,/turf/simulated/shuttle/plating,/area/centcom/evac) "jN" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) -"jO" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"jO" = (/obj/item/weapon/stool{pixel_y = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "jP" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 4},/area/syndicate_mothership) "jQ" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 9},/area/syndicate_mothership) "jR" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 8},/area/syndicate_mothership) @@ -528,47 +528,47 @@ "kh" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/syndicate_mothership) "ki" = (/obj/machinery/sleeper,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor3"},/area/centcom/evac) "kj" = (/obj/machinery/sleep_console,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor3"},/area/centcom/evac) -"kk" = (/obj/machinery/door/airlock/hatch{name = "Infirmary"; req_access_txt = "0"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/centcom/evac) +"kk" = (/obj/machinery/door/window{dir = 1; name = "Cockpit"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "kl" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/stamp,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor4"},/area/centcom/evac) -"km" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor4"},/area/centcom/evac) -"kn" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor4"},/area/centcom/evac) +"km" = (/obj/structure/bed/chair{dir = 1},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor4"},/area/centcom/evac) +"kn" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor4"},/area/centcom/evac) "ko" = (/obj/machinery/computer/card,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor4"},/area/centcom/evac) "kp" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/syndicate_mothership) -"kq" = (/obj/machinery/door/window{dir = 1; name = "Cockpit"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"kq" = (/obj/machinery/door/airlock/centcom{name = "Kitchen"; opacity = 1; req_access = list(150)},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "kr" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/syndicate_mothership) "ks" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/obj/structure/flora/grass/brown,/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 4},/area/syndicate_mothership) -"kt" = (/obj/structure/stool/bed/chair/comfy/black,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) -"ku" = (/obj/machinery/door/airlock/centcom{name = "Kitchen"; opacity = 1; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"kt" = (/obj/structure/bed/chair/comfy/black,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"ku" = (/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = -30; pixel_y = 0},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor3"},/area/centcom/evac) "kv" = (/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/syndicate_mothership) "kw" = (/obj/structure/sink/kitchen{pixel_y = 28},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/syndicate_mothership) -"kx" = (/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = -30; pixel_y = 0; req_access_txt = "0"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor3"},/area/centcom/evac) +"kx" = (/obj/machinery/door/window/northright{base_state = "right"; dir = 4; icon_state = "right"; name = "Security Desk"; req_access = list(103)},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor4"},/area/centcom/evac) "ky" = (/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor4"},/area/centcom/evac) "kz" = (/obj/machinery/computer/secure_data,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor4"},/area/centcom/evac) "kA" = (/obj/structure/closet,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "kB" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_surround"; dir = 8},/area/syndicate_mothership) "kC" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 6},/area/syndicate_mothership) "kD" = (/turf/unsimulated/wall/fakeglass,/area/syndicate_mothership) -"kE" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"kE" = (/obj/structure/bed/chair/comfy/black{dir = 4},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "kF" = (/obj/structure/table,/obj/item/weapon/folder,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) -"kG" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"kG" = (/obj/structure/bed/chair/comfy/black{dir = 8},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "kH" = (/obj/structure/closet/crate/freezer,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/syndicate_mothership) -"kI" = (/obj/machinery/door/window/northright{base_state = "right"; dir = 4; icon_state = "right"; name = "Security Desk"; req_access_txt = "103"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor4"},/area/centcom/evac) +"kI" = (/obj/machinery/door/airlock/hatch{name = "Cockpit"; req_access = list(109)},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor2"},/area/centcom/evac) "kJ" = (/obj/structure/table,/obj/item/weapon/storage/box/handcuffs,/obj/item/device/flash,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor4"},/area/centcom/evac) -"kK" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) -"kL" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"kK" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"kL" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "kM" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) "kN" = (/turf/simulated/shuttle/wall{icon_state = "swall14"; dir = 2},/area/centcom/evac) "kO" = (/turf/simulated/shuttle/wall{icon_state = "swall13"; dir = 2},/area/centcom/evac) -"kP" = (/obj/machinery/door/airlock/hatch{name = "Cockpit"; req_access_txt = "109"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor2"},/area/centcom/evac) +"kP" = (/obj/machinery/door/airlock/external{req_access = list(150)},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "kQ" = (/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) -"kR" = (/obj/machinery/door/airlock/external{req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) -"kS" = (/obj/machinery/door/airlock/centcom{name = "Restroom"; opacity = 1; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"kR" = (/obj/machinery/door/airlock/centcom{name = "Restroom"; opacity = 1; req_access = list(150)},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/syndicate_mothership) +"kS" = (/obj/machinery/door/window{dir = 2; name = "Seating"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "kT" = (/obj/structure/urinal{pixel_y = 32},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "kU" = (/obj/structure/urinal{pixel_y = 32},/obj/effect/decal/cleanable/vomit,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "kV" = (/obj/machinery/computer/crew,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) -"kW" = (/obj/structure/stool/bed/chair{dir = 4; name = "Defense"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) +"kW" = (/obj/structure/bed/chair{dir = 4; name = "Defense"},/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "kX" = (/obj/machinery/computer/communications,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) -"kY" = (/obj/structure/closet/syndicate/personal,/obj/item/clothing/tie/storage/brown_vest,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"kY" = (/obj/structure/closet/syndicate/personal,/obj/item/clothing/accessory/storage/brown_vest,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "kZ" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 8},/area/syndicate_mothership) "la" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "lb" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/structure/mirror{pixel_x = 28},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) @@ -588,21 +588,21 @@ "lp" = (/obj/structure/table,/obj/item/weapon/paper_bin,/turf/unsimulated/floor{icon = 'icons/turf/shuttle.dmi'; icon_state = "floor"},/area/centcom/evac) "lq" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'FOURTH WALL'."; name = "\improper FOURTH WALL"; pixel_x = -32},/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/area/syndicate_mothership) "lr" = (/obj/structure/table,/obj/item/device/aicard,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) -"ls" = (/obj/machinery/door/window{dir = 2; name = "Seating"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"ls" = (/obj/machinery/door/window{dir = 4; name = "Brig"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "lt" = (/obj/structure/table,/obj/machinery/computer/pod/old/syndicate{id = "smindicate"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "lu" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/obj/structure/flora/grass/brown,/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) "lv" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{dir = 1; icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"},/area/syndicate_mothership) -"lw" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/red,/turf/simulated/floor/wood,/area/syndicate_mothership) +"lw" = (/obj/structure/bed,/obj/item/weapon/bedsheet/red,/turf/simulated/floor/wood,/area/syndicate_mothership) "lx" = (/turf/simulated/floor/wood,/area/syndicate_mothership) "ly" = (/turf/simulated/floor/wood{icon_state = "wood-broken6"},/area/syndicate_mothership) "lz" = (/obj/structure/window/shuttle{icon_state = "window4"},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/centcom/evac) "lA" = (/obj/structure/window/shuttle{icon_state = "window12"},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/centcom/evac) "lB" = (/obj/structure/window/shuttle{icon_state = "window8"},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/centcom/evac) -"lC" = (/obj/machinery/door/window{dir = 4; name = "Brig"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) -"lD" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "synd_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "0"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"lC" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "synd_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"lD" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Equipment Room"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) "lE" = (/turf/unsimulated/wall/fakeglass{dir = 1; icon_state = "fakewindows"},/area/syndicate_mothership) -"lF" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/red,/turf/simulated/floor/wood{icon_state = "wood-broken4"},/area/syndicate_mothership) -"lG" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Equipment Room"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"lF" = (/obj/structure/bed,/obj/item/weapon/bedsheet/red,/turf/simulated/floor/wood{icon_state = "wood-broken4"},/area/syndicate_mothership) +"lG" = (/obj/machinery/door/window{dir = 4; name = "Infirmary"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_mothership) "lH" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/syndicate_mothership) "lI" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 10},/area/syndicate_mothership) "lJ" = (/turf/simulated/floor/wood{icon_state = "wood-broken"},/area/syndicate_mothership) @@ -620,14 +620,14 @@ "lV" = (/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "snow"},/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 4},/turf/unsimulated/floor{icon = 'icons/turf/snow.dmi'; icon_state = "gravsnow_corner"; dir = 8},/area/syndicate_mothership) "lW" = (/turf/simulated/floor/wood{icon_state = "wood-broken3"},/area/syndicate_mothership) "lX" = (/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_mothership) -"lY" = (/obj/machinery/door/window{dir = 4; name = "Infirmary"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_mothership) -"lZ" = (/obj/machinery/door/window/westright{name = "Tool Storage"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"lY" = (/obj/machinery/door/window/westright{name = "Tool Storage"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"lZ" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Infirmary"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_mothership) "ma" = (/obj/structure/table,/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/toolbox/syndicate{pixel_x = -3; pixel_y = -3},/obj/effect/spawner/newbomb/timer/syndicate,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) -"mb" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Infirmary"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_mothership) -"mc" = (/obj/machinery/door/window{dir = 8; name = "Tool Storage"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"mb" = (/obj/machinery/door/window{dir = 8; name = "Tool Storage"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_mothership) +"mc" = (/obj/machinery/door/window{dir = 1; name = "Secure Storage"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_mothership) "md" = (/obj/structure/closet/crate/medical,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/o2,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/adv,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_mothership) "me" = (/obj/item/weapon/weldingtool,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_mothership) -"mf" = (/obj/machinery/door/window{dir = 1; name = "Secure Storage"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_mothership) +"mf" = (/obj/machinery/door/airlock/centcom{name = "Barracks"; opacity = 1; req_access = list(150)},/turf/unsimulated/floor{icon_state = "grimy"},/area/syndicate_mothership) "mg" = (/obj/item/weapon/crowbar,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_mothership) "mh" = (/obj/structure/table,/obj/effect/spawner/newbomb/timer/syndicate,/turf/unsimulated/floor{icon_state = "floor4"},/area/syndicate_mothership) "mi" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "syndieshutters_workshop"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_station/start) @@ -667,8 +667,8 @@ "mQ" = (/obj/structure/table,/obj/item/device/flashlight/lamp{pixel_x = 4; pixel_y = 8},/turf/unsimulated/floor{icon_state = "grimy"},/area/syndicate_mothership) "mR" = (/obj/structure/table,/obj/effect/landmark{name = "Nuclear-Code"},/turf/unsimulated/floor{icon_state = "grimy"},/area/syndicate_mothership) "mS" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 8},/obj/item/weapon/pen{pixel_y = 4},/turf/unsimulated/floor{icon_state = "grimy"},/area/syndicate_mothership) -"mT" = (/obj/structure/stool/bed/alien,/turf/unsimulated/floor{icon_state = "floor5"},/area/alien) -"mU" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/hos,/turf/unsimulated/floor{icon_state = "grimy"},/area/syndicate_mothership) +"mT" = (/obj/structure/bed/alien,/turf/unsimulated/floor{icon_state = "floor5"},/area/alien) +"mU" = (/obj/structure/bed,/obj/item/weapon/bedsheet/hos,/turf/unsimulated/floor{icon_state = "grimy"},/area/syndicate_mothership) "mV" = (/obj/effect/landmark{name = "Syndicate-Spawn"},/turf/unsimulated/floor{icon_state = "grimy"},/area/syndicate_mothership) "mW" = (/turf/unsimulated/floor{icon_state = "grimy"},/area/syndicate_mothership) "mX" = (/turf/unsimulated/wall{icon_state = "phoron5"},/area/alien) @@ -676,57 +676,57 @@ "mZ" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/unsimulated/floor{icon_state = "floor5"},/area/syndicate_mothership) "na" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/unsimulated/floor{icon_state = "floor5"},/area/syndicate_mothership) "nb" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "floor5"},/area/syndicate_mothership) -"nc" = (/obj/machinery/door/airlock/centcom{name = "Barracks"; opacity = 1; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "grimy"},/area/syndicate_mothership) +"nc" = (/obj/structure/table,/obj/machinery/chemical_dispenser/bar_soft/full{pixel_x = 2; pixel_y = 6},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "nd" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/unsimulated/floor{icon_state = "floor5"},/area/syndicate_mothership) "ne" = (/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) "nf" = (/obj/structure/sign/double/map/left{pixel_y = 32},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) "ng" = (/obj/structure/sign/double/map/right{pixel_y = 32},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) "nh" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "syndieshutters_infirmary"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_station/start) -"ni" = (/obj/structure/table,/obj/machinery/chem_dispenser/soda{pixel_x = 2; pixel_y = 6},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) +"ni" = (/obj/machinery/computer/shuttle_control/multi/syndicate,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "nj" = (/obj/structure/table,/obj/item/weapon/storage/box/drinkingglasses{pixel_x = 1; pixel_y = 4},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "nk" = (/obj/structure/sink/kitchen{pixel_y = 28},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "nl" = (/obj/structure/closet/secure_closet/freezer/fridge,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) -"nm" = (/obj/structure/stool/bed/chair/comfy/black,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) -"nn" = (/obj/machinery/door/airlock/centcom{name = "Kitchen"; opacity = 1; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) +"nm" = (/obj/structure/bed/chair/comfy/black,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"nn" = (/obj/structure/table,/obj/machinery/door_control{id = "syndieshutters"; name = "remote shutter control"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "no" = (/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "np" = (/obj/structure/table/reinforced,/obj/machinery/microwave{pixel_x = -1; pixel_y = 8},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) -"nq" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"nq" = (/obj/structure/bed/chair/comfy/black{dir = 4},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) "nr" = (/obj/structure/table,/obj/item/weapon/folder{pixel_y = 2},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) "ns" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen{pixel_y = 4},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) -"nt" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"nt" = (/obj/structure/bed/chair/comfy/black{dir = 8},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) "nu" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "nv" = (/turf/space,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/syndicate_station/start) "nw" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "syndieshutters_workshop"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_station/start) "nx" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "syndieshutters_infirmary"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_station/start) "ny" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "syndieshutters_infirmary"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_station/start) "nz" = (/turf/space,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/syndicate_station/start) -"nA" = (/obj/structure/stool/bed/chair/comfy/black{dir = 1},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"nA" = (/obj/structure/bed/chair/comfy/black{dir = 1},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) "nB" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/blast/shutters{density = 0; dir = 4; icon_state = "shutter0"; id = "syndieshutters_workshop"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_station/start) -"nC" = (/obj/structure/closet/secure_closet/freezer/kitchen{req_access = null; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) +"nC" = (/obj/machinery/door/airlock/centcom{name = "Kitchen"; opacity = 1; req_access = list(150)},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "nD" = (/obj/structure/table/reinforced,/obj/item/weapon/tray{pixel_y = 5},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "nE" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka{pixel_x = 3; pixel_y = 12},/obj/item/weapon/reagent_containers/food/drinks/bottle/wine{pixel_x = -1; pixel_y = 8},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) -"nF" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"nF" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/obj/item/ammo_magazine/mc9mm/flash,/obj/item/weapon/gun/projectile/pistol/flash,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "nG" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/red,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/red,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "nH" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/syndicate_station/start) "nI" = (/obj/structure/table,/obj/machinery/recharger,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "nJ" = (/obj/machinery/computer/security/nuclear,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"nK" = (/obj/machinery/computer/shuttle_control/multi/syndicate{req_access_txt = "0"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"nK" = (/obj/structure/closet/secure_closet/freezer/kitchen{req_access = list(150)},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership) "nL" = (/obj/structure/computerframe,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"nM" = (/obj/structure/table,/obj/machinery/door_control{id = "syndieshutters"; name = "remote shutter control"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"nM" = (/obj/machinery/vending/cigarette{name = "hacked cigarette machine"; prices = list(); products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2)},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) "nN" = (/obj/machinery/door/blast/regular{id = "syndieshutters_telebay"; name = "Outer Airlock"},/turf/simulated/shuttle/plating,/area/syndicate_station/start) "nO" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/ionrifle,/obj/machinery/recharger/wallcharger{pixel_x = 5; pixel_y = 32},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "nP" = (/obj/structure/table/rack,/obj/item/ammo_magazine/a12mm,/obj/item/ammo_magazine/a12mm,/obj/item/ammo_magazine/a12mm,/obj/item/ammo_magazine/a12mm,/obj/item/ammo_magazine/a12mm,/obj/item/ammo_magazine/a12mm,/obj/item/weapon/gun/projectile/automatic/c20r,/obj/item/weapon/gun/projectile/automatic/c20r,/obj/item/weapon/gun/projectile/automatic/c20r,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "nQ" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -1; pixel_y = 2},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "nR" = (/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"nS" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"nS" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "nT" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/unsimulated/floor{icon_state = "floor5"},/area/syndicate_mothership) "nU" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/unsimulated/floor{icon_state = "floor5"},/area/syndicate_mothership) "nV" = (/obj/machinery/shower{pixel_y = 32},/obj/structure/window/basic{dir = 8},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "nW" = (/obj/machinery/shower{pixel_y = 32},/obj/item/weapon/soap/syndie,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) -"nX" = (/obj/structure/table/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) -"nY" = (/obj/structure/table/rack,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) +"nX" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) +"nY" = (/obj/structure/table/rack,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "nZ" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets{pixel_x = 2; pixel_y = 3},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"oa" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"oa" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "ob" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "floor5"},/area/syndicate_mothership) "oc" = (/obj/machinery/door/airlock/centcom{name = "Bathroom"; opacity = 1},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) "od" = (/obj/machinery/shower{dir = 1},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership) @@ -739,38 +739,38 @@ "ok" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "floor5"},/area/syndicate_mothership) "ol" = (/obj/machinery/door/airlock/centcom{name = "Suit Storage"; opacity = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "om" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/syndicate_station/start) -"on" = (/obj/machinery/door/window/northright{name = "Flight Deck"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"on" = (/obj/machinery/door/window/northright{name = "Flight Deck"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "oo" = (/turf/space,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/syndicate_station/start) "op" = (/obj/structure/table/rack,/obj/item/weapon/tank/jetpack/carbondioxide,/obj/item/weapon/tank/jetpack/carbondioxide,/obj/item/weapon/tank/jetpack/carbondioxide,/obj/item/weapon/tank/jetpack/carbondioxide,/obj/item/weapon/tank/jetpack/carbondioxide,/obj/item/weapon/tank/jetpack/carbondioxide,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "oq" = (/obj/structure/table/rack,/obj/item/weapon/tank/jetpack/oxygen,/obj/item/weapon/tank/jetpack/oxygen,/obj/item/weapon/tank/jetpack/oxygen,/obj/item/weapon/tank/jetpack/oxygen,/obj/item/weapon/tank/jetpack/oxygen,/obj/item/weapon/tank/jetpack/oxygen,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "or" = (/obj/structure/closet,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"os" = (/obj/effect/landmark{name = "Holocarp Spawn Random"},/turf/simulated/floor/holofloor{icon_state = "17"; dir = 5},/area/holodeck/source_space) +"os" = (/turf/simulated/floor/holofloor{dir = 4; icon_state = "carpet2-0"},/area/holodeck/source_theatre) "ot" = (/obj/structure/window/reinforced,/obj/structure/lattice,/turf/space,/area/space) "ou" = (/obj/structure/closet/hydrant{pixel_y = 32},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "ov" = (/obj/structure/table/rack,/obj/item/weapon/pinpointer/nukeop,/obj/item/weapon/pinpointer/nukeop,/obj/item/weapon/pinpointer/nukeop,/obj/item/weapon/pinpointer/nukeop,/obj/item/weapon/pinpointer/nukeop,/obj/item/weapon/pinpointer/nukeop,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy,/obj/item/weapon/shield/energy,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "ow" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/handcuffs{pixel_x = 4; pixel_y = 2},/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "ox" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) -"oy" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"oy" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "oz" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/machinery/recharger/wallcharger{pixel_x = 5; pixel_y = -32},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) -"oA" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"oA" = (/obj/structure/bed/chair{dir = 8},/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "oB" = (/obj/machinery/recharger/wallcharger{pixel_x = -25},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"oC" = (/obj/machinery/door/airlock/vault{name = "Armory"; req_access_txt = "150"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) +"oC" = (/obj/structure/closet/secure_closet/medical_wall{pixel_x = -32; pixel_y = 0; req_access = list(150)},/obj/item/stack/medical/splint,/obj/item/stack/medical/ointment,/obj/item/stack/medical/ointment,/obj/item/stack/medical/bruise_pack,/obj/item/stack/medical/bruise_pack,/obj/item/stack/medical/bruise_pack,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "oD" = (/obj/effect/landmark{name = "Syndicate-Uplink"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "oE" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/void/merc,/obj/item/clothing/mask/gas/syndicate,/obj/item/clothing/head/helmet/space/void/merc,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "oF" = (/obj/structure/lattice,/obj/structure/grille,/obj/structure/lattice,/turf/space,/area/space) -"oG" = (/obj/structure/closet/secure_closet/medical_wall{pixel_x = -32; pixel_y = 0; req_access = null; req_access_txt = "150"},/obj/item/stack/medical/splint,/obj/item/stack/medical/ointment,/obj/item/stack/medical/ointment,/obj/item/stack/medical/bruise_pack,/obj/item/stack/medical/bruise_pack,/obj/item/stack/medical/bruise_pack,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"oG" = (/obj/structure/closet,/obj/item/weapon/reagent_containers/food/snacks/liquidfood,/obj/item/weapon/reagent_containers/food/snacks/liquidfood,/obj/item/weapon/reagent_containers/food/snacks/liquidfood,/obj/item/weapon/reagent_containers/food/snacks/liquidfood,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "oH" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; freerange = 1; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 0; pixel_y = -32; subspace_transmission = 1; syndie = 1},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "oI" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/lattice,/turf/space,/area/space) "oJ" = (/obj/structure/closet/walllocker/emerglocker{pixel_x = 28},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "oK" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/utility/full,/obj/item/device/multitool,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"oL" = (/obj/structure/table/rack,/obj/item/ammo_magazine/a762,/obj/item/ammo_magazine/a762,/obj/item/ammo_magazine/a762,/obj/item/ammo_magazine/a762,/obj/item/weapon/gun/projectile/automatic/l6_saw,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"oL" = (/obj/structure/closet,/obj/item/weapon/reagent_containers/food/snacks/tastybread,/obj/item/weapon/reagent_containers/food/snacks/tastybread,/obj/item/weapon/reagent_containers/food/snacks/tastybread,/obj/item/weapon/reagent_containers/food/snacks/tastybread,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "oM" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "oN" = (/turf/unsimulated/wall,/area/centcom) "oO" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "synd_sensor"; pixel_x = 8; pixel_y = 25},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "oP" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/unsimulated/floor{icon_state = "floor5"},/area/syndicate_mothership) -"oQ" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"oR" = (/obj/structure/table/rack,/obj/item/ammo_magazine/c9mm,/obj/item/ammo_magazine/c9mm,/obj/item/ammo_magazine/c9mm,/obj/item/ammo_magazine/c9mm,/obj/item/ammo_magazine/c9mm,/obj/item/ammo_magazine/c9mm,/obj/item/ammo_magazine/c9mm,/obj/item/ammo_magazine/c9mm,/obj/item/ammo_magazine/c9mm,/obj/item/weapon/gun/projectile/automatic,/obj/item/weapon/gun/projectile/automatic,/obj/item/weapon/gun/projectile/automatic,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"oS" = (/obj/structure/table/rack,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"oQ" = (/obj/machinery/door/airlock/external{frequency = 1331; icon_state = "door_closed"; id_tag = "synd_outer"; locked = 0; name = "Ship External Access"; req_access = list(150)},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "smindicate"; name = "Outer Airlock"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"oR" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1331; id_tag = "synd_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1331; id_tag = "synd_airlock"; pixel_x = -8; pixel_y = 25; tag_airpump = "synd_pump"; tag_chamber_sensor = "synd_sensor"; tag_exterior_door = "synd_outer"; tag_interior_door = "synd_inner"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"oS" = (/obj/machinery/door/airlock/vault{name = "Armory"; req_access = list(150)},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "oT" = (/turf/unsimulated/wall{desc = "Why it no open!"; icon_state = "pdoor1"; name = "Shuttle Bay Blast Door"},/area/centcom) "oU" = (/turf/unsimulated/floor{icon_state = "warnplate"; dir = 8},/area/centcom) "oV" = (/turf/unsimulated/floor{name = "plating"},/area/centcom) @@ -779,42 +779,42 @@ "oY" = (/obj/item/device/radio/electropack,/turf/simulated/shuttle/floor{icon_state = "floor7"},/area/syndicate_station/start) "oZ" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1331; id_tag = "synd_pump"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "pa" = (/obj/machinery/vending/cola{name = "hacked Robust Softdrinks"; prices = list()},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) -"pb" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1331; id_tag = "synd_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1331; id_tag = "synd_airlock"; pixel_x = -8; pixel_y = 25; req_access_txt = "0"; tag_airpump = "synd_pump"; tag_chamber_sensor = "synd_sensor"; tag_exterior_door = "synd_outer"; tag_interior_door = "synd_inner"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"pb" = (/obj/machinery/door/window{dir = 2; name = "Seating"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "pc" = (/obj/machinery/door/airlock/centcom{name = "Hardsuit Storage"; opacity = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "pd" = (/turf/unsimulated/floor{name = "plating"},/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/administration/centcom) "pe" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/administration/centcom) -"pf" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "admin_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) +"pf" = (/obj/structure/table,/obj/machinery/computer/pod/old/syndicate{id = "smindicate"},/obj/machinery/door/window{dir = 4; name = "Blast Door Control"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "pg" = (/turf/unsimulated/floor{name = "plating"},/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/administration/centcom) "ph" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "floor5"},/area/syndicate_station/start) "pi" = (/obj/structure/toilet{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor7"},/area/syndicate_station/start) "pj" = (/obj/item/weapon/cigbutt,/turf/simulated/shuttle/floor{icon_state = "floor7"},/area/syndicate_station/start) -"pk" = (/obj/machinery/door/window{dir = 2; name = "Seating"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"pk" = (/obj/machinery/door/window{dir = 1; name = "Cell"; req_access = list(150)},/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/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "pl" = (/obj/machinery/atmospherics/pipe/manifold4w/visible,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "pm" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1331; id_tag = "synd_pump"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "pn" = (/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) -"po" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"po" = (/obj/machinery/vending/assist{contraband = null; name = "AntagCorpVend"; products = list(/obj/item/device/assembly/prox_sensor = 5, /obj/item/device/assembly/signaler = 4, /obj/item/device/assembly/infra = 4, /obj/item/device/assembly/prox_sensor = 4, /obj/item/weapon/handcuffs = 8, /obj/item/device/flash = 4, /obj/item/weapon/cartridge/signal = 4)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "pp" = (/obj/machinery/vending/boozeomat,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/administration/centcom) "pq" = (/obj/machinery/vending/coffee,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "pr" = (/obj/machinery/vending/cigarette,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "ps" = (/obj/machinery/microwave,/obj/structure/table/reinforced{icon_state = "table"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) -"pt" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "admin_shuttle"; pixel_x = -25; pixel_y = 0; req_access_txt = "0"; req_one_access_txt = "101"; tag_door = "admin_shuttle_hatch"},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) +"pt" = (/obj/machinery/door/airlock/external{frequency = 1331; icon_state = "door_closed"; id_tag = "synd_inner"; locked = 0; name = "Ship External Access"},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "pu" = (/turf/simulated/floor/plating,/area/shuttle/administration/centcom) "pv" = (/obj/item/device/multitool,/obj/item/weapon/reagent_containers/spray/cleaner,/obj/structure/table/reinforced{icon_state = "table"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "pw" = (/obj/item/weapon/storage/toolbox/mechanical,/obj/structure/table/reinforced{icon_state = "table"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) -"px" = (/obj/machinery/door/window{dir = 1; name = "Cell"; req_access_txt = "150"},/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/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"py" = (/obj/machinery/vending/assist{contraband = null; name = "AntagCorpVent"; products = list(/obj/item/device/assembly/prox_sensor = 5, /obj/item/device/assembly/signaler = 4, /obj/item/device/assembly/infra = 4, /obj/item/device/assembly/prox_sensor = 4, /obj/item/weapon/handcuffs = 8, /obj/item/device/flash = 4, /obj/item/weapon/cartridge/signal = 4)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"px" = (/obj/machinery/vending/cigarette{name = "hacked cigarette machine"; prices = list(); products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/zippo = 4, /obj/item/clothing/mask/smokable/cigarette/cigar/havana = 2)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"py" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "synd_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "pz" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/syndicate_station/start) -"pA" = (/obj/machinery/door/airlock/external{frequency = 1331; icon_state = "door_closed"; id_tag = "synd_inner"; locked = 0; name = "Ship External Access"; req_access = null; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"pA" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "admin_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) "pB" = (/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) -"pC" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access_txt = "101"},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) +"pC" = (/obj/machinery/door/window{dir = 4; name = "Brig"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "pD" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "pE" = (/obj/machinery/cell_charger,/obj/structure/table/reinforced{icon_state = "table"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "pF" = (/turf/unsimulated/wall,/area/centcom/living) -"pG" = (/obj/machinery/vending/cigarette{contraband = newlist(); premium = newlist(); prices = list(/obj/item/weapon/storage/fancy/cigarettes = 15, /obj/item/weapon/storage/box/matches = 1, /obj/item/weapon/flame/lighter/zippo = 4, /obj/item/clothing/mask/cigarette/cigar/havana = 20); products = list(/obj/item/weapon/storage/fancy/cigarettes = 10, /obj/item/weapon/storage/box/matches = 10, /obj/item/weapon/flame/lighter/zippo = 4, /obj/item/clothing/mask/cigarette/cigar/havana = 2)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"pH" = (/obj/structure/stool/bed/chair{dir = 8},/obj/machinery/flasher_button{id = "syndieflash"; name = "Flasher"; pixel_x = 27; pixel_y = 0; tag = "permflash"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"pG" = (/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor{icon_state = "carpet15-15"; dir = 4},/area/holodeck/source_courtroom) +"pH" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/button/flasher{id = "syndieflash"; name = "Flasher"; pixel_x = 27; pixel_y = 0; tag = "permflash"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "pI" = (/obj/machinery/suit_cycler/syndicate{locked = 0},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"pJ" = (/obj/structure/table,/obj/machinery/computer/pod/old/syndicate{id = "smindicate"},/obj/machinery/door/window{dir = 4; name = "Blast Door Control"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"pK" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"pJ" = (/obj/machinery/door/window{base_state = "right"; dir = 8; icon_state = "right"; name = "Preparation"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"pK" = (/obj/structure/table/rack,/obj/item/ammo_magazine/c762,/obj/item/ammo_magazine/c762,/obj/item/ammo_magazine/c762,/obj/item/ammo_magazine/c762,/obj/item/weapon/gun/projectile/automatic/sts35,/obj/item/weapon/gun/projectile/automatic/sts35,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "pL" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "pM" = (/obj/machinery/door/window/northright,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "pN" = (/obj/structure/table/reinforced{icon_state = "table"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) @@ -831,24 +831,24 @@ "pY" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor,/area/centcom/living) "pZ" = (/turf/unsimulated/wall,/area/centcom/suppy) "qa" = (/obj/structure/table,/obj/item/weapon/kitchen/utensil/knife{pixel_x = -6},/obj/item/weapon/reagent_containers/syringe/drugs{pixel_x = 3; pixel_y = -1},/obj/item/weapon/reagent_containers/syringe/drugs{pixel_x = 3; pixel_y = 4},/obj/item/weapon/reagent_containers/syringe/drugs{pixel_x = 3; pixel_y = 9},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"qb" = (/obj/machinery/door/window{dir = 4; name = "Brig"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"qc" = (/obj/machinery/door/window{base_state = "right"; dir = 8; icon_state = "right"; name = "Preparation"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"qb" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "admin_shuttle"; pixel_x = -25; pixel_y = 0; req_one_access = list(101); tag_door = "admin_shuttle_hatch"},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) +"qc" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Brig"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "qd" = (/obj/structure/closet/syndicate/suit{name = "suit closet"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "qe" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 4},/turf/space,/area/shuttle/administration/centcom) "qf" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 8},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/administration/centcom) "qg" = (/obj/machinery/vending/snack,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) -"qh" = (/obj/structure/stool,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) +"qh" = (/obj/item/weapon/stool,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "qi" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "qj" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "qk" = (/obj/machinery/recharge_station,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "ql" = (/obj/machinery/robotic_fabricator,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "qm" = (/obj/machinery/autolathe{desc = "Your typical Autolathe. It appears to have much more options than your regular one, however..."; hacked = 1; name = "Thunderdome Autolathe"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "qn" = (/obj/structure/dispenser,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) -"qo" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/living) -"qp" = (/obj/machinery/door/airlock/centcom{name = "Living Quarters"; opacity = 1; req_access_txt = "105"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/living) +"qo" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/living) +"qp" = (/obj/machinery/door/window{base_state = "left"; dir = 8; icon_state = "left"; name = "Preparation"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "qq" = (/turf/unsimulated/floor{icon_state = "redyellowfull"},/area/centcom/living) "qr" = (/obj/machinery/atm{pixel_y = 24},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/living) -"qs" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/living) +"qs" = (/obj/item/weapon/stool{pixel_y = 8},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/living) "qt" = (/obj/item/weapon/reagent_containers/food/condiment/peppermill{pixel_x = 2; pixel_y = 6},/obj/structure/table,/turf/unsimulated/floor{icon_state = "redyellowfull"},/area/centcom/living) "qu" = (/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/structure/table,/turf/unsimulated/floor{icon_state = "redyellowfull"},/area/centcom/living) "qv" = (/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/living) @@ -859,14 +859,14 @@ "qA" = (/turf/unsimulated/floor{icon_state = "warnplate"; dir = 4},/area/centcom/suppy) "qB" = (/turf/unsimulated/wall{desc = "Why it no open!"; icon_state = "pdoor1"; name = "Shuttle Bay Blast Door"},/area/centcom/suppy) "qC" = (/obj/structure/closet{name = "custodial"},/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/mop,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"qD" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Brig"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"qE" = (/obj/machinery/door/window{base_state = "left"; dir = 8; icon_state = "left"; name = "Preparation"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"qD" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/turf/simulated/floor/plating,/area/shuttle/administration/centcom) +"qE" = (/obj/structure/table,/obj/structure/closet/secure_closet/medical_wall{pixel_y = 32; req_access = list(150)},/obj/item/bodybag,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/glass/bottle/antitoxin{pixel_x = -4; pixel_y = 8},/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline{pixel_x = 4; pixel_y = 7},/obj/item/weapon/reagent_containers/syringe,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) "qF" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/syndicate{pixel_x = -1; pixel_y = 3},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "qG" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"; dir = 4},/turf/space,/area/shuttle/administration/centcom) "qH" = (/turf/unsimulated/floor{name = "plating"},/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/administration/centcom) -"qI" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "admin_shuttle_bay"; name = "shuttle bay controller"; pixel_x = 25; pixel_y = 0; req_access_txt = "0"; req_one_access_txt = "0"; tag_door = "admin_shuttle_bay_door"},/turf/unsimulated/floor{name = "plating"},/area/centcom) +"qI" = (/obj/machinery/door/airlock/centcom{name = "Living Quarters"; opacity = 1; req_access = list(105)},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/living) "qJ" = (/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/obj/structure/table,/turf/unsimulated/floor{icon_state = "redyellowfull"},/area/centcom/living) -"qK" = (/obj/structure/table,/obj/machinery/juicer{pixel_y = 6},/turf/unsimulated/floor{icon_state = "redyellowfull"},/area/centcom/living) +"qK" = (/obj/machinery/suit_cycler/syndicate{locked = 0},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "qL" = (/obj/machinery/door/airlock/external,/turf/unsimulated/floor{name = "plating"},/area/centcom/living) "qM" = (/turf/unsimulated/floor{name = "plating"},/area/centcom/living) "qN" = (/turf/unsimulated/wall{desc = "Why it no open!"; icon_state = "pdoor1"; name = "Shuttle Bay Blast Door"},/area/centcom/living) @@ -884,13 +884,13 @@ "qZ" = (/obj/machinery/sleeper,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) "ra" = (/obj/machinery/sleep_console,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) "rb" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 4; start_pressure = 740.5},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"rc" = (/obj/structure/table,/obj/item/roller{pixel_y = 8},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) -"rd" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "synd_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"rc" = (/obj/structure/table/rack,/obj/item/clothing/suit/storage/vest/heavy/merc{pixel_x = 2; pixel_y = 2},/obj/item/clothing/suit/storage/vest/heavy/merc{pixel_x = -2; pixel_y = -2},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) +"rd" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "admin_shuttle_bay"; name = "shuttle bay controller"; pixel_x = 25; pixel_y = 0; tag_door = "admin_shuttle_bay_door"},/turf/unsimulated/floor{name = "plating"},/area/centcom) "re" = (/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/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "rf" = (/obj/structure/table,/obj/item/clothing/gloves/yellow,/obj/item/device/assembly/signaler{pixel_y = 2},/obj/item/clothing/glasses/night,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "rg" = (/obj/structure/table,/obj/item/clothing/gloves/yellow,/obj/item/device/assembly/prox_sensor{pixel_x = -8; pixel_y = 4},/obj/item/clothing/glasses/night,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"rh" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) -"ri" = (/obj/machinery/vending/cigarette{name = "hacked cigarette machine"; prices = list()},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) +"rh" = (/obj/structure/bed/chair/comfy/black{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) +"ri" = (/obj/machinery/door/window{dir = 4; name = "Infirmary"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) "rj" = (/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) "rk" = (/obj/structure/table,/obj/item/weapon/screwdriver,/obj/effect/spawner/newbomb/timer/syndicate,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "rl" = (/obj/machinery/vending/snack{name = "hacked Getmore Chocolate Corp"; prices = list()},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership) @@ -898,23 +898,23 @@ "rn" = (/obj/machinery/computer/cloning,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) "ro" = (/obj/machinery/clonepod,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) "rp" = (/obj/machinery/computer/scan_consolenew,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) -"rq" = (/obj/machinery/computer/shuttle_control{req_access = null; req_access_txt = "101"; shuttle_tag = "Administration"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) +"rq" = (/obj/machinery/door/window/westright{name = "Tool Storage"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "rr" = (/obj/structure/device/piano{dir = 4},/turf/unsimulated/floor{icon_state = "redyellowfull"},/area/centcom/living) -"rs" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{icon_state = "redyellowfull"},/area/centcom/living) -"rt" = (/obj/structure/closet/secure_closet/bar{req_access_txt = "25"},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/living) +"rs" = (/obj/item/weapon/stool{pixel_y = 8},/turf/unsimulated/floor{icon_state = "redyellowfull"},/area/centcom/living) +"rt" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Infirmary"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) "ru" = (/obj/structure/reagent_dispensers/beerkeg,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/living) "rv" = (/obj/machinery/vending/boozeomat,/turf/unsimulated/wall,/area/centcom/living) "rw" = (/obj/structure/kitchenspike,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/living) "rx" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/living) "ry" = (/obj/machinery/gibber,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/living) "rz" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/turf/simulated/shuttle/floor,/area/supply/dock) -"rA" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "supply_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/plating,/area/supply/dock) +"rA" = (/obj/machinery/door/window{dir = 8; name = "Tool Storage"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "rB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_station/start) "rC" = (/obj/machinery/bodyscanner,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) "rD" = (/obj/machinery/body_scanconsole,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) -"rE" = (/obj/machinery/door/window{dir = 4; name = "Infirmary"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) -"rF" = (/obj/machinery/door/window/westright{name = "Tool Storage"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"rG" = (/obj/structure/stool{pixel_y = 8},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"rE" = (/obj/machinery/door_control{id = "syndieshutters_infirmary"; name = "remote shutter control"; pixel_x = -25},/obj/structure/mopbucket,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) +"rF" = (/obj/machinery/door/window{dir = 1; name = "Secure Storage"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"rG" = (/obj/item/weapon/stool{pixel_y = 8},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "rH" = (/obj/structure/table,/obj/effect/spawner/newbomb/timer/syndicate,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "rI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_station/start) "rJ" = (/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) @@ -922,41 +922,41 @@ "rL" = (/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/living) "rM" = (/obj/structure/closet/secure_closet/freezer/meat,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/living) "rN" = (/obj/machinery/chem_master/condimaster{name = "CondiMaster Neo"; pixel_x = -5},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/living) -"rO" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "supply_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/floor,/area/supply/dock) +"rO" = (/obj/machinery/door_control{id = "syndieshutters_telebay"; name = "remote shutter control"; pixel_x = 0; pixel_y = -25; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "rP" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/shutters{density = 0; icon_state = "shutter0"; id = "syndieshutters"; name = "Blast Shutters"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_station/start) -"rQ" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Infirmary"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) -"rR" = (/obj/machinery/door/window{dir = 8; name = "Tool Storage"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"rQ" = (/obj/machinery/door_control{id = "syndieshutters_workshop"; name = "remote shutter control"; pixel_x = 25},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"rR" = (/obj/machinery/computer/shuttle_control{req_access = list(101); shuttle_tag = "Administration"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "rS" = (/obj/structure/table,/obj/item/device/aicard,/obj/effect/spawner/newbomb/timer/syndicate,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"rT" = (/obj/machinery/door/airlock/external{frequency = 1331; icon_state = "door_closed"; id_tag = "synd_outer"; locked = 0; name = "Ship External Access"; req_access = null; req_access_txt = "150"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "smindicate"; name = "Outer Airlock"; opacity = 0},/turf/simulated/shuttle/plating,/area/syndicate_station/start) +"rT" = (/obj/structure/closet/secure_closet/bar{req_access = list(25)},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/living) "rU" = (/obj/machinery/optable,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) "rV" = (/obj/structure/table/reinforced,/obj/machinery/librarycomp,/turf/simulated/floor{dir = 1; icon_state = "chapel"},/area/shuttle/administration/centcom) "rW" = (/obj/structure/bookcase,/turf/simulated/floor{dir = 4; icon_state = "chapel"},/area/shuttle/administration/centcom) "rX" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/shaker,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/living) "rY" = (/obj/structure/table,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/living) -"rZ" = (/obj/machinery/door/airlock/centcom{name = "Living Quarters"; opacity = 1; req_access_txt = "105"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/living) -"sa" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "supply_shuttle"; pixel_x = 25; pixel_y = 0; req_access_txt = "0"; req_one_access_txt = "13;31"; tag_door = "supply_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/supply/dock) -"sb" = (/obj/machinery/door_control{id = "syndieshutters_infirmary"; name = "remote shutter control"; pixel_x = -25; req_access_txt = "0"},/obj/structure/mopbucket,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) +"rZ" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "supply_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/plating,/area/supply/dock) +"sa" = (/obj/machinery/door/window{dir = 1; name = "Surgery"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) +"sb" = (/obj/machinery/telecomms/allinone{intercept = 1},/obj/machinery/door/window/northright{name = "Telecoms Mainframe"; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "sc" = (/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/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) -"sd" = (/obj/machinery/door/window{dir = 1; name = "Secure Storage"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"sd" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "supply_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/supply/dock) "se" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/structure/sign/nosmoking_1{pixel_y = 32},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) -"sf" = (/obj/machinery/door_control{id = "syndieshutters_workshop"; name = "remote shutter control"; pixel_x = 25; req_access_txt = "0"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"sf" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/syringe,/obj/item/clothing/mask/surgical,/obj/item/clothing/gloves/latex,/obj/item/weapon/surgicaldrill,/obj/structure/closet/secure_closet/medical_wall{pixel_x = 32; pixel_y = 0; req_access = null; req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) "sg" = (/obj/machinery/door/window/northright{icon_state = "right"; dir = 2},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) "sh" = (/obj/structure/table,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) "si" = (/obj/structure/table,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom) "sj" = (/turf/simulated/floor{dir = 8; icon_state = "chapel"},/area/shuttle/administration/centcom) "sk" = (/turf/simulated/floor{icon_state = "chapel"},/area/shuttle/administration/centcom) -"sl" = (/obj/machinery/door/airlock/centcom{name = "Commander Quarters"; opacity = 1; req_access_txt = "109"},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/living) +"sl" = (/obj/structure/closet/secure_closet/medical_wall{pixel_y = 0; req_access = list(150)},/obj/item/weapon/surgicaldrill,/obj/item/clothing/gloves/latex,/obj/item/clothing/mask/surgical,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/syringe,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/syndicate_station/start) "sm" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/living) -"sn" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/living) -"so" = (/obj/structure/table,/obj/machinery/processor{pixel_x = 0; pixel_y = 10},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/living) +"sn" = (/obj/item/weapon/stool{pixel_y = 8},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/living) +"so" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/meter,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "sp" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/table,/obj/item/weapon/bonesetter,/obj/item/weapon/bonegel,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) -"sq" = (/obj/machinery/door/window{dir = 1; name = "Surgery"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) -"sr" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) +"sq" = (/obj/machinery/door/airlock/centcom{name = "Living Quarters"; opacity = 1; req_access = list(105)},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/centcom/living) +"sr" = (/obj/structure/table,/obj/item/roller{pixel_y = 8},/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) "ss" = (/obj/structure/table,/obj/structure/window/reinforced{dir = 8},/obj/item/weapon/storage/firstaid/toxin{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/adv{pixel_x = 1},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) "st" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/firstaid/fire{pixel_x = 1},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) "su" = (/obj/item/weapon/weldingtool,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"sv" = (/obj/structure/table,/obj/structure/closet/secure_closet/medical_wall{pixel_y = 32; req_access = null; req_access_txt = "150"},/obj/item/bodybag,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/glass/bottle/antitoxin{pixel_x = -4; pixel_y = 8},/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline{pixel_x = 4; pixel_y = 7},/obj/item/weapon/reagent_containers/syringe,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) -"sw" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/ionrifle,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"sv" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "supply_shuttle"; pixel_x = 25; pixel_y = 0; req_one_access = list(13,31); tag_door = "supply_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/supply/dock) +"sw" = (/obj/machinery/door/airlock/centcom{name = "Commander Quarters"; opacity = 1; req_access = list(109)},/turf/unsimulated/floor{icon_state = "bar"; dir = 2},/area/centcom/living) "sx" = (/obj/structure/table,/turf/unsimulated/floor{dir = 9; icon_state = "carpetside"},/area/centcom/living) "sy" = (/turf/unsimulated/floor{dir = 1; icon_state = "carpetside"},/area/centcom/living) "sz" = (/obj/machinery/sleeper,/turf/unsimulated/floor{dir = 5; icon_state = "carpetside"},/area/centcom/living) @@ -965,16 +965,16 @@ "sC" = (/obj/machinery/computer/card/centcom,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/living) "sD" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/kitchen/rollingpin,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/living) "sE" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/turf/simulated/shuttle/floor,/area/supply/dock) -"sF" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "supply_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/plating,/area/supply/dock) +"sF" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "supply_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/plating,/area/supply/dock) "sG" = (/obj/structure/table,/obj/item/weapon/scalpel,/obj/item/weapon/circular_saw{pixel_y = 8},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) -"sH" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) -"sI" = (/obj/machinery/door_control{id = "syndieshutters_telebay"; name = "remote shutter control"; pixel_x = 0; pixel_y = -25; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) +"sH" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/iv_drip,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start) +"sI" = (/obj/machinery/chemical_dispenser/full,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) "sJ" = (/obj/effect/landmark{name = "Nuclear-Bomb"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "sK" = (/obj/item/weapon/crowbar,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "sL" = (/obj/machinery/vending/medical,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) "sM" = (/obj/machinery/chem_master,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) -"sN" = (/obj/machinery/chem_dispenser,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/administration/centcom) -"sO" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/turf/unsimulated/floor{dir = 10; icon_state = "carpetside"},/area/centcom/living) +"sN" = (/obj/machinery/door/airlock/centcom{name = "Living Quarters"; opacity = 1; req_access = list(105)},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/living) +"sO" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/unsimulated/floor{dir = 10; icon_state = "carpetside"},/area/centcom/living) "sP" = (/turf/unsimulated/floor{dir = 2; icon_state = "carpetside"},/area/centcom/living) "sQ" = (/turf/unsimulated/floor{dir = 6; icon_state = "carpetside"},/area/centcom/living) "sR" = (/turf/unsimulated/floor{dir = 2; icon_state = "carpetsymbol"},/area/centcom/living) @@ -1002,7 +1002,7 @@ "tn" = (/obj/structure/shuttle/engine/propulsion,/turf/space,/area/syndicate_station/start) "to" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_r"},/turf/space,/area/syndicate_station/start) "tp" = (/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/living) -"tq" = (/obj/machinery/door/airlock/centcom{name = "Living Quarters"; opacity = 1; req_access_txt = "105"},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/living) +"tq" = (/obj/structure/table/rack,/obj/item/ammo_magazine/a762,/obj/item/ammo_magazine/a762,/obj/item/ammo_magazine/a762,/obj/item/ammo_magazine/a762,/obj/item/weapon/gun/projectile/automatic/l6_saw,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "tr" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/supply/dock) "ts" = (/turf/simulated/shuttle/wall{icon_state = "swall15"; dir = 2},/area/supply/dock) "tt" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/shuttle/engine/heater,/turf/simulated/floor/plating/airless,/area/supply/dock) @@ -1015,17 +1015,17 @@ "tA" = (/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"},/turf/space,/area/supply/dock) "tB" = (/obj/structure/shuttle/engine/propulsion,/turf/space,/area/supply/dock) "tC" = (/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"},/turf/space,/area/supply/dock) -"tD" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/emps,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"tE" = (/obj/machinery/shieldgen,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"tF" = (/obj/machinery/shield_gen,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"tG" = (/obj/machinery/shield_capacitor,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"tH" = (/obj/machinery/shieldwallgen,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"tI" = (/obj/structure/stool/bed,/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) +"tD" = (/obj/structure/table/rack,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/obj/item/weapon/plastique,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"tE" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/ionrifle,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"tF" = (/obj/structure/table/rack,/obj/item/ammo_magazine/mc9mmt,/obj/item/ammo_magazine/mc9mmt,/obj/item/ammo_magazine/mc9mmt,/obj/item/ammo_magazine/mc9mmt,/obj/item/ammo_magazine/mc9mmt,/obj/item/ammo_magazine/mc9mmt,/obj/item/ammo_magazine/mc9mmt,/obj/item/ammo_magazine/mc9mmt,/obj/item/ammo_magazine/mc9mmt,/obj/item/ammo_magazine/mc9mmt/rubber,/obj/item/ammo_magazine/mc9mmt/rubber,/obj/item/ammo_magazine/mc9mmt/rubber,/obj/item/ammo_magazine/mc9mmt/rubber,/obj/item/ammo_magazine/mc9mmt/rubber,/obj/item/ammo_magazine/mc9mmt/rubber,/obj/item/weapon/gun/projectile/automatic/wt550,/obj/item/weapon/gun/projectile/automatic/wt550,/obj/item/weapon/gun/projectile/automatic/wt550,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"tG" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/storage/box/emps,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/grenade/smokebomb,/obj/item/weapon/gun/launcher/grenade,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"tH" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/obj/item/weapon/gun/energy/gun,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"tI" = (/obj/structure/bed,/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) "tJ" = (/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) "tK" = (/obj/effect/decal/cleanable/cobweb2,/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) -"tL" = (/obj/structure/stool/bed,/turf/unsimulated/floor{icon_state = "floorscorched2"},/area/prison/solitary) +"tL" = (/obj/structure/bed,/turf/unsimulated/floor{icon_state = "floorscorched2"},/area/prison/solitary) "tM" = (/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) -"tN" = (/turf/space,/area/centcom/control) +"tN" = (/obj/structure/table/rack,/obj/item/ammo_magazine/a556,/obj/item/ammo_magazine/a556,/obj/item/ammo_magazine/a556,/obj/item/ammo_magazine/a556,/obj/item/ammo_magazine/a556,/obj/item/ammo_magazine/a556,/obj/item/weapon/gun/projectile/automatic/z8,/obj/item/weapon/gun/projectile/automatic/z8,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "tO" = (/obj/machinery/telecomms/receiver/preset_cent,/turf/unsimulated/floor{icon_state = "green"; dir = 9},/area/centcom/control) "tP" = (/obj/machinery/telecomms/bus/preset_cent,/turf/unsimulated/floor{icon_state = "green"; dir = 1},/area/centcom/control) "tQ" = (/obj/machinery/telecomms/processor/preset_cent,/turf/unsimulated/floor{icon_state = "green"; dir = 1},/area/centcom/control) @@ -1036,9 +1036,9 @@ "tV" = (/obj/machinery/teleport/hub,/turf/unsimulated/floor{icon_state = "engine"},/area/centcom/control) "tW" = (/turf/unsimulated/floor{icon_state = "engine"},/area/centcom/control) "tX" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "CentComPort"; name = "Security Doors"; opacity = 0},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"tY" = (/obj/machinery/shieldgen,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"tZ" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"ua" = (/obj/machinery/power/emitter,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"tY" = (/obj/machinery/vending/assist,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"tZ" = (/obj/machinery/shieldgen,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"ua" = (/obj/machinery/shield_capacitor,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "ub" = (/obj/effect/landmark{name = "prisonwarp"},/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) "uc" = (/turf/unsimulated/floor{icon_state = "panelscorched"},/area/prison/solitary) "ud" = (/turf/unsimulated/floor{icon_state = "platingdmg3"},/area/prison/solitary) @@ -1046,13 +1046,13 @@ "uf" = (/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "ug" = (/turf/unsimulated/wall,/area/centcom/test) "uh" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"ui" = (/obj/structure/table/rack,/obj/item/weapon/gun/grenadelauncher,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"uj" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"ui" = (/obj/machinery/shield_gen,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"uj" = (/obj/machinery/portable_atmospherics/canister/air,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "uk" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/suit/armor/vest/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/clothing/head/helmet/ert/security,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/obj/item/weapon/storage/backpack/ert/security,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"ul" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/security,/obj/item/clothing/tie/storage/black_vest,/obj/item/weapon/rig/ert/security,/obj/item/clothing/tie/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"um" = (/obj/structure/table/rack,/obj/item/rig_module/mounted,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"un" = (/obj/structure/table/reinforced,/obj/item/weapon/circuitboard/aiupload,/obj/item/weapon/circuitboard/borgupload,/obj/item/weapon/circuitboard/smes,/obj/item/weapon/aiModule/nanotrasen,/obj/item/weapon/aiModule/reset,/obj/item/weapon/aiModule/freeformcore,/obj/item/weapon/aiModule/protectStation,/obj/item/weapon/aiModule/quarantine,/obj/item/weapon/aiModule/paladin,/obj/item/weapon/aiModule/robocop,/obj/item/weapon/aiModule/safeguard,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"uo" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) +"ul" = (/obj/machinery/shieldwallgen,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"um" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/creed) +"un" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/unsimulated/floor{name = "plating"},/area/centcom/control) +"uo" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "up" = (/obj/structure/table,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "uq" = (/obj/structure/closet/secure_closet/security,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "ur" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) @@ -1062,11 +1062,11 @@ "uv" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; listening = 0; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "uw" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 9},/area/centcom/specops) "ux" = (/obj/machinery/door/blast/regular{id = "CentComPort"; name = "Security Doors"},/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control) -"uy" = (/obj/structure/table/rack,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) -"uz" = (/obj/structure/table/reinforced,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/plasteel{amount = 50},/obj/item/stack/sheet/plasteel{amount = 50},/obj/item/stack/sheet/plasteel{amount = 50},/obj/item/stack/sheet/plasteel{amount = 50},/obj/item/stack/sheet/glass/reinforced{amount = 50},/obj/item/stack/sheet/glass/reinforced{amount = 50},/obj/item/stack/sheet/glass/reinforced{amount = 50},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) -"uA" = (/obj/machinery/pipedispenser/disposal/orderable,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"uB" = (/obj/structure/stool/bed,/turf/unsimulated/floor{icon_state = "panelscorched"},/area/prison/solitary) -"uC" = (/obj/structure/stool/bed,/obj/effect/decal/cleanable/cobweb,/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) +"uy" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"uz" = (/obj/machinery/vending/tool,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"uA" = (/obj/structure/table/woodentable{dir = 10},/obj/machinery/door_control{name = "Spec Ops Ready Room"; desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; pixel_y = 15; req_access = list(11); id = "CREED"},/obj/machinery/door_control{name = "Mech Storage"; desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; pixel_y = 0; req_access = list(11); id = "ASSAULT"},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) +"uB" = (/obj/structure/bed,/turf/unsimulated/floor{icon_state = "panelscorched"},/area/prison/solitary) +"uC" = (/obj/structure/bed,/obj/effect/decal/cleanable/cobweb,/turf/unsimulated/floor{name = "plating"},/area/prison/solitary) "uD" = (/turf/unsimulated/floor{icon_state = "green"; dir = 10},/area/centcom/control) "uE" = (/obj/machinery/telecomms/broadcaster/preset_cent,/turf/unsimulated/floor{icon_state = "green"},/area/centcom/control) "uF" = (/obj/machinery/telecomms/hub/preset_cent,/turf/unsimulated/floor{icon_state = "green"},/area/centcom/control) @@ -1080,7 +1080,7 @@ "uN" = (/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "uO" = (/obj/machinery/door/airlock/centcom{name = "Courthouse"; opacity = 1},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "uP" = (/obj/structure/table/woodentable,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) -"uQ" = (/obj/structure/stool/bed/chair,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) +"uQ" = (/obj/structure/bed/chair,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "uR" = (/obj/structure/table/woodentable,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "uS" = (/obj/structure/table/woodentable,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "uT" = (/obj/machinery/door/window/northleft,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) @@ -1093,49 +1093,49 @@ "va" = (/turf/unsimulated/floor{icon_state = "loadingarea"; dir = 8},/area/centcom/specops) "vb" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "vc" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/weapon/energy/ion,/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser,/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster,/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"vd" = (/obj/structure/table/rack,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/tie/holster/waist,/obj/item/clothing/tie/holster/waist,/obj/item/clothing/tie/holster/waist,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"ve" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"vf" = (/obj/structure/table/reinforced,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/flash,/obj/item/device/flash,/obj/item/weapon/rcd,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) -"vg" = (/obj/machinery/pipedispenser/orderable,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"vd" = (/obj/structure/table/rack,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/head/beret/centcom/officer,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/mask/balaclava,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/obj/item/clothing/accessory/holster/waist,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"ve" = (/obj/machinery/door/airlock/centcom{name = "Creed's Office"; opacity = 1; req_access = list(108)},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/creed) +"vf" = (/obj/machinery/door/airlock/centcom{name = "Maintenance Access"; opacity = 1; req_access = list(106)},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) +"vg" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT"; name = "Assault Armor Storage"; p_open = 0},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) "vh" = (/obj/effect/decal/cleanable/blood,/turf/unsimulated/wall,/area/prison/solitary) "vi" = (/turf/unsimulated/floor{icon_state = "platingdmg1"},/area/prison/solitary) "vj" = (/turf/unsimulated/floor{icon_state = "floorscorched2"},/area/prison/solitary) -"vk" = (/obj/machinery/door/airlock/centcom{name = "Maintenance Access"; opacity = 1; req_access_txt = "106"},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/control) +"vk" = (/obj/machinery/vending/engivend,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "vl" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "vm" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "vn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "vo" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) -"vp" = (/obj/machinery/door/airlock/centcom{name = "Teleporter Bay"; opacity = 1; req_access_txt = "107"},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/control) +"vp" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) "vq" = (/turf/unsimulated/floor{icon_state = "white"},/area/centcom/test) -"vr" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/test) -"vs" = (/obj/machinery/door/window/northleft,/obj/structure/stool/bed/chair,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) +"vr" = (/obj/structure/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/test) +"vs" = (/obj/machinery/door/window/northleft,/obj/structure/bed/chair,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "vt" = (/obj/structure/table/woodentable,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "vu" = (/obj/structure/table/woodentable,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "vv" = (/obj/structure/table/woodentable,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) -"vw" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) +"vw" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "vx" = (/obj/structure/table/reinforced,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/obj/item/device/flash,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/storage/belt/security/tactical,/obj/item/weapon/storage/belt/security/tactical,/obj/item/weapon/storage/belt/security/tactical,/obj/item/weapon/storage/belt/security/tactical,/obj/item/taperoll/police,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"vy" = (/obj/machinery/vending/security,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"vz" = (/obj/structure/table/reinforced,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/taperoll/engineering,/obj/item/clothing/glasses/welding/superior,/obj/item/clothing/glasses/welding/superior,/obj/item/clothing/glasses/welding/superior,/obj/item/clothing/glasses/welding/superior,/obj/item/clothing/glasses/welding/superior,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) -"vA" = (/obj/machinery/vending/assist,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"vy" = (/obj/machinery/vending/security,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"vz" = (/obj/machinery/vending/engineering,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"vA" = (/obj/machinery/pipedispenser/disposal/orderable,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "vB" = (/turf/unsimulated/floor{icon_state = "greencorner"},/area/centcom/control) "vC" = (/turf/unsimulated/floor{icon_state = "green"},/area/centcom/control) "vD" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 8},/area/centcom/control) -"vE" = (/obj/machinery/door/airlock/centcom{name = "Research Facility"; opacity = 1; req_access_txt = "104"},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/test) +"vE" = (/obj/machinery/pipedispenser/orderable,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "vF" = (/obj/structure/closet/secure_closet/courtroom,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "vG" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "vH" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 1},/obj/machinery/camera{c_tag = "Court"; invisibility = 1; network = list("thunder"); pixel_x = 10},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "vI" = (/obj/mecha/medical/odysseus/loaded,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom/specops) "vJ" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/tool/sleeper,/obj/item/mecha_parts/mecha_equipment/tool/sleeper,/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"vK" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/engineer,/obj/item/clothing/tie/storage/brown_vest,/obj/item/weapon/rig/ert/engineer,/obj/item/clothing/tie/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"vK" = (/obj/machinery/power/emitter,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "vL" = (/obj/structure/sign/poster{poster_type = "/datum/poster/bay_50"; pixel_x = -32},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"vM" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"vN" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/tie/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"vO" = (/obj/machinery/vending/tool,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"vP" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/command,/obj/item/clothing/head/helmet/ert/command,/obj/item/weapon/storage/backpack/ert/commander,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"vQ" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) -"vR" = (/obj/structure/closet{icon_closed = "syndicate1"; icon_opened = "syndicate1open"; icon_state = "syndicate1"; name = "emergency response team wardrobe"},/obj/item/clothing/under/ert,/obj/item/clothing/under/syndicate/combat,/obj/item/clothing/under/rank/centcom_officer,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"vS" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/obj/item/weapon/handcuffs,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) -"vT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) +"vM" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"vN" = (/obj/structure/table/reinforced,/obj/item/weapon/circuitboard/aiupload,/obj/item/weapon/circuitboard/borgupload,/obj/item/weapon/circuitboard/smes,/obj/item/weapon/aiModule/nanotrasen,/obj/item/weapon/aiModule/reset,/obj/item/weapon/aiModule/freeformcore,/obj/item/weapon/aiModule/protectStation,/obj/item/weapon/aiModule/quarantine,/obj/item/weapon/aiModule/paladin,/obj/item/weapon/aiModule/robocop,/obj/item/weapon/aiModule/safeguard,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"vO" = (/obj/machinery/door/airlock/centcom{name = "Maintenance Access"; opacity = 1; req_access = list(106)},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/control) +"vP" = (/obj/machinery/door/airlock/centcom{name = "Teleporter Bay"; opacity = 1; req_access = list(107)},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/control) +"vQ" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/handcuffs,/obj/item/clothing/glasses/night{pixel_x = -1; pixel_y = -3},/obj/item/clothing/glasses/night{pixel_x = -1; pixel_y = -3},/obj/item/clothing/glasses/night{pixel_x = -1; pixel_y = -3},/obj/item/clothing/glasses/night,/obj/item/weapon/storage/box/handcuffs,/obj/item/clothing/glasses/sunglasses/sechud/tactical,/obj/item/clothing/glasses/sunglasses/sechud/tactical,/obj/item/clothing/glasses/sunglasses/sechud/tactical,/obj/item/clothing/glasses/sunglasses/sechud/tactical,/obj/item/clothing/glasses/sunglasses/sechud/tactical,/obj/item/clothing/glasses/sunglasses/sechud/tactical,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"vR" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/security,/obj/item/clothing/accessory/storage/black_vest,/obj/item/weapon/rig/ert/security,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"vS" = (/obj/structure/table/rack,/obj/item/rig_module/mounted,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"vT" = (/obj/structure/table/reinforced,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/plasteel{amount = 50},/obj/item/stack/sheet/plasteel{amount = 50},/obj/item/stack/sheet/plasteel{amount = 50},/obj/item/stack/sheet/plasteel{amount = 50},/obj/item/stack/sheet/glass/reinforced{amount = 50},/obj/item/stack/sheet/glass/reinforced{amount = 50},/obj/item/stack/sheet/glass/reinforced{amount = 50},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "vU" = (/obj/structure/sign/securearea{name = "\improper CAUTION"; pixel_x = 32},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) "vV" = (/turf/unsimulated/floor{icon_state = "green"; dir = 4},/area/centcom/control) "vW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) @@ -1146,33 +1146,33 @@ "wb" = (/obj/structure/closet/secure_closet/medical2{pixel_x = 5},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/test) "wc" = (/obj/machinery/sleeper,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/test) "wd" = (/obj/machinery/sleep_console,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/test) -"we" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) +"we" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "wf" = (/obj/structure/table/woodentable,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "wg" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/turf/space,/area/space) -"wh" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT1"; name = "Launch Bay #1"; p_open = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom) +"wh" = (/obj/machinery/porta_turret{anchored = 0; check_records = 0; enabled = 0; req_one_access = list(103); use_power = 0},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "wi" = (/obj/machinery/mass_driver{dir = 8; id = "ASSAULT2"; name = "gravpult"},/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/specops) "wj" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/teleporter,/obj/item/mecha_parts/mecha_tracking,/obj/item/mecha_parts/mecha_tracking,/obj/item/mecha_parts/mecha_tracking,/obj/item/mecha_parts/mecha_tracking,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"wk" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/tie/storage/black_vest,/obj/item/weapon/rig/ert,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"wl" = (/obj/machinery/vending/engivend,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"wk" = (/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor{icon_state = "carpet9-4"; dir = 4},/area/holodeck/source_courtroom) +"wl" = (/obj/machinery/portable_atmospherics/powered/pump/filled,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "wm" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) -"wn" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 9},/area/centcom) -"wo" = (/obj/machinery/door/airlock/centcom{name = "Special Operations"; opacity = 1; req_access_txt = "103"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"wp" = (/obj/effect/landmark{name = "Response Team"},/obj/effect/landmark{name = "Commando"},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"wq" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) +"wn" = (/obj/structure/table/reinforced,/obj/item/weapon/cell/high,/obj/item/weapon/cell/high,/obj/item/weapon/cell/high,/obj/item/weapon/cell/high,/obj/item/weapon/cell/high,/obj/item/weapon/cell/high,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"wo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) +"wp" = (/obj/machinery/cell_charger,/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"wq" = (/obj/structure/table/reinforced,/obj/item/weapon/crowbar,/obj/item/weapon/screwdriver,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "wr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "ws" = (/obj/structure/table/reinforced,/obj/machinery/recharger{pixel_y = 4},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "wt" = (/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "wu" = (/mob/living/silicon/decoy{name = "A.L.I.C.E."},/turf/unsimulated/floor{icon_state = "whiteshiny"},/area/centcom/control) "wv" = (/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"ww" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) +"ww" = (/obj/structure/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "wx" = (/obj/mecha/working/ripley/firefighter,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom/specops) "wy" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/tool/extinguisher,/obj/item/mecha_parts/mecha_equipment/tool/rcd,/obj/item/weapon/pickaxe/diamonddrill,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"wz" = (/obj/structure/table/reinforced,/obj/item/device/megaphone,/obj/item/clothing/glasses/sunglasses/sechud,/obj/item/weapon/storage/box/trackimp,/obj/item/weapon/storage/box/cdeathalarm_kit,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"wA" = (/obj/structure/table/reinforced,/obj/item/device/aicard,/obj/item/weapon/pinpointer/advpinpointer,/obj/item/weapon/stamp/centcomm,/turf/unsimulated/floor{icon_state = "blue"},/area/centcom) -"wB" = (/obj/structure/table/reinforced,/obj/item/device/pda/ert,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) +"wz" = (/obj/structure/table/reinforced,/obj/item/weapon/crowbar,/obj/item/weapon/screwdriver,/obj/item/weapon/wrench,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"wA" = (/obj/machinery/door/airlock/centcom{name = "Research Facility"; opacity = 1; req_access = list(104)},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/test) +"wB" = (/obj/structure/table/reinforced,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/device/flash,/obj/item/device/flash,/obj/item/weapon/rcd,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "wC" = (/obj/structure/table/reinforced,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/obj/item/clothing/mask/gas,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"wD" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/medical,/obj/item/clothing/tie/storage/black_vest,/obj/item/weapon/rig/ert/medical,/obj/item/clothing/tie/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"wE" = (/obj/machinery/vending/engineering,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"wD" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/medical,/obj/item/clothing/accessory/storage/black_vest,/obj/item/weapon/rig/ert/medical,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"wE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom) "wF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) "wG" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) "wH" = (/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) @@ -1181,63 +1181,63 @@ "wK" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 4},/area/centcom/control) "wL" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "wM" = (/obj/machinery/computer/ordercomp,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"wN" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"wN" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "wO" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1443; listening = 0; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"wP" = (/obj/machinery/door/window{dir = 2; name = "AI Core Door"; req_access_txt = "109"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"wP" = (/obj/machinery/recharge_station,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "wQ" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"wR" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"wR" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "wS" = (/obj/machinery/computer/crew,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "wT" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 1},/area/centcom/control) -"wU" = (/obj/structure/stool/bed/chair,/turf/unsimulated/floor{dir = 2; icon_state = "carpetside"},/area/centcom/control) -"wV" = (/obj/effect/landmark{name = "Marauder Exit"},/turf/unsimulated/floor{name = "plating"},/area/centcom) +"wU" = (/obj/structure/bed/chair,/turf/unsimulated/floor{dir = 2; icon_state = "carpetside"},/area/centcom/control) +"wV" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/handcuffs,/obj/item/device/flash,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/storage/belt/security/tactical,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/clothing/glasses/sunglasses/sechud/tactical,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "wW" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT2"; name = "Launch Bay #2"; p_open = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) -"wX" = (/obj/machinery/mass_driver{dir = 8; id = "ASSAULT1"; name = "gravpult"},/turf/unsimulated/floor{icon_state = "bot"},/area/centcom) -"wY" = (/turf/unsimulated/floor{icon_state = "loadingarea"; dir = 8},/area/centcom) -"wZ" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill,/obj/item/mecha_parts/mecha_equipment/tool/cable_layer,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"xa" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/device/flash,/obj/item/device/flash,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"xb" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/hand_tele,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"xc" = (/obj/machinery/door/airlock/centcom{name = "Armory Special Operations"; opacity = 1; req_access_txt = "103"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"xd" = (/obj/machinery/door/airlock/centcom{name = "Engineering Special Operations"; opacity = 1; req_access_txt = "103"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"xe" = (/obj/machinery/porta_turret{anchored = 0; check_records = 0; on = 0; req_one_access = list(103); req_one_access_txt = "103"; use_power = 0},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"wX" = (/obj/structure/table/reinforced,/obj/item/device/aicard,/obj/item/weapon/pinpointer/advpinpointer,/obj/item/weapon/stamp/centcomm,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"wY" = (/obj/structure/table/reinforced,/obj/item/device/megaphone,/obj/item/weapon/storage/box/trackimp,/obj/item/weapon/storage/box/cdeathalarm_kit,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"wZ" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/hand_tele,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xa" = (/obj/structure/table/reinforced,/obj/item/device/pda/ert,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xb" = (/obj/structure/table/reinforced,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/clothing/glasses/meson,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/taperoll/engineering,/obj/item/clothing/glasses/welding/superior,/obj/item/clothing/glasses/welding/superior,/obj/item/clothing/glasses/welding/superior,/obj/item/clothing/glasses/welding/superior,/obj/item/clothing/glasses/welding/superior,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xc" = (/obj/machinery/door/airlock/centcom{name = "Special Operations"; opacity = 1; req_access = list(103)},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"xd" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT1"; name = "Launch Bay #1"; p_open = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) +"xe" = (/obj/machinery/mass_driver{dir = 8; id = "ASSAULT1"; name = "gravpult"},/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/specops) "xf" = (/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/specops) -"xg" = (/obj/machinery/door/airlock/centcom{name = "Special Operations"; opacity = 1; req_access_txt = "103"},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/specops) -"xh" = (/obj/machinery/door/airlock/centcom{name = "Bridge"; opacity = 1; req_access_txt = "109"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"xi" = (/obj/structure/stool/bed/chair,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"xg" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill,/obj/item/mecha_parts/mecha_equipment/tool/cable_layer,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xh" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/command,/obj/item/clothing/head/helmet/ert/command,/obj/item/weapon/storage/backpack/ert/commander,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xi" = (/obj/structure/bed/chair,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "xj" = (/obj/machinery/door/airlock/centcom{name = "Courthouse"; opacity = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) -"xk" = (/turf/space,/area/centcom) -"xl" = (/obj/machinery/mech_bay_recharge_port,/turf/unsimulated/floor{icon_state = "bot"},/area/centcom) -"xm" = (/obj/mecha/working/hoverpod,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom) -"xn" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp,/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp,/obj/item/mecha_parts/mecha_equipment/tool/passenger,/obj/item/mecha_parts/mecha_equipment/tool/passenger,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"xo" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/tie/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"xp" = (/obj/structure/table/rack,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"xq" = (/obj/structure/sign/securearea{name = "\improper ARMORY"; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"xr" = (/obj/structure/sign/securearea{name = "ENGINEERING ACCESS"; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"xs" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; listening = 0; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"xt" = (/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"xu" = (/obj/machinery/portable_atmospherics/canister/air,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"xv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) -"xw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) -"xx" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) -"xy" = (/obj/machinery/door/airlock/centcom{name = "Creed's Office"; opacity = 1; req_access_txt = "108"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"xz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) -"xA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) +"xk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) +"xl" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/accessory/storage/black_vest,/obj/item/weapon/rig/ert,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xm" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/suit/armor/vest/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/clothing/head/helmet/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/obj/item/weapon/storage/backpack/ert/engineer,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xn" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/device/flash,/obj/item/device/flash,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/clothing/accessory/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xo" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xp" = (/obj/structure/table/rack,/obj/item/weapon/rig/ert/engineer,/obj/item/clothing/accessory/storage/brown_vest,/obj/item/weapon/rig/ert/engineer,/obj/item/clothing/accessory/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xq" = (/obj/machinery/portable_atmospherics/powered/scrubber,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xr" = (/obj/machinery/door/window{dir = 2; name = "AI Core Door"; req_access = list(109)},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"xs" = (/obj/mecha/working/hoverpod,/turf/unsimulated/floor{icon_state = "delivery"; dir = 6},/area/centcom/specops) +"xt" = (/obj/structure/table/rack,/obj/item/rig_module/mounted/taser,/obj/item/rig_module/mounted/taser,/obj/item/rig_module/mounted/taser,/obj/item/rig_module/maneuvering_jets,/obj/item/rig_module/maneuvering_jets,/obj/item/rig_module/grenade_launcher,/obj/item/rig_module/device/drill,/obj/item/rig_module/device/drill,/obj/item/rig_module/device/healthscanner,/obj/item/rig_module/device/healthscanner,/obj/item/rig_module/device/plasmacutter,/obj/item/rig_module/device/plasmacutter,/obj/item/rig_module/device/rcd,/obj/item/rig_module/device/rcd,/obj/item/rig_module/chem_dispenser/injector,/obj/item/rig_module/chem_dispenser/injector,/obj/item/rig_module/chem_dispenser/combat,/obj/item/rig_module/chem_dispenser/combat,/obj/item/rig_module/mounted/egun,/obj/item/rig_module/mounted/egun,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xu" = (/obj/machinery/door/airlock/centcom{name = "Armory Special Operations"; opacity = 1; req_access = list(103)},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"xv" = (/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) +"xw" = (/obj/machinery/door/airlock/centcom{name = "Special Operations"; opacity = 1; req_access = list(103)},/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/specops) +"xx" = (/obj/machinery/door/airlock/centcom{name = "Bridge"; opacity = 1; req_access = list(109)},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"xy" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT0"; name = "Launch Bay #0"; p_open = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) +"xz" = (/obj/machinery/mass_driver{dir = 8; id = "ASSAULT0"; name = "gravpult"},/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/specops) +"xA" = (/obj/machinery/camera{c_tag = "Assault Armor South"; dir = 1; network = list("ERT")},/turf/unsimulated/floor{icon_state = "loadingarea"; dir = 8},/area/centcom/specops) "xB" = (/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "xC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "xD" = (/obj/machinery/computer/robotics,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "xE" = (/obj/machinery/computer/communications,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "xF" = (/obj/machinery/computer/card,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "xG" = (/obj/machinery/computer/med_data,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"xH" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT0"; name = "Launch Bay #0"; p_open = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom) -"xI" = (/obj/machinery/mass_driver{dir = 8; id = "ASSAULT0"; name = "gravpult"},/turf/unsimulated/floor{icon_state = "bot"},/area/centcom) -"xJ" = (/obj/machinery/camera{c_tag = "Assault Armor South"; dir = 1; network = list("ERT")},/turf/unsimulated/floor{icon_state = "loadingarea"; dir = 8},/area/centcom) -"xK" = (/obj/machinery/door/airlock/centcom{name = "Special Operations Mechbay "; opacity = 1; req_access_txt = "103"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"xL" = (/obj/machinery/door/airlock/centcom{name = "Special Operations Command"; opacity = 1; req_access_txt = "103"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"xM" = (/obj/structure/sign/redcross{pixel_y = -32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"xN" = (/obj/structure/stool/bed/chair,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) +"xH" = (/obj/machinery/door/airlock/centcom{name = "Special Operations Command"; opacity = 1; req_access = list(103)},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"xI" = (/obj/structure/sign/securearea{name = "\improper ARMORY"; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"xJ" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; listening = 0; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"xK" = (/obj/structure/sign/securearea{name = "ENGINEERING ACCESS"; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"xL" = (/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"xM" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,/obj/item/mecha_parts/mecha_equipment/repair_droid,/obj/item/mecha_parts/mecha_equipment/repair_droid,/obj/item/mecha_parts/mecha_equipment/repair_droid,/obj/item/mecha_parts/mecha_equipment/repair_droid,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"xN" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp,/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp,/obj/item/mecha_parts/mecha_equipment/tool/passenger,/obj/item/mecha_parts/mecha_equipment/tool/passenger,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "xO" = (/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/specops) "xP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) "xQ" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) -"xR" = (/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/turf/unsimulated/floor{dir = 6; icon_state = "asteroid8"; name = "sand"},/area/centcom/specops) +"xR" = (/obj/structure/sign/redcross{pixel_y = -32},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) "xS" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "xT" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor,/area/centcom/control) "xU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor,/area/centcom/control) @@ -1246,88 +1246,88 @@ "xX" = (/obj/structure/table,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/control) "xY" = (/obj/machinery/camera{c_tag = "Jury Room"; network = list("thunder"); pixel_x = 10},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "xZ" = (/obj/machinery/vending/cigarette,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) -"ya" = (/obj/structure/table/reinforced,/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay,/obj/item/mecha_parts/mecha_equipment/repair_droid,/obj/item/mecha_parts/mecha_equipment/repair_droid,/obj/item/mecha_parts/mecha_equipment/repair_droid,/obj/item/mecha_parts/mecha_equipment/repair_droid,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"yb" = (/obj/machinery/door/airlock/centcom{name = "Medical Special Operations"; opacity = 1; req_access_txt = "103"},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) -"yc" = (/obj/machinery/autolathe{desc = "Your typical Autolathe. It appears to have much more options than your regular one, however..."; hacked = 1; name = "Unlocked Autolathe"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"yd" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) -"ye" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/donut_box,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) -"yf" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) -"yg" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) +"ya" = (/obj/structure/bed/chair,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"yb" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/obj/item/weapon/handcuffs,/obj/item/weapon/storage/pill_bottle/dice,/obj/item/weapon/deck,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"yc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) +"yd" = (/obj/structure/bed/chair/office/light,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"ye" = (/obj/structure/undies_wardrobe,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"yf" = (/obj/machinery/computer/arcade,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"yg" = (/obj/machinery/door/airlock/centcom{name = "Medical Special Operations"; opacity = 1; req_access = list(103)},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) "yh" = (/turf/unsimulated/wall,/area/centcom/creed) -"yi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/unsimulated/floor{name = "plating"},/area/centcom/creed) -"yj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/unsimulated/floor{name = "plating"},/area/centcom/creed) -"yk" = (/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/creed) -"yl" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/unsimulated/floor{name = "plating"},/area/centcom/creed) -"ym" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/unsimulated/floor{name = "plating"},/area/centcom/creed) +"yi" = (/obj/machinery/autolathe{desc = "Your typical Autolathe. It appears to have much more options than your regular one, however..."; hacked = 1; name = "Unlocked Autolathe"},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"yj" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/donut,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"yk" = (/obj/structure/table/reinforced,/obj/item/weapon/crowbar,/obj/item/weapon/screwdriver,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"yl" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"ym" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 0},/turf/unsimulated/wall,/area/centcom/specops) "yn" = (/obj/structure/table/reinforced,/obj/item/device/pda/captain,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "yo" = (/obj/machinery/computer/secure_data,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "yp" = (/obj/machinery/computer/security,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "yq" = (/obj/structure/table/reinforced,/obj/item/weapon/card/id/captains_spare,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"yr" = (/obj/structure/stool/bed/chair,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/control) +"yr" = (/obj/structure/bed/chair,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/control) "ys" = (/turf/unsimulated/floor{icon_state = "white"},/area/centcom/control) -"yt" = (/obj/structure/stool/bed/chair,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) +"yt" = (/obj/structure/bed/chair,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/control) "yu" = (/turf/unsimulated/wall,/area/centcom/evac) "yv" = (/obj/structure/closet/secure_closet/freezer/meat,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/evac) "yw" = (/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/evac) -"yx" = (/obj/structure/table,/obj/machinery/processor{pixel_x = 0; pixel_y = 10},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/evac) +"yx" = (/obj/structure/table/rack,/obj/item/weapon/rig/merc/empty,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership) "yy" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor,/area/centcom/control) -"yz" = (/obj/machinery/chem_dispenser/meds,/obj/item/weapon/reagent_containers/glass/beaker/large,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"yA" = (/obj/machinery/chem_master,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) +"yz" = (/obj/structure/table/rack,/obj/item/device/lightreplacer,/obj/item/device/lightreplacer,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"yA" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/storage/box/syringes,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "yB" = (/obj/structure/table/rack,/obj/item/weapon/storage/secure/briefcase,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/weapon/flame/lighter/zippo,/obj/item/weapon/storage/belt/utility,/obj/item/weapon/storage/backpack/satchel,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) -"yC" = (/obj/machinery/telecomms/allinone{intercept = 1},/obj/machinery/door/window/northright{name = "Telecoms Mainframe"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"yD" = (/obj/structure/closet/crate/medical,/obj/item/weapon/circular_saw,/obj/item/weapon/surgicaldrill,/obj/item/weapon/bonegel{pixel_x = 4; pixel_y = 3},/obj/item/weapon/bonesetter,/obj/item/weapon/scalpel,/obj/item/weapon/retractor{pixel_x = 0; pixel_y = 6},/obj/item/weapon/hemostat{pixel_y = 4},/obj/item/weapon/cautery{pixel_y = 4},/obj/item/weapon/FixOVein{pixel_x = -6; pixel_y = 1},/obj/item/stack/nanopaste,/obj/item/weapon/tank/anesthetic,/obj/item/clothing/mask/breath/medical,/obj/item/clothing/mask/surgical,/obj/item/clothing/mask/surgical,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"yC" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/autoinjectors,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/storage/box/gloves,/obj/item/weapon/storage/box/pillbottles,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"yD" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/reagent_containers/glass/beaker/large,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "yE" = (/obj/item/weapon/mop,/obj/structure/mopbucket,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "yF" = (/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/reagent_containers/glass/bucket{amount_per_transfer_from_this = 50},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"yG" = (/obj/structure/bookcase{name = "bookcase (Tactics)"},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) +"yG" = (/obj/machinery/chem_master,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "yH" = (/obj/structure/closet/secure_closet/hos,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) "yI" = (/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) "yJ" = (/obj/structure/table/rack,/obj/item/weapon/storage/backpack/security,/obj/item/clothing/under/syndicate/combat,/obj/item/clothing/shoes/galoshes,/obj/item/clothing/head/bio_hood/janitor,/obj/item/clothing/suit/bio_suit/janitor,/obj/item/clothing/gloves/purple,/obj/item/clothing/glasses/science,/obj/item/weapon/storage/backpack/security,/obj/item/clothing/under/syndicate/combat,/obj/item/clothing/shoes/galoshes,/obj/item/clothing/head/bio_hood/janitor,/obj/item/clothing/suit/bio_suit/janitor,/obj/item/clothing/gloves/purple,/obj/item/clothing/glasses/science,/obj/item/weapon/reagent_containers/spray/cleaner{pixel_x = 6; pixel_y = 3},/obj/item/weapon/reagent_containers/spray/cleaner{pixel_x = 6; pixel_y = 3},/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/storage/box/lights/mixed,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/obj/item/weapon/grenade/chem_grenade/cleaner,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"yK" = (/obj/structure/bookcase{name = "bookcase (Reports)"},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) +"yK" = (/obj/machinery/chemical_dispenser/ert,/obj/item/weapon/reagent_containers/glass/beaker/large,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "yL" = (/obj/structure/table/woodentable,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/control) "yM" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/evac) -"yN" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) -"yO" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) +"yN" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) +"yO" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "yP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor,/area/centcom/control) -"yQ" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/flashbangs,/obj/item/weapon/handcuffs,/obj/item/device/flash,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/storage/belt/security/tactical,/obj/item/weapon/gun/energy/stunrevolver,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) +"yQ" = (/obj/structure/closet/crate,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "yR" = (/obj/structure/table/reinforced,/obj/item/device/pda/ert,/obj/item/device/pda/ert,/obj/item/device/pda/ert,/obj/item/device/pda/ert,/obj/item/device/pda/ert,/obj/item/device/pda/ert,/obj/item/device/pda/ert,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) -"yS" = (/obj/item/device/radio/intercom{broadcasting = 1; dir = 8; listening = 0; name = "Station Intercom (General)"; pixel_x = -28},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) +"yS" = (/obj/structure/table/reinforced,/obj/item/device/paicard,/obj/item/device/paicard,/obj/item/device/paicard,/obj/item/device/paicard,/obj/item/device/paicard,/obj/item/device/paicard,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "yT" = (/turf/unsimulated/floor{icon_state = "green"; dir = 1},/area/centcom/control) "yU" = (/obj/structure/closet/secure_closet/injection,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/control) -"yV" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/control) -"yW" = (/obj/structure/table/reinforced,/obj/item/weapon/crowbar,/obj/item/weapon/screwdriver,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom) -"yX" = (/obj/machinery/portable_atmospherics/powered/pump/filled,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"yY" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_centcom_dock"; name = "docking port controller"; pixel_x = 0; pixel_y = -25; req_access_txt = "0"; req_one_access_txt = "103"; tag_door = "specops_centcom_dock_door"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"yZ" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/medical,/obj/item/clothing/suit/armor/vest/ert/medical,/obj/item/clothing/suit/armor/vest/ert/medical,/obj/item/clothing/suit/armor/vest/ert/medical,/obj/item/clothing/head/helmet/ert/medical,/obj/item/clothing/head/helmet/ert/medical,/obj/item/clothing/head/helmet/ert/medical,/obj/item/clothing/head/helmet/ert/medical,/obj/item/weapon/storage/backpack/ert/medical,/obj/item/weapon/storage/backpack/ert/medical,/obj/item/weapon/storage/backpack/ert/medical,/obj/item/weapon/storage/backpack/ert/medical,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"yV" = (/obj/structure/bed/chair{dir = 1},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/centcom/control) +"yW" = (/obj/structure/table/reinforced,/obj/item/weapon/stamp/centcomm,/obj/item/weapon/pen,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"yX" = (/obj/structure/closet{icon_closed = "syndicate1"; icon_opened = "syndicate1open"; icon_state = "syndicate1"; name = "emergency response team wardrobe"},/obj/item/clothing/under/ert,/obj/item/clothing/under/syndicate/combat,/obj/item/clothing/under/rank/centcom_officer,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"yY" = (/obj/effect/landmark{name = "Response Team"},/obj/effect/landmark{name = "Commando"},/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"yZ" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "za" = (/obj/structure/table/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/brown,/obj/item/weapon/melee/energy/axe,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) "zb" = (/obj/structure/table/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/brown,/obj/item/weapon/melee/energy/axe,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) "zc" = (/obj/structure/table/reinforced,/obj/item/device/megaphone,/obj/item/device/megaphone,/obj/item/device/megaphone,/obj/item/device/megaphone,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "zd" = (/obj/machinery/telecomms/relay/preset/centcom,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) -"ze" = (/obj/machinery/door/airlock/centcom{name = "Holding Cell"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"ze" = (/obj/structure/closet/crate,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "zf" = (/obj/structure/table,/obj/item/device/assembly/signaler,/obj/item/weapon/handcuffs,/obj/item/weapon/melee/classic_baton,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/control) -"zg" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/firstaid/o2,/obj/item/weapon/storage/firstaid/regular,/obj/item/device/flash,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/device/flash,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/pill_bottle/antitox,/obj/item/weapon/storage/pill_bottle/kelotane,/obj/item/weapon/storage/pill_bottle/kelotane,/obj/item/weapon/storage/pill_bottle/antitox,/obj/item/weapon/storage/pill_bottle/kelotane,/obj/item/weapon/storage/firstaid/adv,/obj/item/weapon/storage/firstaid/adv,/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/fire,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"zh" = (/obj/machinery/iv_drip,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"zi" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/storage/box/syringes,/obj/item/weapon/reagent_containers/glass/beaker/large,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) +"zg" = (/obj/structure/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) +"zh" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_centcom_dock"; name = "docking port controller"; pixel_x = 0; pixel_y = -25; req_one_access = list(103); tag_door = "specops_centcom_dock_door"},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) +"zi" = (/obj/machinery/door/airlock/centcom{name = "Holding Cell"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "zj" = (/obj/structure/table/rack,/obj/item/clothing/under/color/red,/obj/item/clothing/shoes/brown,/obj/item/clothing/suit/armor/tdome/red,/obj/item/clothing/head/helmet/thunderdome,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/energy/sword/red,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) -"zk" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/autoinjectors,/obj/item/weapon/storage/box/beakers,/obj/item/weapon/storage/box/gloves,/obj/item/weapon/storage/box/pillbottles,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/obj/item/bodybag/cryobag,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"zl" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/storage/belt/medical,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/reagent_containers/hypospray,/obj/item/weapon/storage/box/syringes,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"zm" = (/obj/machinery/portable_atmospherics/powered/scrubber,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"zn" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_centcom_dock_door"; locked = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom) -"zo" = (/obj/structure/table/woodentable{dir = 9},/obj/item/weapon/reagent_containers/food/drinks/flask,/obj/item/clothing/mask/cigarette/cigar/havana,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) +"zk" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/bodybags,/obj/item/weapon/storage/firstaid/o2,/obj/item/weapon/storage/firstaid/regular,/obj/item/device/flash,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/device/flash,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/pill_bottle/antitox,/obj/item/weapon/storage/pill_bottle/kelotane,/obj/item/weapon/storage/pill_bottle/kelotane,/obj/item/weapon/storage/pill_bottle/antitox,/obj/item/weapon/storage/pill_bottle/kelotane,/obj/item/weapon/storage/firstaid/adv,/obj/item/weapon/storage/firstaid/adv,/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/fire,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"zl" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/roller,/obj/item/roller,/obj/item/roller,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"zm" = (/obj/structure/closet/crate/medical,/obj/item/weapon/circular_saw,/obj/item/weapon/surgicaldrill,/obj/item/weapon/bonegel{pixel_x = 4; pixel_y = 3},/obj/item/weapon/bonesetter,/obj/item/weapon/scalpel,/obj/item/weapon/retractor{pixel_x = 0; pixel_y = 6},/obj/item/weapon/hemostat{pixel_y = 4},/obj/item/weapon/cautery{pixel_y = 4},/obj/item/weapon/FixOVein{pixel_x = -6; pixel_y = 1},/obj/item/stack/nanopaste,/obj/item/weapon/tank/anesthetic,/obj/item/clothing/mask/breath/medical,/obj/item/clothing/mask/surgical,/obj/item/clothing/mask/surgical,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"zn" = (/obj/machinery/iv_drip,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"zo" = (/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor{icon_state = "carpet7-3"; dir = 4},/area/holodeck/source_courtroom) "zp" = (/obj/machinery/computer/security/telescreen{name = "Spec. Ops. Monitor"; network = list("ERT")},/obj/structure/table/woodentable{dir = 5},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) "zq" = (/obj/structure/table/woodentable{dir = 5},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) "zr" = (/obj/machinery/computer/card/centcom,/obj/item/weapon/card/id/centcom,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) "zs" = (/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/centcom/control) -"zt" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/centcom/control) +"zt" = (/obj/item/weapon/stool{pixel_y = 8},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/centcom/control) "zu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor,/area/centcom/control) "zv" = (/obj/machinery/computer/secure_data,/turf/unsimulated/floor{dir = 8; icon_state = "red"},/area/centcom/control) -"zw" = (/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{tag = "icon-red (EAST)"; icon_state = "red"; dir = 4},/area/centcom/control) -"zx" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"zw" = (/obj/item/weapon/stool{pixel_y = 8},/turf/unsimulated/floor{tag = "icon-red (EAST)"; icon_state = "red"; dir = 4},/area/centcom/control) +"zx" = (/obj/structure/table/rack,/obj/item/clothing/suit/armor/vest/ert/medical,/obj/item/clothing/suit/armor/vest/ert/medical,/obj/item/clothing/suit/armor/vest/ert/medical,/obj/item/clothing/suit/armor/vest/ert/medical,/obj/item/clothing/head/helmet/ert/medical,/obj/item/clothing/head/helmet/ert/medical,/obj/item/clothing/head/helmet/ert/medical,/obj/item/clothing/head/helmet/ert/medical,/obj/item/weapon/storage/backpack/ert/medical,/obj/item/weapon/storage/backpack/ert/medical,/obj/item/weapon/storage/backpack/ert/medical,/obj/item/weapon/storage/backpack/ert/medical,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "zy" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor,/area/centcom/control) "zz" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/turf/space,/area/space) "zA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) "zB" = (/turf/unsimulated/floor{icon_state = "loadingarea"},/area/centcom/specops) -"zC" = (/obj/structure/table/woodentable{dir = 10},/obj/machinery/door_control{name = "Spec Ops Ready Room"; desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; pixel_y = 15; req_access_txt = "11"; id = "CREED"},/obj/machinery/door_control{name = "Mech Storage"; desc = "A remote control switch to block view of the singularity."; icon_state = "doorctrl0"; pixel_y = 0; req_access_txt = "11"; id = "ASSAULT"},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) -"zD" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) +"zC" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/device/flash,/obj/item/device/flash,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/obj/item/clothing/accessory/storage/black_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"zD" = (/obj/structure/table/rack,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/obj/item/weapon/tank/emergency_oxygen/double,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "zE" = (/obj/machinery/computer/pod{id = "NTrasen"; name = "Hull Door Control"},/obj/item/device/radio/intercom{broadcasting = 1; dir = 1; frequency = 1441; name = "Spec Ops Intercom"; pixel_y = 28},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/creed) "zF" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/centcom/control) "zG" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor,/area/centcom/control) @@ -1335,10 +1335,10 @@ "zI" = (/turf/unsimulated/floor{icon_state = "green"; dir = 9},/area/centcom/control) "zJ" = (/turf/unsimulated/floor{icon_state = "green"; dir = 5},/area/centcom/control) "zK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor,/area/centcom/control) -"zL" = (/obj/structure/stool/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) +"zL" = (/obj/structure/bed/chair{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/control) "zM" = (/obj/structure/shuttle/engine/propulsion{icon_state = "burst_l"; dir = 4},/turf/space,/area/shuttle/specops/centcom) "zN" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/specops/centcom) -"zO" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_shuttle_port_hatch"; locked = 1; name = "Port Docking Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) +"zO" = (/obj/structure/table/rack,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) "zP" = (/turf/space,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/specops/centcom) "zQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/unsimulated/floor,/area/centcom/control) "zR" = (/turf/simulated/shuttle/wall{icon_state = "swall_s6"; dir = 2},/area/shuttle/escape/centcom) @@ -1350,34 +1350,34 @@ "zX" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 4},/turf/space,/area/shuttle/specops/centcom) "zY" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 8},/turf/unsimulated/floor,/area/shuttle/specops/centcom) "zZ" = (/obj/machinery/computer/security/telescreen{desc = ""; name = "Spec. Ops. Monitor"; network = list("ERT"); pixel_y = 30},/obj/machinery/computer/shuttle_control/specops,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) -"Aa" = (/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) -"Ab" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_shuttle_port"; name = "port docking hatch controller"; pixel_x = 0; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "0"; tag_door = "specops_shuttle_port_hatch"},/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) +"Aa" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) +"Ab" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_centcom_dock_door"; locked = 1},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/specops) "Ac" = (/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) "Ad" = (/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = 32},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) -"Ae" = (/obj/machinery/door/airlock/glass_security{name = "Holding Cell"; req_access_txt = "2"},/turf/unsimulated/floor,/area/centcom/control) +"Ae" = (/obj/machinery/vending/snack{name = "hacked Getmore Chocolate Corp"; prices = list()},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "Af" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "Ag" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT"; name = "Assault Weapon Storage"; p_open = 0},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) -"Ah" = (/obj/machinery/door/airlock/centcom{name = "Arrivals Processing"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"Ah" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "Ai" = (/turf/simulated/shuttle/wall{icon_state = "swallc4"},/area/shuttle/escape/centcom) -"Aj" = (/obj/machinery/computer/shuttle_control/emergency,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) -"Ak" = (/obj/machinery/computer/communications,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"Aj" = (/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor{icon_state = "carpet11-12"; dir = 4},/area/holodeck/source_courtroom) +"Ak" = (/turf/simulated/floor/holofloor{icon_state = "carpet15-15"; dir = 4},/area/holodeck/source_courtroom) "Al" = (/turf/simulated/shuttle/wall{icon_state = "swallc3"},/area/shuttle/escape/centcom) -"Am" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) -"An" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_shuttle_fore"; name = "forward docking hatch controller"; pixel_x = 0; pixel_y = -25; req_access_txt = "0"; req_one_access_txt = "0"; tag_door = "specops_shuttle_fore_hatch"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) -"Ao" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_shuttle_fore_hatch"; locked = 1; name = "Forward Docking Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/plating,/area/shuttle/specops/centcom) -"Ap" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/red,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/centcom/control) +"Am" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) +"An" = (/turf/simulated/mineral,/area/syndicate_mothership{name = "\improper Raider Base"}) +"Ao" = (/turf/unsimulated/wall{icon_state = "iron6"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Ap" = (/obj/structure/bed,/obj/item/weapon/bedsheet/red,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/centcom/control) "Aq" = (/turf/unsimulated/floor{tag = "icon-red (EAST)"; icon_state = "red"; dir = 4},/area/centcom/control) -"Ar" = (/obj/machinery/door/airlock/glass_security{name = "Holding Cell"; req_access_txt = "2"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/ferry) -"As" = (/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Arrivals Processing"; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"Ar" = (/turf/unsimulated/wall{icon_state = "iron12"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"As" = (/turf/unsimulated/wall{icon_state = "iron10"},/area/syndicate_mothership{name = "\improper Raider Base"}) "At" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/shuttle/escape/centcom) -"Au" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/extinguisher,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_shuttle"; pixel_x = 8; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13"; tag_door = "escape_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) -"Av" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) -"Aw" = (/obj/machinery/computer/crew,/obj/machinery/status_display{pixel_y = 30},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"Au" = (/obj/machinery/door/window/holowindoor{dir = 1; name = "Jury Box"},/turf/simulated/floor/holofloor{icon_state = "carpet10-8"; dir = 4},/area/holodeck/source_courtroom) +"Av" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"Aw" = (/obj/structure/window/reinforced/holowindow{dir = 1},/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor{icon_state = "carpet14-10"; dir = 4},/area/holodeck/source_courtroom) "Ax" = (/obj/machinery/computer/communications,/obj/item/device/radio/intercom{broadcasting = 0; dir = 1; frequency = 1443; listening = 1; name = "Spec Ops Intercom"; pixel_y = -28},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) "Ay" = (/obj/machinery/computer/prisoner{name = "Implant Management"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) -"Az" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) +"Az" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) "AA" = (/turf/space,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/specops/centcom) -"AB" = (/obj/structure/stool/bed/chair/office/dark,/obj/machinery/door_control{desc = "A remote control switch for port-side blast doors."; icon_state = "doorctrl0"; id = "CentComPort"; name = "Security Doors"; pixel_x = -12; pixel_y = -25; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"AB" = (/obj/machinery/vending/cola{name = "Robust Softdrinks"; prices = list()},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "AC" = (/obj/structure/window/shuttle,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/escape/centcom) "AD" = (/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) "AE" = (/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"; dir = 4},/turf/space,/area/shuttle/specops/centcom) @@ -1386,33 +1386,33 @@ "AH" = (/turf/unsimulated/wall,/area/centcom/ferry) "AI" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT3"; name = "Launch Bay #3"; p_open = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops) "AJ" = (/obj/structure/table/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/computer/skills{icon_state = "medlaptop"; pixel_x = 3; pixel_y = 4},/obj/structure/window/reinforced,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"AK" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/machinery/door/window/southright{name = "Arrivals Processing"; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) -"AL" = (/obj/structure/closet/walllocker/emerglocker{pixel_x = -28},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) -"AM" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) -"AN" = (/obj/machinery/computer/security,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) -"AO" = (/turf/simulated/shuttle/wall{dir = 1; icon_state = "wall_space"},/area/shuttle/escape/centcom) +"AK" = (/turf/unsimulated/wall{icon_state = "iron3"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"AL" = (/obj/structure/bed/chair/holochair,/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_courtroom) +"AM" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"AN" = (/obj/structure/window/reinforced/holowindow{dir = 1},/obj/structure/window/reinforced/holowindow{dir = 8},/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor{icon_state = "carpet6-2"; dir = 4},/area/holodeck/source_courtroom) +"AO" = (/obj/machinery/door/window/holowindoor{name = "Red Team"},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_emptycourt) "AP" = (/obj/machinery/atm{pixel_x = -26},/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control) "AQ" = (/turf/unsimulated/floor{icon_state = "delivery"},/area/centcom/control) "AR" = (/turf/simulated/shuttle/wall{icon_state = "swall13"; dir = 2},/area/shuttle/escape/centcom) -"AS" = (/obj/machinery/door/airlock/glass_command{name = "Escape Shuttle Cockpit"; req_access_txt = "19"},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"AS" = (/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) "AT" = (/turf/simulated/shuttle/wall{icon_state = "swall14"; dir = 2},/area/shuttle/escape/centcom) "AU" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/escape/centcom) "AV" = (/turf/unsimulated/wall{desc = "Why it no open!"; icon_state = "pdoor1"; name = "Shuttle Bay Blast Door"},/area/centcom/ferry) "AW" = (/turf/unsimulated/floor{name = "plating"},/area/centcom/ferry) "AX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{name = "plating"},/area/centcom/ferry) "AY" = (/turf/unsimulated/floor{icon_state = "warnplate"; dir = 8},/area/centcom/ferry) -"AZ" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "centcom_shuttle_bay"; name = "shuttle bay controller"; pixel_x = 0; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "0"; tag_door = "centcom_shuttle_bay_door"},/turf/unsimulated/floor{name = "plating"},/area/centcom/ferry) -"Ba" = (/obj/machinery/computer/shuttle_control{req_access = null; req_access_txt = "101"; shuttle_tag = "Centcom"},/turf/unsimulated/floor{name = "plating"},/area/centcom/ferry) +"AZ" = (/obj/effect/landmark{name = "voxstart"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Ba" = (/obj/structure/table,/obj/effect/decal/cleanable/cobweb2,/obj/effect/decal/cleanable/cobweb2{icon_state = "spiderling"; name = "dead spider"; tag = "icon-spiderling"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Bb" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/ferry) "Bc" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/ferry) "Bd" = (/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/control) -"Be" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control) +"Be" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control) "Bf" = (/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/control) "Bg" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 3},/obj/item/weapon/extinguisher,/obj/item/weapon/crowbar,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) -"Bh" = (/obj/structure/closet/walllocker/emerglocker{pixel_x = 28},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) -"Bi" = (/turf/simulated/shuttle/wall{icon_state = "swall1"; dir = 2},/area/shuttle/escape/centcom) -"Bj" = (/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) -"Bk" = (/obj/machinery/status_display{pixel_y = 30},/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) +"Bh" = (/turf/simulated/floor/holofloor/grass,/obj/structure/flora/ausbushes/brflowers,/turf/simulated/floor/holofloor{dir = 4; icon_state = "wood_siding8"},/area/holodeck/source_picnicarea) +"Bi" = (/turf/simulated/floor/holofloor/grass,/obj/structure/flora/ausbushes/ywflowers,/turf/simulated/floor/holofloor{icon_state = "wood_siding6"; dir = 2},/area/holodeck/source_picnicarea) +"Bj" = (/turf/simulated/floor/holofloor{icon_state = "asteroid"; dir = 2},/area/holodeck/source_picnicarea) +"Bk" = (/obj/structure/table/woodentable/holotable,/obj/structure/window/reinforced/holowindow,/obj/structure/window/reinforced/holowindow{dir = 8},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_courtroom) "Bl" = (/turf/simulated/shuttle/wall{icon_state = "swall_s6"; dir = 2},/area/shuttle/transport1/centcom) "Bm" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/transport1/centcom) "Bn" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/shuttle/transport1/centcom) @@ -1422,56 +1422,56 @@ "Br" = (/turf/simulated/shuttle/wall{icon_state = "swall14"; dir = 2},/area/shuttle/transport1/centcom) "Bs" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 8},/turf/space,/area/shuttle/transport1/centcom) "Bt" = (/obj/machinery/door/airlock/external{frequency = 1380; glass = 1380; icon_state = "door_locked"; id_tag = "centcom_shuttle_bay_door"; locked = 1; name = "Transport Airlock"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/ferry) -"Bu" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) -"Bv" = (/obj/machinery/door/airlock/glass_security{name = "Escape Shuttle Cell"; req_access_txt = "2"},/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) +"Bu" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Bv" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_shuttle_port_hatch"; locked = 1; name = "Port Docking Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) "Bw" = (/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) -"Bx" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) +"Bx" = (/obj/structure/window/reinforced/holowindow,/obj/machinery/door/window/holowindoor{dir = 1; name = "Court Reporter's Box"},/obj/structure/bed/chair/holochair,/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_courtroom) "By" = (/turf/simulated/shuttle/wall{dir = 2; icon_state = "swall_floor_f9"},/area/shuttle/transport1/centcom) -"Bz" = (/obj/machinery/computer/shuttle_control{req_access = null; req_access_txt = "101"; shuttle_tag = "Centcom"},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"Bz" = (/obj/machinery/vending/cigarette{name = "cigarette machine"; prices = list()},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom/specops) "BA" = (/turf/simulated/shuttle/wall{dir = 2; icon_state = "swall_floor_f5"},/area/shuttle/transport1/centcom) "BB" = (/turf/simulated/shuttle/wall{icon_state = "swall11"; dir = 2},/area/shuttle/transport1/centcom) -"BC" = (/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"BC" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) "BD" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/shuttle/transport1/centcom) "BE" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 8},/obj/structure/window/reinforced,/turf/space,/area/shuttle/transport1/centcom) -"BF" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "green"; dir = 4},/area/centcom/control) +"BF" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "green"; dir = 4},/area/centcom/control) "BG" = (/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/evac) -"BH" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) +"BH" = (/obj/structure/window/reinforced/holowindow,/obj/machinery/door/window/holowindoor{base_state = "right"; dir = 1; icon_state = "right"; name = "Witness Box"},/obj/structure/bed/chair/holochair,/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_courtroom) "BI" = (/obj/structure/window/shuttle,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/transport1/centcom) "BJ" = (/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) -"BK" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"BK" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) "BL" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) -"BM" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "centcom_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"BM" = (/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) "BN" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/turf/unsimulated/wall,/area/centcom/ferry) "BO" = (/obj/machinery/door/airlock/external{name = "Arrivals Bar Airlock"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/ferry) -"BP" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "greencorner"; dir = 4},/area/centcom/control) +"BP" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "greencorner"; dir = 4},/area/centcom/control) "BQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "BR" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) "BS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) -"BT" = (/obj/structure/stool/bed/chair{dir = 4},/obj/structure/closet/walllocker/emerglocker{pixel_x = -28},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) -"BU" = (/turf/simulated/shuttle/wall{dir = 2; icon_state = "swall_floor_f5"},/area/shuttle/escape/centcom) +"BT" = (/obj/structure/bed/chair{dir = 4},/obj/structure/closet/walllocker/emerglocker{pixel_x = -28},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"BU" = (/obj/structure/table/woodentable/holotable,/obj/structure/window/reinforced/holowindow,/obj/structure/window/reinforced/holowindow{dir = 4},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_courtroom) "BV" = (/turf/simulated/shuttle/wall{icon_state = "swall11"; dir = 2},/area/shuttle/escape/centcom) "BW" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/shuttle/transport1/centcom) "BX" = (/turf/simulated/shuttle/wall{dir = 1; icon_state = "swall_floor_f10"},/area/shuttle/transport1/centcom) -"BY" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "centcom_shuttle"; pixel_x = 0; pixel_y = -25; req_access_txt = "0"; req_one_access_txt = "0"; tag_door = "centcom_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"BY" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_shuttle_port"; name = "port docking hatch controller"; pixel_x = 0; pixel_y = 25; tag_door = "specops_shuttle_port_hatch"},/obj/structure/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) "BZ" = (/turf/simulated/shuttle/wall{dir = 8; icon_state = "swall_floor_f6"},/area/shuttle/transport1/centcom) -"Ca" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"Ca" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) "Cb" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/shuttle/transport1/centcom) "Cc" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion_l"; dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/space,/area/shuttle/transport1/centcom) -"Cd" = (/obj/structure/stool/bed/chair/comfy/brown,/turf/unsimulated/floor{dir = 9; icon_state = "carpetside"},/area/centcom/ferry) -"Ce" = (/obj/structure/stool/bed/chair/comfy/brown,/turf/unsimulated/floor{dir = 1; icon_state = "carpetside"},/area/centcom/ferry) -"Cf" = (/obj/structure/stool/bed/chair/comfy/brown,/turf/unsimulated/floor{dir = 5; icon_state = "carpetside"},/area/centcom/ferry) +"Cd" = (/obj/structure/bed/chair/comfy/brown,/turf/unsimulated/floor{dir = 9; icon_state = "carpetside"},/area/centcom/ferry) +"Ce" = (/obj/structure/bed/chair/comfy/brown,/turf/unsimulated/floor{dir = 1; icon_state = "carpetside"},/area/centcom/ferry) +"Cf" = (/obj/structure/bed/chair/comfy/brown,/turf/unsimulated/floor{dir = 5; icon_state = "carpetside"},/area/centcom/ferry) "Cg" = (/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/ferry) "Ch" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/ferry) "Ci" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/ferry) -"Cj" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "greencorner"; dir = 1},/area/centcom/control) +"Cj" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "greencorner"; dir = 1},/area/centcom/control) "Ck" = (/obj/machinery/door/airlock/glass{name = "Arrivals Processing"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) "Cl" = (/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) "Cm" = (/turf/unsimulated/floor{dir = 4; heat_capacity = 1; icon_state = "warning"},/area/centcom/evac) -"Cn" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "centcom_dock_airlock"; locked = 1; name = "Arrivals Airlock"; req_access_txt = "13"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/evac) +"Cn" = (/obj/machinery/recharger/wallcharger{pixel_x = 4; pixel_y = 32},/obj/machinery/vending/wallmed1{layer = 3.3; name = "Emergency NanoMed"; pixel_x = 28; pixel_y = 0},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) "Co" = (/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/evac) -"Cp" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access_txt = "13"},/obj/machinery/mech_sensor{dir = 8; frequency = 1380; id_tag = "shuttle_dock_north_mech"; pixel_y = -19},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) -"Cq" = (/obj/structure/closet/hydrant{pixel_y = 30},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) -"Cr" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Cp" = (/obj/machinery/door/airlock/glass_security{name = "Holding Cell"; req_access = list(2)},/turf/unsimulated/floor,/area/centcom/control) +"Cq" = (/obj/structure/table/woodentable/holotable,/obj/structure/window/reinforced/holowindow,/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_courtroom) +"Cr" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) "Cs" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/shuttle/transport1/centcom) "Ct" = (/turf/simulated/shuttle/wall{icon_state = "swall13"; dir = 2},/area/shuttle/transport1/centcom) "Cu" = (/turf/unsimulated/floor{dir = 8; icon_state = "carpetside"},/area/centcom/ferry) @@ -1481,26 +1481,26 @@ "Cy" = (/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/ferry) "Cz" = (/obj/machinery/door/airlock/glass{name = "Arrivals Processing"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/ferry) "CA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) -"CB" = (/obj/structure/stool/bed/chair{dir = 4},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"CB" = (/turf/simulated/floor/holofloor{icon_state = "carpet5-1"; dir = 4},/area/holodeck/source_theatre) "CC" = (/obj/structure/window/shuttle{icon_state = "window2"},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/escape/centcom) -"CD" = (/obj/structure/stool/bed/chair{dir = 8},/obj/structure/closet/walllocker/emerglocker{pixel_x = 28},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) -"CE" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 1},/turf/unsimulated/floor{dir = 10; icon_state = "carpetside"},/area/centcom/ferry) -"CF" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 1},/turf/unsimulated/floor{dir = 2; icon_state = "carpetside"},/area/centcom/ferry) -"CG" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 1},/turf/unsimulated/floor{dir = 6; icon_state = "carpetside"},/area/centcom/ferry) -"CH" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "greencorner"},/area/centcom/control) +"CD" = (/obj/structure/bed/chair/holochair{dir = 1},/turf/simulated/floor/holofloor{icon_state = "carpet15-15"; dir = 4},/area/holodeck/source_courtroom) +"CE" = (/obj/structure/bed/chair/comfy/brown{dir = 1},/turf/unsimulated/floor{dir = 10; icon_state = "carpetside"},/area/centcom/ferry) +"CF" = (/obj/structure/bed/chair/comfy/brown{dir = 1},/turf/unsimulated/floor{dir = 2; icon_state = "carpetside"},/area/centcom/ferry) +"CG" = (/obj/structure/bed/chair/comfy/brown{dir = 1},/turf/unsimulated/floor{dir = 6; icon_state = "carpetside"},/area/centcom/ferry) +"CH" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "greencorner"},/area/centcom/control) "CI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) "CJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) "CK" = (/turf/unsimulated/floor{icon_state = "warning"},/area/centcom/evac) -"CL" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "centcom_dock"; name = "docking port controller"; pixel_x = 25; pixel_y = 0; req_access_txt = "0"; req_one_access_txt = "13"; tag_door = "centcom_dock_airlock"},/turf/unsimulated/floor{dir = 6; icon_state = "warning"},/area/centcom/evac) +"CL" = (/obj/machinery/door/airlock/centcom{name = "Arrivals Processing"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "CM" = (/obj/structure/window/shuttle{icon_state = "window3"},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/escape/centcom) "CN" = (/turf/unsimulated/wall,/area/centcom/holding) "CO" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/flame/lighter/zippo,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/ashtray/bronze{pixel_x = -1; pixel_y = 1},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) "CP" = (/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) "CQ" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) -"CR" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "greencorner"; dir = 8},/area/centcom/control) +"CR" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "greencorner"; dir = 8},/area/centcom/control) "CS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/control) "CT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom/evac) -"CU" = (/obj/machinery/turretcover{density = 1},/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/evac) +"CU" = (/obj/structure/bed/chair/holochair{dir = 1},/turf/simulated/floor/holofloor{icon_state = "carpet11-12"; dir = 4},/area/holodeck/source_courtroom) "CV" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 0},/turf/unsimulated/wall,/area/centcom/evac) "CW" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"; name = "Clothing Storage"},/obj/item/clothing/head/bandana{pixel_y = -10},/obj/item/clothing/glasses/sunglasses,/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/area/centcom/ferry) "CX" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"; name = "Clothing Storage"},/obj/item/clothing/glasses/sunglasses,/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/area/centcom/ferry) @@ -1514,35 +1514,35 @@ "Df" = (/obj/structure/window/shuttle{icon_state = "window1"},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/escape/centcom) "Dg" = (/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/area/centcom/ferry) "Dh" = (/turf/unsimulated/beach/sand{tag = "icon-desert3"; icon_state = "desert3"},/turf/unsimulated/floor{tag = "icon-siding4"; name = "plating"; icon_state = "siding4"},/area/centcom/holding) -"Di" = (/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/turf/unsimulated/floor{tag = "icon-siding8"; name = "plating"; icon_state = "siding8"},/area/centcom/holding) +"Di" = (/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/turf/unsimulated/floor{tag = "icon-siding8"; name = "plating"; icon_state = "siding8"},/area/centcom/holding) "Dj" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/amanita_pie,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) "Dk" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/bigbiteburger,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) -"Dl" = (/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 8},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) -"Dm" = (/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) +"Dl" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 8},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) +"Dm" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) "Dn" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/carrotcakeslice,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) "Do" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/stew,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) "Dp" = (/obj/machinery/vending/coffee,/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control) -"Dq" = (/obj/structure/stool/bed/chair{dir = 8},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Dq" = (/obj/structure/bed/chair{dir = 8},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) "Dr" = (/turf/unsimulated/beach/sand{tag = "icon-desert2"; icon_state = "desert2"},/area/centcom/ferry) "Ds" = (/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/turf/unsimulated/floor{tag = "icon-siding4"; name = "plating"; icon_state = "siding4"},/area/centcom/holding) "Dt" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/boiledrice,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) "Du" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/beetsoup,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) "Dv" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/stuffing,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) "Dw" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/soylenviridians,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) -"Dx" = (/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/obj/structure/stool{pixel_y = 8},/turf/unsimulated/floor{tag = "icon-siding2"; name = "plating"; icon_state = "siding2"},/area/centcom/holding) +"Dx" = (/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/obj/item/weapon/stool{pixel_y = 8},/turf/unsimulated/floor{tag = "icon-siding2"; name = "plating"; icon_state = "siding2"},/area/centcom/holding) "Dy" = (/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/centcom/holding) "Dz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/centcom/holding) "DA" = (/obj/machinery/vending/cigarette,/turf/unsimulated/floor{icon_state = "green"; dir = 10},/area/centcom/holding) "DB" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 8},/area/centcom/holding) "DC" = (/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/holding) "DD" = (/obj/machinery/door/airlock/glass{name = "Arrivals Processing"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/holding) -"DE" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access_txt = "13"},/obj/machinery/mech_sensor{dir = 8; frequency = 1380; id_tag = "shuttle_dock_south_mech"; pixel_y = 19},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"DE" = (/turf/unsimulated/wall{icon_state = "iron13"},/area/syndicate_mothership{name = "\improper Raider Base"}) "DF" = (/obj/item/weapon/inflatable_duck,/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/area/centcom/ferry) "DG" = (/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/turf/unsimulated/floor{tag = "icon-siding4"; name = "plating"; icon_state = "siding4"},/area/centcom/holding) "DH" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/drinks/drinkingglass,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding) -"DI" = (/obj/machinery/door/airlock/glass_medical{name = "Arrivals Medbay"; req_access_txt = "0"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/holding) -"DJ" = (/obj/machinery/door/airlock/glass_medical{name = "Escape Shuttle Infirmary"; req_access_txt = "0"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) -"DK" = (/turf/simulated/shuttle/wall{dir = 1; icon_state = "swall_floor_f10"},/area/shuttle/escape/centcom) +"DI" = (/turf/unsimulated/wall{tag = "icon-iron8"; icon_state = "iron8"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"DJ" = (/turf/simulated/floor/holofloor{icon_state = "carpet9-4"; dir = 4},/area/holodeck/source_theatre) +"DK" = (/turf/simulated/floor/holofloor{dir = 4; icon_state = "carpet1-0"},/area/holodeck/source_theatre) "DL" = (/turf/unsimulated/beach/sand{tag = "icon-desert1"; icon_state = "desert1"},/area/centcom/ferry) "DM" = (/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/obj/effect/overlay/palmtree_r,/turf/unsimulated/beach/sand{tag = "icon-coconuts"; icon_state = "coconuts"},/area/centcom/ferry) "DN" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/bloodsoup,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) @@ -1552,14 +1552,14 @@ "DR" = (/obj/structure/table/woodentable{dir = 5},/obj/item/clothing/under/suit_jacket,/obj/item/clothing/suit/wcoat,/obj/item/clothing/head/that{pixel_x = 4; pixel_y = 6},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding) "DS" = (/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding) "DT" = (/obj/machinery/atmospherics/unary/cryo_cell,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/holding) -"DU" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT"; name = "Assault Armor Storage"; p_open = 0},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) +"DU" = (/turf/unsimulated/wall{tag = "icon-iron4"; icon_state = "iron4"},/area/syndicate_mothership{name = "\improper Raider Base"}) "DV" = (/turf/unsimulated/floor{icon_state = "white"},/area/centcom/holding) -"DW" = (/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = 0; pixel_y = 29; req_access_txt = "0"},/turf/unsimulated/floor{dir = 4; icon_state = "whitegreencorner"},/area/centcom/holding) -"DX" = (/obj/structure/stool/bed/roller,/turf/unsimulated/floor{dir = 4; icon_state = "whitegreenfull"},/area/centcom/holding) +"DW" = (/turf/unsimulated/wall{icon_state = "iron5"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"DX" = (/obj/structure/bed/roller,/turf/unsimulated/floor{dir = 4; icon_state = "whitegreenfull"},/area/centcom/holding) "DY" = (/obj/machinery/sleeper,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) "DZ" = (/obj/machinery/sleep_console,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) "Ea" = (/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) -"Eb" = (/obj/structure/stool/bed/roller,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Eb" = (/obj/structure/bed/roller,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) "Ec" = (/mob/living/simple_animal/crab,/turf/unsimulated/beach/sand{tag = "icon-desert3"; icon_state = "desert3"},/area/centcom/ferry) "Ed" = (/obj/item/weapon/beach_ball,/turf/unsimulated/beach/sand{tag = "icon-desert_dug"; icon_state = "desert_dug"},/area/centcom/ferry) "Ee" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/spesslaw,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) @@ -1568,22 +1568,22 @@ "Eh" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/snacks/meatsteak,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) "Ei" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHEAST)"},/turf/unsimulated/floor{dir = 8; icon_state = "whitegreencorner"},/area/centcom/holding) "Ej" = (/obj/machinery/atmospherics/pipe/manifold/hidden,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/holding) -"Ek" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/holding) +"Ek" = (/obj/structure/bed/chair/holochair{dir = 1},/turf/simulated/floor/holofloor{icon_state = "carpet7-3"; dir = 4},/area/holodeck/source_courtroom) "El" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/holding) -"Em" = (/obj/structure/stool/bed/roller,/obj/machinery/vending/wallmed1{layer = 3.3; name = "Emergency NanoMed"; pixel_x = 28; pixel_y = 0; req_access_txt = "0"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) -"En" = (/obj/structure/closet/crate/freezer/rations,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"Em" = (/turf/space/transit/north/shuttlespace_ns4,/area/shuttle/escape/transit) +"En" = (/turf/space/transit/east/shuttlespace_ew10,/area/shuttle/escape_pod5/transit) "Eo" = (/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/obj/item/weapon/inflatable_duck,/turf/unsimulated/floor{tag = "icon-siding4"; name = "plating"; icon_state = "siding4"},/area/centcom/holding) -"Ep" = (/obj/structure/closet/secure_closet/bar{req_access_txt = "25"},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding) +"Ep" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Eq" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/book/manual/barman_recipes,/obj/item/weapon/reagent_containers/glass/rag,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding) -"Er" = (/obj/structure/table/woodentable{dir = 5},/obj/machinery/chem_dispenser/beer,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding) -"Es" = (/obj/structure/table/woodentable{dir = 5},/obj/machinery/chem_dispenser/soda,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding) +"Er" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "specops_shuttle_fore_hatch"; locked = 1; name = "Forward Docking Hatch"; req_access = list(13)},/turf/simulated/shuttle/plating,/area/shuttle/specops/centcom) +"Es" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "specops_shuttle_fore"; name = "forward docking hatch controller"; pixel_x = 0; pixel_y = -25; tag_door = "specops_shuttle_fore_hatch"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom) "Et" = (/turf/unsimulated/floor{dir = 8; icon_state = "whitegreen"},/area/centcom/holding) -"Eu" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6; icon_state = "intact"; tag = "icon-intact-f (SOUTHEAST)"},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/holding) -"Ev" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/holding) +"Eu" = (/obj/structure/window/reinforced/holowindow{dir = 8},/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor{icon_state = "carpet5-1"; dir = 4},/area/holodeck/source_courtroom) +"Ev" = (/obj/structure/bed/chair/holochair{dir = 1},/turf/simulated/floor/holofloor{icon_state = "carpet9-4"; dir = 4},/area/holodeck/source_courtroom) "Ew" = (/turf/unsimulated/floor{dir = 2; icon_state = "whitegreencorner"},/area/centcom/holding) "Ex" = (/turf/unsimulated/floor{dir = 8; icon_state = "whitegreencorner"},/area/centcom/holding) "Ey" = (/obj/structure/sign/nosmoking_2{pixel_x = 28; pixel_y = 0},/turf/unsimulated/floor{dir = 4; icon_state = "whitegreencorner"},/area/centcom/holding) -"Ez" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 6},/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/bodybag/cryobag{pixel_x = 5},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 30},/obj/item/weapon/storage/firstaid/o2{layer = 2.8; pixel_x = 4; pixel_y = 6},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Ez" = (/obj/structure/bed/chair/holochair{dir = 1},/turf/simulated/floor/holofloor{icon_state = "carpet13-5"; dir = 4},/area/holodeck/source_courtroom) "EA" = (/turf/simulated/shuttle/wall{icon_state = "swall7"; dir = 2},/area/shuttle/escape/centcom) "EB" = (/obj/structure/shuttle/engine/heater,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/shuttle/escape/centcom) "EC" = (/obj/effect/overlay/palmtree_l,/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/area/centcom/ferry) @@ -1594,11 +1594,11 @@ "EH" = (/turf/unsimulated/wall,/area/tdome) "EI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/tdome) "EJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/tdome) -"EK" = (/obj/machinery/door/airlock/centcom{name = "Thunderdome"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome) +"EK" = (/obj/machinery/door/airlock/glass_security{name = "Holding Cell"; req_access = list(2)},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/ferry) "EL" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/tdome) "EM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/tdome) -"EN" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/beaker/cryoxadone{pixel_x = 5; pixel_y = 5},/obj/item/weapon/reagent_containers/glass/beaker/cryoxadone{pixel_x = 0; pixel_y = 0},/obj/item/weapon/reagent_containers/glass/beaker/cryoxadone{pixel_x = 7; pixel_y = 1},/turf/unsimulated/floor{dir = 8; icon_state = "whitegreen"},/area/centcom/holding) -"EO" = (/obj/machinery/atmospherics/pipe/tank/oxygen{dir = 1; volume = 3200},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/holding) +"EN" = (/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor{icon_state = "carpet13-5"; dir = 4},/area/holodeck/source_courtroom) +"EO" = (/turf/simulated/floor/holofloor{icon_state = "carpetsymbol"; dir = 6},/area/holodeck/source_theatre) "EP" = (/turf/unsimulated/floor{dir = 6; icon_state = "whitegreen"},/area/centcom/holding) "EQ" = (/turf/unsimulated/floor{dir = 10; icon_state = "whitegreen"},/area/centcom/holding) "ER" = (/obj/machinery/sleep_console{icon_state = "sleeperconsole-r"; orient = "RIGHT"},/turf/unsimulated/floor{dir = 8; icon_state = "whitehall"; tag = "icon-whitehall (EAST)"},/area/centcom/holding) @@ -1619,12 +1619,12 @@ "Fg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/tdome) "Fh" = (/turf/unsimulated/floor{dir = 4; icon_state = "whitegreencorner"},/area/centcom/holding) "Fi" = (/turf/unsimulated/floor{dir = 5; icon_state = "whitegreen"},/area/centcom/holding) -"Fj" = (/turf/unsimulated/floor{dir = 9; icon_state = "whitegreen"},/area/centcom/holding) +"Fj" = (/obj/structure/bed/chair/holochair{dir = 1},/turf/simulated/floor/holofloor{icon_state = "carpet5-1"; dir = 4},/area/holodeck/source_courtroom) "Fk" = (/turf/unsimulated/floor{dir = 1; icon_state = "whitegreencorner"},/area/centcom/holding) "Fl" = (/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/turf/unsimulated/beach/sand{tag = "icon-coconuts"; icon_state = "coconuts"},/area/centcom/ferry) -"Fm" = (/obj/structure/stool/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome) +"Fm" = (/obj/structure/bed/chair{dir = 4},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome) "Fn" = (/obj/structure/table/reinforced,/turf/unsimulated/floor{icon_state = "floor"},/area/tdome) -"Fo" = (/obj/structure/stool/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome) +"Fo" = (/obj/structure/bed/chair{dir = 8},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome) "Fp" = (/obj/structure/table,/obj/item/weapon/FixOVein{pixel_x = -6; pixel_y = 1},/turf/unsimulated/floor{tag = "icon-whitecorner"; name = "plating"; icon_state = "whitecorner"},/area/centcom/holding) "Fq" = (/obj/structure/table,/obj/item/weapon/cautery{pixel_y = 4},/obj/item/weapon/hemostat{pixel_y = 4},/turf/unsimulated/floor{dir = 2; icon_state = "whitehall"; tag = "icon-whitehall (SOUTHEAST)"},/area/centcom/holding) "Fr" = (/obj/structure/table,/obj/item/weapon/retractor{pixel_x = 0; pixel_y = 6},/obj/item/weapon/scalpel,/turf/unsimulated/floor{dir = 2; icon_state = "whitehall"; tag = "icon-whitehall (SOUTHEAST)"},/area/centcom/holding) @@ -1633,7 +1633,7 @@ "Fu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/shuttle/plating,/area/centcom/holding) "Fv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/unsimulated/floor{name = "plating"},/area/tdome) "Fw" = (/turf/unsimulated/floor{tag = "icon-whitehall (EAST)"; icon_state = "whitehall"; dir = 4},/area/centcom/holding) -"Fx" = (/obj/machinery/door/airlock/medical{name = "Operating Theatre"; req_access_txt = "45"},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/holding) +"Fx" = (/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Arrivals Processing"; req_access = list(101)},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "Fy" = (/turf/unsimulated/floor{dir = 4; icon_state = "whitegreen"},/area/centcom/holding) "Fz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/shuttle/plating,/area/centcom/holding) "FA" = (/turf/unsimulated/floor{dir = 8; icon_state = "red"},/area/tdome) @@ -1642,7 +1642,7 @@ "FD" = (/turf/unsimulated/floor{tag = "icon-whitehall (NORTHEAST)"; icon_state = "whitehall"; dir = 5},/area/centcom/holding) "FE" = (/obj/machinery/optable,/turf/unsimulated/floor{icon_state = "white"},/area/centcom/holding) "FF" = (/turf/unsimulated/floor{tag = "icon-whitehall (NORTHWEST)"; icon_state = "whitehall"; dir = 9},/area/centcom/holding) -"FG" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = 28; req_access_txt = "0"},/turf/unsimulated/floor{tag = "icon-whitecorner (NORTH)"; icon_state = "whitecorner"; dir = 1},/area/centcom/holding) +"FG" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/extinguisher,/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "escape_shuttle"; pixel_x = 8; pixel_y = 25; req_one_access = list(13); tag_door = "escape_shuttle_hatch"},/obj/machinery/camera{c_tag = "Shuttle Bridge West"},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) "FH" = (/obj/structure/table,/obj/item/weapon/storage/box/gloves{pixel_x = 3; pixel_y = 4},/obj/item/weapon/storage/box/masks{pixel_x = 0; pixel_y = 0},/turf/unsimulated/floor{dir = 4; icon_state = "whitegreen"},/area/centcom/holding) "FI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/shuttle/plating,/area/centcom/holding) "FJ" = (/turf/unsimulated/floor{icon_state = "red"; dir = 10},/area/tdome) @@ -1656,12 +1656,12 @@ "FR" = (/obj/structure/table,/obj/item/weapon/reagent_containers/blood/OPlus{pixel_x = 4; pixel_y = 2},/obj/item/weapon/reagent_containers/blood/OPlus{pixel_x = 4; pixel_y = 2},/obj/item/weapon/reagent_containers/blood/OMinus{pixel_x = -5; pixel_y = -1},/obj/item/weapon/reagent_containers/blood/OMinus{pixel_x = -5; pixel_y = -1},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/holding) "FS" = (/obj/machinery/bodyscanner,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/holding) "FT" = (/obj/machinery/body_scanconsole,/turf/unsimulated/floor{tag = "icon-whitehall (EAST)"; icon_state = "whitehall"; dir = 4},/area/centcom/holding) -"FU" = (/obj/structure/stool/bed/roller,/turf/unsimulated/floor{dir = 0; icon_state = "whitegreen"},/area/centcom/holding) +"FU" = (/obj/structure/bed/roller,/turf/unsimulated/floor{dir = 0; icon_state = "whitegreen"},/area/centcom/holding) "FV" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular{pixel_x = 2; pixel_y = 6},/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/weapon/storage/firstaid/adv{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/firstaid/adv{pixel_x = -2},/turf/unsimulated/floor{dir = 0; icon_state = "whitegreen"},/area/centcom/holding) "FW" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{layer = 2.8; pixel_x = 4; pixel_y = 6},/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/fire{layer = 2.9; pixel_x = 2; pixel_y = 3},/turf/unsimulated/floor{dir = 0; icon_state = "whitegreen"},/area/centcom/holding) "FX" = (/obj/structure/table,/obj/item/clothing/glasses/hud/health,/obj/item/clothing/glasses/hud/health,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/unsimulated/floor{dir = 6; icon_state = "whitegreen"},/area/centcom/holding) -"FY" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome) -"FZ" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access_txt = "101"},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"FY" = (/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"FZ" = (/obj/item/tape/engineering{tag = "icon-engineering_v"; icon_state = "engineering_v"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Ga" = (/obj/structure/closet/secure_closet/bar,/turf/unsimulated/floor{icon_state = "white"},/area/tdome) "Gb" = (/turf/unsimulated/floor{icon_state = "white"},/area/tdome) "Gc" = (/obj/machinery/gibber,/turf/unsimulated/floor{icon_state = "white"},/area/tdome) @@ -1674,7 +1674,7 @@ "Gj" = (/obj/machinery/vending/coffee,/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 8},/area/tdome/tdomeobserve) "Gk" = (/obj/structure/closet/secure_closet/freezer/meat,/turf/unsimulated/floor{icon_state = "white"},/area/tdome) "Gl" = (/obj/structure/closet/secure_closet/freezer/fridge,/turf/unsimulated/floor{icon_state = "white"},/area/tdome) -"Gm" = (/obj/structure/stool/bed/chair,/obj/effect/landmark{name = "tdomeobserve"},/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 8},/area/tdome/tdomeobserve) +"Gm" = (/obj/structure/bed/chair,/obj/effect/landmark{name = "tdomeobserve"},/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 8},/area/tdome/tdomeobserve) "Gn" = (/obj/structure/disposalpipe/trunk,/obj/structure/disposaloutlet,/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 8},/area/tdome/tdomeobserve) "Go" = (/obj/machinery/vending/snack,/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 8},/area/tdome/tdomeobserve) "Gp" = (/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 3},/obj/structure/table,/turf/unsimulated/floor{icon_state = "white"},/area/tdome) @@ -1683,7 +1683,7 @@ "Gs" = (/obj/machinery/computer/security/telescreen,/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 8},/area/tdome/tdomeobserve) "Gt" = (/obj/item/device/camera,/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 8},/area/tdome/tdomeobserve) "Gu" = (/obj/structure/disposalpipe/segment,/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 8},/area/tdome/tdomeobserve) -"Gv" = (/obj/structure/stool/bed/chair,/obj/structure/disposalpipe/segment,/obj/effect/landmark{name = "tdomeobserve"},/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 8},/area/tdome/tdomeobserve) +"Gv" = (/obj/structure/bed/chair,/obj/structure/disposalpipe/segment,/obj/effect/landmark{name = "tdomeobserve"},/turf/unsimulated/floor{icon_state = "redbluefull"; dir = 8},/area/tdome/tdomeobserve) "Gw" = (/obj/structure/table/rack,/obj/item/clothing/under/color/green,/obj/item/clothing/shoes/brown,/obj/item/clothing/suit/armor/tdome/green,/obj/item/clothing/head/helmet/thunderdome,/obj/item/weapon/melee/baton/loaded,/obj/item/weapon/melee/energy/sword/green,/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) "Gx" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/turf/simulated/floor,/area/tdome) "Gy" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/tdome) @@ -1719,26 +1719,26 @@ "Hc" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor,/area/tdome) "Hd" = (/obj/effect/overlay/palmtree_l,/turf/unsimulated/beach/sand,/area/beach) "He" = (/obj/effect/overlay/palmtree_r,/obj/effect/overlay/coconut,/turf/unsimulated/beach/sand,/area/beach) -"Hf" = (/obj/machinery/door/airlock/command{name = "Thunderdome Administration"; req_access = null; req_access_txt = "102"},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome) +"Hf" = (/obj/structure/bed/chair/office/dark,/obj/machinery/door_control{desc = "A remote control switch for port-side blast doors."; icon_state = "doorctrl0"; id = "CentComPort"; name = "Security Doors"; pixel_x = -12; pixel_y = -25; req_access = list(101)},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) "Hg" = (/obj/machinery/door/blast/regular{id = "thunderdomeaxe"; name = "Axe Supply"},/turf/unsimulated/floor{icon_state = "dark"},/area/tdome) "Hh" = (/obj/effect/overlay/coconut,/turf/unsimulated/beach/sand,/area/beach) "Hi" = (/turf/unsimulated/floor{icon_state = "redcorner"; dir = 8},/area/tdome) "Hj" = (/obj/structure/table/rack,/obj/item/weapon/kitchenknife/ritual,/turf/unsimulated/floor{dir = 4; icon_state = "chapel"},/area/wizard_station) -"Hk" = (/obj/machinery/door/airlock/command{name = "Thunderdome Administration"; req_access = null; req_access_txt = "102"},/turf/simulated/floor,/area/tdome) +"Hk" = (/obj/item/tape/engineering{tag = "icon-engineering_v"; icon_state = "engineering_v"},/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Hl" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/effect/forcefield{desc = "You can't get in. Heh."; layer = 1; name = "Blocker"},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor,/area/tdome) -"Hm" = (/obj/structure/table/rack,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/obj/item/weapon/tank/nitrogen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"Hm" = (/turf/unsimulated/wall{tag = "icon-iron1"; icon_state = "iron1"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Hn" = (/turf/unsimulated/floor{icon_state = "greencorner"},/area/tdome) "Ho" = (/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) -"Hp" = (/obj/structure/stool/bed/chair{dir = 1},/obj/effect/landmark{name = "tdomeadmin"},/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) +"Hp" = (/obj/structure/bed/chair{dir = 1},/obj/effect/landmark{name = "tdomeadmin"},/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) "Hq" = (/obj/item/weapon/extinguisher,/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) "Hr" = (/obj/machinery/atmospherics/valve,/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) -"Hs" = (/obj/structure/stool/bed/chair{dir = 1},/obj/structure/disposalpipe/segment,/obj/effect/landmark{name = "tdomeadmin"},/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) +"Hs" = (/obj/structure/bed/chair{dir = 1},/obj/structure/disposalpipe/segment,/obj/effect/landmark{name = "tdomeadmin"},/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) "Ht" = (/obj/effect/overlay/palmtree_r,/turf/unsimulated/beach/sand,/area/beach) "Hu" = (/obj/machinery/computer/security/telescreen,/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) "Hv" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/sleeping_agent{pixel_x = 1},/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) "Hw" = (/obj/item/weapon/wrench,/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) "Hx" = (/obj/structure/disposalpipe/trunk{dir = 1},/obj/machinery/disposal,/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) -"Hy" = (/obj/structure/stool/bed/chair,/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) +"Hy" = (/obj/structure/bed/chair,/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) "Hz" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/turf/unsimulated/beach/sand,/area/beach) "HA" = (/obj/structure/table,/obj/item/clothing/under/rainbow,/obj/item/clothing/glasses/sunglasses,/obj/item/clothing/head/collectable/petehat{pixel_y = 5},/turf/unsimulated/beach/sand,/area/beach) "HB" = (/obj/structure/table,/obj/machinery/recharger{pixel_y = 4},/turf/unsimulated/floor{icon_state = "redyellowfull"; dir = 5},/area/tdome/tdomeadmin) @@ -1756,7 +1756,7 @@ "HN" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/snacks/chips,/turf/unsimulated/beach/sand,/area/beach) "HO" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/obj/item/weapon/reagent_containers/food/drinks/cans/cola,/turf/unsimulated/beach/sand,/area/beach) "HP" = (/obj/item/weapon/beach_ball,/turf/unsimulated/beach/sand,/area/beach) -"HQ" = (/obj/structure/stool/bed/chair,/turf/unsimulated/beach/sand,/area/beach) +"HQ" = (/obj/structure/bed/chair,/turf/unsimulated/beach/sand,/area/beach) "HR" = (/mob/living/simple_animal/crab/Coffee,/turf/unsimulated/beach/sand,/area/beach) "HS" = (/obj/item/clothing/head/collectable/paper,/turf/unsimulated/beach/sand,/area/beach) "HT" = (/turf/unsimulated/floor{icon_state = "sandwater"},/area/beach) @@ -1773,7 +1773,7 @@ "Ie" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/security_space_law,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "If" = (/obj/structure/table/woodentable,/obj/item/weapon/book/manual/nuclear,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "Ig" = (/obj/structure/table/woodentable,/obj/effect/landmark{name = "Teleport-Scroll"},/turf/unsimulated/floor{dir = 9; icon_state = "carpetside"},/area/wizard_station) -"Ih" = (/obj/structure/table/woodentable,/obj/item/weapon/paper{info = "

        LIST OF SPELLS AVAILABLE

        Magic Missile:
        This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage.

        Fireball:
        This spell fires a fireball at a target and does not require wizard garb. Be careful not to fire it at people that are standing next to you.

        Disintegrate:
        This spell instantly kills somebody adjacent to you with the vilest of magick. It has a long cooldown.

        Disable Technology:
        This spell disables all weapons, cameras and most other technology in range.

        Smoke:
        This spell spawns a cloud of choking smoke at your location and does not require wizard garb.

        Blind:
        This spell temporarly blinds a single person and does not require wizard garb.

        Forcewall:
        This spell creates an unbreakable wall that lasts for 30 seconds and does not require wizard garb.

        Blink:
        This spell randomly teleports you a short distance. Useful for evasion or getting into areas if you have patience.

        Teleport:
        This spell teleports you to a type of area of your selection. Very useful if you are in danger, but has a decent cooldown, and is unpredictable.

        Mutate:
        This spell causes you to turn into a hulk, and gain telekinesis for a short while.

        Ethereal Jaunt:
        This spell creates your ethereal form, temporarily making you invisible and able to pass through walls.

        Knock:
        This spell opens nearby doors and does not require wizard garb.

        "; name = "List of Available Spells (READ)"},/turf/unsimulated/floor{dir = 1; icon_state = "carpetside"},/area/wizard_station) +"Ih" = (/obj/structure/table/woodentable,/obj/item/weapon/paper{info = "\[center]\[b]LIST OF SPELLS AVAILABLE\[/b]\[/center]\[br]\[br]Magic Missile:\[br]This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage.\[br]\[br]Fireball:\[br]This spell fires a fireball at a target and does not require wizard garb. Be careful not to fire it at people that are standing next to you.\[br]\[br]Disintegrate:\[br]This spell instantly kills somebody adjacent to you with the vilest of magick. It has a long cooldown.\[br]\[br]Disable Technology:\[br]This spell disables all weapons, cameras and most other technology in range.\[br]\[br]Smoke:\[br]This spell spawns a cloud of choking smoke at your location and does not require wizard garb.\[br]\[br]Blind:\[br]This spell temporarly blinds a single person and does not require wizard garb.\[br]Forcewall:\[br]This spell creates an unbreakable wall that lasts for 30 seconds and does not require wizard garb.\[br]\[br]Blink:\[br]This spell randomly teleports you a short distance. Useful for evasion or getting into areas if you have patience.\[br]\[br]Teleport:\[br]This spell teleports you to a type of area of your selection. Very useful if you are in danger, but has a decent cooldown, and is unpredictable.\[br]\[br]Mutate:\[br]This spell causes you to turn into a hulk, and gain telekinesis for a short while.\[br]\[br]Ethereal Jaunt:\[br]This spell creates your ethereal form, temporarily making you invisible and able to pass through walls.\[br]\[br]Knock:\[br]This spell opens nearby doors and does not require wizard garb.\[br]"; name = "List of Available Spells (READ)"},/turf/unsimulated/floor{dir = 1; icon_state = "carpetside"},/area/wizard_station) "Ii" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/backpack/satchel/withwallet,/turf/unsimulated/floor{dir = 5; icon_state = "carpetside"},/area/wizard_station) "Ij" = (/obj/structure/toilet{pixel_y = 8},/turf/unsimulated/floor{icon_state = "engine"},/area/wizard_station) "Ik" = (/turf/unsimulated/floor{icon_state = "engine"},/area/wizard_station) @@ -1791,7 +1791,7 @@ "Iw" = (/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},/obj/structure/table/woodentable,/obj/item/device/flashlight/lamp/green{on = 0; pixel_x = -3; pixel_y = 8},/obj/item/weapon/reagent_containers/food/drinks/flask/barflask,/turf/unsimulated/floor{dir = 6; icon_state = "carpetside"},/area/wizard_station) "Ix" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/bag/cash,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "Iy" = (/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) -"Iz" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/rd,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) +"Iz" = (/obj/structure/bed,/obj/item/weapon/bedsheet/rd,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) "IA" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/suit/wizrobe/red,/obj/item/clothing/shoes/sandal,/obj/item/clothing/head/wizard/red,/obj/item/weapon/staff,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) "IB" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/suit/wizrobe/marisa,/obj/item/clothing/shoes/sandal/marisa,/obj/item/clothing/head/wizard/marisa,/obj/item/weapon/staff/broom,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) "IC" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/suit/wizrobe/magusblue,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) @@ -1800,86 +1800,86 @@ "IF" = (/obj/machinery/vending/magivend,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "IG" = (/obj/structure/mineral_door/wood{tag = "icon-wood"; icon_state = "wood"},/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) "IH" = (/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/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) -"II" = (/turf/simulated/shuttle/wall{icon_state = "swall_s6"; dir = 2},/area/space) -"IJ" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/space) -"IK" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/space) -"IL" = (/obj/structure/table/woodentable,/obj/machinery/chem_dispenser/soda,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"II" = (/obj/structure/table,/obj/item/weapon/storage/box/drinkingglasses{pixel_x = 1; pixel_y = 4},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"IJ" = (/obj/structure/table/reinforced,/obj/item/weapon/tray{pixel_y = 5},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"IK" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/machinery/door/window/southright{name = "Arrivals Processing"; req_access = list(101)},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"IL" = (/turf/unsimulated/wall{icon_state = "iron14"},/area/syndicate_mothership{name = "\improper Raider Base"}) "IM" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/backpack/cultpack,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) "IN" = (/obj/structure/table/woodentable,/obj/item/clothing/glasses/monocle,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) "IO" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/backpack,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) "IP" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/under/psysuit,/obj/item/clothing/suit/wizrobe/psypurple,/obj/item/clothing/head/wizard/amp,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) "IQ" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/shoes/sandal/marisa{desc = "A set of fancy shoes that are as functional as they are comfortable."; name = "Gentlemans Shoes"},/obj/item/clothing/under/gentlesuit,/obj/item/clothing/suit/wizrobe/gentlecoat,/obj/item/clothing/head/wizard/cap,/obj/item/weapon/staff/gentcane,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) "IR" = (/obj/structure/closet{icon_closed = "cabinet_closed"; icon_opened = "cabinet_open"; icon_state = "cabinet_closed"},/obj/item/clothing/suit/wizrobe/magusred,/obj/item/clothing/head/wizard/magus,/obj/item/weapon/staff,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station) -"IS" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/space) -"IT" = (/turf/space,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/vox/station) -"IU" = (/turf/simulated/shuttle/wall{icon_state = "pwall"; dir = 1},/area/space) -"IV" = (/turf/space,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/vox/station) -"IW" = (/turf/simulated/shuttle/wall{icon_state = "swall14"; dir = 2},/area/space) -"IX" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/space) -"IY" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/vox/station) -"IZ" = (/obj/machinery/atmospherics/unary/freezer{set_temperature = 73; dir = 2; icon_state = "freezer_1"; use_power = 1},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/holding) -"Ja" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"Jb" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"Jc" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/space) -"Jd" = (/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"IS" = (/turf/unsimulated/wall{tag = "icon-iron2"; icon_state = "iron2"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"IT" = (/obj/structure/table,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/syndicate_mothership{name = "\improper Raider Base"}) +"IU" = (/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"IV" = (/obj/machinery/door/airlock/glass_command{name = "Escape Shuttle Cockpit"; req_access = list(19)},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"IW" = (/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/obj/effect/decal/cleanable/cobweb2{tag = "icon-cobweb1"; icon_state = "cobweb1"},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"IX" = (/obj/structure/table/reinforced,/obj/machinery/microwave{pixel_x = -1; pixel_y = 8},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"IY" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "centcom_shuttle_bay"; name = "shuttle bay controller"; pixel_x = 0; pixel_y = 25; tag_door = "centcom_shuttle_bay_door"},/turf/unsimulated/floor{name = "plating"},/area/centcom/ferry) +"IZ" = (/obj/structure/flora/pottedplant{tag = "icon-plant-06"; icon_state = "plant-06"},/turf/simulated/floor/holofloor{icon_state = "wood"; dir = 4},/area/holodeck/source_theatre) +"Ja" = (/obj/machinery/computer/shuttle_control{req_access = list(101); shuttle_tag = "Centcom"},/turf/unsimulated/floor{name = "plating"},/area/centcom/ferry) +"Jb" = (/obj/structure/table,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Jc" = (/turf/unsimulated/wall{icon_state = "iron11"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Jd" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "Je" = (/obj/structure/table/woodentable,/obj/item/weapon/dice/d20,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "Jf" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/box/cups,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) -"Jg" = (/obj/structure/stool/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 8},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"Jg" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 8},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "Jh" = (/obj/item/target,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/wizard_station) "Ji" = (/obj/item/target/syndicate,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/wizard_station) "Jj" = (/obj/item/target/alien,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/wizard_station) "Jk" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 1},/area/wizard_station) -"Jl" = (/obj/structure/table/rack,/obj/item/weapon/rcd,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/obj/item/weapon/rcd_ammo,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"Jl" = (/obj/structure/closet/secure_closet/freezer/kitchen,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/syndicate_mothership{name = "\improper Raider Base"}) "Jm" = (/obj/structure/kitchenspike,/obj/structure/table/reinforced,/turf/unsimulated/floor{dir = 4; icon_state = "chapel"},/area/wizard_station) "Jn" = (/obj/structure/kitchenspike,/obj/structure/table/reinforced,/turf/unsimulated/floor{dir = 1; icon_state = "chapel"},/area/wizard_station) -"Jo" = (/obj/structure/table/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/suit/space/vox/carapace,/obj/item/clothing/head/helmet/space/vox/carapace,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Jp" = (/obj/machinery/computer/station_alert,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Jq" = (/obj/machinery/computer/shuttle_control/multi/vox,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/vox/station) -"Jr" = (/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/vox/station) +"Jo" = (/obj/item/tape/engineering{tag = "icon-engineering_h"; icon_state = "engineering_h"},/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Jp" = (/obj/structure/urinal{pixel_y = 32},/obj/item/weapon/soap/syndie,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Jq" = (/obj/structure/urinal{pixel_y = 32},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Jr" = (/turf/unsimulated/wall{icon_state = "iron9"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Js" = (/obj/structure/table/woodentable,/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/snacks/milosoup,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "Jt" = (/obj/structure/table/woodentable,/obj/item/weapon/dice,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "Ju" = (/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/wizard_station) "Jv" = (/turf/unsimulated/wall/fakeglass,/area/wizard_station) "Jw" = (/turf/unsimulated/floor{dir = 8; icon_state = "chapel"},/area/wizard_station) "Jx" = (/turf/unsimulated/floor{icon_state = "chapel"},/area/wizard_station) -"Jy" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1331; master_tag = "vox_west_control"; req_one_access_txt = "150"},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/vox/station) -"Jz" = (/obj/machinery/door/airlock/hatch{frequency = 1331; icon_state = "door_locked"; id_tag = "vox_northwest_lock"; locked = 1; req_access_txt = "150"; req_one_access = null; req_one_access_txt = "0"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"JA" = (/obj/machinery/door_control{id = "skipjack"; pixel_y = 24},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"JB" = (/obj/effect/landmark{name = "voxstart"},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"JC" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"JD" = (/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"JE" = (/obj/machinery/door/airlock/hatch{frequency = 1331; icon_state = "door_locked"; id_tag = "vox_northeast_lock"; locked = 1; req_access_txt = "150"; req_one_access = null; req_one_access_txt = "0"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"JF" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1331; master_tag = "vox_east_control"; req_access_txt = "150"},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/vox/station) +"Jy" = (/obj/structure/closet/secure_closet/freezer/fridge,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Jz" = (/obj/machinery/computer/shuttle_control{req_access = list(101); shuttle_tag = "Centcom"},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"JA" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership{name = "\improper Raider Base"}) +"JB" = (/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership{name = "\improper Raider Base"}) +"JC" = (/obj/machinery/gibber,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"JD" = (/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"JE" = (/obj/structure/kitchenspike,/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"JF" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "centcom_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) "JG" = (/obj/structure/table/woodentable,/obj/item/device/megaphone,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) -"JH" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/donut_box,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) -"JI" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{frequency = 1331; id_tag = "vox_west_vent"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"JJ" = (/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "vox_west_sensor"; pixel_x = 25},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"JK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"JL" = (/obj/item/weapon/stool,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"JM" = (/obj/item/clothing/head/collectable/petehat{desc = "It smells faintly of reptile."; name = "fancy leader hat"},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"JN" = (/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "vox_east_sensor"; pixel_x = -25},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"JO" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{frequency = 1331; id_tag = "vox_east_vent"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) +"JH" = (/obj/machinery/door/airlock/glass_security{name = "Escape Shuttle Cell"; req_access = list(2)},/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) +"JI" = (/obj/item/clothing/head/xenos,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"JJ" = (/obj/item/organ/xenos/plasmavessel,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"JK" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror/raider{pixel_x = -28; pixel_y = 0},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership{name = "\improper Raider Base"}) +"JL" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "centcom_shuttle"; pixel_x = 0; pixel_y = -25; tag_door = "centcom_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/shuttle/transport1/centcom) +"JM" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "centcom_dock_airlock"; locked = 1; name = "Arrivals Airlock"; req_access = list(13)},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/centcom/evac) +"JN" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/obj/machinery/mech_sensor{dir = 8; frequency = 1380; id_tag = "shuttle_dock_north_mech"; pixel_y = -19},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"JO" = (/obj/item/clothing/mask/gas/swat{desc = "A close-fitting mask clearly not made for a human face."; name = "\improper alien mask"},/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) "JP" = (/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/snacks/chawanmushi,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "JQ" = (/obj/structure/table/woodentable,/obj/item/weapon/spacecash/c1,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) "JR" = (/obj/structure/table/reinforced,/obj/item/weapon/book/manual/robotics_cyborgs,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/wizard_station) "JS" = (/obj/structure/table/reinforced,/obj/item/robot_parts/head,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/wizard_station) "JT" = (/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/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/wizard_station) -"JU" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"JV" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "vox_west_vent"; tag_exterior_door = "vox_northwest_lock"; frequency = 1331; id_tag = "vox_west_control"; tag_interior_door = "vox_southwest_lock"; pixel_x = 24; req_access_txt = "150"; tag_chamber_sensor = "vox_west_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1331; id_tag = "vox_west_vent"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"JW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/regular{dir = 2; id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"JX" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "vox_east_vent"; tag_exterior_door = "vox_northeast_lock"; frequency = 1331; id_tag = "vox_east_control"; tag_interior_door = "vox_southeast_lock"; pixel_x = -24; req_access_txt = "150"; tag_chamber_sensor = "vox_east_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1331; id_tag = "vox_east_vent"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"JY" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"JZ" = (/obj/machinery/door/airlock/hatch{frequency = 1331; icon_state = "door_locked"; id_tag = "vox_southwest_lock"; locked = 1; req_access_txt = "150"; req_one_access = null; req_one_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"Ka" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "vox_west_control"; req_one_access_txt = "150"},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/vox/station) -"Kb" = (/obj/machinery/door/airlock/hatch{req_access_txt = "150"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"Kc" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "vox_east_control"; req_one_access_txt = "150"},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/vox/station) -"Kd" = (/obj/machinery/door/airlock/hatch{frequency = 1331; icon_state = "door_locked"; id_tag = "vox_southeast_lock"; locked = 1; req_access_txt = "150"; req_one_access = null; req_one_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) +"JU" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/vox/carapace,/obj/item/clothing/head/helmet/space/vox/carapace,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/gloves/yellow/vox,/obj/item/weapon/gun/launcher/spikethrower,/obj/item/clothing/under/vox/vox_casual,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"JV" = (/obj/item/xenos_claw,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"JW" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/vox/carapace,/obj/item/clothing/head/helmet/space/vox/carapace,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/gloves/yellow/vox,/obj/item/weapon/gun/launcher/spikethrower,/obj/item/clothing/under/vox/vox_robes,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"JX" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{dir = 4; pixel_x = -28; pixel_y = 0},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership{name = "\improper Raider Base"}) +"JY" = (/obj/machinery/shower{dir = 1},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership{name = "\improper Raider Base"}) +"JZ" = (/obj/item/pizzabox/meat,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Ka" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/vox/medic,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/gloves/yellow/vox,/obj/item/clothing/under/vox/vox_robes,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Kb" = (/obj/structure/reagent_dispensers/beerkeg,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Kc" = (/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Kd" = (/obj/effect/decal/cleanable/cobweb2,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Ke" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 8},/area/wizard_station) "Kf" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows2"; dir = 8},/area/wizard_station) "Kg" = (/turf/unsimulated/wall/fakeglass{dir = 1; icon_state = "fakewindows"},/area/wizard_station) "Kh" = (/turf/unsimulated/wall/fakeglass{icon_state = "fakewindows"; dir = 4},/area/wizard_station) -"Ki" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"Kj" = (/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) +"Ki" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "centcom_dock"; name = "docking port controller"; pixel_x = 25; pixel_y = 0; req_one_access = list(13); tag_door = "centcom_dock_airlock"},/turf/unsimulated/floor{dir = 6; icon_state = "warning"},/area/centcom/evac) +"Kj" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/gloves/yellow/vox,/obj/item/clothing/under/vox/vox_casual,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Kk" = (/obj/effect/decal/remains/human,/turf/unsimulated/floor{tag = "icon-lava"; name = "plating"; icon_state = "lava"},/area/wizard_station) "Kl" = (/turf/unsimulated/floor{tag = "icon-lava"; name = "plating"; icon_state = "lava"},/area/wizard_station) "Km" = (/turf/unsimulated/floor{tag = "icon-ironsand8"; icon_state = "ironsand8"},/turf/unsimulated/floor{tag = "icon-asteroid8"; name = "plating"; icon_state = "asteroid8"},/area/wizard_station) @@ -1888,137 +1888,319 @@ "Kp" = (/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/wizard_station) "Kq" = (/obj/structure/flora/ausbushes/fullgrass,/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/wizard_station) "Kr" = (/obj/effect/decal/cleanable/blood,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/wizard_station) -"Ks" = (/mob/living/carbon/monkey{name = "Murphey"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/wizard_station) +"Ks" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/vox/stealth,/obj/item/clothing/head/helmet/space/vox/stealth,/obj/item/clothing/shoes/magboots/vox,/obj/item/clothing/gloves/yellow/vox,/obj/item/clothing/glasses/thermal/monocle,/obj/item/clothing/under/vox/vox_robes,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) "Kt" = (/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/wizard_station) -"Ku" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast/regular{dir = 2; id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"Kv" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Kw" = (/obj/structure/window/basic{dir = 1},/obj/structure/table,/obj/machinery/recharger,/obj/item/robot_parts/chest,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Kx" = (/obj/structure/window/basic{dir = 1},/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weed_extract,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Ky" = (/obj/structure/window/basic{dir = 1},/obj/structure/table,/obj/machinery/bot/floorbot,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Kz" = (/obj/structure/window/basic{dir = 1},/obj/structure/table,/obj/item/broken_device,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KA" = (/obj/structure/table/reinforced,/obj/item/weapon/pickaxe,/obj/item/weapon/storage/firstaid/toxin,/obj/structure/window/basic{dir = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KB" = (/obj/structure/table/reinforced,/obj/item/weapon/scalpel,/obj/item/stack/cable_coil,/obj/item/weapon/storage/firstaid/regular,/obj/structure/window/basic{dir = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KC" = (/obj/structure/table/reinforced,/obj/item/weapon/circular_saw,/obj/structure/window/basic{dir = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KD" = (/obj/machinery/optable,/obj/item/organ/brain,/obj/structure/window/basic{dir = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"Ku" = (/obj/effect/landmark{name = "voxstart"},/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Kv" = (/obj/machinery/porta_turret{anchored = 0; check_records = 0; enabled = 0; req_one_access = list(103); use_power = 0},/turf/unsimulated/floor{icon_state = "bot"},/area/centcom/evac) +"Kw" = (/obj/item/organ/xenos/eggsac,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Kx" = (/obj/item/weapon/tank/nitrogen,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Ky" = (/obj/item/organ/stack,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"Kz" = (/obj/structure/bed/chair,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"KA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"KB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"KC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"KD" = (/obj/machinery/computer/shuttle_control/multi/vox,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) "KE" = (/mob/living/simple_animal/hostile/creature{name = "Experiment 35b"},/turf/unsimulated/floor{tag = "icon-lava"; name = "plating"; icon_state = "lava"},/area/wizard_station) -"KF" = (/obj/effect/landmark{name = "Holocarp Spawn Random"},/turf/simulated/floor/holofloor{icon_state = "1"; dir = 5},/area/holodeck/source_space) +"KF" = (/turf/space/transit/east/shuttlespace_ew8,/area/shuttle/escape_pod5/transit) "KG" = (/turf/unsimulated/floor{tag = "icon-ironsand14"; icon_state = "ironsand14"},/turf/unsimulated/floor{tag = "icon-asteroid7"; name = "plating"; icon_state = "asteroid7"},/area/wizard_station) "KH" = (/obj/structure/flora/ausbushes/grassybush,/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/wizard_station) "KI" = (/mob/living/simple_animal/hostile/retaliate/goat{name = "Experiment 97d"},/turf/unsimulated/floor{icon_state = "grass1"; name = "grass"},/area/wizard_station) "KJ" = (/obj/item/weapon/caution,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/wizard_station) "KK" = (/obj/item/weapon/kitchenknife/ritual,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/wizard_station) -"KL" = (/obj/item/weapon/screwdriver{pixel_y = 15},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KM" = (/obj/item/weapon/organ/r_arm,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KN" = (/obj/machinery/atmospherics/pipe/tank/nitrogen{dir = 1; initialize_directions = 1; start_pressure = 493.6},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KO" = (/obj/machinery/portable_atmospherics/canister/phoron,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KP" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KQ" = (/obj/structure/table/rack,/obj/item/weapon/gun/dartgun/vox/raider,/obj/item/weapon/gun/dartgun/vox/medical,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/obj/item/weapon/dart_cartridge,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KR" = (/obj/structure/table/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/suit/space/vox/medic,/obj/item/clothing/head/helmet/space/vox/medic,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KS" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/pneumatic,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/harpoon,/obj/item/weapon/tank/nitrogen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KT" = (/obj/structure/table/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/suit/space/vox/pressure,/obj/item/clothing/head/helmet/space/vox/pressure,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KU" = (/obj/machinery/sleeper,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KV" = (/obj/machinery/sleep_console,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KW" = (/obj/machinery/bodyscanner,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KX" = (/obj/machinery/body_scanconsole,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"KY" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/shuttle/vox/station) -"KZ" = (/obj/structure/shuttle/engine/heater,/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"La" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/spikethrower,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Lb" = (/obj/structure/table/rack,/obj/item/clothing/tie/storage/black_vest,/obj/item/clothing/suit/space/vox/stealth,/obj/item/clothing/head/helmet/space/vox/stealth,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Lc" = (/turf/space,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/vox/station) -"Ld" = (/obj/structure/shuttle/engine/propulsion,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/vox/station) -"Le" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast/regular{dir = 2; id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"Lf" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/weapon/reagent_containers/blood/OMinus,/obj/item/roller,/obj/item/roller,/obj/item/roller,/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom) -"Lg" = (/obj/structure/table/rack,/obj/item/rig_module/mounted/taser,/obj/item/rig_module/mounted/taser,/obj/item/rig_module/mounted/taser,/obj/item/rig_module/maneuvering_jets,/obj/item/rig_module/maneuvering_jets,/obj/item/rig_module/grenade_launcher,/obj/item/rig_module/device/drill,/obj/item/rig_module/device/healthscanner,/obj/item/rig_module/device/plasmacutter,/obj/item/rig_module/device/rcd,/obj/item/rig_module/chem_dispenser/combat,/obj/item/rig_module/chem_dispenser/injector,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom) -"Lh" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"Li" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"Lj" = (/obj/machinery/door/airlock/hatch{req_access_txt = "150"; req_one_access = null; req_one_access_txt = "0"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station) -"Lk" = (/obj/item/clothing/head/bowler,/obj/item/weapon/broken_bottle,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Ll" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Lm" = (/obj/item/weapon/tank/emergency_oxygen,/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Ln" = (/obj/item/clothing/head/bearpelt,/obj/item/xenos_claw,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Lo" = (/obj/structure/stool/bed/chair{dir = 4},/obj/item/clothing/mask/breath,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Lp" = (/obj/item/clothing/head/collectable/xenom,/obj/item/clothing/head/chicken,/obj/item/weapon/aiModule/syndicate,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Lq" = (/obj/item/weapon/spacecash/c1000,/obj/item/weapon/spacecash/c500,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Lr" = (/obj/item/weapon/spacecash/c50,/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Ls" = (/obj/structure/AIcore,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) -"Lt" = (/obj/item/weapon/spacecash/c200,/obj/item/weapon/spacecash/c50,/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station) +"KL" = (/obj/machinery/computer/station_alert,/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"KM" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/item/weapon/tank/nitrogen,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"KN" = (/obj/item/clothing/head/philosopher_wig,/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"KO" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access = list(13)},/obj/machinery/mech_sensor{dir = 8; frequency = 1380; id_tag = "shuttle_dock_south_mech"; pixel_y = 19},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"KP" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 4},/turf/space,/area/syndicate_mothership{name = "\improper Raider Base"}) +"KQ" = (/obj/machinery/door/airlock/external{req_access = list(150)},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"KR" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 8},/turf/space,/area/syndicate_mothership{name = "\improper Raider Base"}) +"KS" = (/obj/machinery/door/airlock/glass_medical{name = "Arrivals Medbay"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/holding) +"KT" = (/obj/machinery/door/airlock/glass_medical{name = "Escape Shuttle Infirmary"; req_access = list(5)},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"KU" = (/obj/structure/window/reinforced{dir = 4},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"KV" = (/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"}) +"KW" = (/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = 0; pixel_y = 29},/turf/unsimulated/floor{dir = 4; icon_state = "whitegreencorner"},/area/centcom/holding) +"KX" = (/obj/machinery/vending/wallmed1{layer = 3.3; name = "Emergency NanoMed"; pixel_x = 28; pixel_y = 0},/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"KY" = (/turf/space,/turf/simulated/shuttle/wall{dir = 8; icon_state = "diagonalWall3"},/area/shuttle/skipjack/station) +"KZ" = (/turf/space,/turf/simulated/shuttle/wall{dir = 1; icon_state = "diagonalWall3"},/area/shuttle/skipjack/station) +"La" = (/obj/structure/closet/secure_closet/bar{req_access = list(25)},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding) +"Lb" = (/obj/structure/table/woodentable{dir = 5},/obj/machinery/chemical_dispenser/bar_alc/full,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding) +"Lc" = (/obj/structure/table/woodentable{dir = 5},/obj/machinery/chemical_dispenser/bar_soft/full,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding) +"Ld" = (/turf/unsimulated/wall{tag = "icon-iron2"; icon_state = "iron2"},/area/shuttle/skipjack/station) +"Le" = (/obj/machinery/door/airlock/hatch{frequency = 1331; icon_state = "door_locked"; id_tag = "vox_northwest_lock"; locked = 1; req_access = list(150)},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Lf" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1331; master_tag = "vox_west_control"; req_one_access = list(150)},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/skipjack/station) +"Lg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast{dir = 2; id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Lh" = (/turf/unsimulated/wall{icon_state = "iron6"},/area/shuttle/skipjack/station) +"Li" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast{dir = 2; id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Lj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast{dir = 2; id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Lk" = (/turf/unsimulated/wall{icon_state = "iron10"},/area/shuttle/skipjack/station) +"Ll" = (/obj/machinery/door/airlock/hatch{frequency = 1331; icon_state = "door_locked"; id_tag = "vox_northeast_lock"; locked = 1; req_access = list(150)},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Lm" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1331; master_tag = "vox_east_control"; req_access = list(150)},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/skipjack/station) +"Ln" = (/obj/machinery/door/airlock/centcom{name = "Thunderdome"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome) +"Lo" = (/turf/unsimulated/wall{icon_state = "iron3"},/area/shuttle/skipjack/station) +"Lp" = (/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "vox_west_sensor"; pixel_x = 25},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Lq" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{frequency = 1331; id_tag = "vox_west_vent"},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Lr" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/skipjack/station) +"Ls" = (/obj/machinery/computer/shuttle_control/multi/vox,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"Lt" = (/obj/machinery/computer/station_alert,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) "Lu" = (/turf/unsimulated/floor{tag = "icon-ironsand7"; icon_state = "ironsand7"},/turf/unsimulated/floor{tag = "icon-asteroid7"; name = "plating"; icon_state = "asteroid7"},/area/wizard_station) "Lv" = (/turf/unsimulated/floor{tag = "icon-ironsand12"; icon_state = "ironsand12"},/turf/unsimulated/floor{tag = "icon-asteroid2"; name = "plating"; icon_state = "asteroid2"},/area/wizard_station) -"Lw" = (/obj/structure/closet/secure_closet/medical_wall{pixel_y = 0; req_access = null; req_access_txt = "150"},/obj/item/weapon/surgicaldrill,/obj/item/clothing/gloves/latex,/obj/item/clothing/mask/surgical,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/glass/bottle/stoxin,/obj/item/weapon/reagent_containers/syringe,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/syndicate_station/start) +"Lw" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) "Lx" = (/obj/structure/sign/nosmoking_2{pixel_x = 32},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start) -"Ly" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/box/handcuffs,/obj/item/clothing/glasses/sunglasses/sechud{pixel_y = 3},/obj/item/clothing/glasses/sunglasses/sechud{pixel_y = 3},/obj/item/clothing/glasses/sunglasses/sechud{pixel_y = 3},/obj/item/clothing/glasses/sunglasses/sechud{pixel_y = 3},/obj/item/clothing/glasses/night{pixel_x = -1; pixel_y = -3},/obj/item/clothing/glasses/night{pixel_x = -1; pixel_y = -3},/obj/item/clothing/glasses/night{pixel_x = -1; pixel_y = -3},/obj/item/clothing/glasses/night,/obj/item/weapon/storage/box/handcuffs,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom/specops) +"Ly" = (/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "vox_east_sensor"; pixel_x = -25},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Lz" = (/turf/simulated/floor/holofloor{icon_state = "carpet7-3"; dir = 4},/area/holodeck/source_theatre) +"LA" = (/turf/simulated/floor/holofloor/grass,/turf/simulated/floor/holofloor{icon_state = "wood_siding1"; dir = 2},/obj/structure/flora/ausbushes/ywflowers,/turf/simulated/floor/holofloor{icon_state = "wood_siding5"; dir = 2},/area/holodeck/source_picnicarea) +"LB" = (/turf/simulated/floor/holofloor{icon_state = "carpet11-12"; dir = 4},/area/holodeck/source_theatre) +"LC" = (/turf/simulated/floor/holofloor{dir = 4; icon_state = "carpet3-0"},/area/holodeck/source_theatre) +"LD" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdownside"; nostop = 1; tiles = 0},/turf/space,/area/space) +"LE" = (/turf/simulated/floor/holofloor{icon_state = "carpet11-12"; dir = 4},/area/holodeck/source_courtroom) +"LF" = (/turf/simulated/floor/holofloor{icon_state = "carpet7-3"; dir = 4},/area/holodeck/source_courtroom) +"LG" = (/obj/machinery/door/window/holowindoor{base_state = "right"; icon_state = "right"},/turf/simulated/floor/holofloor{icon_state = "grimy"; dir = 2},/area/holodeck/source_courtroom) +"LH" = (/obj/machinery/door/window/holowindoor{base_state = "right"; icon_state = "right"; name = "Green Team"},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_emptycourt) +"LI" = (/turf/simulated/floor/holofloor{icon_state = "wood"; dir = 4},/area/holodeck/source_meetinghall) +"LJ" = (/obj/structure/window/reinforced/holowindow,/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_boxingcourt) +"LK" = (/obj/machinery/door/window/holowindoor{base_state = "right"; dir = 2; icon_state = "right"; name = "Red Corner"},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_boxingcourt) +"LL" = (/obj/machinery/door/window/holowindoor{name = "Red Team"},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_thunderdomecourt) +"LM" = (/obj/machinery/door/window/holowindoor{name = "Red Team"},/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_basketball) +"LN" = (/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor{icon_state = "wood"; dir = 4},/area/holodeck/source_meetinghall) +"LO" = (/turf/unsimulated/wall{icon_state = "iron7"},/area/space) +"LP" = (/turf/space/transit/east/shuttlespace_ew9,/area/shuttle/escape_pod5/transit) +"LQ" = (/obj/structure/flora/pottedplant{tag = "icon-plant-06"; icon_state = "plant-06"},/turf/simulated/floor/holofloor{icon_state = "wood"; dir = 4},/area/holodeck/source_meetinghall) +"LR" = (/obj/structure/table/holotable,/obj/item/clothing/gloves/boxing/hologlove,/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_boxingcourt) +"LS" = (/turf/space/transit/east/shuttlespace_ew2,/area/shuttle/escape_pod5/transit) +"LT" = (/turf/space/transit/east/shuttlespace_ew3,/area/shuttle/escape_pod5/transit) +"LU" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 8; name = "thrower_escapeshuttletop(left)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns12,/area/space) +"LV" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 8; name = "thrower_escapeshuttletop(left)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns11,/area/space) +"LW" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{frequency = 1331; id_tag = "vox_east_vent"},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"LX" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "vox_west_vent"; tag_exterior_door = "vox_northwest_lock"; frequency = 1331; id_tag = "vox_west_control"; tag_interior_door = "vox_southwest_lock"; pixel_x = 24; req_access = list(150); tag_chamber_sensor = "vox_west_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1331; id_tag = "vox_west_vent"},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"LY" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"LZ" = (/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"Ma" = (/turf/unsimulated/wall{icon_state = "iron9"},/area/shuttle/skipjack/station) +"Mb" = (/obj/structure/bed/chair{dir = 1},/obj/item/clothing/glasses/thermal/monocle,/obj/item/clothing/head/pirate,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"Mc" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"Md" = (/turf/unsimulated/wall{icon_state = "iron5"},/area/shuttle/skipjack/station) +"Me" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "vox_east_vent"; tag_exterior_door = "vox_northeast_lock"; frequency = 1331; id_tag = "vox_east_control"; tag_interior_door = "vox_southeast_lock"; pixel_x = -24; req_access = list(150); tag_chamber_sensor = "vox_east_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1331; id_tag = "vox_east_vent"},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Mf" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Mg" = (/turf/unsimulated/wall{tag = "icon-iron7"; icon_state = "iron7"},/area/shuttle/skipjack/station) +"Mh" = (/turf/unsimulated/wall{tag = "icon-iron4"; icon_state = "iron4"},/area/shuttle/skipjack/station) +"Mi" = (/obj/machinery/door/airlock/hatch{frequency = 1331; icon_state = "door_locked"; id_tag = "vox_southwest_lock"; locked = 1; req_access = list(150)},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Mj" = (/turf/unsimulated/wall{icon_state = "iron12"},/area/shuttle/skipjack/station) +"Mk" = (/turf/unsimulated/wall{icon_state = "iron13"},/area/shuttle/skipjack/station) +"Ml" = (/turf/unsimulated/wall{icon_state = "iron11"},/area/shuttle/skipjack/station) +"Mm" = (/obj/structure/table/rack,/obj/item/weapon/rig/industrial,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"Mn" = (/obj/structure/table/rack,/obj/item/weapon/rig/light/hacker,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"Mo" = (/turf/unsimulated/wall{tag = "icon-iron8"; icon_state = "iron8"},/area/shuttle/skipjack/station) +"Mp" = (/obj/machinery/door/airlock/hatch{frequency = 1331; icon_state = "door_locked"; id_tag = "vox_southeast_lock"; locked = 1; req_access = list(150)},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Mq" = (/obj/machinery/door/airlock/medical{name = "Operating Theatre"; req_access = list(45)},/turf/unsimulated/floor{icon_state = "white"},/area/centcom/holding) +"Mr" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/ionrifle,/obj/item/weapon/harpoon,/obj/item/clothing/suit/space/void/merc,/obj/item/clothing/head/helmet/space/void/merc,/obj/item/clothing/head/helmet/space/void/engineering,/obj/item/clothing/suit/space/void/engineering,/obj/item/weapon/tank/oxygen,/obj/item/weapon/tank/oxygen,/obj/item/clothing/shoes/magboots,/obj/item/clothing/shoes/magboots,/obj/item/weapon/rig/light/stealth,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"Ms" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"Mt" = (/obj/structure/table,/obj/item/seeds/potatoseed,/obj/item/seeds/potatoseed,/obj/item/seeds/ambrosiavulgarisseed,/obj/item/weapon/minihoe,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"Mu" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -1; pixel_y = 8},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"Mv" = (/obj/machinery/vending/hydroseeds,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"Mw" = (/obj/structure/table/rack,/obj/item/weapon/melee/energy/sword/pirate,/obj/item/clothing/suit/space/pirate,/obj/item/clothing/suit/space/pirate,/obj/item/weapon/tank/oxygen,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"Mx" = (/obj/machinery/washing_machine,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"My" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/utility/full,/obj/item/weapon/storage/belt/utility/full,/obj/item/device/multitool,/obj/item/device/multitool,/obj/item/clothing/shoes/magboots,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"Mz" = (/obj/structure/table/rack,/obj/item/weapon/gun/energy/sniperrifle,/obj/item/clothing/suit/space/void/mining,/obj/item/clothing/head/helmet/space/void/mining,/obj/item/clothing/head/helmet/space/void/atmos,/obj/item/clothing/suit/space/void/atmos,/obj/item/weapon/tank/oxygen,/obj/item/weapon/tank/oxygen,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"MA" = (/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/turf/space/transit/north/shuttlespace_ns12,/area/space) +"MB" = (/obj/structure/table,/obj/item/weapon/storage/fancy/cigarettes,/obj/structure/table/reinforced{icon_state = "table"},/obj/item/weapon/flame/lighter/zippo,/obj/item/clothing/gloves/yellow,/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/weapon/card/emag,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"MC" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = 28},/turf/unsimulated/floor{tag = "icon-whitecorner (NORTH)"; icon_state = "whitecorner"; dir = 1},/area/centcom/holding) +"MD" = (/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"ME" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"MF" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast{dir = 2; id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"MG" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast{dir = 2; id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"MH" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"MI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast{dir = 2; id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"MJ" = (/obj/structure/table/rack,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/syndicate/black/engie,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/syndicate/black/engie,/turf/unsimulated/floor{icon_state = "dark"},/area/shuttle/skipjack/station) +"MK" = (/obj/item/robot_parts/head,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"ML" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast{id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"MM" = (/obj/item/robot_parts/l_leg,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"MN" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome) +"MO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast{id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"MP" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) +"MQ" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) +"MR" = (/obj/machinery/hologram/holopad,/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) +"MS" = (/obj/machinery/camera{c_tag = "Shuttle"},/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) +"MT" = (/obj/machinery/status_display{pixel_y = 30},/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) +"MU" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 30},/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor4,/area/shuttle/escape/centcom) +"MV" = (/obj/structure/bed/chair{dir = 4},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/camera{c_tag = "Shuttle West"; dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"MW" = (/obj/structure/bed/chair{dir = 8},/obj/structure/closet/walllocker/emerglocker{pixel_x = 28},/obj/machinery/camera{c_tag = "Shuttle East"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"MX" = (/obj/machinery/camera{c_tag = "Shuttle Center"},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"MY" = (/obj/machinery/status_display{pixel_y = 30},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"MZ" = (/obj/machinery/camera{c_tag = "Crescent Arrivals East"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/evac) +"Na" = (/obj/structure/window/shuttle{icon_state = "window12"},/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/escape/centcom) +"Nb" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"Nc" = (/obj/machinery/hologram/holopad,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"Nd" = (/obj/machinery/computer/secure_data,/obj/machinery/camera{c_tag = "Crescent Arrivals North"; dir = 8},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"Ne" = (/turf/simulated/shuttle/wall{tag = "icon-swall2"; icon_state = "swall2"; dir = 2},/area/shuttle/escape/centcom) +"Nf" = (/obj/machinery/computer/crew,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Ng" = (/obj/structure/AIcore/deactivated,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"Nh" = (/obj/machinery/computer/security,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Ni" = (/obj/machinery/computer/secure_data,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Nj" = (/obj/machinery/computer/station_alert,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Nk" = (/obj/machinery/computer/shuttle_control/emergency,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Nl" = (/obj/machinery/computer/communications,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Nm" = (/obj/machinery/computer/med_data,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Nn" = (/obj/structure/table/rack,/obj/item/weapon/gun/launcher/crossbow,/obj/item/stack/rods{amount = 10},/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"No" = (/obj/machinery/status_display{pixel_y = 30},/obj/structure/table,/obj/machinery/camera{c_tag = "Shuttle Bridge East"},/obj/item/weapon/storage/firstaid/toxin,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"Np" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"Nq" = (/obj/machinery/hologram/holopad,/turf/unsimulated/floor{dir = 9; icon_state = "whitegreen"},/area/centcom/holding) +"Nr" = (/obj/machinery/camera{c_tag = "Crescent Medical"; dir = 4},/turf/unsimulated/floor{dir = 4; icon_state = "whitegreencorner"},/area/centcom/holding) +"Ns" = (/obj/machinery/sleeper{icon_state = "sleeper_0-r"; orient = "RIGHT"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Nt" = (/obj/machinery/sleep_console{icon_state = "sleeperconsole-r"; orient = "RIGHT"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"Nu" = (/obj/machinery/hologram/holopad,/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/area/centcom/ferry) +"Nv" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/beaker/cryoxadone{pixel_x = 5; pixel_y = 5},/obj/item/weapon/reagent_containers/glass/beaker/cryoxadone{pixel_x = 0; pixel_y = 0},/obj/item/weapon/reagent_containers/glass/beaker/cryoxadone{pixel_x = 7; pixel_y = 1},/obj/item/weapon/wrench,/turf/unsimulated/floor{dir = 8; icon_state = "whitegreen"},/area/centcom/holding) +"Nw" = (/obj/machinery/camera{c_tag = "Crescent Bar Center"},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) +"Nx" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/camera{c_tag = "Crescent Arrivals South"; dir = 4},/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/control) +"Ny" = (/obj/machinery/hologram/holopad,/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) +"Nz" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/flame/lighter/zippo,/obj/item/weapon/storage/fancy/cigarettes,/obj/item/ashtray/bronze{pixel_x = -1; pixel_y = 1},/obj/machinery/camera{c_tag = "Crescent Bar East"; dir = 4},/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/area/centcom/holding) +"NA" = (/obj/machinery/hologram/holopad,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/control) +"NB" = (/obj/structure/table/rack,/obj/item/weapon/grenade/empgrenade,/obj/item/weapon/grenade/flashbang,/obj/item/weapon/grenade/spawnergrenade,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"NC" = (/obj/machinery/status_display{pixel_y = -30},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom) +"ND" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/oxygen/prechilled,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/holding) +"NE" = (/obj/structure/closet/walllocker/emerglocker{pixel_x = -28},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape/centcom) +"NF" = (/obj/structure/closet/hydrant{pixel_x = 30; pixel_y = 0},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape/centcom) +"NG" = (/obj/structure/closet/walllocker/emerglocker{pixel_x = 28},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape/centcom) +"NH" = (/obj/machinery/atmospherics/unary/cryo_cell{layer = 3.3},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"NI" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/oxygen/prechilled,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"NJ" = (/obj/structure/closet/crate/medical,/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/weapon/storage/firstaid/regular{pixel_x = -2; pixel_y = 4},/obj/item/bodybag/cryobag{pixel_x = 5},/obj/item/bodybag/cryobag{pixel_x = 5},/obj/item/weapon/storage/firstaid/o2{layer = 2.8; pixel_x = 4; pixel_y = 6},/obj/item/weapon/storage/box/masks{pixel_x = 0; pixel_y = 0},/obj/item/weapon/storage/box/gloves{pixel_x = 3; pixel_y = 4},/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/fire{layer = 2.9; pixel_x = 2; pixel_y = 3},/obj/item/weapon/storage/firstaid/adv{pixel_x = -2},/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/obj/item/weapon/reagent_containers/blood/empty,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"NK" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/beaker/cryoxadone{pixel_x = -4; pixel_y = 0},/obj/item/weapon/wrench,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"NL" = (/obj/structure/closet/hydrant{pixel_x = -30; pixel_y = 0},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape/centcom) +"NM" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"NN" = (/obj/machinery/door/airlock/glass_mining{name = "Shuttle Cargo"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape/centcom) +"NO" = (/obj/machinery/camera{c_tag = "Crescent Bar West"; dir = 4},/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/area/centcom/ferry) +"NP" = (/obj/structure/bed/roller,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"NQ" = (/obj/machinery/iv_drip,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"NR" = (/obj/machinery/hologram/holopad,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"NS" = (/obj/machinery/recharge_station,/obj/machinery/camera{c_tag = "Shuttle East Storage"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape/centcom) +"NT" = (/obj/machinery/recharge_station,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape/centcom) +"NU" = (/obj/item/robot_parts/robot_suit,/obj/item/robot_parts/r_leg,/obj/item/robot_parts/r_arm,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"NV" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"NW" = (/obj/machinery/camera{c_tag = "Shuttle Medical"; dir = 4},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom) +"NX" = (/obj/structure/closet/crate/freezer/rations,/obj/machinery/camera{c_tag = "Shuttle West Storage"; dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape/centcom) +"NY" = (/obj/structure/closet/crate/freezer/rations,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/escape/centcom) +"NZ" = (/obj/machinery/door/airlock/centcom{name = "General Access"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/tdome) +"Oa" = (/obj/structure/table,/turf/unsimulated/floor{icon_state = "redyellowfull"},/area/centcom/living) +"Ob" = (/obj/structure/table,/turf/unsimulated/floor{icon_state = "cafeteria"; dir = 2},/area/centcom/evac) +"Oc" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast{id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Od" = (/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Oe" = (/obj/structure/table,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"Of" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"Og" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"Oh" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Oi" = (/obj/item/weapon/wrench,/obj/item/weapon/mop,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"Oj" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"Ok" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/item/weapon/crowbar,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"Ol" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"Om" = (/obj/machinery/atmospherics/pipe/tank/nitrogen{dir = 1; initialize_directions = 1; start_pressure = 493.6},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"On" = (/turf/simulated/shuttle/floor{icon_state = "floor7"},/area/shuttle/skipjack/station) +"Oo" = (/obj/structure/table,/obj/item/weapon/deck,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"Op" = (/obj/machinery/body_scanconsole,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/skipjack/station) +"Oq" = (/obj/machinery/bodyscanner,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/skipjack/station) +"Or" = (/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/skipjack/station) +"Os" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/item/weapon/tank/nitrogen,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"Ot" = (/obj/structure/toilet{dir = 4},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station) +"Ou" = (/turf/unsimulated/wall{tag = "icon-iron1"; icon_state = "iron1"},/area/shuttle/skipjack/station) +"Ov" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "diagonalWall3"},/area/shuttle/skipjack/station) +"Ow" = (/obj/structure/shuttle/engine/heater,/turf/simulated/shuttle/plating/vox,/area/shuttle/skipjack/station) +"Ox" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/skipjack/station) +"Oy" = (/turf/space,/turf/simulated/shuttle/wall{dir = 4; icon_state = "diagonalWall3"},/area/shuttle/skipjack/station) +"Oz" = (/obj/structure/shuttle/engine/propulsion,/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/skipjack/station) +"OA" = (/obj/structure/table,/obj/item/weapon/deck,/turf/simulated/shuttle/floor{icon_state = "floor7"},/area/shuttle/skipjack/station) +"OB" = (/obj/structure/table,/obj/item/weapon/legcuffs,/turf/simulated/shuttle/floor{icon_state = "floor7"},/area/shuttle/skipjack/station) +"OC" = (/obj/structure/table,/obj/item/weapon/circular_saw{pixel_y = 8},/obj/item/weapon/hemostat,/obj/item/weapon/scalpel,/obj/item/stack/medical/advanced/bruise_pack,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/skipjack/station) +"OD" = (/obj/machinery/optable,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/skipjack/station) +"OE" = (/obj/structure/table,/obj/item/weapon/cautery,/obj/item/weapon/retractor,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/skipjack/station) +"OF" = (/obj/structure/sink{dir = 4; icon_state = "sink"; pixel_x = 11; pixel_y = 0},/turf/simulated/shuttle/floor{icon_state = "floor7"},/area/shuttle/skipjack/station) +"OG" = (/obj/structure/bed,/obj/item/weapon/bedsheet/rainbow,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"OH" = (/obj/structure/bed,/obj/item/weapon/bedsheet/hos,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"OI" = (/obj/structure/table,/obj/item/weapon/bonesetter,/obj/item/weapon/bonegel,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/skipjack/station) +"OJ" = (/obj/structure/toilet{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor7"},/area/shuttle/skipjack/station) +"OK" = (/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"OL" = (/obj/structure/bed,/obj/item/weapon/bedsheet/green,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"OM" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/adv{pixel_x = 1},/obj/item/weapon/storage/firstaid/toxin{pixel_x = 3; pixel_y = 3},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/skipjack/station) +"ON" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/fire{pixel_x = 1},/obj/item/weapon/storage/firstaid/o2{pixel_x = 3; pixel_y = 3},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/skipjack/station) +"OO" = (/turf/unsimulated/wall{icon_state = "iron14"},/area/shuttle/skipjack/station) +"OP" = (/obj/item/pizzabox/meat,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"OQ" = (/obj/structure/bed,/obj/item/weapon/bedsheet/rd,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"OR" = (/obj/structure/bed,/obj/item/weapon/bedsheet/clown,/turf/simulated/shuttle/floor{icon_state = "floor4"; oxygen = 0},/area/shuttle/skipjack/station) +"OS" = (/obj/machinery/door/airlock/command{name = "Thunderdome Administration"; req_access = list(102)},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome) +"OT" = (/obj/machinery/door/airlock/command{name = "Thunderdome Administration"; req_access = list(102)},/turf/simulated/floor,/area/tdome) +"OU" = (/obj/structure/table/woodentable,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"OV" = (/turf/space,/area/shuttle/skipjack/station) +"OW" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/box/donut,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station) +"OX" = (/mob/living/carbon/human/monkey{name = "Murphey"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/wizard_station) +"OY" = (/obj/machinery/door/airlock/centcom{name = "Engineering Special Operations"; opacity = 1; req_access = list(103)},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops) (1,1,1) = {" -aaabacadaeafagahaaaiajakalamanaoagafajacadahakaeamaiaoapaqarasatauavawaxayazaAaBaCaDaEaFaGaHaIaJaKawaxayazaAaBaCaDaEaFaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaNaOaOaOaOaOaPaOaOaOaOaOaPaOaOaOaOaOaPaOaOaOaOaOaPaOaOaOaOaOaPaOaOaOaOaOaPaOaOaOaOaOaQ -ajaRaSaTaUaVaWaXaYaZbabbbcbdbebfaWaVbaaSaTaXbbaUbdaZabatauavbgbhbibjaAbkblbmapaqarasatauavbgbhbibjbnbkblbmapaqarasataJaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbpbpbpbrbsbtbsbtbsbrbubqbqbqbqbrbwbwbwbwbwbrbxbxbxbxbxbraMaMaMaMaMbrbybzbzbzbAbB -amaUaZbcaXbeaSaWbaaVbdaYbfaTbbaRaSbebdaZbcaWaYaXaTaVaeaqarasatauavbgaxbibjbnbkblbmapaqararasataubgbhbibjbnbkblbmapaqaGaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbvbpbpbpbrbEbFbEbFbEbrbGbGbGbGbGbrbwbHbwbHbwbrbxbxbxbxbxbraMaMaMaMaMbrbIbJbJbJbKbB -adaXaVbfaWbbaZaSbdbeaTbaaRbcaYaUaZbbaTaVbfaSbaaWbcbeahbgbhbibjbnbkblaDapaqarasatauavbgbhavbgbhbiblbmapaqarasatauavbgaxaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbpbpbpbrbMbNbMbNbMbrbGbGbGbGbGbrbwbwbwbwbwbrbxbxbxbxbxbraMaMaMaMaMbrbIbJbJbJbKbB -alaWbeaRaSaYaVaZaTbbbcbdaUbfbaaXaVaYbcbeaRaZbdaSbfbbagblbmapaqarasataJavbgbhbibjbnbkblbmasatauavatauavbgbhbibjbnbkblaDaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbCbpbpbrbQbQbQbQbQbrbRbRbRbRbSbrbwbwbwbwbwbrbxbxbxbxbxbraMaMaMaMaMbrbIbJbJbJbKbB -aoaSbbaUaZbabeaVbcaYbfaTaXaRbdaWbebabfbbaUaVaTaZaRaYacbgbhbibjbnbkblaDapaqarasatauavbgbhbibjbnbkblbmapaqarasatauavbgaxaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbpbpbpbrbUbVbWbVbXbrbYbZcacbbYbrbwbwbHbwbwbrbxbxbxbxbxbraMaMaMaMaMbrbIbJbJbJbKbB -abaZaYaXaVbdbbbebfbacccdcecfcgchbbbdaRaYaXbebcaVaUbaaiarasatauavbgbhaybjbnbkblbmapaqarasapaqarasbhbibjbnbkblbmapaqaraHaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbpbpbpbrcjbVbWbVckbrbYclcmcnbYbrbwbwbHbwbwbrbxbxbxbxbxbraMaMaMaMaMbrcobJbJbJcpbB -aeaVbaaWbeaTaYbbaRcqcrcsctcucvcwcxaTaUbaaWbbbfbeaXbdafbnbkblbmapaqaraHatauavbgbhbibjbnbiavaraqbhauasatauavbgbhbibjbnaBaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbvbpbpbCbrbQbQbQbQbQbrcyclcmcncybrbwbwbwbwbwbrbxbxbxbxbxbraMaMaMaMaMbrcobJbJbJcpbB -ahbebdaSbbbcbaaYaUczcucAcBcCcscDcEbcaXbdaSaYaRbbaWaTanbmapaqarasatauaKbgbhbibjbnbkblbmcFcGcHcIcJcKavbgbhbibjbnbkblbmaEaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbpbpbpbrcLcMcLcMcLbrcNclcmcncNbrbwbwbwbwbwbrbxbxbxbxbxbraMaMaMaMaMbrcobJbJbJcpbB -agbbaTaZaYbfbdbaaXcOcPcBcQcRcSctcTbeaWaTaZbaaUaYaSbcakbibjbnbkblbmapaFarasatauavbgbhbicKcUcVcWcXcYaqarasatauavbgbhbiazaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbpbpbpbrbEbFbEbFbEbrcNclcmcncNbrbwbHbwbHbwbrbxbxbxbxbxbraMaMaMaMaMbrcobJbJbJcpbB -acaYbcaVbaaRaTbdaWchcvcDdacucQcBdbdcaSbcaVbdaXbaaZbfaaasatauavbgbhbiazbnbkblbmapaqarasdddedfdgdhdibhbnbkblbmapaqarasaIaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobCbpbpbpbvbrbsbtbsbtbsbrdkdldmdndkbrbwbwbwbwbwbrbxbxbxbxbxbraMaMaMaMaMbrdodpdpdpdqbB -aibabfbebdaUbcaTchdrcsdscPcCdacDcAdtdubfbeaTaWbdaVaRajbhbibjbnbkblbmaEaqarasatauavbgbhdvdwdxdydedzapaqarasatauavbgbhayaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMdAdBdBdBdBdBdCdBdBdBdBdBdCdBdBdBdBdBdCdDdDdDdDdDdCdDdDdDdDdDdCdDdDdDdDdDdCdDdDdDdDdDdE -afbdaRbbaTaXbfbcducDcAdFcvctcPdscRcQdGaRbbbcaSaTbeaUamaqarasatauavbgaxbibjbnbkblbmapaqdHdddIcGcHcIbhbibjbnbkblbmapaqaGaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbodJdKdLdJdKbrdMdMdMdMdMbrdNdNdNdNdNbrdOdOdPdQdQbrdRdSdTdRdUbrdVdWdWdWdXbrdYdZdZdZeabB -anaTaUaYbcaWaRbfdGdscRcScscBcvdFcudaebaUaYbfaZbcbbaXadauavbgbhbibjbnaBblbmapaqarasatauarbibjbnbkbgbkblbmapaqarasatauaKaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbodKdLdJosdLbrdMecdMdMdMbrdNedeeefdNbregegeheieibrdUejekelembreneoeoeoepbreqerereresbB -akbcaXbabfaSaUaRebdFcucQcAcDcscScCcPdcaXbaaRaVbfaYaWalbjbnbkblbmapaqaGasatauavbgbhbibjcFcGcHcIcJcKarasatauavbgbhbibjaAaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbodLdJdKdLdJbrdMdMdMetdMbrdNeueueudNbregeveveveibrdRewdRdSdRbreneoeoeoepbreqerereresbB -aabfaWbdaRaZaXaUdccScCdacRdscAcQctcvcxaWbdaUbeaRbaaSaobkblbmapaqarasaIauavbgbhbibjbnbkcKexeyezeAcYatauavbgbhbibjbnbkaCaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbodJosdLdJdKbrdMdMdMdMdMbrdNdNdNdNdNbregeheheheibrdSdRdUekdUbreneoeoeoepbreqerereresbB -ajaRaSaTaUaVaWaXcxcQctcPcudFcRdacBcscEaSaTaXbbaUbdaZabavbgbhbibjbnbkaCbmapaqarasatauavddeBeCeDeEdiblbmapaqarasatauavawaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbodKdLdJdKdLbrdMdMdMeFdMbrdNeGeHeIdNbreJeKeKeKeLbrdRdTdReMdTbreNeOeOeOePbreqerereresbB -amaUaZbcaXbeaSaWcEdacBcvcCcScucPcDcAcqaZbcaWaYaXaTaVaebnbkblbmapaqaraHatauavbgbhbibjbndveQeReSeBdzasatauavbgbhbibjbnaBaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbodLdJdKdLdJbrdMeTdMdMdMbrdNeUeVeWdNbreXeYeYeYeZbrdUfafbfcdSbrfdfefefeffbrfgerererfhbB -adaXaVbfaWbbaZaScqcPcDcsctcQcCcvdscRczaVbfaSbaaWbcbeaharasatauavbgbhaybjbnbkblbmapaqardHdddIcGcHcIbibjbnbkblbmapaqaraHaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbodJdKdLKFdKbrdMdMdMdMecbrdNeUeVeWdNbrfiehfjehfkbrfaflfmfnfcbrfoeoeoeofpbrfgerererfhbB -alaWbeaRaSaYaVaZczcvdscAcBdactcsdFcucTbeaRaZbdaSbfbbagbibjbnbkblbmapaFarasatauavbgbhbibjbnbkblbmapaqarasatauavbgbhbiazaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbodKdLdJdKdLbrfqdMdMdMdMbrdNeUeVeWdNbrfifrfrfrfkbrflfmfmfmfnbrfoeoeoeofpbrfgerererfhbB -aoaSbbaUaZbabeaVcTcsdFcRcDcPcBcAcScCfsbbaUaVaTaZaRaYacatauavbgbhbibjaAbkblbmapaqarasatauavbgbhbibjbnbkblbmapaqarasataJaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbodLKFdKdLdJbrdMeFdMeTdMbrdNftfufvdNbrfifiehfkfkbrfmfmfmfmfmbrfoeoeoeofpbrfgerererfhbB -abaZaYaXaVbdbbbefscAcScudscvcDcRcQctccaYaXbebcaVaUbaaibmapaqarasatauaKbgbhbibjbnbkblbmapaqarasatauavbgbhbibjbnbkblbmaEaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbodJdKdLdJdKbrdMdMdMdMfqbrdNdNdNdNdNbrfwfwfxfyfybrfmfmfmfmfmbrfzfAfAfAfBbrfCfDfDfDfEbB -aeaVbaaWbeaTaYbbcccRcQcCdFcsdscudacBfFbaaWbbbfbeaXbdafbkblbmapaqarasaIauavbgbhbibjbnbkblbmapaqarasatauavbgbhbibjbnbkaCaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfGfHfHfHfHfHfIfHfHfHfHfHfIfHfHfHfHfHfIfHfHfHfHfHfIfHfHfHfHfHfIfHfHfHfHfHfIfHfHfHfHfHfJ -ahbebdaSbbbcbaaYfFcudactcScAdFcCcPcDfKbdaSaYaRbbaWaTanauavbgbhbibjbnaBblbmapaqarasatauavbgbhbibjbnbkblbmapaqarasatauaKaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -agbbaTaZaYbfbdbafKcCcPcBcQcRcSctcvdscOaTaZbaaUaYaSbcakbhbibjbnbkblbmaEaqarasatauavbgbhbibjbnbkblbmapaqarasatauavbgbhayaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -acaYbcaVbaaRaTbdcOctcvcDdacucQcBcsdFchbcaVbdaXbaaZbfaaasatauavbgbhbiazaAaBaCaDaEaFaGaHaIaJaKawaxayazaAaBaCaDaEaFaGaHaIaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aibabfbebdaUbcaTchcBcsdscPcCdacDcAcSdubfbeaTaWbdaVaRajaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -afbdaRbbaTaXbfbcducDcAdFcvctcPdscRcQdGaRbbbcaSaTbeaUamaRaaabacadaeafagahaaaiajakalamanaoagafajacadahakaeamaiaoaRbbaLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -anaTaUaYbcaWaRbfdGdscRcScscBcvdFcudaebaUaYbfaZbcbbaXadaUajaRaSaTaUaVaWaXaYaZbabbbcbdbebfaWaVbaaSaTaXbbaUbdaZabaUaYaLfLaZaRaYaZaYaZaRaYaZaRaYaZaRaYaZaRaYaZaRaYaZaYaZaRaYaZaRaYaZaRaYaZaRaYaZaZfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -akbcaXbabfaSaUaRebcOdFcDdacScBczfFchdcaXbaaRaVbfaYaWalaXamaUaZbcaXbeaSaWbaaVbdaYbfaTbbaRaSbebdaZbcaWaYaXaTaVaeaXbaaLfLaVaUbaaVbaaVaUbaaVaUbaaVaUbaaVaUbaaVaUbaaVbaaVaUbaaVaUbaaVaUbaaVaUbaaMaVfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aabfaWbdaRaZaXaUbbchcxebczcEdGcTaXaZaYaWbdaUbeaRbaaSaoaWadaXaVbfaWbbaZaSbdbeaTbaaRbcaYaUaZbbaTaVbfaSbaaWbcbeahaWbdaLfLbeaXbdbebeaXbdbeaXbdbeaXbdbeaXbdbebeaXbdbeaXbdbeaXbdbeaXbdbeaXbdbebeaXaMfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -ajaRaSaTaUaVaWaXaYaZbabbbcbdbebfaWaVbaaSaTaXbbaUbdaZabaSalaWbeaRaSaYaVaZaTbbbcbdaUbfbaaXaVaYbcbeaRaZbdaSbfbbagaSaTaLfLbeaWaWbcbeaWbcbeaWbcbeaWbcbeaWbcbebeaWaWbcbeaWbcbeaWbcbeaWbcbeaWbcbeaWaWfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfMfNfNfNfNfNfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -amaUaZbcaXbeaSaWbaaVbdaYbfaTbbaRaSbebdaZbcaWaYaXaTaVaeaZaoaSbbaUaZbabeaVbcaYbfaTaXaRbdaWbebabfbbaUaVaTaZaRaYacaZbcaLfLbbaSaSbfbbaSbfbbaSbfbbaSbfbbaSbfbbbbaSaSbfbbaSbfbbaSbfbbaSbfbbaSbfbbaSaSfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfPfQfRfSfTfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -adaXaVbfaWbbaZaSbdbeaTbaaRbcaYaUaZbbaTaVbfaSbaaWbcbeahaVabaZaYaXaVbdbbbebfbaaRbcaWaUaTaSbbbdaRaYaXbebcaVaUbaaiaVbfaLfLbfbabaaZbfbaaZbfbaaZbfbaaZbfbaaZbfbfbabaaZbfbaaZbfbaaZbfbaaZbfbaaZbfaTbafLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUfVfVfVfUfOfOfOfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -alaWbeaRaSaYaVaZaTbbbcbdaUbfbaaXaVaYbcbeaRaZbdaSbfbbagbeaeaVbaaWbeaTaYbbaRfWcfdbfXfYfZcwdtcgaUbaaWbbbfbeaXbdafbeaRaLfLaRbdbdaVaRbdaVaRbdaVaRbdaVaRbdaVaRaRbdbdaVaRbdaVaRbdaVaRbdaVaRbdaVaRbdbdfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUgagagafUfOgbgcfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aoaSbbaUaZbabeaVbcaYbfaTaXaRbdaWbebabfbbaUaVaTaZaRaYacbbahbebdaSbbbcbaaYgdgegfggghgigjgkglfZgmbdaSaYaRbbaWaTanbbaUaLfLaUaTaTbeaUaTbeaUaTbeaUaTbeaUaTbeaUaUaTaTbeaUaTbeaUaTbeaUaTbeaUaTbeaUaTaTfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUgngogpfUfOfOfOfOfOfOfOfOfOfOfOfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -abaZaYaXaVbdbbbebfbaaRbcaWaUaTaSbbbdaRaYaXbebcaVaUbaaiaYagbbaTaZaYbfbdbagmgigqghglgrgsgtgugvgwaTaZbaaUaYaSbcakaYaXaLfLaXbcbcbbaXbcbbaXbcbbaXbcbbaXgxgygmgmgxgxgyaXbcbbaXbcbbaXbcbbaXbcbbaXbcbcfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUgngogpfUgzgAgBgCgDgEgAgFgGgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aeanamacakalajaaaeadahabaiagaoafajalahamacaaabakagadafbaacaYbcaVbaaRaTbdgwgtgugkgIgfglghgjgJgKbcaVbdaXbaaZbfaabaaWaLfLaWbfbfaYaWbfaYaWbfaYaWbfaYaWgLgMgwgwgLgNgOaWbfaYaWbfaYaWbfaYaWbfaYaWbfbffLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUgngogpfUgPgAgEgEgDgEgAgEgHgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -ahbdaSaYaRbbaWaTbbbdaSaYaRbbaWaTbbaWaTbdaSaYaRbbaWaTanbdaibabfbebdaUbcaTgKghgjgvgqgigIgkgggsgQbfbeaTaWbdaVaRajbdaSaLfLaSaRaRbaaSaRbagKgRgSgKgRgSgKgRgTgUgUgVgVgSgKgRgSgKgRgSgKaRbaaSaRbaaSaRaRfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUgogogohtgXgYgEgEgDgEgAgFgGgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -agaTaZbaaUaYaSbcaYaTaZbaaUaYaSbcaYaSbcaTaZbaaUaYaSbcakaTafbdaRbbaTaXbfbcgQgkgggJgugtgqgvgrglgZaRbbbcaSaTbeaUamaTaZaLfLaZaUaUbdaZaUbdgQhabdaZhahbgQhahchdhdhahahcgQgdhcaZaUhcgQaUbdaZaUbdaZaUaUfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUgogogohtgXgYgEgEgEgEjugEgHgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhfhfhfaMhghghgaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -acbcaVbdaXbaaZbfbabcaVbdaXbaaZbfbaaZbfbcaVbdaXbaaZbfaabcanaTaUaYbcaWaRbfgZgvgrgsgjghgugJgfgIhhaUaYbfaZbcbbaXadbcbeaLfLaVaXaXaTaVaXaTgZhihjhkhihlhkhihjhkhkhihihjhkgmhjhkhihjgZaXaTaVaXaTaVaXaXfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUhmgohnfUgPgAgEgEgDgEgAgFgGgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhfhfhfaMhghghgaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aibfbeaTaWbdaVaRbdbfbeaTaWbdaVaRbdaVaRbfbeaTaWbdaVaRajbfakbcaXbabfaSaUaRhhhogfglgggkgjgsgicggyaXbaaRaVbfaYaWalbfbbaLfLbeaWaWbcbeaWbchhhphqhrhpgxhrhphqhrhrhphphqhrgwhqhrhphqhhaWbcbeaWbcbeaWaWfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNhsfUjvfUhugzgAgEgEgDgEgAgEgHgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhfhfhfaMhghghgaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -afaRbbbcaSaTbeaUaTaRbbbcaSaTbeaUaTbeaUaRbbbcaSaTbeaUamaRaabfaWbdaRaZaXaUhodtgrgvgrgvgggrgvfZgOaWbdaUbeaRbaaSaoaRaYaLfLbbaSaSbfbbaSbfgygUgNhvgUgLhvgUgNhvhvgUgUgNhvgKgNhvgUgNgyaSbfbbaSbfbbaSaSfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNaMhshwhuaMgzgAgEgEgDgEgAgFgGgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhxhyhzhAhBhfhfhfaMhghghghxhyhzhAhBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -anaUaYbfaZbcbbaXbcaUaYbfaZbcbbaXbcbbaXaUaYbfaZbcbbaXadaUajaRaSaTaXicfXhChDgrgigsgigsgfgigsgkfZfZgxhCaYaUbdaZabaUbaaLfLaZaRaYaZaYaZaRgOhdgVgMhdgVgMhdgVgMhdgVgMhdgMhdgVgMhdgVgOaZaRaYaZaRaYaZaZfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEhFhFhFhGhHhIhHhHhHhJhHhKhFhFhFhEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -akaXbaaRaVbfaYaWbfaXbaaRaVbfaYaWbfaYaWaXbaaRaVbfaYaWalaXamaUaZbcaWgygkgtgIgigsgjgrgvgigugvgrgqgkgkfXbaaXaTaVaeaXbdaLfLaVaUbaaVbaaVaUgShkhagThkhagThkhagThkhagThkgThkhagThkhagSaVaUbaaVaUbaaMaVfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEhLhMhNhOhPhQhRhShThUhPhVhWhXhYhEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aaaWbdaUbbaSaYbeaTaUhZiaibicidbaiecdifcwigaUbeaRbaaSaoaWadaXaVbfaSgOgkghgqgugvgggigsgtgjgkgfgugvggcwbdaWbcbeahaWaTaLfLbeaXbdbebdbeaXhbhrhihchrhihchrhihchrhihchrhchrhihchrhihbbeaXbdbeaXbdaMbefLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEiiiiijikilimilinilimilioijiiiihEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -ajbaaTaXaRbdaUbfaSaXipiqirisitaXiuiviwixiyaXbbaUbdaZabaSalaWbeaRaZgSgvgkgugjgJgrgkgqghgggsgigjgJgrizaTaSbfbbagaSbcaLfLbeaXbdbebdbegmhbhrhihchrhihchrhihchrhihchrhchrhihchrhihbhhaXbdbeaXbdaMbefLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAiAiAiAiBiAiAiAiCiDiAiAiAiCiAiAiAiAiAiAiCiAiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMiEhWiiiFimimimimimimimimimiFiihNiGaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -ambdbcaWaUaTaXaRaZaWiyiHiIiJiKaWiLiMiNiOiPaWaYaXaTaVaeaZaoaSbbaUaViQgJgvgjgggsgfgvgugkgrglgtgggsgficbcaZaRaYacaZbfaLfLbeaXbdbebdbegmhchrhihchrhihchrhihchrhihchrhchrhihchrhihchhaXbdbeaXbdaMbefLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiBiAiAiAiAiAiAiAiAiAiAiAiCiAiAiAiAiAiCiAiAiAiAiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMiEhHhKiRilimiliSiSilimiThGhHiGaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -adaTbfaSaXbcaWaUaVaSiPiUiVirieaSipiWiXiYiZaSbaaWbcbeahaVabaZaYaXbecggsgJgggrglgigJgjgvgfgIghgrglgihobfaVaUbaaibeaRaLfLbbaWaTbbaTbbgwhjhvhphjhvhphjhvhphjhvhphjhvhjhvhphjhvhphjgyaWaTbbaWaTaMbbfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAiAjaiAiAiAiAiAiBiAiAiDiCiAiAiCiAiAiCiDiAiCiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEjbinimjcjbjbjdimjehEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -albcaRaZaWbfaSaXbeaZiZisjfiIjgaZiyjhixjiitaZbdaSbfbbagbeaeaVbaaWbbfZglgsgrgfgIgtgsgggJgigqgkgfgIgtdtaRbeaXbdafaMaUaLfLbfbabaaZbfbagQgLgThdgNgTgQgLgThdgNgNgTgThdgLgShdgNgThdgLgSaZbfbaaZbfaTbafLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAiAiAiAiAiAiAiAiAiAiAiAiAiBiAiAiCiDiAiAiCiAiDihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMjjjjjjjjhEjkilimjcjbjbjdimhPhEjljljljlaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aobfaUaVaSaRaZaWbbaVitipiKiZhZaViPigiuiyiKaVaTaZaRaYacbbahbebdaSgOdbgIglgfgigqghglgrgsgtgugvgigqghhDgdbbaWaTanbbaXaLfLaRbdbdaVaRbdaVgRhbgZgRhbgZgRhchkgVgVhchchkgRhbgZgRhbgZgRbdaVaRbdaVaRbdbdfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAiAiAiAiAiAiAiAiAiAiBiAiAiAiAiAiDiAiCiDiAiCiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMjjjjjjjjjmjnimimiljojoilimjpjqjljljljlaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -abaRaXbebcaVaUbaaVaRaXbebcaVaUbaaVaUbaaRaXbebcaVaUbaaiaYagbbaTaZgSgggqgIgigtgugkgIgfglghgjgJgtgugkgIgmaYaSbcakaYaWaLfLaUaTaTbeaUaTbeaUaTbeaUaTbegdhjhrhahahjhjhrgdaTbeaUaTbeaUaTbeaUaTbeaUaTaTfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAjrjrjrjrjrjrjriAiAiAiAiAiAiAiCiAiAjaiDiAiAiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMjjjjjjjjhEhPjsimimimimimimilhEjljljljlaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aebaaWbbbfbeaXbdbebaaWbbbfbeaXbdbeaXbdbaaWbbbfbeaXbdafbaacaYbcaVhbgrgugqgtghgjgvgqgigIgkgggsghgjgvgqgwbaaZbfaabaaSaLfLaXbcbcbbaXbcbbaXbcbbaXbcbbgmhqhvhihihqhqhvgmbcbbaXbcbbaXbcbbaXbcbbaXbcbcfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAjtfOdjgWgWgWhefOjxiAiAiAiAjaiAiAiBiAiBiAiCiAiCihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhGhHhHhHjyimilimimjzhEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -ahaSaSaYaRbbaWaTbbaSaSaYaRbbaWaTbbaWaTaSaSaYaRbbaWaTanbdaibabfbehlgfgjgughgkgggJgugtgqgvgrglgkgggJgugKbdaVaRajbdaZaLfLaWbfbfaYaWbfaYaWbfaYaWbfaYgwgNgMhphpgNgNgMgwbfaYaWbfaYaWbfaYaWbfaYaWbfbffLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAfOjAjBjCjDjEjFjFfOjGiAiAjrjrjrjrjrjrjrjrjHjIjrihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEjJjJjKjLimilimimiljMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -agaZaZbaaUaYaSbcaYaZaZbaaUaYaSbcaYaSbcaZaZbaaUaYaSbcakaTafbdaRbbgxgigggjgkgvgrgsgjghgugJgfgIgvgrgsgjgQaTbeaUamaTbeaLfLaSaRaRbaaSaRbaaSaRbaaSaRbagKgVgTgUgUgVgVgTgKaRbaaSaRbaaSaRbaaSaRbaaSaRaRfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAfOjNjBjBjOjBjBjBfOjGiAjPjQjRjRjSihihihihihihihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMjTjUjUjUjVimjWjXjYjXhEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -acaVaVbdaXbaaZbfbaaVaVbdaXbaaZbfbaaZbfaVaVbdaXbaaZbfaabcanaTaUaYgLgtgrgggvgigJgkgIgsghgqgrgtgJgfglgggZbcbbaXadbcbbaLfLaZaUaUbdaZaUbdaZaUbdaZaUbdgQgdhchdhdhahahbgQaUbdaZaUbdaZaUbdaZaUbdaZaUaUfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAfOjZjBjBjBkajBkbfOjGjajPkckdkdkdkekfihkgkhihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEkikjjUkkimklkmknkohEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aibebeaTaWbdaVaRbdbebeaTaWbdaVaRbdaVaRbebeaTaWbdaVaRajbfakbcaXbagRghgfgrgJgtgsgvgqglgkgugfghgsgigIgrhhbfaYaWalbfaYaLfLaVaXaXaTaVaXaTaVaXaTaVaXaTaVgmhlgZgZgmgmhlaVaXaTaVaXaTaVaXaTaVaXaTaVaXaXfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAkpfOfOfOkqfOfOfOkriAiAkskckdkdktkdkdkukvkvkwihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEkxjUjUjLimjXkykykzhEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -afbbbbbcaSaTbeaUaTbbbbbcaSaTbeaUaTbeaUbbbbbcaSaTbeaUamaRaabfaWbdfFgkgigfgsghglgJgugIgvgjgigkglgtgqgfdcaRbaaSaoaRbaaLfLbeaWaWbcbeaWbcbeaWbcbeaWbcbeaWbcbebeaWaWbcbeaWbcbeaWbcbeaWbcbeaWbcbeaWaWfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAiAfOkAjBkAfOkBjrjrjrkCkDkdkEkFkGkdihkvkHkHihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEkikjjUjVimkIkykykJhEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -analahajaoacaeabanagakafamaafLfLfLfLfLahajabafaoaaagadaUajaRaSaTfYgvgtgiglgkgIgsgjgqgJgggtgvgIghgugidtaUbdaZabaUbdaLfLbbaSaSbfbbaSbfbbaSbfbbaSbfbbaSbfbbbbaSaSbfbbaSbfbbaSbfbbaSbfbbaSbfbbaSaSfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAiAfOkKjBkLfOjQjRjRjRjSihkdkEkMkGkdihihihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMiEkNkNhHkOkPhHhHkNkNiGaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -bebcaXbabfaSaUaRbeaWbbaVbdaYaZaTaUaSbbaXbaaRaVbfaYaWaTaXamaUaZbchCgJghgtgIgvcgglgggugsgrcwgJgqgkgjgthDaXaTbeaeaXaTaLfLaZaRaYaZaYaZaRaYaZaRaYaZaRaYaZaRaYaZaRaYaZaYaZaRaYaZaRaYaZaRaYaZaRaYaZaZfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAjtfOfOfOfOfOkKjBkLfOkckQkQkQkQkRkdkdkdkdkdkSkTkUihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMiEhKkVjdimkWkXhGiGaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -bbaWbdaUbeaRaUbeaRaWbdaUbeaRaWbdaUbeaRaWbdaUbeaRbaaSbcaWadaXaVbffXgsgkghgqgJfZgIgrgjglgfizgsgugvggghfWaWbcbeahaWbcaLfLaVaUbaaVbaaVaUbaaVaUbaaVaUbaaVaUbaaVaUbaaVbaaVaUbaaVaUbaaVaUbaaVaUbaaMaVfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAfOkYjBjBjBfOkKjBkLfOkDkQkZjRjSihkdkdkdkdkdihlalalbihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEjbiliSillchEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aYaSaTaXbbaUaXbbaUaSaTaXbbaUaSaTaXbbaUaSaTaXbbaUbdaZbfaSalaWbeaRcwglgvgkgugsdbcgfYldfWhCicglgjgJgrgkcgaSbfbbagaSbfaLfLbeaWaWbcbeaWbcbeaWbcbeaWbcbeaWbcbebeaWaWbcbeaWbcbeaWbcbeaWbcbeaWbcbeaWaWfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAfOkYjBkKlefOkKjBkLfOfOlflglhliihihihihihljihlklalbihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhElllmlnlolphEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -baaZbcaWaYaXaWaYaXaZbcaWaYaXaZbcaWaYaXaZbcaWaYaXaTaVaRaZaoaSbbaUizfWhoicdbhDldbcaWaUaTaShofWlddtfYicfZaZaRaYacaZaRaLfLbbaSaSbfbbaSbfbbaSbfbbaSbfbbaSbfbbbbaSaSbfbbaSbfbbaSbfbbaSbfbbaSbfbbaSaSfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihlqiAfOkYjBkKlrfOfOlsfOfOltjBjBfOlulvliihlwlxlyihihihihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMiElzlAlAlAlBiGaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -bdaVbfaSbaaWaSbaaWaVbfaSbaaWaVbfaSbaaWaVbfaSbaaWbcbeaUaVaeaVbaaWbeaTaYbbaRbdaUbfaSaXbcaZaYaTaUbaaWbbbfbeaXbdafaVaXaLfLaZaRaYaZaYaZaRaYaZaRaYaZaRaYaZaRaYaZaRaYaZaYaZaRaYaZaRaYaZaRaYaZaRaYaZaZfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAfOkYjBjBjBlCjBjBlDjBjBjBjBfOjGiAjPlElFlxlxihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aTbeaRaZbdaSaZbdaSbeaRaZbdaSbeaRaZbdaSbeaRaZbdaSbfbbaXbeahakadaiaaaoamajahalagaeafacabanamaoagadacaiaeaaacalanbeaWaLfLaVaUbaaVbaaVaUbaaVaUbaaVaUbaaVaUbaaVaUbaaVbaaVaUbaaVaUbaaVaUbaaVaUbaaMaVfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAfOkYjBjBjBlGjBjBjBlHjBjBjBfOlIiAjPkclwlJlxihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -bcbbaUaVaTaZaVaTaZbbaUaVaTaZbbaUaVaTaZbbaUaVaTaZaRaYaWaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAjtfOfOfOfOfOfOlKjBjBfOfOfOfOfOfOjxjPkDlwlxlxihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAfOlLlMlNlOlPfOjBjBjBfOlQlRlSlTlUfOlVihlwlxlWihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAfOlXlXlXlXlXlYjBjBjBlZjBjBjBjBmafOlVihihihihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAfOlLlMlXlXlXmbjBjBjBmcjBjBjBjBmafOjGiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAfOlXlXlXlXmdfOmemfmgfOmhfOjwfOfOfOmjiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aaabacadaeafagahaaaiajakalamanaoagafajacadahakaeamaiaoalahajeEapaqarasatauavawaxayazaAaBaCaDaEaFaGaHaIaJaKawaxayazaAaBaCaDaEaFaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtwtwtwtwtwtwtwtwtwtwtwtwtwaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaNaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaPaOaOaOaOaOaOaOaOaOaOaQ +ajaRaSaTaUaVaWaXaYaZbabbbcbdbebfaWaVbaaSaTaXbbaUbdaZbfbcaXbaabatauavbgbhbibjaAbkblbmapaqarasatauavbgbhbibjbnbkblbmapaqarasataJaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtwtItJtwtItKtwtLtMtwtItJtwaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbpbCbpbpbpbpbpbpbrbsbtbsbtbsbsbtbsbtbsbrbubqbqbqbqbqbqbqbqbqbreVeUeSeSeSeSeSeSeSeSbrbwbwbwbwbwbwbwbwbwbwbrbxbxbxbxbxbxbxbxbxbxbreReQePbybzbzbzbzbzbAbB +amaUaZbcaXbeaSaWbaaVbdaYbfaTbbaRaSbebdaZbcaWaYaXaTaVaRbfaWbdaeaqarasatauavbgaxbibjbnbkblbmapaqararasataubgbhbibjbnbkblbmapaqaGaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtwubtMtwubuctwubtJtwubudtwaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbpbpbpbpbpbpbvbpbrbEbFbEbFbEbFbEbFbEbFbrbGbGbGbGbGbGbGbGbGbGbreVfdeWeWeWeWeWeWeWeWbrbwbHbwbwbwbwbwbwbHbwbrbxbxbxbxbxbxbxbxbxbxbreReQePbIbJbJbJbJbJbKbB +adaXaVbfaWbbaZaSbdaSaTbaaRbcaYaUaZbbaTaVbfaSbaaWbcbeaUaRaSaTahbgbhbibjbnbkblaDapaqarasatauavbgbhavbgbhbiblbmapaqarasatauavbgaxaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtwtwtwtwtwtwtwtwtwtwtwtwtwaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbvbpbpbpbpbpbpbpbpbrbFbEbFbNbMbNbMbEbFbEbrbGbGbGbGbGbGbGbGbGbGbreVffeWeSALeSeWANAwAubrbwbwbwbwbwbwbwbwbwbwbrbxbxbxbxbxbxbxbxbxbxbreReRAObIbJbJbJbJbJbKbB +alaWbeaRaSaYaVaZaTaZbcbdaUbfbaaXaVaYbcbeaRaZbdaSbfbbaXaUaZbcagblbmapaqarasataJavbgbhbibjbnbkblbmasatauavatauavbgbhbibjbnbkblaDaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtwuBudtwtIudtwuCtJtwtItMtwaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbpbpbpbCbpbpbpbpbrbNbMBiBjbVbVbQBhbEbFbrbGbGbGbGbGbGbGbGbGbGbreVffBxBkCqBUBHftfCfvbrbwbwbwbHbwbwbHbwbwbwbrbxbxbxbxbxbxbxbxbxbxbreReQePbIbJbJbJbJbJbKbB +aoaSbbaUaZbabeaVbcaVbfcxfKcccqiZjgbUiLhZaUaVaTaZaRaYaWaXaVbfacbgbhbibjbnbkblaDapaqarasatauavbgbhbibjbnbkblbmapaqarasatauavbgaxaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtwubtJvhubtJtwubvitwubvjtwaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbCbpbpbpbCbpbpbpbrbQbQbQbQfEfEbQgebFbEbrbRbRbRbRbRbRbRbRbRfebreVfffjfgfgfgfuftfCfvbrbwbwbwbwbwbwbwbwbwbwbrbxbxbxbxbxbxbxbxbxbxbreReQePbIbJbJbJbJbJbKbB +abaZaYaXaVbdbbbebfbecqcEbSbSbSbSbSbSbSiLbUaUbcaVaUbaaSaWbeaRaiarasatauavbgbhaybjbnbkblbmapaqarasapaqarasbhbibjbnbkblbmapaqaraHaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtwtwtwtwtwtwtwtwtwtwtwtwtwaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbpbpbpbpbpbpbpbpbrbQbQbQbQfEfEbQgebFbEbrbYbZiQiQiQiQiQiQcbosbreVffzopGAkpGAjftfCfvbrbwbwbwbwbwbwbwbwbwbwbrbxbxbxbxbxbxbxbxbxbxbreReQePcobJbJbJbJbJcpbB +aeaVbaaWbeaTaYbbaRebczbSbSbSbSbSbSbSbSbSjgLDbfbeaXbdaZaSbbaUafbnbkblbmapaqaraHatauavbgbhbibjbnbiavaraqbhauasatauavbgbhbibjbnaBaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbpbpbpbvbpbpbpbCbrcMcLLABjbVbVbQBhbEbFbrbYLzcmcmcmcmcmcmLBLCbreVffEkCDAkCDCUftfCfvbrbwbwbwbHbwbwbHbwbwbwbrbxbxbxbxbxbxbxbxbxbxbreReQePcobJbJbJbJbJcpbB +ahbebdaSbbbcbaaYaUcxbSbSbSbSbSbSbSbSbSbSbSiyaRbbaWaTaVaZaYaXanbmapaqarasatauaKbgbhbibjbnbkblbmcFcGcHcIcJcKavbgbhbibjbnbkblbmaEaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbvbpbpbpbpbpbpbpbrbFbEbFcMcLcMcLbEbFbEbrbYLzcmcmcmcmcmcmLBLCbreVLGLFAkAkAkLEftfCfvbrbwbwbwbwbwbwbwbwbwbwbrbxbxbxbxbxbxbxbxbxbxbreReRLHcobJbJbJbJbJcpbB +agbbaTaZaYbfbdbaaXcEbSbSbSbSbSbSbSbSbSbSbShZaUaYaSbcbeaVbaaWakbibjbnbkblbmapaFarasatauavbgbhbicKcUKFLPEncYaqarasatauavbgbhbiazaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobpbpbpbpbpbpbpbpbpbpbrbEbFbEbFbEbFbEbFbFbEbrbYCBdmdmdmdmdmdmDJDKbreVffEkCDCDCDCUftfCfvbrbwbHbwbwbwbwbwbwbHbwbrbxbxbxbxbxbxbxbxbxbxbreReQePcobJbJbJbJbJcpbB +acaYbcaVbaaRaTbdaWcqbSbSbSbSbSbSbSbSbSbSbSigaXbaaZbfbbbebdaSaaasatauavbgbhbiazbnbkblbmapaqarasddLSLTdgdhdibhbnbkblbmapaqarasaIaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobCbpbpbpbvbpbpbpbpbvbrbsbtbsbtbsbsbtbsbtbsbrIZbYbYbYbYbYbYbYbYEObreVeUFjEzEzEzEvEuENwkbrbwbwbwbwbwbwbwbwbwbwbrbxbxbxbxbxbxbxbxbxbxbreReQePdodpdpdpdpdpdqbB +aibabfbebdaUbcaTaSczbSbSbSbSbSbSbSbSbSbSbSbUaWbdaVaRaYbbaTaZajbhbibjbnbkblbmaEaqarasatauavbgbheGdwdxdyLSdzapaqarasatauavbgbhayaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMLOdBdBdBdBdBdBdBdBdBdBdCdBdBdBdBdBdBdBdBdBdBdCdBdBdBdBdBdBdBdBdBdBdCdDdDdDdDdDdDdDdDdDdDdCdDdDdDdDdDdDdDdDdDdDdCdDdDdDdDdDdDdDdDdDdDdCdDdDdDdDdDdDdDdDdDdDdE +afbdaRbbaTaXbfbcaZcTbSbSbSbSbSbSbSbSbSbSbSdYaSaTbeaUbaaYbcaVamaqarasatauavbgaxbibjbnbkblbmapaqdHdddIcGcHcIbhbibjbnbkblbmapaqaGaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobWbWbWbWbWbWbWbWbWbWbrdMdMdMdMdMdMdMdMdMdMbrLILILILILILILILILILQbrcncrcldOevdOdPdQevdQbrdRdSdTdRdUdRdSdTdRdUbrctcscudVdWdWdWdWdWdXbrLRLRcBcBcBcBcBcBcBcBbB +anaTaUaYbcaWaRbfdGfsbSbSbSbSbSbSbSbSbSbSbSidiKbcbbaXbdbabfbeadauavbgbhbibjbnaBblbmapaqarasatauarbibjbnbkbgbkblbmapaqarasatauaKaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobWbWbWbXbWbWbWbWbXbWbrdMecdMdMdMdMecdMdMdMbrLILIedefeeedefLILILIbrcncrclegehegeheieheibrdUekejdUdRdUdRekekdRbrctcscueneoeoeoeoeoepbrcBcBcBcBcAcAcAcBcBcBbB +akbcaXbabfaSaUaRebbSbSbSbSbSbSbSbSbSbSbSbSbSiebfaYaWaRaTaUaYaobjbnbkblbmapaqaGasatauavbgbhbibjcFcGcHcIcJcKarasatauavbgbhbibjaAaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobWbWbWbWbWbWbWbWbWbWbrdMdMdMdMdMdMdMdMetdMbrLILILNLNLNLNLNLILILIbrcncnLMegeheveveveheibrdRdUdRdSdRdReweldSdRbrctctLLeneoeoeoeoeoepbrcBcBcBLKLJLJLJcBcBcBbB +aabfaWbdaRaZaXaUdcbSbSbSbSbSbSbSbSbSbSbSbSbSjgaRbaaSbcbcaXbaabbkblbmapaqarasaIauavbgbhbibjbnbkcKexeyezeAcYatauavbgbhbibjbnbkaCaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobWbXbWbWbWbWbXbWbWbWbrdMdMeTdMetdMdMdMdMdMbrdvdvdvdvdvdvdvdvdvdAbrcncrclegeheheheheheibrdSdRdUekdsdSdRdUekdUbrctcscueneoeoeoeoeoepbrcBcAcCdrdZdZercycAcBbB +ajaRaSaTaUaVaWaXcxbSbSbSbSbSbSbSbSbSbSbSbSbShZaUbdaZbfbfaWbdaeavbgbhbibjbnbkaCbmapaqarasatauavddeBeCeDeHdiblbmapaqarasatauavawaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobWbWbWbWbWbWbWbWbWbWbrdMdMdMeFdMdMdMdMeFdMbreedfdedededededldNcjbrcncrcleJeKeKdkeKeKeLbrdRdTdRdSdTdRdTcXdSfabrctcscucVcWcWcWcWcWdabrcBcAcCeqcNcNfhcycAcBbB +amaUaZbcaXbeaSaWcEbSbSbSbSbSbSbSbSbSbSbSbSbSigaXaTaVaRaRaSaTahbnbkblbmapaqaraHatauavbgbhbibjbneGdncScDeBdzasatauavbgbhbibjbnaBaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobWbWbWbWbWbWbWbWbWbWbrdMdMdMdMdMdMdMdMdMdMbreececacacacacackdNcjbrcncrcleXeYeYeYeYeYeZbrdUfafbfbfcdTfafbfbflbrctcscucRcPcPcPcPcPcQbrcBcAcCeqcNcNfhcycAcBbB +adaXaVbfaWbbaZaScqbSbSbSbSbSbSbSbSbSbSbSbSbSbUaWbcbeaUaUaZbcagarasatauavbgbhaybjbnbkblbmapaqardHdddIcGcHcIbibjbnbkblbmapaqaraHaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobWbWbWbXbWbWbWbWbXbWbrdMdMdMdMecdMeTdMdMecbrdNcecacacacacackdNcjbrcncrclfiehehehehehfkbrfaflfmfmfnfbflfmfmfmbrctcscufoeoeoeoeoeofpbrcBcAcCerfDfDcvcycAcBbB +alaWbeaRaSaYaVaZczbSbSbSbSbSbSbSbSbSbSbSbSbSdYaSbfbbaXaXaVbfacbibjbnbkblbmapaFarasatauavbgbhbibjbnbkblbmapaqarasatauavbgbhbiazaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobWbWbWbWbWbWbWbWbWbWbrfqdMdMdMdMfqdMdMdMdMbrdNcecacacacacackdNcjbrcncneufiehfrfrfrehfkbrflfmfmfmfmfmfmfmfmfmbrctctesfoeoeoeoeoeofpbrcBcBcBeaeaeaemcBcBcBbB +aoaSbbaUaZbabeaVcTbSbSbSbSbSbSbSbSbSbSbSbSbSidaZaRaYaWaWbeaRaiatauavbgbhbibjaAbkblbmapaqarasatauavbgbhbibjbnbkblbmapaqarasataJaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobWbXbWbWbWbWbXbWbWbWbrdMeFdMeTdMdMeFdMeTdMbrdNdKdJdJdJdJdJdLdNcjbrcncrclfiehfiehfkehfkbrfmfmfmfmfmfmfmfmfmfmbrctcscufoeoeoeoeoeofpbrcBcBcBcAcAcAcBcBcBcBbB +abaZaYaXaVbdbbbefsbSbSbSbSbSbSbSbSbSbSbSbSbSiuaVaUbaaSaSbbaUafbmapaqarasatauaKbgbhbibjbnbkblbmapaqarasatauavbgbhbibjbnbkblbmaEaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMbobWbWbWbWbWbWbWbWbWbWbrdMdMdMdMfqdMdMdMdMfqbrdNdNdNdNdNdNdNdNdNcjbrcncrclfwfrfwfxfyfrfybrfmfmfmfmfmfmfmfmfmfmbrctcscufzfAfAfAfAfAfBbrcBcBcBcBcBcBcBcBdFdFbB +aeaVbaaWbeaTaYbbccbSbSbSbSbSbSbSbSbSbSbSbSbSiLbeaXbdaZaZaYaXanbkblbmapaqarasaIauavbgbhbibjbnbkblbmapaqarasatauavbgbhbibjbnbkaCaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfGfHfHfHfHfHfHfHfHfHfHfIfHfHfHfHfHfHfHfHfHfHfIfHfHfHfHfHfHfHfHfHfHfIfHfHfHfHfHfHfHfHfHfHfIfHfHfHfHfHfHfHfHfHfHfIfHfHfHfHfHfHfHfHfHfHfIfHfHfHfHfHfHfHfHfHfHfJ +ahbebdaSbbbcbaaYfFbSbSbSbSbSbSbSbSbSbSbSbSbSipbbaWaTaVaTaUaYeEauavbgbhbibjbnaBblbmapaqarasatauavbgbhbibjbnbkblbmapaqarasatauaKaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +agbbaTaZaYbfbdbafKbSbSbSbSbSbSbSbSbSbSbSbSbSiyaYaSbcbeaTaUaYaobhbibjbnbkblbmaEaqarasatauavbgbhbibjbnbkblbmapaqarasatauavbgbhayaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +acaYbcaVbaaRaTbdcObSbSbSbSbSbSbSbSbSbSbSbSbSiPbaaZbfbbbcaXbaabasatauavbgbhbiazaAaBaCaDaEaFaGaHaIaJaKawaxayazaAaBaCaDaEaFaGaHaIaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aibabfbebdaUbcaTchbSbSbSbSbSbSbSbSbSbSbSbSbSiZbdaVaRaYbfaWbdaeaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +afbdaRbbaTaXbfbcdubSbSbSbSbSbSbSbSbSbSbSbSbSitaTbeaUbaaRaSaTahaRaaabacadaeafagahaaaiajakalamanaoagafajacadahakaeamaiaoaRbbaLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +anaTaUaYbcaWaRbfieigigbUeIbSbSbSbSbSeIiLipigiKbcbbaXbdaUaZbcagaUajaRaSaTaUaVaWaXaYaZbabbbcbdbebfaWaVbaaSaTaXbbaUbdaZabaUaYaLfLaZaRaYaZaYaZaRaYaZaRaYaZaRaYaZaRaYaZaRaYaZaYaZaRaYaZaRaYaZaRaYaZaRaYaZaZfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +akbcaXbabfaSaUaRbeaWbbiedYeIeMeOeNEmhZiPbaaRaVbfaYaWaTaXaVbfacaXamaUaZbcaXbeaSaWbaaVbdaYbfaTbbaRaSbebdaZbcaWaYaXaTaVaeaXbaaLfLaVaUbaaVbaaVaUbaaVaUbaaVaUbaaVaUbaaVaUbaaVbaaVaUbaaVaUbaaVaUbaaVaUbaaMaVfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aabfaWbdaRaZaXaUbbaSaYbeidbUieiuiPiKigaWbdaUbeaRbaaSbcaWbeaRaiaWadaXaVbfaWbbaZaSbdbeaTbaaRbcaYaUaZbbaTaVbfaSbaaWbcbeahaWbdaLfLbeaXbdbebeaXbdbeaXbdbeaXbdbeaXbdbebeaXbdbeaXbdbeaXbdbeaXbdbeaXbdbebeaXaMfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +ajaRaSaTaUaVaWaXaYaZbabbbcbdbebfaWaVbaaSaTaXbbaUbdaZbfaSbbaUafaSalaWbeaRaSaYaVaZaTbbbcbdaUbfbaaXaVaYbcbeaRaZbdaSbfbbagaSaTaLfLbeaWaWbcbeaWbcbeaWbcbeaWbcbeaWbcbebeaWaWbcbeaWbcbeaWbcbeaWbcbeaWbcbeaWaWfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfMfNfNfNfNfNfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +amaUaZbcaXbeaSaWbaaVbdaYbfaTbbaRaSbebdaZbcaWaYaXaTaVaRaZaYaXanaZaoaSbbaUaZbabeaVbcaYbfaTaXaRbdaWbebabfbbaUaVaTaZaRaYacaZbcaLfLbbaSaSbfbbaSbfbbaSbfbbaSbfbbaSbfbbbbaSaSbfbbaSbfbbaSbfbbaSbfbbaSbfbbaSaSfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfPfQfRfSfTfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +adaXaVbfaWbbaZaSbdbeaTbaaRbcaYaUaZbbaTaVbfaSbaaWbcbeaUaVbaaWakaVabaZaYaXaVbdbbbebfbaaRbcaWaUaTaSbbbdaRaYaXbebcaVaUbaaiaVbfaLfLbfbabaaZbfbaaZbfbaaZbfbaaZbfbaaZbfbfbabaaZbfbaaZbfbaaZbfbaaZbfbaaZbfaTbafLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUfVfVfVfUfOfOfOfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +alaWbeaRaSaYaVaZaTbbbcbdaUbfbaaXaVaYbcbeaRaZbdaSbfbbaXbebdaSaabeaeaVbaaWbeaTaYbbaRfWcfdbfXfYfZcwdtcgaUbaaWbbbfbeaXbdafbeaRaLfLaRbdbdaVaRbdaVaRbdaVaRbdaVaRbdaVaRaRbdbdaVaRbdaVaRbdaVaRbdaVaRbdaVaRbdbdfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUgagagafUfOgbgcfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aoaSbbaUaZbabeaVbcaYbfaTaXaRbdaWbebabfbbaUaVaTaZaRaYaWbbaTaZajbbahbebdaSbbbcbaaYgdLVgfggghgigjgkglfZgmbdaSaYaRbbaWaTanbbaUaLfLaUaTaTbeaUaTbeaUaTbeaUaTbeaUaTbeaUaUaTaTbeaUaTbeaUaTbeaUaTbeaUaTbeaUaTaTfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUgngogpfUfOfOfOfOfOfOfOfOfOfOfOfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +abaZaYaXaVbdbbbebfbaaRbcaWaUaTaSbbbdaRaYaXbebcaVaUbaaSaYbcaVamaYagbbaTaZaYbfbdbagmgigqghglgrgsgtgugvgwaTaZbaaUaYaSbcakaYaXaLfLaXbcbcbbaXbcbbaXbcbbaXbcbbaXgxgygmgmgxgxgyaXbcbbaXbcbbaXbcbbaXbcbbaXbcbcfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUgngogpfUgzgAgBgCgDgEgAgFgGgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aeanamacakalajaaaeadahabaiagaoafajalahamacaaabakagadafamabakMAbaacaYbcaVbaaRaTbdgwgtgugkgIgfglghgjgJgKbcaVbdaXbaaZbfaabaaWaLfLaWbfbfaYaWbfaYaWbfaYaWbfaYaWgLcZgwgwgLgMgOaWbfaYaWbfaYaWbfaYaWbfaYaWbfbffLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUgngogpfUgPgAgEgEgDgEgAgEgHgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +ahbdaSaYaRbbaWaTbbbdaSaYaRbbaWaTbbaWaTbdaSaYaRbbaWaTanaMaMaMaMbdaibabfbebdaUbcaTgKghgjgvgqgigIgkgggsgQbfbeaTaWbdaVaRajbdaSaLfLaSaRaRbaaSaRbagKgRgSgKgRgSgKgRgNgTgTgUgUgSgKgRgSgKgRgSgKaRbaaSaRbaaSaRaRfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUgogogogVgXgYgEgEgDgEgAgFgGgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +agaTaZbaaUaYaSbcaYaTaZbaaUaYaSbcaYaSbcaTaZbaaUaYaSbcakaMaMaMaMaTafbdaRbbaTaXbfbcgQgkgggJgugtgqgvgrglgZaRbbbcaSaTbeaUamaTaZaLfLaZaUaUbdaZaUbdgQhchahdhchbgQhchahdhdhchchagQgdhahdhchagQaUbdaZaUbdaZaUaUfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUgogogogVgXgYgEgEgEgEhigEgHgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhfhfhfaMhghghgaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +acbcaVbdaXbaaZbfbabcaVbdaXbaaZbfbaaZbfbcaVbdaXbaaZbfaaaMaMaMaMbcanaTaUaYbcaWaRbfgZgvgrgsgjghgugJgfgIhhaUaYbfaZbcbbaXadbcbeaLfLaVaXaXaTaVaXaTgZhkhjhphkhlhphkhjhphphkhkhjhpgmhjhphkhjgZaXaTaVaXaTaVaXaXfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNfUhmgohnfUgPgAgEgEgDgEgAgFgGgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhfhfhfaMhghghgaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aibfbeaTaWbdaVaRbdbfbeaTaWbdaVaRbdaVaRbfbeaTaWbdaVaRajaMaMaMaMbfakbcaXbabfaSaUaRhhhogfglgggkgjgsgicggyaXbaaRaVbfaYaWalbfbbaLfLbeaWaWbcbeaWbchhhrhqhthrgxhthrhqhththrhrhqhtgwhqhthrhqhhaWbcbeaWbcbeaWaWfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNhsfUhvfUhugzgAgEgEgDgEgAgEgHgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhfhfhfaMhghghgaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +afaRbbbcaSaTbeaUaTaRbbbcaSaTbeaUaTbeaUaRbbbcaSaTbeaUamaMaMaMaMaRaabfaWbdaRaZaXaUhodtgrgvgrgvgggrgvfZgOaWbdaUbeaRbaaSaoaRaYaLfLbbaSaSbfbbaSbfgygTgMhIgTgLhIgTgMhIhIgTgTgMhIgKgMhIgTgMgyaSbfbbaSbfbbaSaSfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfNaMhshwhuaMgzgAgEgEgDgEgAgFgGgHgHfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhxhyhzhAhBhfhfhfaMhghghghxhyhzhAhBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +anaUaYbfaZbcbbaXbcaUaYbfaZbcbbaXbcbbaXaUaYbfaZbcbbaXadaMaMaMaMaUajaRaSaTaXicfXhChDgrgigsgigsgfgigsgkfZfZgxhCaYaUbdaZabaUbaaLfLaZaRaYaZaYaZaRgOhdgUcZhdgUcZhdgUcZhdgUcZhdcZhdgUcZhdgUgOaZaRaYaZaRaYaZaZfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOfOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEhFhFhFhGhHhJhHhHhHhQhHhKhFhFhFhEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +akaXbaaRaVbfaYaWbfaXbaaRaVbfaYaWbfaYaWaXbaaRaVbfaYaWalaMaMaMaMaXamaUaZbcaWgygkgtgIgigsgjgrgvgigugvgrgqgkgkfXbaaXaTaVaeaXbdaLfLaVaUbaaVbaaVaUgShphcgNhphcgNhphcgNhphcgNhpgNhphcgNhphcgSaVaUbaaVaUbaaMaVfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEhLhMhNhOhPhUhRhShTikhPhVhWhXhYhEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aaaWbdaUbbaSaYbeaTaUhZiaibicidbaiecdifcwigaUbeaRbaaSaoaMaMaMaMaWadaXaVbfaSgOgkghgqgugvgggigsgtgjgkgfgugvggcwbdaWbcbeahaWaTaLfLbeaXbdbebdbeaXhbhthkhahthkhahthkhahthkhahthahthkhahthkhbbeaXbdbeaXbdaMbefLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihihihihihihihihihihihihihihihihihihihihihihihihihihihihihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEiiiiijioilimilinilimiliFijiiiihEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +ajbaaTaXaRbdaUbfaSaXipiqirisitaXiuiviwixiyaXbbaUbdaZabaMaMaMaMaSalaWbeaRaZgSgvgkgugjgJgrgkgqghgggsgigjgJgrizaTaSbfbbagaSbcaLfLbeaXbdbebdbegmhbhthkhahthkhahthkhahthkhahthahthkhahthkhbhhaXbdbeaXbdaMbefLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAiAiAiAiBiAiAiAiCiDiAiAiAiCiAiAiAiAiAiAiCiAiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMiEhWiijmimimimimimimimimimjmiihNiGaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +ambdbcaWaUaTaXaRaZaWiyiHiIiJiKaWiLiMiNiOiPaWaYaXaTaVaeaMaMaMaMaZaoaSbbaUaVLUgJgvgjgggsgfgvgugkgrglgtgggsgficbcaZaRaYacaZbfaLfLbeaXbdbebdbegmhahthkhahthkhahthkhahthkhahthahthkhahthkhahhaXbdbeaXbdaMbefLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiBiAiAiAiAiAiAiAiAiAiAiAiCiAiAiAiAiAiCiAiAiAiAiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMiEhHhKiRilimiliSiSilimiThGhHiGaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +adaTbfaSaXbcaWaUaVaSiPiUiVirieaSipiWiXiYiZaSbaaWbcbeahaMaMaMaMaVabaZaYaXbecggsgJgggrglgigJgjgvgfgIghgrglgihobfaVaUbaaibeaRaLfLbbaWaTbbaTbbgwhjhIhrhjhIhrhjhIhrhjhIhrhjhIhjhIhrhjhIhrhjgyaWaTbbaWaTaMbbfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAiAjaiAiAiAiAiAiBiAiAiDiCiAiAiCiAiAiCiDiAiCiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEjbinimjcjbjbjdimjehEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +albcaRaZaWbfaSaXbeaZiZisjfiIjgaZiyjhixjiitaZbdaSbfbbagaMaMaMaMbeaeaVbaaWbbfZglgsgrgfgIgtgsgggJgigqgkgfgIgtdtaRbeaXbdafaMaUaLfLbfbabaaZbfbagQgLgNhdgMgNgQgLgNhdgMgMgNgNhdgLgShdgMgNhdgLgSaZbfbaaZbfaTbafLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAiAiAiAiAiAiAiAiAiAiAiAiAiBiAiAiCiDiAiAiCiAiDihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMjjjjjjjjhEjkilimjcjbjbjdimhPhEjljljljlaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aobfaUaVaSaRaZaWbbaVitipiKiZhZaViPigiuiyiKaVaTaZaRaYacaMaMaMaMbbahbebdaSgOdbgIglgfgigqghglgrgsgtgugvgigqghhDgdbbaWaTanbbaXaLfLaRbdbdaVaRbdaVgRhbgZgRhbgZgRhahpgUgUhahahpgRhbgZgRhbgZgRbdaVaRbdaVaRbdbdfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAiAiAiAiAiAiAiAiAiAiBiAiAiAiAiAiDiAiCiDiAiCiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMjjjjjjjjjnjpimimiljojoilimjujqjljljljlaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +abaRaXbebcaVaUbaaVaRaXbebcaVaUbaaVaUbaaRaXbebcaVaUbaaiaMaMaMaMaYagbbaTaZgSgggqgIgigtgugkgIgfglghgjgJgtgugkgIgmaYaSbcakaYaWaLfLaUaTaTbeaUaTbeaUaTbeaUaTbegdhjhthchchjhjhtgdaTbeaUaTbeaUaTbeaUaTbeaUaTaTfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAjrjrjrjrjrjrjriAiAiAiAiAiAiAiCiAiAjaiDiAiAiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMjjjjjjjjhEhPjsimimimimimimilhEjljljljlaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aebaaWbbbfbeaXbdbebaaWbbbfbeaXbdbeaXbdbaaWbbbfbeaXbdafaMaMaMaMbaacaYbcaVhbgrgugqgtghgjgvgqgigIgkgggsghgjgvgqgwbaaZbfaabaaSaLfLaXbcbcbbaXbcbbaXbcbbaXbcbbgmhqhIhkhkhqhqhIgmbcbbaXbcbbaXbcbbaXbcbbaXbcbcfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAjtfOdjgWgWgWhefOjxiAiAiAiAjaiAiAiBiAiBiAiCiAiCihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhGhHhHhHjyimilimimjzhEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +ahaSaSaYaRbbaWaTbbaSaSaYaRbbaWaTbbaWaTaSaSaYaRbbaWaTanaMaMaMaMbdaibabfbehlgfgjgughgkgggJgugtgqgvgrglgkgggJgugKbdaVaRajbdaZaLfLaWbfbfaYaWbfaYaWbfaYaWbfaYgwgMcZhrhrgMgMcZgwbfaYaWbfaYaWbfaYaWbfaYaWbfbffLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAfOjAjBjCjvjDjFjFfOjGiAiAjrjrjrjrjrjrjrjrjHjIjrihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEjJjJjKjLimilimimiljMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +agaZaZbaaUaYaSbcaYaZaZbaaUaYaSbcaYaSbcaZaZbaaUaYaSbcakaMaMaMaMaTafbdaRbbgxgigggjgkgvgrgsgjghgugJgfgIgvgrgsgjgQaTbeaUamaTbeaLfLaSaRaRbaaSaRbaaSaRbaaSaRbagKgUgNgTgTgUgUgNgKaRbaaSaRbaaSaRbaaSaRbaaSaRaRfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAfOjNjBjBjOjBjBjBfOjGiAjPjQjRjRjSihihihihihihihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMjTjUjUjUjVimjWjXjYjXhEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +acaVaVbdaXbaaZbfbaaVaVbdaXbaaZbfbaaZbfaVaVbdaXbaaZbfaaaMaMaMaMbcanaTaUaYgLgtgrgggvgigJgkgIgsghgqgrgtgJgfglgggZbcbbaXadbcbbaLfLaZaUaUbdaZaUbdaZaUbdaZaUbdgQgdhahdhdhchchbgQaUbdaZaUbdaZaUbdaZaUbdaZaUaUfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAfOjZjBjBjBkajBkbfOjGjajPkckdkdkdkekfihkgkhihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEkikjjUjEimklkmknkohEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aibebeaTaWbdaVaRbdbebeaTaWbdaVaRbdaVaRbebeaTaWbdaVaRajaMaMaMaMbfakbcaXbagRghgfgrgJgtgsgvgqglgkgugfghgsgigIgrhhbfaYaWalbfaYaLfLaVaXaXaTaVaXaTaVaXaTaVaXaTaVgmhlgZgZgmgmhlaVaXaTaVaXaTaVaXaTaVaXaTaVaXaXfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAkpfOfOfOkkfOfOfOkriAiAkskckdkdktkdkdkqkvkvkwihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEkujUjUjLimjXkykykzhEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +afbbbbbcaSaTbeaUaTbbbbbcaSaTbeaUaTbeaUbbbbbcaSaTbeaUamaMaMaMaMaRaabfaWbdfFgkgigfgsghglgJgugIgvgjgigkglgtgqgfdcaRbaaSaoaRbaaLfLbeaWaWbcbeaWbcbeaWbcbeaWbcbeaWbcbebeaWaWbcbeaWbcbeaWbcbeaWbcbeaWbcbeaWaWfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAiAfOkAjBkAfOkBjrjrjrkCkDkdkEkFkGkdihkvkHkHihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEkikjjUjVimkxkykykJhEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +analahajaoacaeabanagakafamaafLfLfLfLfLahajabafaoaaagadaMaMaMaMaUajaRaSaTfYgvgtgiglgkgIgsgjgqgJgggtgvgIghgugidtaUbdaZabaUbdaLfLbbaSaSbfbbaSbfbbaSbfbbaSbfbbaSbfbbbbaSaSbfbbaSbfbbaSbfbbaSbfbbaSbfbbaSaSfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAiAiAiAiAiAfOkKjBkLfOjQjRjRjRjSihkdkEkMkGkdihihihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMiEkNkNhHkOkIhHhHkNkNiGaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +bebcaXbabfaSaUaRbeaWbbaVbdaYaZaTaUaSbbaXbaaRaVbfaYaWaTaMaMaMaMaXamaUaZbchCgJghgtgIgvcgglgggugsgrcwgJgqgkgjgthDaXaTbeaeaXaTaLfLaZaRaYaZaYaZaRaYaZaRaYaZaRaYaZaRaYaZaRaYaZaYaZaRaYaZaRaYaZaRaYaZaRaYaZaZfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAjtfOfOfOfOfOkKjBkLfOkckQkQkQkQkPkdkdkdkdkdkRkTkUihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMiEhKkVjdimkWkXhGiGaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +bbaWbdaUbeaRaUbeaRaWbdaUbeaRaWbdaUbeaRaWbdaUbeaRbaaSbcaMaMaMaMaWadaXaVbffXgsgkghgqgJfZgIgrgjglgfizgsgugvggghfWaWbcbeahaWbcaLfLaVaUbaaVbaaVaUbaaVaUbaaVaUbaaVaUbaaVaUbaaVbaaVaUbaaVaUbaaVaUbaaVaUbaaMaVfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAfOkYjBjBjBfOkKjBkLfOkDkQkZjRjSihkdkdkdkdkdihlalalbihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhEjbiliSillchEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aYaSaTaXbbaUaXbbaUaSaTaXbbaUaSaTaXbbaUaSaTaXbbaUbdaZbfaMaMaMaMaSalaWbeaRcwglgvgkgugsdbcgfYldfWhCicglgjgJgrgkcgaSbfbbagaSbfaLfLbeaWaWbcbeaWbcbeaWbcbeaWbcbeaWbcbebeaWaWbcbeaWbcbeaWbcbeaWbcbeaWbcbeaWaWfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAfOkYjBkKlefOkKjBkLfOfOlflglhliihihihihihljihlklalbihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMhElllmlnlolphEaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +baaZbcaWaYaXaWaYaXaZbcaWaYaXaZbcaWaYaXaZbcaWaYaXaTaVaRaMaMaMaMaZaoaSbbaUizfWhoicdbhDldbcaWaUaTaShofWlddtfYicfZaZaRaYacaZaRaLfLbbaSaSbfbbaSbfbbaSbfbbaSbfbbaSbfbbbbaSaSbfbbaSbfbbaSbfbbaSbfbbaSbfbbaSaSfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihlqiAfOkYjBkKlrfOfOkSfOfOltjBjBfOlulvliihlwlxlyihihihihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMiElzlAlAlAlBiGaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +bdaVbfaSbaaWaSbaaWaVbfaSbaaWaVbfaSbaaWaVbfaSbaaWbcbeaUaMaMaMaMaVaeaVbaaWbeaTaYbbaRbdaUbfaSaXbcaZaYaTaUbaaWbbbfbeaXbdafaVaXaLfLaZaRaYaZaYaZaRaYaZaRaYaZaRaYaZaRaYaZaRaYaZaYaZaRaYaZaRaYaZaRaYaZaRaYaZaZfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAfOkYjBjBjBlsjBjBlCjBjBjBjBfOjGiAjPlElFlxlxihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aTbeaRaZbdaSaZbdaSbeaRaZbdaSbeaRaZbdaSbeaRaZbdaSbfbbaXaMaMaMaMbeahakadaiaaaoamajahalagaeafacabanamaoagadacaiaeaaacalanbeaWaLfLaVaUbaaVbaaVaUbaaVaUbaaVaUbaaVaUbaaVaUbaaVbaaVaUbaaVaUbaaVaUbaaVaUbaaMaVfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAiAfOkYjBjBjBlDjBjBjBlHjBjBjBfOlIiAjPkclwlJlxihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +bcbbaUaVaTaZaVaTaZbbaUaVaTaZbbaUaVaTaZbbaUaVaTaZaRaYaWaMaMaMaMaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLfLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAjtfOfOfOfOfOfOlKjBjBfOfOfOfOfOfOjxjPkDlwlxlxihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaMaMaMaMaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaLaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAfOlLlMlNlOlPfOjBjBjBfOlQlRlSlTlUfOlVihlwlxlWihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAfOlXlXlXlXlXlGjBjBjBlYjBjBjBjBmafOlVihihihihihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAfOlLlMlXlXlXlZjBjBjBmbjBjBjBjBmafOjGiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAfOlXlXlXlXmdfOmemcmgfOmhfOjwfOfOfOmjiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAfOlXlXlXfOfOfOlXlXlXfOfOfOjBjBjBfOjGiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAfOlLlMbDfOiAfOmlmlmlfOiAfOjFmmmnfOjGiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihiAfOmlmlmlfOiAkpmompmqkriAfOmlmlmlfOjGiAihaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM @@ -2045,103 +2227,103 @@ aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmCmImDmDmTmCaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMkDmUmVmWmVmUihmumumumumumumumumumumumumumumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmXmxmxmxmxmOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMmumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMihihmWmWmYihihmumumumumumumumumumumumumumumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMihmWmWmWihmumumumumumumumumumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMmumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmZnananbihihncihihihihihihihmumumumumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMmumumumumumuaMaMaMaMaMaMaMaMaMaMnvrPrIrIrIrBnzaMaMndnenfngnenenerlihninjnknlihmumumumumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMnvnHnInJnKnLnMnHnzaMndnenmnmnenenenennnonononpihmumumumumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMnHnQnRnRnSnRnRnLnHaMndnqnrnsntneneneihnonononuihihihihihmumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMnHnZnRnRnRnRoanLnHaMndnenAnAnenenepaihnCnonDnEihbLkQbOihmumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHofnRnRognRnRohnHaMndneneneneneneriihihihihihihbPkQbTihmumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMomnHonnHnHnHnHnHooaMnTnananUihkdkdkdihkTkTnVnWihcikQmkihmumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHoGoyoaounFnHaMaMaMaMaMaMobkdkdkdoclalaododihcikQnGihmumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHoBoAoanRornHaMaMaMaMaMaMoikdkdkdihojlaihihihokolokihihihmumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnvnHoBoyoanRornHnzaMaMmPmKoFihkdkdkdihihihihnOnOkQkQkQnPnPihihmumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnvnHnHnHnHvLoyoanRornHnHnHnHnzototihkdkdkdkdihnYnXkQkQkQkQkQkQkQoxihmumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHpioXoYnHnRoHnRoJnHnHoZoOpbrTkRpnkRkdkdkdkdoCkQkQkQkQkQoDkQkQkQoeihmumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMmumuaMaMaMaMphoWpjoWnHnHnHpknHnHpJoZplpmrTkRpLkRkdkdkdkdihoqopkQkQkQkQkQkQkQoMihmumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMmumumuaMaMaMaMnHnHphpxnHnHnRnRpynHnHpzpApznHoIoIihoPnanUihihihihowovkQkQkQozozihihmumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMmumumumuaMaMaMaMnHpGnRnRpHnHnRnRnRnHrbpKrdpInHmBaMmBaMaMaMaMmumuihihihokpcokihihihmumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVoVpdpepepepepfpfpepepepepgoVoVoVoVoNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMmumumumuaMaMaMaMnHqanRnRnRqbnRnRnRqcnRnRnRqdnHmKmKmKmKaMaMaMaMmumumuihoEkQoEihmumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVpdpppqprpspeptpupepvpwpepepepgoVoVoNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMnHqCnRnRnRqDnRnRnRqEnRnRnRqFnHaMaMaMaMaMaMaMaMaMmumuihoEkQoEihmumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVpdpepBpBpBpBpepCpCpepBpBpDpEpepepgoVpFpFpFpFpFaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMmumumumuaMaMaMaMnvnHnHnHnHnHnHnRnRnRnHnHnHnHnHnHnzaMaMaMaMaMmAaMmBmumuihoEkQoEihmumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUpdpepepMpNpOpPpepBpBpQpBpBpBpBpRpSpeoVpFpTpUpVpFpFpFpFpFpWpXpXpYpFpFaMaMaMaMaMaMaMaMpZpZpZpZpZpZpZpZpZpZpZaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMmumumumuaMaMaMaMnHqZrasercsvnHrenRnRnHrfrfrfrgrgnHaMaMaMaMaMmAmBmumumuihoEkQoEihmumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUqeqfqgpBqhqhqhpepBpBpeqiqjqkqlqmqnpeoVpFqopUpUqpqqqrqsqtquqsqvqwqxpFpFpFpFpFpFpFpFpFpFqyqzqzqzqzqzqzqzqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMmumumuaMaMaMaMaMnxrjrjrjrjrjnHnRnRnRnHrenRnRnRrknwaMaMaMaMaMmPaMmumumuihihihihihmumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUqGqfpBpBpBpBpBpQpBpBpepepepepepepeqHqIpFpFpFpFpFqqqvqsqJqKqsqvqvqvqLqMqMqMqMqMqMqMqMqNqyqOqPqPqPqPqPqQqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMnhrCrDrjrjrjrEnRnRnRrFnRnRnRrGrHmiaMaMaMaMaMmAmBmBmumumumumumumumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUqRpeqSpBqSpBqSpepBpBpBqTqUoVoVoVoVoVqVqWqMqMqMqLqvqvqvqvqvqvqvqvqvqLqMqMqMqMqMqMqMqMqNqyqXqYqYqYqYqYqXqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnyrjrjrjrjrjrQnRnRnRrRnRnRnRnRrSnBaMaMaMaMaMmAaMaMmBmumumumumumumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVpepepepepepepepBpBrhpBqUoVoVoVoVoVqVqWqMqMqMqLqvqvqvqvqvqvqvqqqqpFpFpFpFpFpFpFpFpFpZqyqXqYqYqYqYqYqXpZqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHsbrjrjrjscnHpzsdpznHoKoKsInRsfnHaMaMaMaMaMaMaMaMaMmumumumumumumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUpdpermrnrormrppepBpBpBrqqUoVoVoVoVoVoVpFpFpFpFpFqvqvqsqJquqsqvrrrspFrtrururvpFrwrxrypZqzqXqYqYqYqYrzrApZqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHspsqsrssstnHsunRvUnHyCnHnHnNnHnHaMaMaMaMaMaMaMmAaMmBmumumumumumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUqeqfrJrJrJrJrJpQpBpBpepepepepepepepgoVpFpTpUpVpFqvqvqsqJrKqsqvqqqqpFrLrLrLrLpFrMrxrNpZqzqXqYqYqYqYqYrOpZqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHsGrjsHLwnHnHnRsJsKnHnHnHnRnRLxnHaMaMaMaMaMaMaMmAmBmBmumumumumumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUqGqfrUrJrJrJrJpepBpBpBpBpBpepBrVrWpeoVpFqopUpUqpqvqvqvqvqvqvqvqvqvpFrLrXrYrYpFpFrZpFpZqzqXqYqYqYqYsaqXpZqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHsWsXsYnHaMnHsZsZsZnHaMnHnLtatbnHaMaMaMaMaMaMaMmAaMmBaMmumumumumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUqRpepesgshshshpepBpNsipNpBpQpBsjskpeoVpFpFpFpFpFpFpFslpFpFpFqvqvqvsmrLsnsnrLrLrLrLsopZqzqXqYqYqYqYqYrOpZqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHsZsZsZnHaMomtmtntoooaMnHsZsZsZnHaMaMaMaMaMaMaMmAmBmBmBmBmBmumumumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMmumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmZnananbihihmfihihihihihihihmumumumumumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMmumumumumumuaMaMaMaMaMaMaMaMaMaMnvrPrIrIrIrBnzaMaMndnenfngnenenerlihncnjnknlihmumumumumumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMnvnHnInJninLnnnHnzaMndnenmnmnenenenenCnonononpihihihihihmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMnHnQnRnRnSnRnRnLnHaMndnqnrnsntneneneihnonononuihbOkQbTihmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMnHnZnRnRnRnRoanLnHaMndnenAnAnenenepaihnKnonDnEihbLkQmkihmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHofnRnRognRnRohnHaMndnenenenenenenMihihihihihihbPkQnGihmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMomnHonnHnHnHnHnHooaMnTnananUihkdkdkdihkTkTnVnWihcikQrcihmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHoCoyoaounFnHaMaMaMaMaMaMobkdkdkdoclalaododihcikQrcihmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHoBoAoanRornHaMaMaMaMaMaMoikdkdkdihojlaihihihokolokihihihihmumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnvnHoBoyoanRoGnHnzaMaMmPmKoFihkdkdkdihihihihnOnOkQkQkQnPnPpKihihmumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnvnHnHnHnHvLoyoanRoLnHnHnHnHnzototihkdkdkdkdihnYnXkQkQkQkQkQkQkQkQqKihmumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHpioXoYnHnRoHnRoJnHnHoZoOoRoQkPpnkPkdkdkdkdoSkQkQkQkQkQoDkQkQkQkQoxihmumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMmumuaMaMaMaMphoWpjoWnHnHnHpbnHnHpfoZplpmoQkPpLkPkdkdkdkdihoqopkQkQkQkQkQkQkQkQoMihmumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMmumumuaMaMaMaMnHnHphpknHnHnRnRponHnHpzptpznHoIoIihoPnanUihihihihowovkQkQkQozozoeihihmumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMmumumumuaMaMaMaMnHpxnRnRpHnHnRnRnRnHrbsopypInHmBaMmBaMaMaMaMmumuihihihokpcokihihihihmumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVoVpdpepepepepApApepepepepgoVoVoVoVoNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMmumumumuaMaMaMaMnHqanRnRnRpCnRnRnRpJnRnRnRqdnHmKmKmKmKaMaMaMaMmumumuihoEkQoEihmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVpdpppqprpspeqbpupepvpwpepepepgoVoVoNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMnHqCnRnRnRqcnRnRnRqpnRnRnRqFnHaMaMaMaMaMaMaMaMaMmumuihoEkQoEihmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVpdpepBpBpBpBpeqDqDpepBpBpDpEpepepgoVpFpFpFpFpFaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMmumumumuaMaMaMaMnvnHnHnHnHnHnHnRnRnRnHnHnHnHnHnHnzaMaMaMaMaMmAaMmBmumuihoEkQoEihmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUpdpepepMpNpOpPpepBpBpQpBpBpBpBpRpSpeoVpFpTpUpVpFpFpFpFpFpWpXpXpYpFpFaMaMaMaMaMaMaMaMpZpZpZpZpZpZpZpZpZpZpZaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMmumumumuaMaMaMaMnHqZrasesrqEnHrenRnRnHrfrfrfrgrgnHaMaMaMaMaMmAmBmumumuihoEkQoEihmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUqeqfqgpBqhqhqhpepBpBpeqiqjqkqlqmqnpeoVpFqopUpUqIqqqrqsqtquqsqvqwqxpFpFpFpFpFpFpFpFpFpFqyqzqzqzqzqzqzqzqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMmumumuaMaMaMaMaMnxrjrjrjrjrjnHnRnRnRnHrenRnRnRrknwaMaMaMaMaMmPaMmumumuihihyxihihmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUqGqfpBpBpBpBpBpQpBpBpepepepepepepeqHrdpFpFpFpFpFqqqvqsqJOaqsqvqvqvqLqMqMqMqMqMqMqMqMqNqyqOqPqPqPqPqPqQqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMnhrCrDrjrjrjrinRnRnRrqnRnRnRrGrHmiaMaMaMaMaMmAmBmBmumumuihihihmumumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUqRpeqSpBqSpBqSpepBpBpBqTqUoVoVoVoVoVqVqWqMqMqMqLqvqvqvqvqvqvqvqvqvqLqMqMqMqMqMqMqMqMqNqyqXqYqYqYqYqYqXqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnyrjrjrjrjrjrtnRnRnRrAnRnRnRnRrSnBaMaMaMaMaMmAaMaMmBmumumumumumumumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVpepepepepepepepBpBrhpBqUoVoVoVoVoVqVqWqMqMqMqLqvqvqvqvqvqvqvqqqqpFpFpFpFpFpFpFpFpFpZqyqXqYqYqYqYqYqXpZqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHrErjrjrjscnHpzrFpznHoKoKrOnRrQnHaMaMaMaMaMaMaMaMaMmumumumumumumumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUpdpermrnrormrppepBpBpBrRqUoVoVoVoVoVoVpFpFpFpFpFqvqvqsqJquqsqvrrrspFrTrururvpFrwrxrypZqzqXqYqYqYqYrzrZpZqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHspsasHssstnHsunRvUnHsbnHnHnNnHnHaMaMaMaMaMaMaMmAaMmBmumumumumumumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUqeqfrJrJrJrJrJpQpBpBpepepepepepepepgoVpFpTpUpVpFqvqvqsqJrKqsqvqqqqpFrLrLrLrLpFrMrxrNpZqzqXqYqYqYqYqYsdpZqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHsGrjsfslnHnHnRsJsKnHnHnHnRnRLxnHaMaMaMaMaMaMaMmAmBmBmumumumumumumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUqGqfrUrJrJrJrJpepBpBpBpBpBpepBrVrWpeoVpFqopUpUqIqvqvqvqvqvqvqvqvqvpFrLrXrYrYpFpFsqpFpZqzqXqYqYqYqYsvqXpZqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHsWsXsYnHaMnHsZsZsZnHaMnHnLtatbnHaMaMaMaMaMaMaMmAaMmBaMmumumumumumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUqRpepesgshshshpepBpNsipNpBpQpBsjskpeoVpFpFpFpFpFpFpFswpFpFpFqvqvqvsmrLsnsnrLrLrLrLrYpZqzqXqYqYqYqYqYsdpZqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMnHsZsZsZnHaMomtmtntoooaMnHsZsZsZnHaMaMaMaMaMaMaMmAmBmBmBmBmBmumumumumumumumumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVqRperJrJrJrJpepBsipNsipBpeqSpepeqHoVpFsxsyszpFsAsBsBsBsCpFqvqvqvqvrLrLrLrLsDrLrLrYpZqzqXqYqYqYqYsEsFpZqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMmumuaMaMaMomtmtntoooaMaMaMaMaMaMaMomtmtntoooaMaMaMaMaMaMaMmAaMmBaMmBaMaMmumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVqRpesLsMsNpepBpBpBpBpBpepepeqHoVoVpFsOsPsQsRsBsBsBsBsSpFqvqvqvsmsTrLrLrLsUrLrLsVpZqzqXqYqYqYqYqYqXpZqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMmumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVqRpesLsMsIpepBpBpBpBpBpepepeqHoVoVpFsOsPsQsRsBsBsBsBsSpFqvqvqvsmsTrLrLrLsUrLrLsVpZqzqXqYqYqYqYqYqXpZqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMmumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumumu aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVoVqRpepepepepepepepepepeqHoVoVoVoVpFpFtctdpFpFpFtctetdpFqvqvqvpFtftgtgtgtgtgthpFpZqztitjqYqYqYtktlqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVpFtptptptptptptptptppFpFtqpFpFtptptptptptptppFpZqztrtstttttttstuqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNtvoNoNoNoNoNoNoNoNoNoNoNoNtwtwtwtwtwtwtwtwtwtwtwtwtxtxtxtxtxtxtxpFtytztypFtxtxtxtxtxtxtxtxpZqzqztAtBtBtBtCqzqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNoLoNaMaMaMaMoNtEtFtGtHtHoNtItJtwtItKtwtLtMtwtItJtwtNtxtOtPtQtRtSpFtytztypFtTtUtVtWtWtxaMaMpZqzqzqzqzqzqzqzqzqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNAgoNoNoNoNoNoNtYtZtZtZuaoNubtMtwubuctwubtJtwubudtwtNtxueufufufufpFtytztypFtWtWtWtWtWtxaMaMugugugugugugugugugugugtxtxtxtxtxtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvoNuhoQoSoRswpooNuntZtZtZuaoNtwtwtwtwtwtwtwtwtwtwtwtwtNtxueufufufufpFpFtqpFpFtWtWtWtWtWtxuguguguguguguoupuqtxurururtxururururururururtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutuuuvuwDUuhtZtZtZtZtDoNuztZtZtZuAoNuBudtwtIudtwuCtJtwtItMtwtNtxuDuEuFuGuHtxuIuIuItxtWtWtWtWtWtxuJuKuJuLuMuguNuNuNuOurururuOuruPuQuPuruRuSuTtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVAIuXuVuVuVuYAIuZvavbvcoNvxtZtZtZtZuioNvftZtZtZvgoNubtJvhubtJtwubvitwubvjtwtNtxvktxvlvmvntxufufuftxvlvmvotxvptxvqvrvqvrvqugtxtxtxtxurururtxvsvtuPvuvsvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvoNLytZtZtZtZvyoNvztZtZvAoNoNoNtvtvtvtvtvtvtvtvtvtvtvtNtxufufvBvCvCvCvCvCvCvCvCvCvDufufvEvqvqvqvqvqugvFuNuotxurururtxvGvGvHvGvGvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutvIvbvJoNukujulumtZoNoNxatZtZvOoNuyvQoNvRvRvRvRvRvRvSvTcZtvtNtxufufvVvWvXvXvXvXvXvXvXvYueufufugvZwawbwcwdugweuNuptxurururtxwfwfuNwfwfvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMwgaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVwWuXuVuVuVuYwWwivavbwjoNtvoNoNoNtZoNvetZtZtZwloNwmwnwowpwpwpwpwpwpwqtvtvtvtvtvufufvVwrwsufwtwuwvufwswrueufufugugugugugugugweuNuptxurururtxwwwwuNwwwwvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutwxvbwyoNwzwAwBoNtZoNvNvKtZtZwEoNwmvMtvwFwGwGwGwHwGwItvwJwJwJtvufufwKwLwMwNwOwPwQwRwSwLwTufuftxwUwUwUwUwUtxtxuOtxtxtxuOtxtxuNuNuNuNuNvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMwVoVoVoVoVoVoVoVoVoVoVoVoVoVwhoUoVoVoVqVwhwXwYvMwZoNyQtZxboNxcoNoNoNxdoNoNoNwmwnuWxfxfxfxfxfxfxfxgxfxfxfxgufufufxhufufxiufxiufufxhufufufxjurururururxjurururururururxjwwwwwwwwwwvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMmu -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMxkoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNxlxmvMxnoNvPuhwkoNtZxqtZxrtZxsxtxttZxutvxvxwxwxxxyxzxAtvxBxBxBtvufufvBxCxDwNxEufxFwRxGxCvDufufxjurururururxjurururururururxjwwwwwwwwwwtxuOuOtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMwVoVoVoVoVoVoVoVoVoVoVoVoVoVxHoUoVoVoVqVxHxIxJvMwnxKuhtZtZxLtZxMtZwmwmxNxNwmwmxutvxOxOxOxPxQxPxRtvtvtvtvtvufufvVwLxSufxiufxiufxSwLueufuftxxTxUxUxUxVtxtxxWtxtxtxuOtxtxtxxXxXxXtxtxurururxYurxZtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMxkoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNoNLgyaoNoNoNoNoNyboNycwmydyeyWygwmxutvtvyhyiyjykylymyhaMaMaMtxufufvVtxtxynyoufypyqtxtxueufuftxaMaMaMaMaMtxyrystxuNytuNuNyuyvywywywyxtxururuQuQururyyaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNoNoNoNyzyAxowDtZoNxewmydyfyfygwmxpyEyFyhyGyHyIyByKyhaMaMaMtxufufvVtxtxvlvmvmvmvotxtxueufuftxaMaMaMaMaMtxysystxyLyLyLuNyuywywywywyMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNzitZtZtZtZtZtZoNxetZtZwqwqwmwmwmwmyRyhySyIyIyIyIyhaMaMaMtxufufwKyTyTyTyTyTyTyTyTyTwTufuftxaMaMaMaMaMtxyUystxyLyVyLuNyuyuyuyuyuyutxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNzltZtZtZtZtZLfoNyXtZtZyYtZtZwCvdyJzcyhyIyIyIyIzdyhtxtxtxtxtxtxzetxtxufufufufuftxtxtxtxtxtxaMaMaMaMaMtxzfystxvFuNuNuNyuaMaMaMaMaMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNzgzgzhyDyZxazkoNyXzmzmoNznznoNoNoNoNyhyIzozpzqzryhzsztztzszuzvufzwtxtxtxzxtxtxdCaMaMaMaMaMaMaMaMaMaMtxtxtxtxtxtxtxtxyuaMaMaMaMaMzyuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzzmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtwgmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmt -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoNoNoNoNoNoNoNoNoNoNoNoNzAzBzBzAaMaMaMyhyIzCzDzEzDyhzszFzFzszGzHufzwtxzIwTufwKzJtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzKururzLzLururzKaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzMzNzNzNzNzOzOzNzNzPaMyhyIyIyIyIyIyhzsztztzszQzHufzwtxueufufufvVtxaMaMaMaMaMaMaMaMaMaMaMzRzSzTzUaMaMaMaMaMaMaMaMaMtxzVururururzWtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzXzYzZAaAbAcAcAdAdzNzPyhyhyhyhyhyhyhzszszszsAezHufzwtxAfuxAfAhAftxaMaMaMaMaMaMaMaMaMaMzRAiAjAkAlzUaMaMaMaMaMaMaMaMtxtxtxtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzXzYAmAcAcAcAcAcAcAnAoaMaMaMaMaMaMtxApzsApzszuzHufAqArueufAsufxFyuaMaMaMaMaMaMaMaMaMaMAtAuAvAvAwAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzXzYAxAyAzAzAzAzAzzNAAaMaMaMaMaMaMtxApzsApzszGzHufAqAruDufwtAByoyuaMaMaMaMaMaMaMaMaMaMACADADADAvACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAEzNzNzNzNzNzNzNzNAAaMaMaMaMaMaMaMtxApzsApzszQAFxSAGAHAftXAJAKAfyuaMaMaMaMaMaMaMaMaMaMAtALADAMANAtAOaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAPufufAQvVyuyuyuaMaMaMaMaMaMaMzRARASACATAUARAUzUaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWAWAWAWAWAWAWAWAWAWAWAWAXAYAZBaBbBcBcBcBcBcAHBdxCBeufufBfvVxCBdyuaMaMaMaMaMaMaMAtBgADBhBiBjBkBjAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWBlBmBnBlBmBmBoBpBqBmBrBsAYAWAWBtBcBcBcBcBcAHBdwrBeufufufvVwrBdyuyuyuyuyuyuaMaMAtBuADADBvBwBwBxAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWBlByBzBABBBCBCBCBCBCBCBDBEAYAWAWBbBcBcBcBcBcAHBdwrBeufufufBFwrBdBGBGBGBGBGyuaMaMACBuADADACBHBHBHAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWBIBJBKBJBLBJBJBJBJBJBJBJBMAWAWAWAHAHAHAHBNBOAHBdwrBeufufufBPBQvmBRBRBRBRBRBRBRBSAtBTADADBUAUAUAUBVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWBWBXBYBZBBCaCaCaCaCaCaCbCcAYAWAWAHCdCeCfCgCgAHChCiCjufufufufCkClClClClClCmCnCoCnCpADADADADCqCqCrACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWBWBmCsBWBmBmBoBpBqBmCtBsAYAWAWAHCuCvCwCgCgCxCyCzufufufufufCkClClClClClCmCABRBSAtCBADCrCCBuADCDAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWAWAWAWAWAWAWAWAWAWAWAWAXAYAWAWAHCECFCGCgCgCxCyCzufufufufCHCIBRCJClClCKCLyuaMaMCCBuADCrCMBuADCrCCaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHAHAHAHAHAHCNCNCNCNCNCNCNCNCNCNCNCNCNCOCOCOCPCPCNCQvYCRufufufBFCSBdCTClCmCUCVyuaMaMCMBuADCrCMBuADCrCMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHCWCXCXCXCYCZDaCPCPCPCPCPCPCPCPCPCPCPCPCPCPCPCPCNBdwrBeufufufBPDbBRDcClClDdDeyuaMaMDfBuADCrCMBuADCrDfaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgDgDgDgDgDhDiDjDkDlCPDmDnDoDlCPCPCPCPCPCPCPCPCNBdwrDpufufufufCkClClClClClCmCABRBSAtBTADCrDfBuADDqAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgDrDgDgDgDsDiDtDuDlCPDmDvDwDlCPCPDxDxDxDxDxDxCNDyDzDADBDCDCDCDDDCDCClClClCmCnCoCnDEADADADADADADCrACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgDFDgDgDgDsDaCPCPCPCPCPCPCPCPCPDGDHDHDHDHDHDHCNCNCNCNCNDIDICNCNCNCNCABRBRBRBRBRBSAtzSzTDJACDKADBhAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgDgDLDgDMDsDiDNDODlCPDmDPDQDlCPDGDRDSDSDSDSDSCNDTDTDTIZDVDVDWDXDXCNBGBGBGBGyuaMaMAtDYDZEaEbAtALBhAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHEcDgDgEdDgDsDiEeEfDlCPDmEgEhDlCPDGDSDSDSDSDSDSCNEiEjEkElDVDVDVDXDXCNyuyuyuyuyuaMaMACEaEaEaEmAtEnEnAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgDgDgDgDgEoDaCPCPCPCPCPCPCPCPCPDGDSDSEpEqErEsCNEtEuEvDVEwExDVDVEyCNaMaMaMaMaMaMaMAtDYDZEaEzEAEBEBBVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgECDgDrEDEEEFEGEGEGEHEHEHEIEJEKELEMEHEHEHCNCNCNENEOEOEwEPEQExERESCNaMaMaMaMaMaMaMETATEUEUEUBVEVEVEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgDgDgEDEXEYEZEZEZEZEHFaFbFcFdFeFfFgFbFaEHCNCNCNCNCNCNFhFiFjFkERESCNaMaMaMaMaMaMaMaMETEVEVEVEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHFlDgEDEXEYEYEZEZEZEZEHFbFmFnFdFeFfFnFoFbEHFpFqFrFsFtCNDVFhFkDVDVEwFuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgEDEXEYEYEYEZEZEZEZEHFvFbFvFdFeFfFvFbFvEHFwDVDVDVDVFxDVDVDVDVDVFyFzaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHEDEXEYEYEYEYEYEYEYEYEHFAFbFbFdFeFfFbFbFBEHFCFDFEFFFGCNDVDVDVDVDVFHFIaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHAHAHAHAHAHAHAHAHAHAHAHEHFJFKFKFdFeFfFLFLFMEHFNFOFPFQFRCNFSFTFUFVFWFXCNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeFeFeFeFeFeFeFeFeFeFeEHEHFYEHEHFeEHEHFYEHEHEHEHEHEHEHCNCNCNCNCNCNCNCNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHEHEHEHFZEHEHEHFeFeFeFeFeFeEHFeEHFeFeFeFeFeFeFeFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGaGbGbGbGbGcEHEHEHEHEHEHEHEHGdEHEHEHEHEHEHEHEHFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGaGbGbGbGbGcEHGeGfGgGfGhGiGiGiGiGiGhGiGhGiGjEHFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGkGbGbGbGbGlEHGiGmGmGmGmGmGiGiGiGmGmGmGmGnGoEHFeEHEHEHEHEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGkGpGqGqGbGbGrGiGiGsGtGsGiGiGiGiGiGsGtGsGuGiEHFeFeFeFeFeFeFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHFeEHEHEHEHEHEHEHEHGiGmGmGmGmGmGiGiGiGmGmGmGmGvGiEHEHEHEHEHEHEHFeEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAFeEHEHzazazazazaEHGxGxGxGxGxGxGxGxGxGxGxGxGxGyGxEHzbzbzbzbzbEHFeFeFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHEHEHHgHgHgHgHgEHGBGCGCGCGCGCGCGCGCGCGCGCGCGDGBEHHgHgHgHgHgEHEHEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGGGGGGGGGFGIGCGCGCGCGCGCGCGCGCGCGCGCGDGJGFGKGKGKGKGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGMGGGMGGGFGIGCGCGCGCGCGCGCGCGCGCGCGCGDGJGFGKGNGKGNGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGGGOGGGGGFGIGCGCGCGCGCGPGQGPGCGCGCGCGDGJGFGKGKGRGKGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGGGGGGGGGFGIGCGCGCGCGCGSGTGSGCGCGCGCGDGJGFGKGKGKGKGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGU -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGMGGGMGGGFGIGCGCGCGCGCGVGWGXGCGCGCGCGDGJGFGKGNGKGNGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGZGYGYGYHaHaHaGYGYHaHaHaGYGYGYGYGYGU -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHFbGHGGGGGGGGGGGFGIGCGCGCGCGCGCHcGCGCGCGCGCGDGJGFGKGKGKGKGKGHFbEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUHdGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYHeGU -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHHfEHHbHbHbHbHbEHGBGCGCGCGCGCGCHcGCGCGCGCGCGDGBEHHbHbHbHbHbEHHfEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYHhGYGYGYGYGYGU -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFJHiFbEHGzGzGzGzGzEHGxGxGxGxGxGxHkHlHkGxGxGxGxGyGxEHGEGEGEGEGEEHFbHnFMEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYHdGYGYGYGYGYGU -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHFbEHEHEHEHEHEHEHHoHpHpHpHpHpHqHrHoHpHpHpHpHsHoEHEHEHEHEHEHEHFbEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYHtHhGYGYGYGYGYGYGYGYGYGYGYGYGYGU -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFbFbFeFeFeFeFeEHHoHoHuHoHuHoHoHvHwHoHuHoHuHxHoEHFeFeFeFeFeFbFbEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGU -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHEHEHEHEHFeFYHoHoHoHyHyHyHoHoHoHyHyHyHyHyHoFYFeEHEHEHEHEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYHzHAGYGYGYGYGYGYGYGYGYGYGYGYGU +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMoToUoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVoVpFtptptptptptptptptppFpFsNpFpFtptptptptptptppFpZqztrtstttttttstuqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvyhyhyhyhyhyhyhxOxOBdtxtxtxtxtxtxpFtytztypFtxtxtxtxtxtxtxtxpZqzqztAtBtBtBtCqzqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtqtvtDtFtEuytNtGtvtYuhtZtZuiuaujujululyhzdyIyIyIyIumwGxvwGuntOtPtQtRtSpFtytztypFtTtUtVtWtWtxaMaMpZqzqzqzqzqzqzqzqzqAqBaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvtvtvAgtvuhuhuhuhuhuhtvuzuhuhuhuhuhuhuhuhuhyhyByIuAyIyIvexQxQxQvfueufufufufpFtytztypFtWtWtWtWtWtxaMaMugugugugugugugugugugugtxtxtxtxtxtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutuuvbuvuwvguhuhuhuhuhuhuhvytvvkuhuhuhuhuhuhuhuhuhyhyHvpzqyIyIumwGxvwGunueufufufufpFpFsNpFpFtWtWtWtWtWtxuguguguguguguoupuqtxurururtxururururururururtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVAIuXuVuVuVuYAIuZvavbvbvctvtHuhuhuhuhuhuhuhtvvzuhuhuhuhujvEvAvKvKyhzrzpzEyIyIyhvMvMvMtxuDuEuFuGuHtxuIuIuItxtWtWtWtWtWtxuJuKuJuLuMuguNuNuNuOurururuOuruPuQuPuruRuSuTtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvvgtvtvtvuhuhuhuhuhuhuhuhtvuhuhuhuhvNtvtvtvtvtvyhyhyhyhyhyhyhxQxQxQtxvOtxvlvmvntxufufuftxvlvmvotxvPtxvqvrvqvrvqugtxtxtxtxurururtxvsvtuPvuvsvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutvIvbvbvJtvvxvQukxovRvSuhuhtvuhuhuhuhvTtvwlwhwhwlwownwqwpxQxQxQxQxQwztxufufvBvCvCvCvCvCvCvCvCvCvDufufwAvqvqvqvqvqugvFuNuotxurururtxvGvGvHvGvGvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVwWuXuVuVuVuYwWwivavbvbwjtvwFwGwGwGwItvuhuhtvuhuhuhuhwBtvuhxQxQwmwEwmwmwmwmwmxQxQxQwPtxufufvVvWvXvXvXvXvXvXvXvYueufufugvZwawbwcwdugweuNuptxurururtxwfwfuNwfwfvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMwgaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutwxvbvbwywowVwYwXxawZwouhuhwouhuhuhuhxbwouhxQxQuwxcxQxQxQwqwqtvtvtvtvtvufufvVwrwsufwtwuwvufwswrueufufugugugugugugugweuNuptxurururtxwwwwuNwwwwvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVxduXuVuVuVuYxdxevavbvbxgxkxhuhuhuhxlxkuhuhxkuhuhxnxmxpxkxqxQxQxQtvwFwGwHwGwItvwJwJwJtvufufwKwLwMwNwOxrwQwRwSwLwTufuftxwUwUwUwUwUtxtxuOtxtxtxuOtxtxuNuNuNuNuNvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvutxsvbvbxMtvxtuhuhuhuhtvxuxutvOYOYtvtvtvtvxqxQxQuwuWxfxfxfxfxfxwxfxfxfxwufufufxxufufxiufxiufufxxufufufxjurururururxjurururururururxjwwwwwwwwwwvvvwvwtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMmu +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMuUuVuVuVuVuVuVuVuVuVuVuVuVuVxyuXuVuVuVuYxyxzxAvbvbuwxHuhuhuhuhuhxHuhuhxIuhuhxKxJxLxLuhxQxQvdtvwFwGwHwGwItvxBxBxBtvufufvBxCxDwNxEufxFwRxGxCvDufufxjurururururxjurururururururxjwwwwwwwwwwtxuOuOtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMustvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvtvvbvbuwxHuhuhuhuhuhxHuhuhxRuhuhxQyayayaxQxQxQzcycybydxQyfyetvtvtvtvtvufufvVwLxSufxiufxiufxSwLueufuftxxTxUxUxUxVtxtxxWtxtxtxuOtxtxtxxXxXxXtxtxurururxYurxZtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvvbvbxNtvwFwGwGwGwItvygygtvyiuhxQyjylykxQxQxQyRymydxQxQxQxQxcxQxnyztvufufvVtxtxynyoufypyqtxtxueufuftxaMaMaMaMaMtxyrystxuNytuNuNyuyvywywywObtxururuQuQururyyaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvyAyDyCyKyGuhuhuhwoyQuhxQylyWySxQxQxQxQxcxQxQxQyYyXwoxQxQyZtvufufvVtxtxvlvmvmvmvotxtxueufuftxaMaMaMaMaMtxysystxyLyLyLuNyuywywywywyMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvuhuhuhuhuhuhuhuhxkzeuhxQzgzgzgxQxQxQxQxcxQxQxQyYyXxkyJyEyFtvufufwKyTyTyTyTyTyTyTyTyTwTufuftxaMaMaMaMaMtxyUystxyLyVyLuNyuyuyuyuyuyutxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvuhuhuhuhuhuhuhuhtvwCuhuhzhuhuhuhxQxQwCymxQxQxQyYyXtvtvtvtvtvtxtxzitxtxufufufufuftxtxtxtxtxtxaMaMaMaMaMtxzfystxvFuNuNuNyuaMaMaMaMaMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvzkzkzlznzmzCzxwDtvzOzDvMtvAbAbtvvMzDzOycAexQxQyYyXtvzsztztzszuzvufzwtxtxtxAhtxtxtxaMaMaMaMaMaMaMaMaMaMtxtxtxtxtxtxtxtxyuaMaMaMaMaMzyuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzzmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtwgmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmt +mumumumumumumumumumumuAnAnAnAnAnAoArArArAsAnAnAnAnAnAnAnAnAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvtvtvtvtvtvtvtvtvzAzBzBzAtvtvtvtvABxQxQyYyXtvzszFzFzszGzHufzwtxzIwTufwKzJtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzKururzLzLururzKaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumumumumumumuAnAnAnAnAnAKAZASBaAKAnAnAnAnAnAnAnAnAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzMzNzNzNzNBvBvzNzNzPaMtvBzxQxQyYyXtvzsztztzszQzHufzwtxueufufufvVtxaMaMaMaMaMaMaMaMaMaMaMaMzRzSNaNaNazTzUaMaMaMaMaMtxzVururururzWtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumumumumumumuAnAnAnAnAnAKBMASASAKAnAnAnAnAnAnAnAnAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzXzYzZAaBYAcAcAdCnzNzPtvtvxcxctvtvtvzszszszsCpzHufzwtxAfuxAfCLAftxaMaMaMaMaMaMaMaMaMaMaMzRAiNiNjNkNlNmAlzUaMaMaMaMtxtxtxtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumumuAnAnAnArDEArDIAnDUDEArDIEpDWArArArArArAsAnAnAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzXzYAmAcAcAcAcAcAcEsErwoxQxQxQxQxQtvApzsApzszuzHufAqEKueufFxufxFyuaMaMaMaMaMaMaMaMaMaMzRAiFGAMADAvADNpNoAlzUaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumuAnAnAnAnFYFZASASASASASASASASASASASASASASASASAKAnAnAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzXzYAxAyAzAzAzAzAzzNAAxPxQxQxQxQxQxcApzsApzszGzHufAqEKuDufwtHfNdyuaMaMaMaMaMaMaMaMaMaMACADADADADNcADADADADACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumuAnAnASHkFYHkASASASASASASASASASASASASASASASASHmIJIIAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAEzNzNzNzNzNzNzNzNAAaMxkxQxQxQxQxQtvApzsApzszQAFxSAGAHAftXAJIKAfyuaMaMaMaMaMaMaMaMaMaMAtADBuNhNeNgNeNfCrADAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumuAnAnFYHkFYAnAnAnDUArArAsEpDUArILDIEpISASASASEpIUITAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAPufufAQvVyuyuyuaMaMaMaMaMaMaMaMAtIVACATARAUARATACIVAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumuAnFYFYAnAnAnAnAnAnAnAnAKASASBMAKIWASAKASASASEpIUIXAnAnISmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWAWAWAWAWAWAWAWAWAWAWAWAXAYIYJaBbBcBcBcBcBcAHBdxCBeufufBfvVxCBdyuaMaMaMaMaMaMaMaMAtADCrAtMSMTMUAtBuADAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumuAnFYAnAnAnmumuAnDUArDIJcJbASAZAKJbAZAKASASASISIUIUIUJlAKmumumumumumuaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWBlBmBnBlBmBmBoBpBqBmBrBsAYAWAWBtBcBcBcBcBcAHBdwrBeufufufvVwrBdyuyuyuyuyuyuaMaMaMACADCrCCMQMRMPCCBuADACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumuAnJoJoAnmumumuAnJpJqJqDWArArArDEArArJrASASASAKIUIUIUJyAKmumumumumumuaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWBlByJzBABBBCBCBCBCBCBCBDBEAYAWAWBbBcBcBcBcBcAHBdwrBeufufufBFwrBdBGBGBGBGBGyuaMaMzRAiADCrDfMQBwMPDfBuADAlzUaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumuAnFYFYFYFYAnAnmumuAnJAJBJAEpASASASASASASASASASASAKJDJCJEDUJrmumumumumumuaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWBIBJBKBJBLBJBJBJBJBJBJBJJFAWAWAWAHAHAHAHBNBOAHBdwrBeufufufBPBQvmBRBRBRBRBRBRBRBSAtBgADCrAlACJHACAiBuADBgAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumuJIFYFYFYFYJJAnmumuISJKJAJAEpASASASASASASASASASASAKAnAnAnAnAnmumumumumumuaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWBWBXJLBZBBCaCaCaCaCaCaCbCcAYAWAWAHCdCeCfCgCgAHChCiCjufufufufCkClClMZClClCmJMCoJMJNADADADMYMXADADMYADADCrACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumuJOJVJUFYJWFYFYmumuHmJXJYAoArArArArArArILArDIEpDUDEILArArArArArArAsmumuaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWBWBmCsBWBmBmBoBpBqBmCtBsAYAWAWAHCuCvCwCgCgCxCyCzufufufufufCkClClClClClCmCABRBSAtMVADCrCCBuADCrCCBuADMWAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumuJZFYKaFYJUFYFYmumuAnAnAnAKASASASASASASAKKbKcKcKcKdAKASASASASASASAKmuaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWAWAWAWAWAWAWAWAWAWAWAWAXAYAWAWAHCECFCGCgCgCxCyCzufufufufCHCIBRCJClClCKKiyuaMaMCCBuADCrCMBuADCrCMBuADCrCCaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumuAnFYKjFYKsFYFYmumuaMaMmuAKASAZASASASASHmKcKcKuKcKcHmASASASASAZASAKmuaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHAHAHAHAHAHCNCNCNCNCNCNCNCNCNCNCNCNCNNzCOCOCPCPCNCQvYCRufNAufBFCSBdCTClCmKvCVyuaMaMCMBuADCrCMBuNcCrCMBuADCrCMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumuAnKxKwFYFYKyFYmumuaMaMmuAKASASASASASASEpKcKcKzKcKcEpASASASASASASAKmuaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHCWCXCXCXCYCZDaCPCPCPNwCPCPCPCPCPCPCPCPCPCPNyCPCNBdwrNxufufufBPDbBRDcClClDdDeyuaMaMDfBuADCrCMBuADCrCMBuADCrDfaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumuAnAnFYFYFYFYAnmumumAaMaMAKASASISKAKCKBISKcKLKDKcKcISKAKCKBISASASAKaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgDgDgDgDgDhDiDjDkDlCPDmDnDoDlCPCPCPCPCPCPCPCPCNBdwrDpufufufufCkClClClClClCmCABRBSAtBTADCrDfBuADCrDfBuADDqAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumuAnAnAnAnKMKNAnmumBmAaMaMHmASASHmaMaMaMDWDIKAKCKBDUJraMaMaMHmASASHmaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgDrDgDgDgDsDiDtDuDlCPDmDvDwDlCPCPDxDxDxDxDxDxCNDyDzDADBDCDCDCDDDCDCClClClCmJMCoJMKOADADNCADADADADADNCADCrACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumuAnAnAnAnAnAnmuaMaMaMaMaMKPKQKQKRaMaMaMaMaMaMaMaMaMaMaMaMaMKPKQKQKRaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgDFDgDgDgDsDaCPCPCPNyCPCPCPCPCPDGDHDHDHDHDHDHCNCNCNCNCNKSKSCNCNCNCNCABRBRBRBRBRBSEAACNNATzSzTKTzSzTATNNACBVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumumumumumuaMaMaMaMKPKVKUKRaMaMaMaMaMaMaMaMaMaMaMaMaMKPKVKUKRaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgDgDLDgDMDsDiDNDODlCPDmDPDQDlCPDGDRDSDSDSDSDSCNDTDTDTNDDVDVKWDXDXCNBGBGBGBGyuaMaMAtNENFAtNHNIEaNKNJAtNLNGAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumumumumuaMaMaMaMaMKPKVKUKRaMaMaMaMaMaMaMaMaMaMaMaMaMKPKVKUKRaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHEcDgDgEdDgDsDiEeEfDlCPDmEgEhDlCPDGDSDSDSDSDSDSCNEiEjEjElDVDVDVDXDXCNyuyuyuyuyuaMaMAtNXNYAtNWNVEaEaKXAtNTNSAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumumumumuaMaMaMaMaMKYKQKQKZaMaMaMKYaMaMaMaMaMKZaMaMaMKYKQKQKZaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHNODgDgDgDgEoDaCPCPCPCPCPCPCPCPCPDGDSDSLaEqLbLcCNEtDVDVDVEwExDVDVEyCNaMaMaMaMaMaMaMEAEBEBAtNQEaNREbNPAtEBEBBVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumuaMaMaMaMaMaMaMaMLdLfLeLdaMaMaMLhLgLiLiLiLjLkaMaMaMLdLlLmLdaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgECNuDrEDEEEFEGEGEGEHEHEHEIEJLnELEMEHEHEHCNCNCNNvDVDVEwEPEQExERESCNaMaMaMaMaMaMaMETEVEVBVDYDZEaNtNsEAEVEVEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumuaMaMaMaMaMaMaMaMLoLqLpLoaMaMKYLoLrLtLsLwLrLoKZaMaMLoLyLWLoaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgDgDgEDEXEYEZEZEZEZEHFaFbFcFdFeFfFgFbFaEHCNCNCNCNCNCNNrFiNqFkERESCNaMaMaMaMaMaMaMaMaMaMETATEUEUEUATEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumuaMaMaMaMaMaMaMaMLoLYLXLoaMaMLhMaLZMcMbMcLZMdLkaMaMLoMeMfLoaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHFlDgEDEXEYEYEZEZEZEZEHFbFmFnFdFeFfFnFoFbEHFpFqFrFsFtCNDVFhFkDVDVEwFuaMaMaMaMaMaMaMaMaMaMaMETEVEVEVEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumuaMaMaMaMaMaMaMaMMgMiMhMkMjMjMlMmLZLZLZLZLZMnMgMjMjMkMoMpMlaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHDgEDEXEYEYEYEZEZEZEZEHFvFbFvFdFeFfFvFbFvEHFwDVDVDVDVMqDVDVDVDVDVFyFzaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumuaMaMaMaMaMaMaMaMLoMsMrMuMtMvLoMwLZLZLZLZLZMwLoMyMxMBMzMsLoaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHEDEXEYEYEYEYEYEYEYEYEHFAFbFbFdFeFfFbFbFBEHFCFDFEFFMCCNDVDVDVDVDVFHFIaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumuaMaMaMaMaMaMaMaMaMaMaMLoMsMDMDMDMEMgMGMFMIMHMGMFMIMlMJMDMDMKMsLoaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHAHAHAHAHAHAHAHAHAHAHAHEHFJFKFKFdFeFfFLFLFMEHFNFOFPFQFRCNFSFTFUFVFWFXCNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumuaMaMaMaMaMaMaMaMaMaMaMMLMsMDMDMDMDMHLZLZLZLZLZLZLZMHMDMDMMMDMsMLaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeFeFeFeFeFeFeFeFeFeFeEHEHMNEHEHFeEHEHMNEHEHEHEHEHEHEHCNCNCNCNCNCNCNCNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumuaMaMaMaMaMaMaMaMaMaMMONbMDMDMDMDLoNnLZLZLZLZLZNBLoMDNMMDNUMsMOaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHEHEHEHNZEHEHEHFeFeFeFeFeFeEHFeEHFeFeFeFeFeFeFeFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumuaMaMaMaMaMaMaMaMaMaMOcNbMDMDLhOdMkMjLkOfOeOgLhMjMkOhLkOjOiOkOcaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGaGbGbGbGbGcEHEHEHEHEHEHEHEHGdEHEHEHEHEHEHEHEHFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumuaMaMaMaMaMaMaMaMaMKYLoOmOlOlLoOnOnOnMLOfOoOgMLOqOpOrLoOtOsOmLoKZaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGaGbGbGbGbGcEHGeGfGgGfGhGiGiGiGiGiGhGiGhGiGjEHFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumuaMaMaMaMmumuaMaMaMOvOuOwOwMhMlOnOnOnMOOfOeOgMOOrOrOxMgMoOwOwOuOyaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGkGbGbGbGbGlEHGiGmGmGmGmGmGiGiGiGmGmGmGmGnGoEHFeEHEHEHEHEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumuaMaMaMaMmumuaMaMaMaMOvOzOzOyLoOBOAOnOcLZLZLZOcOrOrOCLoOvOzOzOyaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGkGpGqGqGbGbGrGiGiGsGtGsGiGiGiGiGiGsGtGsGuGiEHFeFeFeFeFeFeFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumuaMaMaMaMmumuaMaMaMaMaMaMaMaMLoOnOnOnMgMjMHMjMlODOrOELoaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHFeEHEHEHEHEHEHEHEHGiGmGmGmGmGmGiGiGiGmGmGmGmGvGiEHEHEHEHEHEHEHFeEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMLoOnOnOFLoOGLZOHLoOrOrOILoaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAFeEHEHzazazazazaEHGxGxGxGxGxGxGxGxGxGxGxGxGxGyGxEHzbzbzbzbzbEHFeFeFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMMdLkOJOnLoOKLZOLLoONOMLhMaaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHEHEHHgHgHgHgHgEHGBGCGCGCGCGCGCGCGCGCGCGCGCGDGBEHHgHgHgHgHgEHEHEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMOvMdMjOOMaOQOPORMdOOMjMaOyaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGGGGGGGGGFGIGCGCGCGCGCGCGCGCGCGCGCGCGDGJGFGKGKGKGKGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumuaMaMaMaMmumuaMaMaMaMaMaMaMaMOvOuOwOwOwOwOwOuOyaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGMGGGMGGGFGIGCGCGCGCGCGCGCGCGCGCGCGCGDGJGFGKGNGKGNGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumuaMaMaMaMmumumuaMaMaMaMaMaMaMaMOvOzOzOzOzOzOyaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGGGOGGGGGFGIGCGCGCGCGCGPGQGPGCGCGCGCGDGJGFGKGKGRGKGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +mumumumumumuaMaMaMaMmumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGGGGGGGGGFGIGCGCGCGCGCGSGTGSGCGCGCGCGDGJGFGKGKGKGKGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGU +mumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGMGGGMGGGFGIGCGCGCGCGCGVGWGXGCGCGCGCGDGJGFGKGNGKGNGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGZGYGYGYHaHaHaGYGYHaHaHaGYGYGYGYGYGU +mumumumuaMaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHFbGHGGGGGGGGGGGFGIGCGCGCGCGCGCHcGCGCGCGCGCGDGJGFGKGKGKGKGKGHFbEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUHdGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYHeGU +mumumumuaMaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHOSEHHbHbHbHbHbEHGBGCGCGCGCGCGCHcGCGCGCGCGCGDGBEHHbHbHbHbHbEHOSEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYHhGYGYGYGYGYGU +mumumumuaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFJHiFbEHGzGzGzGzGzEHGxGxGxGxGxGxOTHlOTGxGxGxGxGyGxEHGEGEGEGEGEEHFbHnFMEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYHdGYGYGYGYGYGU +mumuaMaMaMaMaMaMaMaMaMaMmumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHFbEHEHEHEHEHEHEHHoHpHpHpHpHpHqHrHoHpHpHpHpHsHoEHEHEHEHEHEHEHFbEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYHtHhGYGYGYGYGYGYGYGYGYGYGYGYGYGU +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFbFbFeFeFeFeFeEHHoHoHuHoHuHoHoHvHwHoHuHoHuHxHoEHFeFeFeFeFeFbFbEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGU +mtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHEHEHEHEHFeMNHoHoHoHyHyHyHoHoHoHyHyHyHyHyHoMNFeEHEHEHEHEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYHzHAGYGYGYGYGYGYGYGYGYGYGYGYGU aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHHBHBHBHCHDHEHFHoHGHHHIHJHKHLHMEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYHNHOGYGYGYHtGYHPGYGYGYGYGYGYGU aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHEHEHEHEHEHEHEHEHEHEHEHEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGU aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYHhGYGYGYGYGYGYGYGYGYGYGYGYGYHdGYGYGU @@ -2183,26 +2365,26 @@ aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIaIbIcIdIeIfHYIgIhIiHYIjIkIlHYHYaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcIcImInIoIpIqIkIkIrHYHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIsIsIcIcIcItHYIuIvIwHYHYHYHYHYHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcIxHYIyIyIzHYIAIBICIDHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIEIEIcIcIcIFHYIyIyIyIGIyIyIyIHHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMIIIJIKaMIIIJIKaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcILHYIMINIOHYIPIQIRIDHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMISITIUIUIUIVISaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcItHYHYHYHYHYHYHYHYHYHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMIIIJIWIJIXIYKuLeJWIYJcIJIWIJIKaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJeJfJgIcJhJiJjJhJkGLJmJnHjHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMITIUIUIVISaMITIYJpJqJrIYIVaMISITIUIUIVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJsJtJgIcJuJuJuJuJvJwJxJwJxHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMIYJyJzIYISITIYJAJBJCJBJDIYIVISIYJEJFIYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJGJHJgIcJuJuJuJuJuJuJuJuJuHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMIYJIJJIYIUJKJLJDJBJMJBJDJLJKIUIYJNJOIYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJPJQJgIcJuJuJuJuJuJuJRJSJTHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMIYJUJVIYIUJbJLJDJBJDJBJDJLJbIUIYJXJYIYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcIcJuJuJuJuJuJuJuJuJuHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMIYJZKaIYIYIYIYIYIYKbIYIYIYIYIYIYKcKdIYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYKeKfKfKgKfKfKfKgKfKfKfKgKfKfKhHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMIUJKKiKjKjKjKjKjKjIYKjIYKjKjKjKjKjKjKiJKIUaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYKkKlKlJkKmKoKnJkKpKpKqJkKrKsKtHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMIUJaKvKwKxKyKzIYKbIYKbIYKbIYKAKBKCKDKvJaIUaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYKlKEKkJvKGLvLuJvKHKIKpJvKJKtKKHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMIUJbKvJDJDJDKLIYJDJDJDJDJDIYJDJDKMJDKvJbIUaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYHYHYHYHYHYHYHYHYHYHYHYHYHYHYHYHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMITIYKNKOKPJlHmIYJoJDJDJDKQIYKUKVKWKXKNIYIVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMKYIYKZKZIYIYIYIYKRJDJDJDKSIYIYIYIYKZKZIYLcaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMKYLdLdLcaMaMIYKTJDJDJDLaIYaMaMKYLdLdLcaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMIYLbJDJDJDLaIYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMIYLhLiLjLhLiIYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMIYLkLlJDLmLnIYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMIYLoLpJDLqLrIYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMKYIYLsLtJDIYLcaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM -aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMKYIYIYIYLcaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIEIEIcIcIcIFHYIyIyIyIGIyIyIyIHHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcOUHYIMINIOHYIPIQIRIDHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVaMaMaMOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcItHYHYHYHYHYHYHYHYHYHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJeJfJgIcJhJiJjJhJkGLJmJnHjHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVaMaMOVaMaMOVOVOVOVOVOVOVaMaMOVaMaMOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJsJtJgIcJuJuJuJuJvJwJxJwJxHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVaMOVOVOVOVOVOVOVOVOVaMOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJGOWJgIcJuJuJuJuJuJuJuJuJuHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVaMOVOVOVOVOVOVOVOVOVaMOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJPJQJgIcJuJuJuJuJuJuJRJSJTHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVaMOVOVOVOVOVOVOVOVOVaMOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcIcJuJuJuJuJuJuJuJuJuHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYKeKfKfKgKfKfKfKgKfKfKfKgKfKfKhHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYKkKlKlJkKmKoKnJkKpKpKqJkKrOXKtHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYKlKEKkJvKGLvLuJvKHKIKpJvKJKtKKHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYHYHYHYHYHYHYHYHYHYHYHYHYHYHYHYHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVaMaMOVOVOVOVOVOVOVaMaMOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM +aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM "} diff --git a/maps/exodus-3.dmm b/maps/exodus-3.dmm index ad3f736587..0e2012a824 100644 --- a/maps/exodus-3.dmm +++ b/maps/exodus-3.dmm @@ -26,7 +26,7 @@ "az" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/shuttle/plating,/area/derelict/ship) "aA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/shuttle/plating,/area/derelict/ship) "aB" = (/obj/machinery/door/airlock/glass{name = "Hibernation Pods"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) -"aC" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) +"aC" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "aD" = (/obj/structure/table,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "aE" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/derelict/ship) "aF" = (/obj/item/device/multitool,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) @@ -41,11 +41,11 @@ "aO" = (/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "aP" = (/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "aQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/plating,/area/derelict/ship) -"aR" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) +"aR" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "aS" = (/obj/machinery/door/window,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "aT" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "aU" = (/obj/structure/lattice,/turf/space,/area/space) -"aV" = (/obj/structure/table,/obj/item/weapon/gun/energy/laser/retro,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) +"aV" = (/obj/structure/table,/obj/item/weapon/gun/energy/retro,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "aW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/shuttle/plating,/area/derelict/ship) "aX" = (/obj/machinery/light/small{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "aY" = (/obj/structure/table,/obj/item/weapon/tank/oxygen,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) @@ -56,7 +56,7 @@ "bd" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/space) "be" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/space) "bf" = (/obj/structure/table,/obj/item/device/analyzer,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) -"bg" = (/obj/structure/stool/bed/chair{dir = 8},/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) +"bg" = (/obj/structure/bed/chair{dir = 8},/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "bh" = (/obj/machinery/door/airlock/glass{name = "Living Module"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "bi" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "bj" = (/turf/simulated/shuttle/wall{icon_state = "swall7"; dir = 2},/area/space) @@ -65,7 +65,7 @@ "bm" = (/turf/simulated/shuttle/floor{icon_state = "floor3"},/turf/simulated/shuttle/wall{icon_state = "swall_f5"; dir = 2},/area/space) "bn" = (/turf/simulated/shuttle/wall{icon_state = "swall11"; dir = 2},/area/space) "bo" = (/obj/machinery/door/window/northright,/obj/effect/decal/remains/human,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) -"bp" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) +"bp" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "bq" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "br" = (/obj/machinery/door/unpowered/shuttle,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/space) "bs" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/derelict/ship) @@ -79,8 +79,8 @@ "bA" = (/turf/simulated/shuttle/wall{icon_state = "swall13"; dir = 2},/area/space) "bB" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/space) "bC" = (/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) -"bD" = (/obj/item/weapon/shard,/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) -"bE" = (/obj/structure/stool/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) +"bD" = (/obj/item/weapon/shard,/obj/structure/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) +"bE" = (/obj/structure/bed/chair,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "bF" = (/obj/structure/cable,/obj/structure/computerframe{anchored = 1},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "bG" = (/obj/structure/cable,/obj/structure/computerframe{anchored = 1},/obj/item/stack/cable_coil/cut,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) "bH" = (/obj/structure/table/rack,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/obj/item/weapon/tank/emergency_oxygen,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/derelict/ship) @@ -118,11 +118,11 @@ "cn" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 1; icon_state = "map"; tag = "icon-manifold-f (NORTH)"},/obj/machinery/meter,/turf/simulated/floor/plating,/area/turret_protected/tcomsat) "co" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating,/area/turret_protected/tcomsat) "cp" = (/turf/simulated/floor/engine,/area/tcommsat/computer) -"cq" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/green,/turf/simulated/floor,/area/tcommsat/computer) +"cq" = (/obj/structure/bed,/obj/item/weapon/bedsheet/green,/turf/simulated/floor,/area/tcommsat/computer) "cr" = (/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/tcommsat/computer) -"cs" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor,/area/tcommsat/computer) +"cs" = (/obj/structure/bed,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor,/area/tcommsat/computer) "ct" = (/obj/machinery/camera{c_tag = "Lounge"; dir = 2; network = list("Tcomsat")},/turf/simulated/floor,/area/tcommsat/computer) -"cu" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/red,/turf/simulated/floor,/area/tcommsat/computer) +"cu" = (/obj/structure/bed,/obj/item/weapon/bedsheet/red,/turf/simulated/floor,/area/tcommsat/computer) "cv" = (/turf/simulated/floor,/area/tcommsat/computer) "cw" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 4},/turf/space,/area/turret_protected/tcomsat) "cx" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/plating,/area/turret_protected/tcomsat) @@ -145,9 +145,9 @@ "cO" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/closet,/turf/simulated/floor/plating,/area/turret_protected/tcomsat) "cP" = (/obj/structure/window/reinforced{dir = 8},/turf/space,/area/turret_protected/tcomsat) "cQ" = (/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/turf/simulated/floor,/area/tcommsat/computer) -"cR" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/turf/simulated/floor,/area/tcommsat/computer) +"cR" = (/obj/structure/bed/chair/office/dark{dir = 1},/turf/simulated/floor,/area/tcommsat/computer) "cS" = (/obj/machinery/computer/telecomms/monitor{network = "tcommsat"},/obj/item/device/radio/intercom{anyai = 1; freerange = 1; name = "General Listening Channel"; pixel_x = 28; pixel_y = 0},/turf/simulated/floor,/area/tcommsat/computer) -"cT" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/orange,/obj/machinery/light{dir = 8},/turf/simulated/floor,/area/tcommsat/computer) +"cT" = (/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/obj/machinery/light{dir = 8},/turf/simulated/floor,/area/tcommsat/computer) "cU" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/lattice,/turf/space,/area/turret_protected/tcomsat) "cV" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/lattice,/turf/space,/area/turret_protected/tcomsat) "cW" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/turret_protected/tcomsat) @@ -157,20 +157,20 @@ "da" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/tcommsat/computer) "db" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor,/area/tcommsat/computer) "dc" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/tcommsat/computer) -"dd" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor,/area/tcommsat/computer) +"dd" = (/obj/structure/bed/chair/office/dark{dir = 4},/turf/simulated/floor,/area/tcommsat/computer) "de" = (/obj/machinery/computer/telecomms/server{network = "tcommsat"},/turf/simulated/floor,/area/tcommsat/computer) "df" = (/obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh{name = "Cuban Pete-Meat"},/obj/item/weapon/spacecash/c1,/turf/simulated/floor/engine,/area/tcommsat/computer) "dg" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/tcommsat/computer) "dh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/tcommsat/computer) "di" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor,/area/tcommsat/computer) -"dj" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor,/area/tcommsat/computer) +"dj" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor,/area/tcommsat/computer) "dk" = (/obj/structure/table,/obj/item/weapon/storage/fancy/cigarettes,/turf/simulated/floor,/area/tcommsat/computer) -"dl" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor,/area/tcommsat/computer) +"dl" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor,/area/tcommsat/computer) "dm" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat) "dn" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat) "do" = (/obj/structure/window/reinforced,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat) "dp" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat) -"dq" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/airlock/hatch{name = "Telecoms Control Room"; req_access_txt = "61"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/tcommsat/computer) +"dq" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/airlock/hatch{name = "Telecoms Control Room"; req_access = list(61)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/tcommsat/computer) "dr" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/tcommsat/computer) "ds" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1; icon_state = "map"; tag = "icon-manifold-f (NORTH)"},/turf/simulated/floor,/area/tcommsat/computer) "dt" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor,/area/tcommsat/computer) @@ -181,7 +181,7 @@ "dy" = (/obj/machinery/vending/cola,/turf/simulated/floor,/area/tcommsat/computer) "dz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/tcommsat/computer) "dA" = (/obj/item/weapon/cigbutt,/obj/machinery/light,/turf/simulated/floor,/area/tcommsat/computer) -"dB" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor,/area/tcommsat/computer) +"dB" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/floor,/area/tcommsat/computer) "dC" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor,/area/tcommsat/computer) "dD" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/tcommsat/computer) "dE" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/space) @@ -196,9 +196,9 @@ "dN" = (/obj/machinery/atmospherics/unary/freezer{set_temperature = 73; dir = 1; icon_state = "freezer_1"; use_power = 1},/turf/simulated/floor,/area/tcommsat/computer) "dO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/tcommsat/computer) "dP" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/tcommsat/computer) -"dQ" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/window/eastleft{req_access_txt = "61"},/obj/machinery/door/window/westleft{req_access_txt = "61"},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/tcommsat/chamber) +"dQ" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/window/eastleft{req_access = list(61)},/obj/machinery/door/window/westleft{req_access = list(61)},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/tcommsat/chamber) "dR" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/tcommsat/chamber) -"dS" = (/obj/machinery/door/airlock/hatch{name = "Telecoms Lounge"; req_access_txt = "61"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/tcommsat/computer) +"dS" = (/obj/machinery/door/airlock/hatch{name = "Telecoms Lounge"; req_access = list(61)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/tcommsat/computer) "dT" = (/obj/machinery/porta_turret/stationary,/turf/simulated/floor/plating/airless,/area/turret_protected/tcomsat) "dU" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/lattice,/turf/space,/area/turret_protected/tcomsat) "dV" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/tcommsat/chamber) @@ -206,7 +206,7 @@ "dX" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/structure/cable,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/tcommsat/chamber) "dY" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/tcommsat/chamber) "dZ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'SERVER ROOM'."; name = "SERVER ROOM"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/tcommsat/chamber) -"ea" = (/obj/machinery/door/airlock/maintenance_hatch{name = "Telecoms Server Access"; req_access_txt = "61"},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/tcommsat/chamber) +"ea" = (/obj/machinery/door/airlock/maintenance_hatch{name = "Telecoms Server Access"; req_access = list(61)},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/tcommsat/chamber) "eb" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat) "ec" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/lattice,/turf/space,/area/turret_protected/tcomsat) "ed" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat) @@ -263,7 +263,7 @@ "fc" = (/obj/structure/sign/nosmoking_2{pixel_x = 32; pixel_y = 0},/obj/machinery/light{dir = 4},/turf/simulated/floor/bluegrid{name = "Mainframe Base"; nitrogen = 100; oxygen = 0; temperature = 80},/area/tcommsat/chamber) "fd" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/lattice,/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/space,/area/turret_protected/tcomsat) "fe" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat) -"ff" = (/obj/machinery/door/airlock/maintenance_hatch{name = "Telecoms Storage"; req_access_txt = "61"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat) +"ff" = (/obj/machinery/door/airlock/maintenance_hatch{name = "Telecoms Storage"; req_access = list(61)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat) "fg" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/turret_protected/tcomsat) "fh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/turret_protected/tcomsat) "fi" = (/obj/structure/table,/obj/item/weapon/stock_parts/subspace/amplifier,/obj/item/weapon/stock_parts/subspace/amplifier,/obj/item/weapon/stock_parts/subspace/amplifier,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_x = 29; pixel_y = 0},/obj/machinery/light/small{dir = 4},/turf/simulated/floor,/area/turret_protected/tcomsat) @@ -307,12 +307,12 @@ "fU" = (/obj/structure/window/reinforced,/obj/machinery/light{dir = 1},/turf/space,/area/turret_protected/tcomsat) "fV" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/space,/area/turret_protected/tcomsat) "fW" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat) -"fX" = (/obj/machinery/door/airlock/hatch{name = "Telecoms West Wing"; req_access_txt = "61"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomfoyer) +"fX" = (/obj/machinery/door/airlock/hatch{name = "Telecoms West Wing"; req_access = list(61)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomfoyer) "fY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/turret_protected/tcomfoyer) "fZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/turret_protected/tcomfoyer) "ga" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor,/area/turret_protected/tcomfoyer) "gb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/turret_protected/tcomfoyer) -"gc" = (/obj/machinery/door/airlock/hatch{name = "Telecoms East Wing"; req_access_txt = "61"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomfoyer) +"gc" = (/obj/machinery/door/airlock/hatch{name = "Telecoms East Wing"; req_access = list(61)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomfoyer) "gd" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat) "ge" = (/obj/machinery/camera{c_tag = "East Wing South"; dir = 8; network = list("Tcomsat")},/turf/space,/area/turret_protected/tcomsat) "gf" = (/obj/machinery/camera{c_tag = "West Wing South"; dir = 4; network = list("Tcomsat")},/turf/space,/area/turret_protected/tcomsat) @@ -324,7 +324,7 @@ "gl" = (/obj/machinery/light/small,/turf/simulated/floor{icon_state = "warningcorner"; dir = 2},/area/turret_protected/tcomfoyer) "gm" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'LETHAL TURRETS'. Enter at your own risk!"; name = "LETHAL TURRETS"; pixel_x = 32; pixel_y = 0},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/turret_protected/tcomfoyer) "gn" = (/turf/simulated/wall/r_wall,/area/tcommsat/entrance) -"go" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/hatch{name = "Telecoms Satellite"; req_access_txt = "61"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/turret_protected/tcomfoyer) +"go" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/hatch{name = "Telecoms Satellite"; req_access = list(61)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/turret_protected/tcomfoyer) "gp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/tcommsat/entrance) "gq" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "warningcorner"; dir = 4},/area/tcommsat/entrance) "gr" = (/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/tcommsat/entrance) @@ -343,7 +343,7 @@ "gE" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/camera{c_tag = "Power Room East"; dir = 1; network = list("Tcomsat")},/obj/machinery/light/small{dir = 1},/turf/simulated/floor,/area/tcommsat/entrance) "gF" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/tcommsat/entrance) "gG" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/tcommsat/entrance) -"gH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/hatch{name = "Telecoms Satellite"; req_access_txt = "61"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/tcommsat/entrance) +"gH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/hatch{name = "Telecoms Satellite"; req_access = list(61)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/tcommsat/entrance) "gI" = (/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/tcommsat/entrance) "gJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/tcommsat/entrance) "gK" = (/obj/machinery/camera{c_tag = "Entrance North"; dir = 2; network = list("Tcomsat")},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/tcommsat/entrance) @@ -357,11 +357,11 @@ "gS" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/tcommsat/entrance) "gT" = (/obj/item/weapon/cell,/turf/simulated/floor,/area/tcommsat/entrance) "gU" = (/obj/structure/closet/malf/suits,/turf/simulated/floor,/area/tcommsat/entrance) -"gV" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1381; master_tag = "telecoms_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = "13"},/turf/simulated/floor/plating/airless,/area/space) -"gW" = (/obj/machinery/door/airlock/external{frequency = 1381; icon_state = "door_locked"; id_tag = "telecoms_outer"; locked = 1; name = "External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/tcommsat/entrance) -"gX" = (/obj/machinery/camera/xray{c_tag = "External Airlock"; network = list("Tcomsat")},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1381; id_tag = "telecoms_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "telecoms_pump"; tag_exterior_door = "telecoms_outer"; frequency = 1381; id_tag = "telecoms_airlock"; tag_interior_door = "telecoms_inner"; pixel_x = 0; pixel_y = -25; req_access_txt = "13"; tag_chamber_sensor = "telecoms_sensor"},/obj/machinery/airlock_sensor{frequency = 1381; id_tag = "telecoms_sensor"; pixel_x = 12; pixel_y = -25},/turf/simulated/floor/plating,/area/tcommsat/entrance) -"gY" = (/obj/machinery/door/airlock/external{frequency = 1381; icon_state = "door_locked"; id_tag = "telecoms_inner"; locked = 1; name = "External Access"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating,/area/tcommsat/entrance) -"gZ" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1381; master_tag = "telecoms_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/tcommsat/entrance) +"gV" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1381; master_tag = "telecoms_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access = list(13)},/turf/simulated/floor/plating/airless,/area/space) +"gW" = (/obj/machinery/door/airlock/external{frequency = 1381; icon_state = "door_locked"; id_tag = "telecoms_outer"; locked = 1; name = "External Access"; req_access = list(10,13)},/turf/simulated/floor/plating,/area/tcommsat/entrance) +"gX" = (/obj/machinery/camera/xray{c_tag = "External Airlock"; network = list("Tcomsat")},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1381; id_tag = "telecoms_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "telecoms_pump"; tag_exterior_door = "telecoms_outer"; frequency = 1381; id_tag = "telecoms_airlock"; tag_interior_door = "telecoms_inner"; pixel_x = 0; pixel_y = -25; req_access = list(13); tag_chamber_sensor = "telecoms_sensor"},/obj/machinery/airlock_sensor{frequency = 1381; id_tag = "telecoms_sensor"; pixel_x = 12; pixel_y = -25},/turf/simulated/floor/plating,/area/tcommsat/entrance) +"gY" = (/obj/machinery/door/airlock/external{frequency = 1381; icon_state = "door_locked"; id_tag = "telecoms_inner"; locked = 1; name = "External Access"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating,/area/tcommsat/entrance) +"gZ" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1381; master_tag = "telecoms_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/tcommsat/entrance) "ha" = (/obj/machinery/bluespace_beacon,/turf/simulated/floor,/area/tcommsat/entrance) "hb" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_x = 29; pixel_y = 0},/turf/simulated/floor,/area/tcommsat/entrance) "hc" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating/airless,/area/space) diff --git a/maps/exodus-4.dmm b/maps/exodus-4.dmm index d0a2adf82a..0d9ffaf86b 100644 --- a/maps/exodus-4.dmm +++ b/maps/exodus-4.dmm @@ -10,264 +10,108 @@ "aj" = (/obj/machinery/door/airlock/maintenance_hatch,/turf/simulated/floor/plating/airless,/area/constructionsite/bridge) "ak" = (/turf/simulated/floor/airless,/area/space) "al" = (/turf/simulated/floor/plating/airless,/area/space) -"am" = (/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access_txt = "19"},/turf/simulated/floor/airless,/area/constructionsite/bridge) +"am" = (/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access = list(19)},/turf/simulated/floor/airless,/area/constructionsite/bridge) "an" = (/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/fore) "ao" = (/turf/simulated/floor/airless,/area/constructionsite/hallway/fore) "ap" = (/turf/simulated/wall,/area/constructionsite/hallway/fore) "aq" = (/obj/machinery/door/airlock/maintenance_hatch,/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/fore) "ar" = (/obj/machinery/door/airlock/glass{name = "Library"},/turf/simulated/floor/airless,/area/constructionsite/hallway/fore) -"as" = (/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access_txt = "19"},/turf/simulated/floor/airless,/area/constructionsite/hallway/fore) -"at" = (/obj/machinery/door/airlock/glass{name = "Kitchen"; req_access_txt = "28"},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/fore) +"as" = (/obj/machinery/door/airlock/glass_command{name = "Bridge"; req_access = list(19)},/turf/simulated/floor/airless,/area/constructionsite/hallway/fore) +"at" = (/obj/machinery/door/airlock/glass{name = "Kitchen"; req_access = list(28)},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/fore) "au" = (/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/fore) "av" = (/turf/simulated/wall,/area/space) "aw" = (/turf/simulated/wall,/area/constructionsite/storage) "ax" = (/turf/simulated/floor/airless,/area/constructionsite/storage) "ay" = (/obj/machinery/door/airlock/glass_science,/turf/simulated/floor/airless,/area/constructionsite/storage) "az" = (/obj/machinery/door/airlock/glass_science,/turf/simulated/floor/airless,/area/constructionsite/hallway/fore) -"aA" = (/obj/machinery/door/airlock/research,/turf/simulated/floor/airless,/area/constructionsite/hallway/fore) -"aB" = (/obj/machinery/door/airlock/research,/turf/simulated/floor/airless,/area/constructionsite/storage) +"aA" = (/turf/simulated/wall,/area/constructionsite/teleporter) +"aB" = (/obj/machinery/portable_atmospherics/canister/air,/obj/structure/window/basic{tag = "icon-window (WEST)"; icon_state = "window"; dir = 8},/obj/structure/window/basic{tag = "icon-window (NORTH)"; icon_state = "window"; dir = 1},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/constructionsite/teleporter) "aC" = (/obj/machinery/door/airlock/maintenance_hatch,/turf/simulated/floor/plating/airless,/area/constructionsite/storage) "aD" = (/turf/simulated/wall,/area/solar/constructionsite) "aE" = (/turf/simulated/floor/plating/airless,/area/solar/constructionsite) "aF" = (/obj/structure/lattice,/turf/space,/area/solar/constructionsite) "aG" = (/turf/space,/area/solar/constructionsite) "aH" = (/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/solar/constructionsite) -"aI" = (/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/djstation/solars) -"aJ" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/solar{id = "construction_solar"; name = "Construction Solar Array"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/djstation/solars) -"aK" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating/airless,/area/djstation/solars) -"aL" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/solar{id = "construction_solar"; name = "Construction Solar Array"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/djstation/solars) -"aM" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating/airless,/area/djstation/solars) -"aN" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/tracker,/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/djstation/solars) -"aO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating/airless,/area/djstation/solars) -"aP" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating/airless,/area/djstation/solars) -"aQ" = (/turf/simulated/wall,/area/djstation) -"aR" = (/obj/machinery/door/airlock/highsecurity{icon_state = "door_closed"; locked = 0; name = "AI Upload Access"; req_access_txt = "16"},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/fore) -"aS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/djstation) -"aT" = (/obj/machinery/autolathe,/turf/simulated/floor/plating,/area/djstation) -"aU" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/drone_fabricator,/turf/simulated/floor/plating,/area/djstation) -"aV" = (/turf/simulated/floor/plating,/area/djstation) +"aI" = (/obj/machinery/portable_atmospherics/canister/air,/obj/structure/window/basic{tag = "icon-window (EAST)"; icon_state = "window"; dir = 4},/obj/structure/window/basic{tag = "icon-window (NORTH)"; icon_state = "window"; dir = 1},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/constructionsite/teleporter) +"aJ" = (/obj/machinery/shieldgen,/obj/structure/window/basic{tag = "icon-window (WEST)"; icon_state = "window"; dir = 8},/obj/structure/window/basic{tag = "icon-window (NORTH)"; icon_state = "window"; dir = 1},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/constructionsite/teleporter) +"aK" = (/obj/machinery/shieldgen,/obj/structure/window/basic{tag = "icon-window (EAST)"; icon_state = "window"; dir = 4},/obj/structure/window/basic{tag = "icon-window (NORTH)"; icon_state = "window"; dir = 1},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/constructionsite/teleporter) +"aL" = (/obj/structure/table/reinforced,/obj/item/stack/sheet/plasteel{amount = 50},/obj/random/tech_supply,/turf/simulated/floor,/area/constructionsite/teleporter) +"aM" = (/obj/structure/table/reinforced,/obj/random/powercell,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor,/area/constructionsite/teleporter) +"aN" = (/obj/structure/table/reinforced,/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 0; pixel_y = 0},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 0; pixel_y = 0},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 0; pixel_y = 0},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 0; pixel_y = 0},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 0; pixel_y = 0},/obj/random/tech_supply,/turf/simulated/floor,/area/constructionsite/teleporter) +"aO" = (/obj/structure/table/reinforced,/obj/machinery/camera/autoname,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/random/tech_supply,/turf/simulated/floor,/area/constructionsite/teleporter) +"aP" = (/obj/machinery/shieldgen,/obj/structure/window/basic{tag = "icon-window (WEST)"; icon_state = "window"; dir = 8},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/constructionsite/teleporter) +"aQ" = (/obj/machinery/shieldgen,/obj/structure/window/basic{tag = "icon-window (EAST)"; icon_state = "window"; dir = 4},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/constructionsite/teleporter) +"aR" = (/obj/machinery/door/airlock/highsecurity{icon_state = "door_closed"; locked = 0; name = "AI Upload Access"; req_access = list(16)},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/fore) +"aS" = (/obj/machinery/portable_atmospherics/canister/air,/obj/structure/window/basic{tag = "icon-window (WEST)"; icon_state = "window"; dir = 8},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/constructionsite/teleporter) +"aT" = (/obj/machinery/portable_atmospherics/canister/air,/obj/structure/window/basic{tag = "icon-window (EAST)"; icon_state = "window"; dir = 4},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/constructionsite/teleporter) +"aU" = (/turf/simulated/floor,/area/constructionsite/teleporter) +"aV" = (/obj/structure/table/reinforced,/obj/item/clothing/shoes/magboots,/obj/item/clothing/suit/space/void/engineering,/obj/item/clothing/glasses/meson,/obj/item/clothing/head/helmet/space/void/engineering,/obj/item/weapon/tank/oxygen,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor,/area/constructionsite/teleporter) "aW" = (/turf/simulated/wall,/area/constructionsite/ai) "aX" = (/turf/simulated/floor/plating/airless,/area/constructionsite/ai) "aY" = (/turf/simulated/floor/airless{tag = "icon-bcircuit"; icon_state = "bcircuit"},/area/constructionsite/ai) -"aZ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/djstation) -"ba" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/plating,/area/djstation) -"bb" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/plating,/area/djstation) -"bc" = (/turf/simulated/wall,/area/djstation/solars) -"bd" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/djstation/solars) -"be" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/djstation/solars) -"bf" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/djstation/solars) -"bg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/djstation/solars) -"bh" = (/obj/machinery/door/airlock/engineering{name = "Construction Area"; req_access_txt = "32"},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area/djstation) -"bi" = (/obj/structure/cable,/obj/machinery/power/solar{id = "construction_solar"; name = "Construction Solar Array"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/djstation/solars) -"bj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/djstation/solars) -"bk" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/djstation) -"bl" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/djstation) -"bm" = (/obj/machinery/light{dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/solar_control{id = "construction_solar"; name = "Construction Solar Control"; track = 0},/turf/simulated/floor/plating,/area/djstation) -"bn" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/djstation) -"bo" = (/obj/machinery/power/port_gen/pacman,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/djstation) -"bp" = (/obj/machinery/recharge_station,/turf/simulated/floor/plating,/area/djstation) -"bq" = (/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area/djstation) -"br" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/simulated/floor/plating,/area/djstation) -"bs" = (/obj/machinery/driver_button{id = "constructiondriver0"; name = "Construction Driver #0"; pass_flags = null; pixel_x = 25; pixel_y = 7},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/plating,/area/djstation) -"bt" = (/obj/machinery/door/airlock/highsecurity{icon_state = "door_closed"; locked = 0; name = "AI Upload"; req_access_txt = "16"},/turf/simulated/floor/plating/airless,/area/constructionsite/ai) -"bu" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating/airless,/area/djstation/solars) -"bv" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating/airless,/area/djstation/solars) -"bw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/djstation/solars) -"bx" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/djstation) -"by" = (/obj/machinery/power/terminal,/obj/structure/cable,/turf/simulated/floor/plating,/area/djstation) -"bz" = (/obj/item/device/multitool,/turf/simulated/floor/plating,/area/djstation) -"bA" = (/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/djstation) -"bB" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating/airless,/area/djstation/solars) -"bC" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating/airless,/area/djstation/solars) -"bD" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/floor/plating,/area/djstation) -"bE" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating,/area/djstation) -"bF" = (/obj/machinery/atmospherics/pipe/manifold/visible,/turf/simulated/floor/plating,/area/djstation) -"bG" = (/obj/machinery/mass_driver{dir = 4; id = "constructiondriver0"; name = "construction driver #0"},/obj/machinery/door/window{dir = 8; name = "Construction Driver"; req_access_txt = "10"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/machinery/alarm/monitor{frequency = 1441; pixel_y = 22},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/djstation) -"bH" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/djstation) -"bI" = (/obj/machinery/door/blast/regular{id = "constructiondriver2"; name = "Construction Driver Door"},/turf/simulated/floor/plating,/area/djstation) +"aZ" = (/obj/structure/table/reinforced,/obj/item/stack/sheet/mineral/phoron{amount = 10},/obj/random/powercell,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor,/area/constructionsite/teleporter) +"ba" = (/obj/structure/window/basic,/obj/machinery/portable_atmospherics/canister/air/airlock,/obj/machinery/atmospherics/portables_connector{tag = "icon-map_connector (EAST)"; icon_state = "map_connector"; dir = 4},/turf/simulated/floor,/area/constructionsite/teleporter) +"bb" = (/obj/machinery/atmospherics/pipe/simple/hidden/blue{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor,/area/constructionsite/teleporter) +"bc" = (/obj/structure/cable/blue,/obj/machinery/power/apc/high{dir = 2; environ = 0; equipment = 0; lighting = 0; locked = 0; name = "south bump"; pixel_y = -24},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor,/area/constructionsite/teleporter) +"bd" = (/obj/machinery/light,/obj/structure/closet/crate/solar,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/constructionsite/teleporter) +"be" = (/obj/machinery/computer/teleporter,/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/constructionsite/teleporter) +"bf" = (/obj/machinery/teleport/station,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/constructionsite/teleporter) +"bg" = (/obj/machinery/teleport/hub,/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/constructionsite/teleporter) +"bh" = (/obj/machinery/pipedispenser,/turf/simulated/floor,/area/constructionsite/teleporter) +"bi" = (/obj/machinery/pipedispenser/disposal,/turf/simulated/floor,/area/constructionsite/teleporter) +"bj" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/constructionsite/teleporter) +"bk" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/constructionsite/teleporter) +"bl" = (/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/turf/simulated/floor,/area/constructionsite/teleporter) +"bm" = (/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/constructionsite/teleporter) +"bn" = (/obj/machinery/atmospherics/pipe/simple/hidden/blue{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/constructionsite/teleporter) +"bo" = (/obj/machinery/atmospherics/pipe/simple/hidden/blue{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor,/area/constructionsite/teleporter) +"bp" = (/obj/item/device/radio/beacon,/turf/simulated/floor,/area/constructionsite/teleporter) +"bq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/blue,/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "constructionsite_sensor"; pixel_x = 0; pixel_y = -25},/turf/simulated/floor,/area/constructionsite/teleporter) +"br" = (/obj/machinery/atmospherics/pipe/simple/hidden/blue{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "constructionsite_inner"; locked = 1; req_access = list(10)},/turf/simulated/floor,/area/constructionsite/teleporter) +"bs" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "constructionsite_outer"; locked = 1; req_access = list(10)},/turf/simulated/floor,/area/constructionsite/teleporter) +"bt" = (/obj/machinery/door/airlock/highsecurity{icon_state = "door_closed"; locked = 0; name = "AI Upload"; req_access = list(16)},/turf/simulated/floor/plating/airless,/area/constructionsite/ai) +"bu" = (/obj/machinery/atmospherics/pipe/simple/hidden/blue{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/obj/machinery/light/small,/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "constructionsite_airlock"; pixel_x = 0; pixel_y = -25; req_access = list(10); tag_airpump = "constructionsite_pump"; tag_chamber_sensor = "constructionsite_sensor"; tag_exterior_door = "constructionsite_outer"; tag_interior_door = "constructionsite_inner"},/turf/simulated/floor,/area/constructionsite/teleporter) +"bv" = (/obj/machinery/power/smes/batteryrack{should_be_mapped = 1},/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/constructionsite/teleporter) +"bw" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/autolathe,/turf/simulated/floor,/area/constructionsite/teleporter) +"bx" = (/obj/structure/window/basic{tag = "icon-window (NORTH)"; icon_state = "window"; dir = 1},/obj/machinery/portable_atmospherics/canister/air/airlock,/obj/machinery/atmospherics/portables_connector{tag = "icon-map_connector (EAST)"; icon_state = "map_connector"; dir = 4},/turf/simulated/floor,/area/constructionsite/teleporter) +"by" = (/obj/machinery/atmospherics/pipe/manifold/hidden/blue{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/turf/simulated/floor,/area/constructionsite/teleporter) +"bz" = (/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/constructionsite/teleporter) +"bA" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/constructionsite/teleporter) +"bB" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'VACUUM'"; icon_state = "space"; layer = 4; name = "VACUUM"; pixel_x = -32; pixel_y = 0},/obj/machinery/access_button/airlock_interior{master_tag = "constructionsite_airlock"; pixel_x = -20; pixel_y = 0; req_access = list(10)},/turf/simulated/floor,/area/constructionsite/teleporter) +"bC" = (/obj/machinery/access_button/airlock_exterior{master_tag = "constructionsite_airlock"; pixel_x = 20; pixel_y = 0; req_access = list(10)},/turf/simulated/floor/airless,/area/constructionsite/hallway/fore) +"bD" = (/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/obj/machinery/power/port_gen/pacman,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/constructionsite/teleporter) +"bE" = (/obj/structure/cable/blue,/obj/machinery/power/port_gen/pacman,/obj/machinery/power/terminal,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/constructionsite/teleporter) +"bF" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{id_tag = "constructionsite_vent"},/turf/simulated/floor,/area/constructionsite/teleporter) +"bG" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{id_tag = "constructionsite_vent"},/obj/machinery/camera/autoname,/turf/simulated/floor,/area/constructionsite/teleporter) +"bH" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "constructionsite_inner"; locked = 1; req_access = list(10)},/turf/simulated/floor,/area/constructionsite/teleporter) "bJ" = (/turf/simulated/floor/airless{tag = "icon-gcircuit"; icon_state = "gcircuit"},/area/constructionsite/ai) -"bK" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/solar{id = "construction_solar"; name = "Construction Solar Array"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/djstation/solars) -"bL" = (/obj/item/weapon/extinguisher,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/djstation) -"bM" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/smes/buildable{charge = 2e+006},/turf/simulated/floor/plating,/area/djstation) -"bN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/djstation) -"bO" = (/obj/structure/table,/obj/item/clothing/head/helmet/space/void/engineering,/obj/item/clothing/suit/space/void/engineering,/turf/simulated/floor/plating,/area/djstation) -"bP" = (/obj/machinery/driver_button{id = "constructiondriver1"; name = "Construction Driver #1"; pixel_x = 25; pixel_y = 7},/turf/simulated/floor/plating,/area/djstation) -"bQ" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating/airless,/area/djstation/solars) -"bR" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating/airless,/area/djstation/solars) -"bS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/djstation/solars) -"bT" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/djstation) -"bU" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/plating,/area/djstation) -"bV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/plating,/area/djstation) -"bW" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/djstation) -"bX" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating/airless,/area/djstation/solars) -"bY" = (/obj/structure/table/rack,/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/wood{amount = 30},/obj/item/stack/sheet/wood{amount = 30},/obj/item/stack/sheet/wood{amount = 30},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/turf/simulated/floor/plating,/area/djstation) -"bZ" = (/obj/machinery/mass_driver{dir = 4; id = "constructiondriver1"; name = "construction driver #1"},/obj/machinery/door/window{dir = 8; name = "Construction Driver"; req_access_txt = "10"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/machinery/alarm/monitor{frequency = 1441; pixel_y = 22},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/djstation) -"ca" = (/obj/machinery/door/blast/regular{id = "constructiondriver0"; name = "Construction Driver Door"},/turf/simulated/floor/plating,/area/djstation) -"cb" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/djstation/solars) -"cc" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor/plating,/area/djstation) -"cd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/item/weapon/storage/box/lights/mixed,/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/plating,/area/djstation) -"ce" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area/djstation) -"cf" = (/obj/machinery/telecomms/relay/preset/ruskie,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/djstation) -"cg" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/syndicate,/obj/item/clothing/head/helmet/space/syndicate,/obj/item/clothing/mask/breath,/turf/simulated/floor/plating,/area/djstation) -"ch" = (/obj/structure/table/rack,/obj/item/weapon/module/power_control,/obj/item/weapon/module/power_control,/obj/item/weapon/module/power_control,/obj/item/weapon/module/power_control,/obj/item/weapon/module/power_control,/obj/item/weapon/module/power_control,/turf/simulated/floor/plating,/area/djstation) -"ci" = (/obj/machinery/driver_button{id = "constructiondriver2"; name = "Construction Driver #2"; pixel_x = 25; pixel_y = 7},/turf/simulated/floor/plating,/area/djstation) "cj" = (/obj/structure/lattice,/turf/space,/area/constructionsite/maintenance) -"ck" = (/obj/machinery/door/airlock/highsecurity{name = "Messaging Server"; req_access_txt = "30"},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/fore) -"cl" = (/obj/machinery/door/airlock/highsecurity{name = "Messaging Server"; req_access_txt = "30"},/turf/simulated/floor/plating/airless,/area/constructionsite/ai) -"cm" = (/obj/machinery/door/airlock/highsecurity{name = "Cyborg Station"; req_access_txt = "16"},/turf/simulated/floor/plating/airless,/area/constructionsite/ai) -"cn" = (/obj/machinery/door/airlock/highsecurity{name = "Cyborg Station"; req_access_txt = "16"},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/fore) -"co" = (/obj/machinery/door/airlock/maintenance{req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area/djstation) -"cp" = (/obj/structure/table/rack,/obj/item/weapon/airlock_electronics,/obj/item/weapon/airlock_electronics,/obj/item/weapon/airlock_electronics,/obj/item/weapon/airlock_electronics,/obj/item/weapon/airlock_electronics,/obj/item/weapon/airlock_electronics,/turf/simulated/floor/plating,/area/djstation) -"cq" = (/obj/machinery/mass_driver{dir = 4; id = "constructiondriver2"; name = "construction driver #2"},/obj/machinery/door/window{dir = 8; name = "Construction Driver"; req_access_txt = "10"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/machinery/alarm/monitor{frequency = 1441; pixel_y = 22},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/djstation) -"cr" = (/obj/machinery/door/blast/regular{id = "constructiondriver1"; name = "Construction Driver Door"},/turf/simulated/floor/plating,/area/djstation) +"ck" = (/obj/machinery/door/airlock/highsecurity{name = "Messaging Server"; req_access = list(30)},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/fore) +"cl" = (/obj/machinery/door/airlock/highsecurity{name = "Messaging Server"; req_access = list(30)},/turf/simulated/floor/plating/airless,/area/constructionsite/ai) +"cm" = (/obj/machinery/door/airlock/highsecurity{name = "Cyborg Station"; req_access = list(16)},/turf/simulated/floor/plating/airless,/area/constructionsite/ai) +"cn" = (/obj/machinery/door/airlock/highsecurity{name = "Cyborg Station"; req_access = list(16)},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/fore) "cs" = (/obj/machinery/recharge_station,/turf/simulated/floor/plating/airless,/area/constructionsite/ai) -"ct" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/djstation) -"cu" = (/obj/structure/table,/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"cv" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"cw" = (/obj/structure/stool/bed/chair,/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"cx" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"cy" = (/obj/structure/closet/emcloset,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"cz" = (/obj/machinery/vending/snack,/obj/machinery/light/small{dir = 1},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"cA" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"cB" = (/obj/machinery/light_switch{pixel_y = 28},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"cC" = (/obj/machinery/newscaster{pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"cD" = (/obj/machinery/door/airlock/engineering{name = "Construction Area"; req_access_txt = "32"},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating,/area/djstation) -"cE" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating,/area/djstation) -"cF" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor/plating,/area/djstation) -"cG" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4},/obj/machinery/meter,/turf/simulated/floor/plating,/area/djstation) -"cH" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/plating,/area/djstation) "cI" = (/obj/machinery/door/airlock/maintenance_hatch,/turf/simulated/wall,/area/constructionsite/hallway/fore) "cJ" = (/obj/structure/lattice,/turf/space,/area/constructionsite/hallway/fore) -"cK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/djstation) -"cL" = (/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"cM" = (/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"cN" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"cO" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plating,/area/djstation) -"cP" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating,/area/djstation) -"cQ" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/turf/simulated/floor/plating,/area/djstation) -"cR" = (/obj/machinery/atmospherics/binary/pump/on{dir = 8; name = "Air to Distro"; target_pressure = 285},/obj/machinery/door/airlock/atmos{name = "Atmospherics Maintenance"; req_access_txt = "12;24"},/turf/simulated/floor/plating,/area/djstation) -"cS" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/obj/machinery/meter,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor/plating,/area/djstation) -"cT" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/djstation) -"cU" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor/plating,/area/djstation) "cV" = (/turf/simulated/wall,/area/constructionsite/hallway/aft) "cW" = (/turf/simulated/floor/airless,/area/constructionsite/hallway/aft) "cX" = (/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/aft) -"cY" = (/obj/structure/table,/obj/machinery/cell_charger,/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"cZ" = (/obj/structure/table,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"da" = (/obj/structure/table,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"db" = (/obj/structure/stool/bed/chair/office/light,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"dc" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"dd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/djstation) -"de" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "grimy"},/area/djstation) -"df" = (/obj/machinery/light_switch{pixel_y = 28},/turf/simulated/floor{icon_state = "grimy"},/area/djstation) -"dg" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor{icon_state = "grimy"},/area/djstation) -"dh" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/turf/simulated/floor{icon_state = "grimy"},/area/djstation) -"di" = (/obj/machinery/mech_bay_recharge_port,/turf/simulated/floor/plating,/area/djstation) -"dj" = (/turf/simulated/floor/mech_bay_recharge_floor,/area/djstation) -"dk" = (/obj/machinery/computer/mech_bay_power_console,/turf/simulated/floor/plating,/area/djstation) -"dl" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 1},/turf/simulated/floor/plating,/area/djstation) "dm" = (/obj/structure/lattice,/turf/space,/area/constructionsite/hallway/aft) -"dn" = (/obj/structure/table,/obj/machinery/microwave{pixel_y = 8},/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"do" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"dp" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"dq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/djstation) -"dr" = (/obj/structure/table,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"ds" = (/obj/structure/table,/obj/machinery/atmospherics/pipe/manifold4w/hidden,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"dt" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"du" = (/obj/machinery/door/airlock/glass{name = "Cabin"},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"dv" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; icon_state = "intact"; tag = "icon-intact-f (SOUTHWEST)"},/turf/simulated/floor{icon_state = "grimy"},/area/djstation) -"dw" = (/turf/simulated/floor{icon_state = "grimy"},/area/djstation) -"dx" = (/obj/machinery/sleeper,/turf/simulated/floor{icon_state = "grimy"},/area/djstation) "dy" = (/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/aft) -"dz" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"dA" = (/obj/machinery/light/small,/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"dB" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"dC" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor{icon_state = "bar"},/area/djstation) -"dD" = (/obj/machinery/door/airlock/glass{name = "Kitchen"},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"dE" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"dF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/djstation) -"dG" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHEAST)"},/turf/simulated/floor{icon_state = "grimy"},/area/djstation) -"dH" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor{icon_state = "grimy"},/area/djstation) -"dI" = (/obj/structure/closet,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "grimy"},/area/djstation) -"dJ" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/plating,/area/djstation) -"dK" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/djstation) -"dL" = (/obj/machinery/door/airlock{name = "Restroom"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor{icon_state = "freezerfloor"},/area/djstation) -"dM" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"dN" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; icon_state = "intact"; tag = "icon-intact-f (SOUTHWEST)"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"dO" = (/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/obj/machinery/light{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"dP" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/djstation) -"dQ" = (/obj/machinery/access_button/airlock_interior{master_tag = "listeningpost_airlock"; name = "airlock access button"; pixel_x = -23},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/floor/plating,/area/djstation) -"dR" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor/plating,/area/djstation) -"dS" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor/plating,/area/djstation) -"dT" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; icon_state = "intact"; tag = "icon-intact-f (SOUTHWEST)"},/turf/simulated/floor/plating,/area/djstation) -"dU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/djstation) -"dV" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating/airless,/area/space) -"dW" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor{icon_state = "freezerfloor"},/area/djstation) -"dX" = (/obj/structure/toilet{pixel_y = 8},/obj/machinery/light/small{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/djstation) -"dY" = (/obj/structure/stool/bed/chair{dir = 4},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"dZ" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "listeningpost_inner"; locked = 1; name = "Engineering Dock Airlock"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/djstation) -"ea" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating,/area/djstation) "eb" = (/obj/machinery/door/airlock/maintenance_hatch,/turf/simulated/wall,/area/constructionsite/hallway/aft) -"ec" = (/obj/machinery/door/airlock/highsecurity{icon_state = "door_closed"; locked = 0; name = "AI Upload Access"; req_access_txt = "16"},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/aft) +"ec" = (/obj/machinery/door/airlock/highsecurity{icon_state = "door_closed"; locked = 0; name = "AI Upload Access"; req_access = list(16)},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/aft) "ed" = (/obj/machinery/door/airlock/maintenance_hatch,/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/aft) -"ee" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor{icon_state = "freezerfloor"},/area/djstation) -"ef" = (/obj/machinery/door/airlock{name = "Restroom"; req_access_txt = "0"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/djstation) -"eg" = (/obj/machinery/computer/shuttle_control/engineering,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"eh" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "engineering_station_airlock"; name = "interior access button"; pixel_x = 30; pixel_y = -25; req_access_txt = "0"; req_one_access_txt = "13;32"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/djstation) -"ei" = (/obj/structure/computerframe{anchored = 1},/turf/simulated/floor{icon_state = "grimy"},/area/djstation) -"ej" = (/obj/structure/stool/bed/chair/comfy/black{dir = 8},/turf/simulated/floor{icon_state = "grimy"},/area/djstation) -"ek" = (/obj/machinery/light/small,/turf/simulated/floor{icon_state = "grimy"},/area/djstation) -"el" = (/obj/structure/closet,/turf/simulated/floor{icon_state = "grimy"},/area/djstation) -"em" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "listeningpost_airlock"; pixel_x = -25; req_access_txt = "0"; tag_airpump = "listeningpost_pump"; tag_chamber_sensor = "listeningpost_sensor"; tag_exterior_door = "listeningpost_outer"; tag_interior_door = "listeningpost_inner"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/turf/simulated/floor/plating,/area/djstation) -"en" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; icon_state = "intact"; tag = "icon-intact-f (SOUTHWEST)"},/turf/simulated/floor/plating,/area/djstation) -"eo" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/light/small,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHEAST)"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/djstation) -"ep" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "freezerfloor"},/area/djstation) -"eq" = (/turf/simulated/floor{icon_state = "freezerfloor"},/area/djstation) -"er" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/light/small,/turf/simulated/floor{icon_state = "freezerfloor"},/area/djstation) -"es" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "engineering_station_inner"; locked = 1; name = "Engineering Dock Airlock"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/visible,/turf/simulated/floor/plating,/area/djstation) -"et" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/djstation) -"eu" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/djstation) -"ev" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/djstation) -"ew" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/djstation) -"ex" = (/obj/machinery/airlock_sensor{id_tag = "listeningpost_sensor"; master_tag = "listeningpost_airlock"; pixel_x = -23},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "listeningpost_pump"},/turf/simulated/floor/plating,/area/djstation) -"ey" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "listeningpost_pump"},/turf/simulated/floor/plating,/area/djstation) -"ez" = (/obj/structure/disposalpipe/trunk{dir = 1},/obj/structure/disposaloutlet,/turf/simulated/floor/plating/airless,/area/space) -"eA" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "engineering_station_airlock"; pixel_x = -25; pixel_y = 0; req_access_txt = "0"; req_one_access_txt = "13;32"; tag_airpump = "engineering_station_pump"; tag_chamber_sensor = "engineering_station_sensor"; tag_exterior_door = "engineering_station_outer"; tag_interior_door = "engineering_station_inner"},/obj/machinery/atmospherics/pipe/manifold/visible{dir = 8},/turf/simulated/floor/plating,/area/djstation) -"eB" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1380; id_tag = "engineering_station_pump"},/turf/simulated/floor/plating,/area/djstation) -"eC" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "listeningpost_outer"; locked = 1; name = "Engineering Dock Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/djstation) -"eD" = (/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "engineering_station_sensor"; pixel_x = -25; pixel_y = 8},/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating,/area/djstation) -"eE" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1380; id_tag = "engineering_station_pump"},/turf/simulated/floor/plating,/area/djstation) -"eF" = (/obj/machinery/access_button/airlock_exterior{master_tag = "listeningpost_airlock"; name = "airlock access button"; pixel_y = 23},/turf/simulated/floor/plating/airless,/area/space) -"eG" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "engineering_station_outer"; locked = 1; name = "Engineering Dock Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/djstation) -"eH" = (/obj/structure/lattice,/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "engineering_station_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -8; req_access_txt = "0"; req_one_access_txt = "13;32"},/turf/space,/area/space) -"eI" = (/turf/simulated/shuttle/wall{icon_state = "swall_s6"; dir = 2},/area/shuttle/constructionsite/site) -"eJ" = (/turf/simulated/shuttle/wall{icon_state = "swall12"; dir = 2},/area/shuttle/constructionsite/site) -"eK" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "engineering_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/shuttle/constructionsite/site) -"eL" = (/turf/simulated/shuttle/wall{icon_state = "swall_s10"; dir = 2},/area/shuttle/constructionsite/site) -"eM" = (/turf/simulated/shuttle/wall{tag = "icon-propulsion (EAST)"; icon_state = "propulsion"; dir = 4},/area/shuttle/constructionsite/site) -"eN" = (/turf/simulated/shuttle/wall,/area/shuttle/constructionsite/site) -"eO" = (/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/constructionsite/site) -"eP" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/constructionsite/site) -"eQ" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "engineering_shuttle"; pixel_x = 0; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13;11;24"; tag_door = "engineering_shuttle_hatch"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/constructionsite/site) -"eR" = (/obj/machinery/computer/station_alert,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/constructionsite/site) -"eS" = (/turf/simulated/shuttle/wall{icon_state = "swall1"; dir = 2},/area/shuttle/constructionsite/site) -"eT" = (/obj/machinery/computer/shuttle_control/engineering,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/constructionsite/site) -"eU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/shuttle/constructionsite/site) -"eV" = (/obj/machinery/computer/atmos_alert,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/constructionsite/site) -"eW" = (/turf/simulated/shuttle/wall{tag = "icon-swall2"; icon_state = "swall2"; dir = 2},/area/shuttle/constructionsite/site) -"eX" = (/turf/simulated/shuttle/wall{icon_state = "swall_s5"; dir = 2},/area/shuttle/constructionsite/site) -"eY" = (/turf/simulated/shuttle/wall{icon_state = "swall_s9"; dir = 2},/area/shuttle/constructionsite/site) "eZ" = (/turf/simulated/floor/airless{icon_state = "white"},/area/constructionsite/medical) "fa" = (/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/constructionsite/medical) "fb" = (/obj/machinery/sleeper,/turf/simulated/floor/airless{icon_state = "white"},/area/constructionsite/medical) "fc" = (/turf/simulated/floor/plating/airless,/area/constructionsite/atmospherics) "fd" = (/turf/simulated/floor/airless,/area/constructionsite/atmospherics) "fe" = (/turf/simulated/floor/plating/airless,/area/constructionsite/medical) -"ff" = (/obj/machinery/door/airlock/glass_medical{name = "Medbay"; req_access_txt = "0"; req_one_access_txt = "65;5"},/turf/simulated/wall,/area/constructionsite/medical) +"ff" = (/obj/machinery/door/airlock/glass_medical{name = "Medbay"; req_one_access = list(65,5)},/turf/simulated/wall,/area/constructionsite/medical) "fg" = (/obj/structure/lattice,/turf/space,/area/constructionsite/medical) "fh" = (/turf/space,/area/constructionsite/medical) -"fi" = (/obj/machinery/door/airlock/glass_medical{name = "Medbay"; req_access_txt = "0"; req_one_access_txt = "65;5"},/turf/simulated/wall,/area/constructionsite/hallway/aft) -"fj" = (/obj/machinery/door/airlock/glass_atmos{name = "Atmospherics"; req_access_txt = "24"},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/aft) +"fi" = (/obj/machinery/door/airlock/glass_medical{name = "Medbay"; req_one_access = list(65,5)},/turf/simulated/wall,/area/constructionsite/hallway/aft) +"fj" = (/obj/machinery/door/airlock/glass_atmos{name = "Atmospherics"; req_access = list(24)},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/aft) "fk" = (/turf/space,/area/constructionsite/hallway/aft) "fl" = (/turf/simulated/wall,/area/constructionsite/atmospherics) "fm" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/plating/airless,/area/constructionsite/atmospherics) @@ -279,7 +123,7 @@ "fs" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/wall,/area/constructionsite/atmospherics) "ft" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "d_o2_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/constructionsite/atmospherics) "fu" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/constructionsite/atmospherics) -"fv" = (/obj/machinery/door/airlock/glass_medical{name = "Medbay"; req_access_txt = "0"; req_one_access_txt = "65;5"},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/aft) +"fv" = (/obj/machinery/door/airlock/glass_medical{name = "Medbay"; req_one_access = list(65,5)},/turf/simulated/floor/plating/airless,/area/constructionsite/hallway/aft) "fw" = (/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/airless,/area/constructionsite/atmospherics) "fx" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "d_o2_in"; name = "Oxygen Supply Control"; output_tag = "d_o2_out"; sensors = list("d_o2_sensor" = "Tank")},/obj/machinery/atmospherics/pipe/simple/visible{dir = 4},/turf/simulated/floor/airless,/area/constructionsite/atmospherics) "fy" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 8; frequency = 1443; icon_state = "map_injector"; id = "d_air_in"; use_power = 1},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/constructionsite/atmospherics) @@ -293,8 +137,6 @@ "fG" = (/obj/machinery/light/small{dir = 1},/obj/machinery/air_sensor{frequency = 1441; id_tag = "d_n2_sensor"},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/constructionsite/atmospherics) "fH" = (/turf/simulated/floor/plating/airless,/area/constructionsite) "fI" = (/obj/structure/lattice,/turf/space,/area/constructionsite) -"fJ" = (/obj/machinery/pipedispenser,/turf/simulated/floor/airless,/area/constructionsite/atmospherics) -"fK" = (/obj/machinery/pipedispenser/disposal,/turf/simulated/floor/airless,/area/constructionsite/atmospherics) "fL" = (/obj/machinery/atmospherics/pipe/simple/visible{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/airless,/area/constructionsite/atmospherics) "fM" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1443; icon_state = "map_vent_in"; id_tag = "d_air_out"; internal_pressure_bound = 2000; internal_pressure_bound_default = 2000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{name = "air floor"; nitrogen = 10580; oxygen = 2644},/area/constructionsite/atmospherics) "fN" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/constructionsite/atmospherics) @@ -302,13 +144,13 @@ "fP" = (/turf/space,/area/constructionsite) "fQ" = (/obj/machinery/door/airlock/maintenance_hatch,/turf/simulated/floor/plating/airless,/area/constructionsite) "fR" = (/turf/simulated/wall,/area/constructionsite/engineering) -"fS" = (/obj/machinery/door/airlock/maintenance_hatch{icon_state = "door_closed"; locked = 0; name = "Engine Access"; req_access_txt = "0"; req_one_access_txt = "11;24"},/turf/simulated/floor/plating/airless,/area/constructionsite/engineering) +"fS" = (/obj/machinery/door/airlock/maintenance_hatch{icon_state = "door_closed"; locked = 0; name = "Engine Access"; req_one_access = list(11,24)},/turf/simulated/floor/plating/airless,/area/constructionsite/engineering) "fT" = (/turf/simulated/floor/plating/airless,/area/constructionsite/engineering) "fU" = (/obj/machinery/door/airlock/maintenance_hatch,/turf/simulated/floor/plating/airless,/area/constructionsite/engineering) "fV" = (/obj/structure/lattice,/turf/space,/area/constructionsite/engineering) "fW" = (/turf/space,/area/constructionsite/engineering) "fX" = (/obj/structure/grille,/turf/simulated/floor/plating/airless,/area/constructionsite/engineering) -"fY" = (/obj/machinery/door/airlock/maintenance_hatch{name = "SMES Access"; req_access_txt = "11"},/turf/simulated/floor/plating/airless,/area/constructionsite/engineering) +"fY" = (/obj/machinery/door/airlock/maintenance_hatch{name = "SMES Access"; req_access = list(11)},/turf/simulated/floor/plating/airless,/area/constructionsite/engineering) "fZ" = (/obj/machinery/power/smes/buildable,/turf/simulated/floor/plating/airless,/area/constructionsite/engineering) "ge" = (/obj/machinery/field_generator,/turf/simulated/floor/plating/airless,/area/space) @@ -381,16 +223,16 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabavabababaaaaabanaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoauauauaoaoaoauauauauauauanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavababaaaaaaabanaoaoaoaoapapapapaqapapapapapapapapapapaoaoaoapapapapapapapapapapaqapapapapauauauauanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababaaaaabapapaoaoapapaeaeaeaeaeaeaeaeaeaeaeaeaeapaoaoaoapaeaeaeaeaeaeaeaeaeaeaeaeaeapapauauapapabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababaaaaabababanaoaoapaeaeawawawawawawawawawawaeaeapaoaoaoapaeaeawawawawawawawawawawaeaeapauaoanabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabavabababaaaaaaabanaoaoapaeawawaxaxaxaxaxaxaxaxawaeaeapaoaoaoapaeaeawaxaxaxaxaxaxaxaxawawaeapauaoanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababaaaaaaaaabanaoaoapaeawaxaxaxaxaxaxaxaxaxawaeaeapaoaoaoapaeaeawaxaxaxaxaxaxaxaxaxawaeapauaoanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabavabababaaabababanaoaoapaeawaxaxaxaxaxaxaxaxaxawawawapaoaoaoapawawawaxaxaxaxaxaxaxaxaxawaeapaoaoanabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavababavaaaaaaabanaoaoapaeawaxaxaxaxaxaxaxaxaxayaxaxazaoaoaoaAaxaxaBaxaxaxaxaxaxaxaxaxawaeapaoaoanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabavabababaaaaaaabanaoaoapaeaCaxaxaxaxaxaxaxaxaxayaxaxazaoaoaoaAaxaxaBaxaxaxaxaxaxaxaxaxaCaeapaoaoanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavababaaaaabababanaoaoapaeawaxaxaxaxaxaxaxaxaxawawawapaoaoaoapawawawaxaxaxaxaxaxaxaxaxawaeapaoaoanabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaabaaababavababavaaaaaaabanaoaoapaeawaxaxaxaxaxaxaxaxaxawaeaeaqaoaoaoaqaeaeawaxaxaxaxaxaxaxaxaxawaeapaoaoanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababavababavaaaaaaabanaoaoapaeawawaxaxaxaxaxaxaxaxawaeapapaoaoaoapapaeawaxaxaxaxaxaxaxaxawawaeapaoaoanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaabaaabaaavababavaaabababanaoaoapaeaeawawawawawawawawawawaeapaoaoaoaoaoapaeawawawawawawawawawawaeaeapaoaoanabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababaaaaabababanaoaoapaeaeawawawawawawawawawawaeaeapaoaoaoapaeaeaAaAaAaAaAaAaAaAaAaAaeaeapauaoanabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabavabababaaaaaaabanaoaoapaeawawaxaxaxaxaxaxaxaxawaeaeapaoaoaoapaeaeaAaJaKaBaIaNaOaLaMaAaAaeapauaoanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababaaaaaaaaabanaoaoapaeawaxaxaxaxaxaxaxaxaxawaeaeapaoaoaoapaeaeaAaPaQaSaTaUaUaUaVaZaAaeapauaoanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabavabababaaabababanaoaoapaeawaxaxaxaxaxaxaxaxaxawawawapaoaobCaAaAaAaAbBaUaUaUaUaUaUaUbDaAaeapaoaoanabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavababavaaaaaaabanaoaoapaeawaxaxaxaxaxaxaxaxaxayaxaxazaoaoaobsbFbGbHaUaUaUaUaUaUaUaUbEaAaeapaoaoanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabavabababaaaaaaabanaoaoapaeaCaxaxaxaxaxaxaxaxaxayaxaxazaoaoaobsbubqbrbnboblbmaUbpaUaUbvaAaeapaoaoanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavababaaaaabababanaoaoapaeawaxaxaxaxaxaxaxaxaxawawawapaoaoaoaAaAaAaAbxbyaUbzbAbAbAbAbwaAaeapaoaoanabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaabaaababavababavaaaaaaabanaoaoapaeawaxaxaxaxaxaxaxaxaxawaeaeaqaoaoaoaqaeaeaAbabbaUaUaUaUaUaUbcaAaeapaoaoanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababavababavaaaaaaabanaoaoapaeawawaxaxaxaxaxaxaxaxawaeapapaoaoaoapapaeaAbhbibjbkbdbebfbgaAaAaeapaoaoanabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaabaaabaaavababavaaabababanaoaoapaeaeawawawawawawawawawawaeapaoaoaoaoaoapaeaAaAaAaAaAaAaAaAaAaAaeaeapaoaoanabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababavababavaaacacapapaoaoapapaeaeaeaeaeaeaeaeaeaeaeaeapaoaoaoaoaoapaeaeaeaeaeaeaeaeaeaeaeaeapapaoaoapapacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaabaaabaDaDaDaDaDacacaeapauaoaoauapapapapapapapapapapapapapapaoaoaoaoaoapapapapapapapapapapapapapapauaoaoauapaeacacaDaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababaEaEaEaEaFaEaEabababababaDaEaEaEaEaeaeaeauaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoaoauaoauauaoauaoaoaoaoaoapaeaeacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -402,35 +244,35 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababacaeapaoaoanabababababababacaeaeaeaeapapapaoaoaoapapapaeaeaeaeacabababababababanauauapaeacaEaEaEaEaEaEaEaEaEaEaEaFaEaFaFaFabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaabaaabacaeapaoaoanabaaabaaabaaabacaeapapapapauauaoaoaoauauapapapapaeacabaaabaaabaaabanauauapaeacaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababacaeapaoaoanabaaabaaabababapaqapauauauauauaoaoaoauauauauauapaqapabababaaabaaabanaoauapaeacaFaEaFaEaFaEaFaEaFaFaEaEaEaFaFaFabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaIaIaIaIaIaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaabaaabacaeapaoaoanababababababapapauauauaoaoaoaoaoaoaoaoaoaoauauauauapapababababababanaoauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaIaJaKaNaMaLaIabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababacaeapaoaoanabacacacacapapauauauaoaoaoaoaoaoaoaoaoaoaoaoaoaoauauapapacacacacabanaoauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababaIaJaOaJaPaLaIababaaaaaQaQaQaQaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaabaaabacaeapaoaoanabacaeaeaeaqauauaoaoaoaoaoapapapaRapapapaoaoaoaoauauauaqaeaeaeacabanaoauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababaIaJaOaJaPaLaIabababaaaSaTaUaVaSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababacaeapaoaoanabacaeaeapapauauaoaoaoapapapaWaXaYaXaWapapapaoaoaoauauapapaeaeacabanaoauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababaIaJaOaJaPaLaIababababaZbabbaVaZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaabaaabacaeapaoaoanabacaeaeapauauauaoaoapapababaWaXaYaXaWababapapaoaoaoauauapaeaeacabanauauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIaIaIaIaIbcbdbebcbfbgbcaIaIaIaIaQaQbhaQaQaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaababalabalalababalababalacaeapaoaoanabacaeaeapauaoaoaoapapabababaWaXaYaXaWabababapapauaoauauapaeaeacabanaoauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaIbKbKbKbKbjbkblbmbnbobjbKbKbKbKaQbpbqbrbsaQaQaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababalababalalalalalalalalalalalacaeapaoaoapacacaeapapauaoaoaoapabababaWaWaWbtaWaWaWabababapauauaoauapapaeacacapauaoapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaIbubvbvbvbwbxaVbybzbAbwbBbBbBbCaQbpbDbEbFbGbHcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabalalalalalalalalalalalalalalalalalalacaeapaoaoapaeaeaeapauauaoaoapapababaWaWbJbJaXbJbJaWaWababapapauaoauauapaeaeaeapauauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaIbibibibibcbLaVbMaVbNbcbibibibiaQbObqaVbPaQaQaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabavabababababavavavavavabalabalabalabalabalacacacacacacacacacacacaeapaoaoapaqapapapauauauauapaWaWaWaWaXbJaXaXaXbJaXaWaWaWaWapauauaoauapapapaqapauauapacacavavavababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaIbQbRbRbRbSbTbUbVaVbWbSbXbXbXaKaQbYbDbEbEbZbHcraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalabalalalalalalalalalalalalalaeaeaeaeaeaeaeaeaeaeaeaeapaoaoauauauauauauaoauauapaXaXaXaWbJbJaXaYaXbJbJaWaXaXaXapauauaoauauauauaoauauaoapaeaealalalalalalalalalalalalaaaaabaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaIbibibibicbcccdcecfcgcbbibibibiaQchbqaVciaQaQaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababalalalalalababalalabalabalabalabalabalcjaecjaeaeaeaeaeaeaeaeaeapauauauauauauauaoauauauckaYaYaYclaXaXaXaYaXaXaXcmaYaYaYcnaoauaoaoaoaoaoaoauauauapaeaealalalalalalalalalabalabalabalalalabalaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQaQaQaQaQaQaQaQaQcoaQaQaQaQaQaQaQaQcpbDbEbEcqbHbIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababalalalalalalalabalabalalalalalaeaeaecjaeaeaeaeaeaeaeaeapaoaoauaoaoaoaoaoaoaoaoapaXaXaXaWbJbJaXaYaXbJbJaWcscscsapauauaoauauauauauauaoaoapaeaealalalalalalalalalalalalalalalalabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabctcucvcwcwcxctcyczcAcBcCcDcEcFbEcEcDbEcGaVcHaQaQaQaQaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavavavabababababavavavavavavavavavavavacacacacacacacacacacacacapaoaoapcIapapapcJaucJauapaWaWaWaWaXbJaXaXaXbJaXaWaWaWaWapauauaoauapapapaqapauaoapacacavavavavavababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcKcucLcucucLcKcMcMcNcMcMaQaQaQaQaQaQcOcPbEcQcRcScTcUaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababaccjcVcWcWcVaeaeaecVcXcXcXcXcVcVababaWaWbJbJaXbJbJaWaWababcVcVcXcXcXcXcVaeaeaecVcWcWcXaeacababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcKcYcLcZcucLcKdadbdccMcMdddedfdgdhaQdidjdkbqaQdldlaQaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcWcVacacaecVcVcXdmcXdmcVabababaWaWaWbtaWaWaWabababcVcXcXcWcXcVcVaeacaccVcWcWcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcKdncLdodpcLdqdadrdsdtdtdudvdwdwdxaQaVaVaVbqaQaQaQaQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcWdyabacaeaecVcXcXcXcXcVcVabababaWaXaYaXaWabababcVcVcXcXcWcXcVaeaeacabdycWcWcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdqdzdAdBdCdCdDdtdtdEcMcMdFdGdHdHdIaQdidjdkdJdFabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababaccjcVcWcWdyabacaeaecVcXdmcXdmcXcVcVababaWaXaYaXaWababcVcVcXcXcXcXcXcVaeaeacabdycXcWcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaQdKaQdLaQaQaQaQaQdMdNdOdPdwdwdgdhaQdQdRdSdTdUabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcXdyabacaeaecVcVcXcXcXcXcXcVcVcVaWaXaYaXaWcVcVcVcXcWcWcWcXcVcVaeaeacabdycXcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdVaQdWaQdXaQdXaQdYcNcMdPdwdwdwdxaQdZddaQeaaQabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcXdyabacaeaeaeebdmcXdmcXdmcXcWcVcVcVeccVcVcVcXcXcWcWcWcXcXedaeaeaeacabdycWcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadVaQeeaQefaQefaQegehcMdUeiejekelaQemenaQaQaQabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababaccjcVcWcXdyabacacacaccVcVcXcXcXcXcWcWcWcWcWcWcWcWcWcWcWcWcWcXcXcVcVacacacacabdycWcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadVaQeoepeqeqeraQaQesddaQeteuevewaQexeyaQababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcXdyababababababcVcVdmcXdmcXcWcWcWcWcWcWcWcWcWcWcWcXcXcVcVababababababdycWcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaezaQaQaQaQaQaQaQaQeAeBaQababababaQeCddaQabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcXdyabaaabaaabababcVedcVcXcWcWcWcWcWcWcWcWcWcWcWcWcVedcVabababaaabaaabdycWcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababaQeDeEaQababaaabeFalalalabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababaccjcVcWcWdyabaaabaaabaaabacaecVcVcVcVcWcWcWcWcWcWcWcVcVcVcVaeacabaaabaaabaaabdycWcWcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababaQeGddaQeHaaaaaaababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcXdyabababababababacaeaeaeaecVcVcVcWcWcWcVcVcVaeaeaeaeacabababababababdycWcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeIeJeJeKeJeJeLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcXcXdyabaaabaaabaaabacaeaeaeaeaeaecVcWcWcWcVaeaeaeaeaeaeacabaaabaaabaaabdycWcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeMeNeOePeQeReSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaccjcVcXcXdyabaaabaaabaaabacacacacacacaecVcWcWcWcVaeacacacacacacabaaabaaabaaabdycXcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeMeNeOePePeTeUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaccVcVcXcXcVcVabababababababababababacaeedcWcWcWedaeacabababababababababababcVcVcXcXcVcVacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeMeNeOePeOeVeWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcVcXcXcXcXcVdydydydydydydydydydydycVcVcVcWcWcWcVcVcVdydydydydydydydydydydycVcWcWcWcWdyababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeXeJeJeJeJeJeYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcVcXcXcWcXcXcXcXcXcXcXcXcXcWcWcWcXcWcWcXcWcWcWcXcXcXcWcWcWcWcXcWcXcXcWcWcWcXcWcWcWcWdyababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaabaaabacaeapaoaoanababababababapapauauauaoaoaoaoaoaoaoaoaoaoauauauauapapababababababanaoauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababacaeapaoaoanabacacacacapapauauauaoaoaoaoaoaoaoaoaoaoaoaoaoaoauauapapacacacacabanaoauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaabaaabacaeapaoaoanabacaeaeaeaqauauaoaoaoaoaoapapapaRapapapaoaoaoaoauauauaqaeaeaeacabanaoauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababacaeapaoaoanabacaeaeapapauauaoaoaoapapapaWaXaYaXaWapapapaoaoaoauauapapaeaeacabanaoauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaabaaabacaeapaoaoanabacaeaeapauauauaoaoapapababaWaXaYaXaWababapapaoaoaoauauapaeaeacabanauauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaababalabalalababalababalacaeapaoaoanabacaeaeapauaoaoaoapapabababaWaXaYaXaWabababapapauaoauauapaeaeacabanaoauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababalababalalalalalalalalalalalacaeapaoaoapacacaeapapauaoaoaoapabababaWaWaWbtaWaWaWabababapauauaoauapapaeacacapauaoapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabalalalalalalalalalalalalalalalalalalacaeapaoaoapaeaeaeapauauaoaoapapababaWaWbJbJaXbJbJaWaWababapapauaoauauapaeaeaeapauauapaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabavabababababavavavavavabalabalabalabalabalacacacacacacacacacacacaeapaoaoapaqapapapauauauauapaWaWaWaWaXbJaXaXaXbJaXaWaWaWaWapauauaoauapapapaqapauauapacacavavavababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalabalalalalalalalalalalalalalaeaeaeaeaeaeaeaeaeaeaeaeapaoaoauauauauauauaoauauapaXaXaXaWbJbJaXaYaXbJbJaWaXaXaXapauauaoauauauauaoauauaoapaeaealalalalalalalalalalalalaaaaabaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababalalalalalababalalabalabalabalabalabalcjaecjaeaeaeaeaeaeaeaeaeapauauauauauauauaoauauauckaYaYaYclaXaXaXaYaXaXaXcmaYaYaYcnaoauaoaoaoaoaoaoauauauapaeaealalalalalalalalalabalabalabalalalabalaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababalalalalalalalabalabalalalalalaeaeaecjaeaeaeaeaeaeaeaeapaoaoauaoaoaoaoaoaoaoaoapaXaXaXaWbJbJaXaYaXbJbJaWcscscsapauauaoauauauauauauaoaoapaeaealalalalalalalalalalalalalalalalabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavavavabababababavavavavavavavavavavavacacacacacacacacacacacacapaoaoapcIapapapcJaucJauapaWaWaWaWaXbJaXaXaXbJaXaWaWaWaWapauauaoauapapapaqapauaoapacacavavavavavababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababaccjcVcWcWcVaeaeaecVcXcXcXcXcVcVababaWaWbJbJaXbJbJaWaWababcVcVcXcXcXcXcVaeaeaecVcWcWcXaeacababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcWcVacacaecVcVcXdmcXdmcVabababaWaWaWbtaWaWaWabababcVcXcXcWcXcVcVaeacaccVcWcWcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcWdyabacaeaecVcXcXcXcXcVcVabababaWaXaYaXaWabababcVcVcXcXcWcXcVaeaeacabdycWcWcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababaccjcVcWcWdyabacaeaecVcXdmcXdmcXcVcVababaWaXaYaXaWababcVcVcXcXcXcXcXcVaeaeacabdycXcWcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcXdyabacaeaecVcVcXcXcXcXcXcVcVcVaWaXaYaXaWcVcVcVcXcWcWcWcXcVcVaeaeacabdycXcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcXdyabacaeaeaeebdmcXdmcXdmcXcWcVcVcVeccVcVcVcXcXcWcWcWcXcXedaeaeaeacabdycWcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababaccjcVcWcXdyabacacacaccVcVcXcXcXcXcWcWcWcWcWcWcWcWcWcWcWcWcWcXcXcVcVacacacacabdycWcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcXdyababababababcVcVdmcXdmcXcWcWcWcWcWcWcWcWcWcWcWcXcXcVcVababababababdycWcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcXdyabaaabaaabababcVedcVcXcWcWcWcWcWcWcWcWcWcWcWcWcVedcVabababaaabaaabdycWcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababaccjcVcWcWdyabaaabaaabaaabacaecVcVcVcVcWcWcWcWcWcWcWcVcVcVcVaeacabaaabaaabaaabdycWcWcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcWcXdyabababababababacaeaeaeaecVcVcVcWcWcWcVcVcVaeaeaeaeacabababababababdycWcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaababaccjcVcXcXdyabaaabaaabaaabacaeaeaeaeaeaecVcWcWcWcVaeaeaeaeaeaeacabaaabaaabaaabdycWcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaccjcVcXcXdyabaaabaaabaaabacacacacacacaecVcWcWcWcVaeacacacacacacabaaabaaabaaabdycXcXcVaeacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaccVcVcXcXcVcVabababababababababababacaeedcWcWcWedaeacabababababababababababcVcVcXcXcVcVacabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcVcXcXcXcXcVdydydydydydydydydydydycVcVcVcWcWcWcVcVcVdydydydydydydydydydydycVcWcWcWcWdyababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcVcXcXcWcXcXcXcXcXcXcXcXcXcWcWcWcXcWcWcXcWcWcWcXcXcXcWcWcWcWcXcWcXcXcWcWcWcXcWcWcWcWdyababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcVcXcXcXcXcXcWcWcWcWcWcWcXcWcWcWcWcXcXcWcWcWcWcXcXcWcWcXcXcXcWcWcWcWcWcWcWcWcWcWcWcWdyabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcVcXcXcXcXcVdydydydydydydydydydydydycVcWcWcXcXcWcVdydydydydydydydydydydydycVcWcWcWcWdyabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcVcVcVcVcVcVeZeZeZeZfaeZfbeZfbeZfbeZcVcWcWcWcWcXcVfcfcfdfdfdfdfdfdfdfdfcfccVcVcWcWcVcVabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -454,7 +296,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafkfkfkfkfhfhfhfhfhfefefefefefefvcWcWcWcWcWcWcWcWcWfjfdfdfdfdfdfdfdfwfsfpfBcVcXcXdyabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafkfkfkfkfhfhfhfhfhfhfhfhfhfgfgcVcWcWcWcWcWcWcWcWcWcVfdfdfdfdfdfdfdfdflflflcVcXcXdyabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafCfDfDfDfDfDfDfDfDfDfDfDfCfgfgfgfgfgcVcWcWcWcWcWcWcWcWcWcVfdfdfdfdfdfdfwfEfofFfGcVcXcXdyabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafCfHfIfHfIfHfHfHfHfHfHfIfDfhfgfhfefecVcVcWcWcWcWcWcWcWcVcVflflfJfKfLfwfdfwfsfAfNcVdmdmdyabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafCfHfIfHfIfHfHfHfHfHfHfIfDfhfgfhfefecVcVcWcWcWcWcWcWcWcVcVflflfdfdfLfwfdfwfsfAfNcVdmdmdyabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafCfHfHfHfHfHfIfHfIfCfIfIfDaaabaafIfHfIcVcVcVcWcWcWcVcVcVababflflflflflflflflflflcVcXcXdyalabalabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafCfHfIfHfIfHfHfHfHfHfHfOfDabababfHfHfHfHfHcVcWcWcWcVfIfIfHfHfIfHfIfHfHfHfHfIfHfIcXdmdmcXabababalaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafCfHfHfHfHfHfOfHfHfOfOfOfDaaabaafIfHfIfHfIcVcXcWcWcVfIfHfHfHfCfCfCfCfCfCfCfCfCfCfCfCfCfCfCfIfIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/maps/exodus-5.dmm b/maps/exodus-5.dmm index e026786fa4..98aae30971 100644 --- a/maps/exodus-5.dmm +++ b/maps/exodus-5.dmm @@ -1,979 +1,982 @@ "aa" = (/turf/space,/area/space) -"ab" = (/turf/simulated/mineral,/area/mine/unexplored) +"ab" = (/turf/unsimulated/mask,/area/mine/unexplored) "ac" = (/turf/space,/area/syndicate_station/mining) "ad" = (/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) "ae" = (/obj/structure/lattice,/turf/space,/area/space) -"af" = (/obj/structure/transit_tube{icon_state = "D-SE"},/obj/structure/lattice,/turf/space,/area/space) -"ag" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "E-SW"},/turf/space,/area/space) -"ah" = (/obj/structure/lattice,/obj/structure/transit_tube,/turf/space,/area/space) -"ai" = (/obj/structure/transit_tube,/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"aj" = (/obj/machinery/light/small,/obj/structure/transit_tube,/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"ak" = (/obj/structure/transit_tube{icon_state = "W-SE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"al" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/mineral,/area/mine/unexplored) -"am" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) -"an" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) -"ao" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) -"ap" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "NE-SW"},/turf/space,/area/space) -"aq" = (/obj/structure/transit_tube{icon_state = "D-NW"},/obj/structure/lattice,/turf/space,/area/space) -"ar" = (/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) -"as" = (/obj/structure/transit_tube{icon_state = "D-NE"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) -"at" = (/obj/structure/transit_tube{icon_state = "NW-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) -"au" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/mineral,/area/mine/unexplored) -"av" = (/obj/structure/transit_tube{icon_state = "E-SW"},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"aw" = (/obj/structure/transit_tube,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) -"ax" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"ay" = (/obj/structure/transit_tube/station,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/research_outpost/hallway) -"az" = (/obj/structure/transit_tube,/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/research_outpost/hallway) -"aA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/transit_tube,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) -"aB" = (/obj/structure/transit_tube,/obj/structure/lattice,/turf/space,/area/space) -"aC" = (/obj/structure/transit_tube{icon_state = "W-SE"},/obj/structure/lattice,/turf/space,/area/space) -"aD" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "D-SW"},/turf/space,/area/space) -"aE" = (/obj/structure/transit_tube{icon_state = "S-NE"},/obj/structure/lattice,/turf/space,/area/space) -"aF" = (/obj/structure/reagent_dispensers/fueltank,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) -"aG" = (/obj/structure/closet/hydrant{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) -"aH" = (/obj/structure/table,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/cell,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) -"aI" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) -"aJ" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) -"aK" = (/obj/structure/transit_tube{icon_state = "NE-SW"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) -"aL" = (/obj/structure/transit_tube{icon_state = "D-NW"},/turf/simulated/wall/r_wall,/area/research_outpost/hallway) -"aM" = (/turf/simulated/wall/r_wall,/area/research_outpost/hallway) -"aN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/research_outpost/hallway) -"aO" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/research_outpost/hallway) -"aP" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "D-NE"},/turf/space,/area/space) -"aQ" = (/obj/structure/transit_tube{icon_state = "NW-SE"},/obj/structure/lattice,/turf/space,/area/space) -"aR" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "N-S"},/turf/space,/area/space) -"aS" = (/turf/simulated/wall/r_wall,/area/research_outpost/spectro) -"aT" = (/obj/structure/table/rack,/obj/item/stack/sheet/metal{amount = 50; pixel_x = 5; pixel_y = 5},/obj/item/stack/sheet/glass{amount = 50},/obj/item/weapon/storage/belt/utility{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/storage/toolbox/emergency{pixel_x = 5; pixel_y = 5},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) -"aU" = (/turf/simulated/floor/plating,/area/research_outpost/maintstore1) -"aV" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/research_outpost/maintstore1) -"aW" = (/turf/simulated/wall,/area/research_outpost/maintstore1) -"aX" = (/obj/structure/transit_tube{icon_state = "D-NE"},/obj/structure/table,/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/research_outpost/maintstore1) -"aY" = (/obj/structure/transit_tube{icon_state = "E-NW"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/research_outpost/maintstore1) -"aZ" = (/obj/structure/transit_tube/station,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/research_outpost/maintstore1) -"ba" = (/obj/structure/transit_tube{icon_state = "W-NE"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/research_outpost/maintstore1) -"bb" = (/obj/structure/transit_tube{icon_state = "D-NW"},/obj/structure/reagent_dispensers/watertank,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/research_outpost/maintstore1) -"bc" = (/turf/simulated/wall,/area/research_outpost/hallway) -"bd" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/brown,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor/carpet,/area/research_outpost/hallway) -"be" = (/obj/machinery/door_control{id = "rddorm1"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/carpet,/area/research_outpost/hallway) -"bf" = (/obj/machinery/camera{c_tag = "Research Outpost Hallway Fore"; dir = 4; network = list("Research","SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/hallway) -"bg" = (/turf/simulated/floor,/area/research_outpost/hallway) -"bh" = (/obj/machinery/door_control{id = "rdorm2"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = -25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/carpet,/area/research_outpost/hallway) -"bi" = (/obj/structure/transit_tube{icon_state = "D-NE"},/obj/structure/lattice,/turf/space,/area/space) -"bj" = (/obj/structure/transit_tube{icon_state = "S-NW"},/obj/structure/lattice,/turf/space,/area/space) -"bk" = (/turf/simulated/mineral/random,/area/mine/unexplored) -"bl" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/shovel/spade,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/minihoe,/obj/item/weapon/reagent_containers/spray/plantbgone{pixel_x = 13; pixel_y = 5},/obj/item/weedkiller/triclopyr,/obj/item/weapon/reagent_containers/glass/fertilizer/ez,/turf/simulated/floor/plating,/area/research_outpost/maintstore1) -"bm" = (/obj/machinery/light/small,/obj/structure/closet/walllocker/emerglocker/north{dir = 1; pixel_y = -32},/turf/simulated/floor/plating,/area/research_outpost/maintstore1) -"bn" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/maintenance{name = "Auxiliary Storage"; req_access_txt = "0"; req_one_access_txt = "65;12"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/maintstore1) -"bo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor,/area/research_outpost/maintstore1) -"bp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/research_outpost/maintstore1) -"bq" = (/obj/machinery/camera{c_tag = "Research Outpost Auxiliary Storage"; dir = 8; network = list("Research","SS13")},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/research_outpost/maintstore1) -"br" = (/obj/structure/table,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor/carpet,/area/research_outpost/hallway) -"bs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/research_outpost/hallway) -"bt" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "rddorm1"; name = "Dorm 1"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "carpet"},/area/research_outpost/hallway) -"bu" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/hallway) -"bv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/research_outpost/hallway) -"bw" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "rdorm2"; name = "Dorm 2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "carpet"},/area/research_outpost/hallway) -"bx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/research_outpost/hallway) -"by" = (/obj/structure/table,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/carpet,/area/research_outpost/hallway) -"bz" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; external_pressure_bound = 140; external_pressure_bound_default = 140; icon_state = "map_vent_out"; use_power = 1; pressure_checks = 0; pressure_checks_default = 0},/turf/simulated/floor/plating/airless,/area/research_outpost/atmos) -"bA" = (/obj/structure/transit_tube{icon_state = "N-S"},/obj/structure/lattice,/turf/space,/area/space) -"bB" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/spectro) -"bC" = (/obj/structure/reagent_dispensers/coolanttank,/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/research_outpost/spectro) -"bD" = (/turf/simulated/wall/r_wall,/area/research_outpost/sample) -"bE" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor,/area/research_outpost/maintstore1) -"bF" = (/turf/simulated/floor,/area/research_outpost/maintstore1) -"bG" = (/turf/simulated/floor{icon_state = "warning"},/area/research_outpost/maintstore1) -"bH" = (/obj/structure/sign/botany{pixel_x = 32},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/research_outpost/maintstore1) -"bI" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/hallway) -"bJ" = (/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor{dir = 2; icon_state = "whitecorner"},/area/research_outpost/hallway) -"bK" = (/turf/simulated/wall/r_wall,/area/research_outpost/atmos) -"bL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor/plating,/area/research_outpost/atmos) -"bM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"bN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"bO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/mine/abandoned) -"bP" = (/obj/machinery/door/airlock/external,/turf/simulated/floor,/area/mine/abandoned) -"bQ" = (/obj/structure/table,/obj/machinery/light/small{dir = 1},/obj/item/stack/nanopaste,/obj/item/stack/nanopaste,/obj/item/stack/nanopaste,/turf/simulated/floor{icon_state = "dark"},/area/research_outpost/spectro) -"bR" = (/obj/structure/stool,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/spectro) -"bS" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/research_outpost/spectro) -"bT" = (/obj/machinery/door/airlock/research{name = "Spectrometry Lab Sample Preparation"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/spectro) -"bU" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/sample) -"bV" = (/obj/structure/sign/nosmoking_2{pixel_y = 32},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/sample) -"bW" = (/obj/structure/table,/obj/machinery/light{dir = 1},/obj/machinery/reagentgrinder,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/sample) -"bX" = (/obj/structure/table,/obj/item/weapon/storage/box/solution_trays,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/sample) -"bY" = (/obj/machinery/door/window/westleft{dir = 1; name = "Sample Preparation Loading"; req_access_txt = "65"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor{dir = 1; icon_state = "whiteblue"},/area/research_outpost/sample) -"bZ" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "bluecorner"},/area/research_outpost/sample) -"ca" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/grass,/area/research_outpost/maintstore1) -"cb" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/grass,/area/research_outpost/maintstore1) -"cc" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/research_outpost/maintstore1) -"cd" = (/obj/structure/sink{pixel_y = 30},/obj/structure/mirror{dir = 4; pixel_x = -32; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "showroomfloor"},/area/research_outpost/hallway) -"ce" = (/obj/structure/toilet{dir = 8},/obj/machinery/light/small{dir = 1},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "showroomfloor"},/area/research_outpost/hallway) -"cf" = (/obj/structure/closet/walllocker/emerglocker/west,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "whitecorner"},/area/research_outpost/hallway) -"cg" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) -"ch" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister,/turf/simulated/floor/plating,/area/research_outpost/atmos) -"ci" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/atmospherics/binary/pump/on{dir = 8; name = "Filter to Waste"; target_pressure = 4500},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"cj" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 1},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"ck" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 1},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"cl" = (/obj/machinery/atmospherics/valve{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"cm" = (/obj/machinery/door/window/westleft{req_one_access_txt = "65;10;24"},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 9},/turf/simulated/floor,/area/research_outpost/atmos) -"cn" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/research_outpost/atmos) -"co" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"cp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/mine/abandoned) -"cq" = (/turf/simulated/floor,/area/mine/abandoned) -"cr" = (/obj/machinery/radiocarbon_spectrometer,/turf/simulated/floor{icon_state = "dark"},/area/research_outpost/spectro) -"cs" = (/turf/simulated/floor{icon_state = "white"},/area/research_outpost/spectro) -"ct" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/research_outpost/spectro) -"cu" = (/obj/structure/table,/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/sample) -"cv" = (/turf/simulated/floor{icon_state = "white"},/area/research_outpost/sample) -"cw" = (/obj/structure/stool,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/sample) -"cx" = (/obj/structure/table,/obj/machinery/bunsen_burner,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/sample) -"cy" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/sample) -"cz" = (/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/research_outpost/sample) -"cA" = (/obj/structure/disposaloutlet{dir = 8},/obj/structure/disposalpipe/trunk{dir = 2},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1) -"cB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/research_outpost/maintstore1) -"cC" = (/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5},/obj/structure/curtain/open/shower,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{icon_state = "showroomfloor"},/area/research_outpost/hallway) -"cD" = (/obj/machinery/door_control{id = "rbath"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 0; pixel_y = -25; req_access_txt = "0"; specialfunctions = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "showroomfloor"},/area/research_outpost/hallway) -"cE" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "rbath"; name = "Bathroom"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "showroomfloor"},/area/research_outpost/hallway) -"cF" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) -"cG" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) -"cH" = (/obj/machinery/door/airlock/atmos{name = "Outpost Atmospherics"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/universal{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"cI" = (/obj/machinery/meter,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 1},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"cJ" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/binary/pump/on{dir = 8; name = "Air to Distro"; target_pressure = 285},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"cK" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plating,/area/research_outpost/atmos) -"cL" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"cM" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"cN" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor,/area/research_outpost/atmos) -"cO" = (/obj/structure/transit_tube/station{dir = 8; icon_state = "closed"},/turf/simulated/floor{icon_state = "bot"},/area/research_outpost/atmos) -"cP" = (/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"cQ" = (/obj/item/stack/rods,/obj/structure/door_assembly/door_assembly_ext{name = "Broken External Airlock"},/turf/simulated/floor,/area/mine/abandoned) -"cR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/mine/abandoned) -"cS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/mine/abandoned) -"cT" = (/obj/structure/transit_tube{icon_state = "N-SW"},/obj/structure/lattice,/turf/space,/area/space) -"cU" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/spectro) -"cV" = (/obj/structure/sign/nosmoking_2{pixel_x = 32},/obj/machinery/camera{c_tag = "Research Outpost Mass Spectrometry"; dir = 8; network = list("Research","SS13")},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/research_outpost/spectro) -"cW" = (/obj/machinery/chem_dispenser,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/sample) -"cX" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/sample) -"cY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/sample) -"cZ" = (/obj/machinery/light/small{dir = 4},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/cable,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/sample) -"da" = (/turf/simulated/wall/r_wall,/area/research_outpost/anomaly) -"db" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/research_outpost/anomaly) -"dc" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials Loading"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/anomaly) -"dd" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) -"de" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) -"df" = (/obj/structure/sign/nosmoking_1{pixel_x = -32},/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; icon_state = "map_vent_out"; level = 2; use_power = 1},/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"dg" = (/obj/machinery/atmospherics/omni/mixer{use_power = 1; tag_east = 2; tag_north = 0; tag_north_con = null; tag_south = 1; tag_south_con = 0.8; tag_west = 1; tag_west_con = 0.2},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"dh" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan,/obj/machinery/meter,/turf/simulated/floor/plating,/area/research_outpost/atmos) -"di" = (/obj/machinery/atmospherics/unary/freezer{dir = 8; icon_state = "freezer_1"; use_power = 1},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"dj" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/light/small,/turf/simulated/floor,/area/research_outpost/atmos) +"af" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/outpost/abandoned) +"ag" = (/obj/machinery/door/airlock/external,/turf/simulated/floor,/area/outpost/abandoned) +"ah" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"ai" = (/turf/simulated/wall,/area/outpost/research/hallway) +"aj" = (/obj/structure/toilet{dir = 8},/obj/machinery/light/small{dir = 1},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "showroomfloor"},/area/outpost/research/hallway) +"ak" = (/obj/structure/sink{pixel_y = 30},/obj/structure/mirror{dir = 4; pixel_x = -32; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "showroomfloor"},/area/outpost/research/hallway) +"al" = (/turf/unsimulated/mask,/area/mine/explored) +"am" = (/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/kitchen) +"an" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/hallway) +"ao" = (/obj/structure/closet/walllocker/emerglocker/west,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "whitecorner"},/area/outpost/research/hallway) +"ap" = (/obj/machinery/door/window/westleft{dir = 1; name = "Sample Preparation Loading"; req_access = list(65)},/turf/simulated/floor{dir = 1; icon_state = "whiteblue"},/area/outpost/research/chemistry) +"aq" = (/obj/structure/table,/obj/item/weapon/storage/box/solution_trays,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/outpost/research/chemistry) +"ar" = (/obj/structure/table,/obj/machinery/light{dir = 1},/obj/machinery/reagentgrinder,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/chemistry) +"as" = (/obj/structure/sign/nosmoking_2{pixel_y = 32},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/chemistry) +"at" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/outpost/research/chemistry) +"au" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/grass,/area/outpost/research/chemistry) +"av" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/grass,/area/outpost/research/chemistry) +"aw" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "bluecorner"},/area/outpost/research/chemistry) +"ax" = (/obj/structure/bed/chair,/obj/machinery/status_display{pixel_y = 32},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/kitchen) +"ay" = (/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/kitchen) +"az" = (/turf/simulated/wall/r_wall,/area/outpost/research/kitchen) +"aA" = (/turf/simulated/wall/r_wall,/area/outpost/research/analysis) +"aB" = (/obj/structure/table,/obj/machinery/light/small{dir = 1},/obj/item/stack/nanopaste,/obj/item/stack/nanopaste,/obj/item/stack/nanopaste,/turf/simulated/floor{icon_state = "dark"},/area/outpost/research/analysis) +"aC" = (/obj/item/weapon/stool,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/analysis) +"aD" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/outpost/research/analysis) +"aE" = (/obj/machinery/door/airlock/research{name = "Spectrometry Lab Sample Preparation"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/analysis) +"aF" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/chemistry) +"aG" = (/turf/simulated/wall/r_wall,/area/outpost/research/hallway) +"aH" = (/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor{dir = 2; icon_state = "whitecorner"},/area/outpost/research/hallway) +"aI" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/research/hallway) +"aJ" = (/turf/simulated/wall/r_wall,/area/outpost/research/chemistry) +"aK" = (/turf/simulated/floor,/area/outpost/research/chemistry) +"aL" = (/turf/simulated/floor{icon_state = "warning"},/area/outpost/research/chemistry) +"aM" = (/obj/structure/sign/botany{pixel_x = 32},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/outpost/research/chemistry) +"aN" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/bucket,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/analysis) +"aO" = (/obj/structure/reagent_dispensers/coolanttank,/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/outpost/research/analysis) +"aP" = (/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"aQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/outpost/abandoned) +"aR" = (/obj/item/stack/rods,/obj/structure/door_assembly/door_assembly_ext{name = "Broken External Airlock"},/turf/simulated/floor,/area/outpost/abandoned) +"aS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/outpost/abandoned) +"aT" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/analysis) +"aU" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 22},/obj/structure/bed/chair,/obj/machinery/light{dir = 1},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/kitchen) +"aV" = (/obj/machinery/chemical_dispenser/full,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/chemistry) +"aW" = (/obj/machinery/radiocarbon_spectrometer,/turf/simulated/floor{icon_state = "dark"},/area/outpost/research/analysis) +"aX" = (/obj/structure/cable/blue,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/kitchen) +"aY" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/hallway) +"aZ" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/hallway) +"ba" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials Loading"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/research/lab) +"bb" = (/turf/simulated/wall/r_wall,/area/outpost/research/lab) +"bc" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall/r_wall,/area/outpost/research/lab) +"bd" = (/obj/machinery/light/small{dir = 4},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/chemistry) +"be" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/chemistry) +"bf" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/chemistry) +"bg" = (/obj/item/weapon/stool,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/chemistry) +"bh" = (/obj/structure/table,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/kitchen) +"bi" = (/obj/structure/sign/nosmoking_2{pixel_x = 32},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera/autoname/research_outpost{dir = 8},/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/outpost/research/analysis) +"bj" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/kitchen) +"bk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"bl" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/outpost/abandoned) +"bm" = (/turf/simulated/floor,/area/outpost/abandoned) +"bn" = (/obj/structure/table,/obj/item/weapon/storage/box/beakers{pixel_x = 2; pixel_y = 2},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/chemistry) +"bo" = (/turf/simulated/floor{icon_state = "white"},/area/outpost/research/analysis) +"bp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor{dir = 4; icon_state = "whitegreen"},/area/outpost/research/analysis) +"bq" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/hallway) +"br" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/hallway) +"bs" = (/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/kitchen) +"bt" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "rbath"; name = "Kitchen"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/hallway) +"bu" = (/obj/machinery/shower{dir = 4; icon_state = "shower"; pixel_x = 5},/obj/structure/curtain/open/shower,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{icon_state = "showroomfloor"},/area/outpost/research/hallway) +"bv" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "rbath"; name = "Bathroom"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "showroomfloor"},/area/outpost/research/hallway) +"bw" = (/obj/machinery/door_control{id = "rbath"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 0; pixel_y = -25; specialfunctions = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "showroomfloor"},/area/outpost/research/hallway) +"bx" = (/obj/structure/disposaloutlet{dir = 8},/obj/structure/disposalpipe/trunk{dir = 2},/turf/simulated/wall/r_wall,/area/outpost/research/chemistry) +"by" = (/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/outpost/research/chemistry) +"bz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/outpost/research/chemistry) +"bA" = (/turf/simulated/floor{icon_state = "white"},/area/outpost/research/chemistry) +"bB" = (/obj/structure/table,/obj/machinery/bunsen_burner,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/chemistry) +"bC" = (/turf/simulated/floor/airless{icon_state = "damaged5"},/area/outpost/abandoned) +"bD" = (/obj/item/weapon/shard{icon_state = "medium"},/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"bE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/outpost/abandoned) +"bF" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Sample Preparation"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"bG" = (/obj/machinery/artifact_analyser,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor/bluegrid,/area/outpost/research/lab) +"bH" = (/obj/structure/table,/obj/item/weapon/flame/lighter/random,/obj/item/weapon/crowbar,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) +"bI" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 4; icon_state = "whitepurple"},/area/outpost/research/lab) +"bJ" = (/obj/machinery/conveyor{dir = 1; id = "anolaser"},/obj/structure/plasticflaps,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/outpost/research/lab) +"bK" = (/obj/machinery/conveyor_switch{id = "anolaser"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) +"bL" = (/obj/machinery/artifact_scanpad,/turf/simulated/floor/bluegrid,/area/outpost/research/lab) +"bM" = (/turf/simulated/floor/wood,/area/outpost/research/kitchen) +"bN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/research/hallway) +"bO" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 4; icon_state = "whiteyellow"},/area/outpost/research/hallway) +"bP" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/hallway) +"bQ" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor/wood,/area/outpost/research/kitchen) +"bR" = (/obj/structure/table,/turf/simulated/floor/wood,/area/outpost/research/kitchen) +"bS" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/turf/simulated/floor/wood,/area/outpost/research/kitchen) +"bT" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_x = 32; pixel_y = 0},/obj/structure/lattice,/turf/space,/area/space) +"bU" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Spectrometry Lab"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"bV" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"bW" = (/obj/item/stack/rods,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"bX" = (/obj/structure/table,/obj/machinery/camera{c_tag = "Research Outpost Sample Preparation"; dir = 1; network = list("Research","SS13")},/obj/item/weapon/reagent_containers/glass/beaker/water,/obj/item/weapon/reagent_containers/glass/beaker/fuel,/obj/item/weapon/reagent_containers/glass/bottle/toxin,/obj/item/weapon/reagent_containers/glass/beaker/sulphuric{name = "beaker 'sulphuric acid'"},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"},/area/outpost/research/chemistry) +"bY" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/dropper{pixel_y = -4},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"},/area/outpost/research/chemistry) +"bZ" = (/turf/simulated/floor{dir = 2; icon_state = "whiteblue"},/area/outpost/research/chemistry) +"ca" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"},/area/outpost/research/chemistry) +"cb" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor{dir = 2; icon_state = "whitepurplecorner"},/area/outpost/research/lab) +"cc" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials Sample Preparation"; req_access = list(65)},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) +"cd" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/outpost/research/lab) +"ce" = (/obj/machinery/alarm{dir = 2; pixel_y = 25},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/outpost/research/lab) +"cf" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 6; icon_state = "whitepurple"},/area/outpost/research/lab) +"cg" = (/obj/structure/sign/nosmoking_2{pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/outpost/research/lab) +"ch" = (/obj/machinery/conveyor{dir = 1; id = "anolaser"},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/outpost/research/lab) +"ci" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/hallway) +"cj" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/hallway) +"ck" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/research/hallway) +"cl" = (/obj/machinery/chem_master,/turf/simulated/floor{dir = 2; icon_state = "whiteblue"},/area/outpost/research/chemistry) +"cm" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/outpost/research/analysis) +"cn" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 6; icon_state = "whitegreen"},/area/outpost/research/analysis) +"co" = (/obj/item/stack/rods,/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/shard,/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"cp" = (/turf/simulated/floor/airless{icon_state = "damaged2"},/area/outpost/abandoned) +"cq" = (/obj/item/stack/rods,/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"cr" = (/turf/simulated/wall,/area/outpost/abandoned) +"cs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/hallway) +"ct" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"cu" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"cv" = (/obj/machinery/hologram/holopad,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"cw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"cx" = (/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"cy" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"cz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/outpost/research/lab) +"cA" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/outpost/research/lab) +"cB" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{dir = 4; icon_state = "whitepurplecorner"},/area/outpost/research/lab) +"cC" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access = list(65)},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"cD" = (/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/research/hallway) +"cE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/research/hallway) +"cF" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/outpost/research/hallway) +"cG" = (/obj/machinery/vending/coffee,/turf/simulated/floor/wood,/area/outpost/research/kitchen) +"cH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/research/hallway) +"cI" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteyellow"},/area/outpost/research/hallway) +"cJ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{dir = 8; icon_state = "whitepurple"},/area/outpost/research/hallway) +"cK" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"cL" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/outpost/research/lab) +"cM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/outpost/research/lab) +"cN" = (/obj/structure/table,/obj/machinery/microwave,/turf/simulated/floor/wood,/area/outpost/research/kitchen) +"cO" = (/obj/machinery/vending/snack,/turf/simulated/floor/wood,/area/outpost/research/kitchen) +"cP" = (/obj/item/weapon/shard,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"cQ" = (/obj/machinery/alarm{dir = 2; pixel_y = 25},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"cR" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"cS" = (/obj/structure/sign/science{desc = "A warning sign which reads 'MASS SPECTROMETRY'"; name = "\improper MASS SPECTROMETRY"; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "whitegreencorner"},/area/outpost/research/hallway) +"cT" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/outpost/research/hallway) +"cU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"cV" = (/obj/machinery/camera{c_tag = "Research Outpost Lobby"; dir = 2; network = list("Research","SS13")},/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor{dir = 4; icon_state = "whitegreencorner"},/area/outpost/research/hallway) +"cW" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_x = -30; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"cX" = (/obj/structure/noticeboard/anomaly{icon_state = "nboard05"; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"cY" = (/obj/structure/disposalpipe/segment,/obj/machinery/light/small{dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = -25; pixel_y = 0},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 4; icon_state = "whitepurple"},/area/outpost/research/lab) +"cZ" = (/obj/structure/table,/obj/item/weapon/reagent_containers/dropper{pixel_y = -4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) +"da" = (/obj/item/weapon/stool,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) +"db" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/research/hallway) +"dc" = (/obj/structure/closet/walllocker/emerglocker/north,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/outpost/research/hallway) +"dd" = (/obj/structure/sign/chemistry{desc = "A warning sign which reads 'SAMPLE PREPARATION'"; name = "\improper SAMPLE PREPARATION"; pixel_y = 32},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/machinery/camera{c_tag = "Research Outpost Hallway Port"; dir = 2; network = list("Research","SS13")},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/research/hallway) +"de" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/research/hallway) +"df" = (/turf/simulated/floor{dir = 4; icon_state = "whiteyellow"},/area/outpost/research/hallway) +"dg" = (/obj/structure/extinguisher_cabinet{pixel_x = -25; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 8; icon_state = "whitepurplecorner"},/area/outpost/research/hallway) +"dh" = (/obj/machinery/power/emitter{anchored = 1; dir = 4; state = 2},/turf/simulated/floor{icon_state = "delivery"},/area/outpost/research/lab) +"di" = (/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) +"dj" = (/obj/machinery/conveyor{dir = 1; id = "anolaser"},/obj/machinery/door/window/westleft{dir = 2; layer = 3.1; name = "laser testing"; req_access = list(65)},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/outpost/research/lab) "dk" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "pwall"; dir = 9},/area/shuttle/alien/mine) "dl" = (/turf/simulated/shuttle/wall{icon_state = "pwall"; dir = 1},/area/shuttle/alien/mine) -"dm" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"dn" = (/obj/item/stack/rods,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"do" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"dp" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "D-SE"},/turf/space,/area/space) -"dq" = (/obj/structure/transit_tube{icon_state = "E-SW"},/obj/structure/lattice,/turf/space,/area/space) -"dr" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "W-NE"},/turf/space,/area/space) -"ds" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "D-NW"},/turf/space,/area/space) -"dt" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitegreen"},/area/research_outpost/spectro) -"du" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 6; icon_state = "whitegreen"},/area/research_outpost/spectro) -"dv" = (/obj/machinery/chem_master,/turf/simulated/floor{dir = 2; icon_state = "whiteblue"},/area/research_outpost/sample) -"dw" = (/obj/structure/table,/obj/item/weapon/reagent_containers/glass/beaker/large,/obj/item/weapon/reagent_containers/dropper{pixel_y = -4},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"},/area/research_outpost/sample) -"dx" = (/obj/structure/table,/obj/machinery/camera{c_tag = "Research Outpost Sample Preparation"; dir = 1; network = list("Research","SS13")},/obj/item/weapon/reagent_containers/glass/beaker/water,/obj/item/weapon/reagent_containers/glass/beaker/fuel,/obj/item/weapon/reagent_containers/glass/bottle/toxin,/obj/item/weapon/reagent_containers/glass/beaker/sulphuric{name = "beaker 'sulphuric acid'"},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"},/area/research_outpost/sample) -"dy" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "whiteblue"},/area/research_outpost/sample) -"dz" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor{dir = 2; icon_state = "whiteblue"},/area/research_outpost/sample) -"dA" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials Sample Preparation"; req_access_txt = "65"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"dB" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/disposalpipe/segment,/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor{dir = 2; icon_state = "whitepurplecorner"},/area/research_outpost/anomaly) -"dC" = (/obj/machinery/alarm{dir = 2; pixel_y = 25},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/research_outpost/anomaly) -"dD" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/research_outpost/anomaly) -"dE" = (/obj/structure/sign/nosmoking_2{pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/research_outpost/anomaly) -"dF" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 6; icon_state = "whitepurple"},/area/research_outpost/anomaly) -"dG" = (/obj/machinery/conveyor{dir = 1; id = "anolaser"},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/research_outpost/anomaly) -"dH" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) -"dI" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Firelock North"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) -"dJ" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/obj/structure/window/reinforced/tinted{dir = 4; health = 1000; icon_state = "twindow"; name = "hardened window"; opacity = 0},/obj/structure/window/reinforced/tinted{dir = 1; health = 1000; icon_state = "twindow"; name = "hardened window"; opacity = 0},/turf/simulated/floor/engine{name = "Outpost O2"; nitrogen = 0; oxygen = 5000},/area/research_outpost/atmos) -"dK" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 5},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"dL" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow,/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"dM" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/obj/machinery/atmospherics/portables_connector{dir = 1},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"dN" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/obj/structure/window/reinforced/tinted{dir = 8; health = 1000; icon_state = "twindow"; name = "hardened window"; opacity = 0},/obj/structure/window/reinforced/tinted{dir = 1; health = 1000; icon_state = "twindow"; name = "hardened window"; opacity = 0},/turf/simulated/floor/engine{name = "Outpost N2"; nitrogen = 20000; oxygen = 0},/area/research_outpost/atmos) -"dO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"dP" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos) +"dm" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/outpost/research/disposal) +"dn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/disposal) +"do" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/plating,/area/outpost/research/disposal) +"dp" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 22},/turf/simulated/floor/plating,/area/outpost/research/disposal) +"dq" = (/turf/simulated/floor/plating/airless/asteroid,/area/outpost/research/disposal) +"dr" = (/obj/machinery/mass_driver{dir = 4; id = "research"},/turf/simulated/floor/plating/airless/asteroid,/area/outpost/research/disposal) +"ds" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access = list(65)},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) +"dt" = (/obj/structure/table/rack,/obj/item/weapon/storage/toolbox/emergency{pixel_x = 5; pixel_y = 5},/turf/simulated/floor/plating,/area/outpost/research/disposal) +"du" = (/turf/simulated/floor{dir = 4; icon_state = "whiteyellowcorner"},/area/outpost/research/hallway) +"dv" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/kitchen) +"dw" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/outpost/research/hallway) +"dx" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"dy" = (/obj/machinery/vending/snack,/obj/machinery/light{dir = 4},/turf/simulated/floor/wood,/area/outpost/research/hallway) +"dz" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/research{name = "Anomalous Materials Locker Room"; req_access = list(65)},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) +"dA" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"dB" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/wood,/area/outpost/research/hallway) +"dC" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor/wood,/area/outpost/research/hallway) +"dD" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 5},/obj/item/weapon/clipboard,/obj/item/weapon/pen,/obj/item/weapon/tape_roll,/turf/simulated/floor/wood,/area/outpost/research/hallway) +"dE" = (/obj/structure/table,/obj/item/device/camera,/obj/item/weapon/stamp,/obj/item/weapon/folder,/turf/simulated/floor/wood,/area/outpost/research/hallway) +"dF" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor/wood,/area/outpost/research/hallway) +"dG" = (/turf/simulated/floor/wood,/area/outpost/research/hallway) +"dH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/hallway) +"dI" = (/obj/effect/decal/remains/xeno,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/outpost/abandoned) +"dJ" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/airless{icon_state = "damaged2"},/area/outpost/abandoned) +"dK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"dL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"dM" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"dN" = (/obj/machinery/light/small,/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) +"dO" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/screwdriver{pixel_y = 15},/obj/item/weapon/melee/baton/loaded,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) +"dP" = (/obj/machinery/camera{c_tag = "Research Outpost Anomalous Materials Lab"; dir = 8; network = list("Research","SS13")},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) "dQ" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 4},/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"},/turf/simulated/floor/plating/airless,/area/shuttle/alien/mine) "dR" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/alien/mine) "dS" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/alien/mine) "dT" = (/obj/machinery/door/airlock/hatch,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/alien/mine) -"dU" = (/obj/item/weapon/shard{icon_state = "medium"},/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"dV" = (/turf/simulated/floor/airless{icon_state = "damaged5"},/area/mine/abandoned) -"dW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/mine/abandoned) -"dX" = (/turf/simulated/mineral/random,/area/mine/explored) -"dY" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "S-NE"},/turf/space,/area/space) -"dZ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_x = 32; pixel_y = 0},/turf/space,/area/space) -"ea" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Spectrometry Lab"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/spectro) -"eb" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Sample Preparation"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"ec" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/research_outpost/sample) -"ed" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{dir = 4; icon_state = "whitepurple"},/area/research_outpost/anomaly) -"ee" = (/obj/structure/table,/obj/item/weapon/flame/lighter/random,/obj/item/weapon/crowbar,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"ef" = (/obj/machinery/artifact_analyser,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor/bluegrid,/area/research_outpost/anomaly) -"eg" = (/obj/machinery/artifact_scanpad,/turf/simulated/floor/bluegrid,/area/research_outpost/anomaly) -"eh" = (/obj/machinery/conveyor_switch{id = "anolaser"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"ei" = (/obj/machinery/conveyor{dir = 1; id = "anolaser"},/obj/structure/plasticflaps,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/research_outpost/anomaly) -"ej" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) -"ek" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 4; icon_state = "whiteyellow"},/area/research_outpost/hallway) -"el" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH PRESSURE'."; name = "\improper HIGH PRESSURE"},/turf/simulated/wall/r_wall,/area/research_outpost/atmos) -"em" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 4; icon_state = "map_injector"; use_power = 1},/obj/structure/window/reinforced/tinted{dir = 4; health = 1000; icon_state = "twindow"; name = "hardened window"; opacity = 0},/turf/simulated/floor/engine{name = "Outpost O2"; nitrogen = 0; oxygen = 5000},/area/research_outpost/atmos) -"en" = (/obj/machinery/meter,/obj/machinery/light/small,/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"eo" = (/obj/machinery/atmospherics/omni/filter{use_power = 1; tag_east = 4; tag_north = 2; tag_south = 1; tag_west = 3},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"ep" = (/obj/machinery/meter,/obj/structure/sign/fire{pixel_x = 0; pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/visible/purple{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/atmos) -"eq" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 8; icon_state = "map_injector"; use_power = 1},/obj/structure/window/reinforced/tinted{dir = 8; health = 1000; icon_state = "twindow"; name = "hardened window"; opacity = 0},/turf/simulated/floor/engine{name = "Outpost N2"; nitrogen = 20000; oxygen = 0},/area/research_outpost/atmos) -"er" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"es" = (/turf/simulated/mineral,/area/mine/explored) +"dU" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{dir = 4; icon_state = "whiteyellow"},/area/outpost/research/hallway) +"dV" = (/obj/structure/sign/science{desc = "A warning sign which reads 'ANOMALOUS MATERIALS'"; name = "\improper ANOMALOUS MATERIALS"; pixel_x = -32},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 1; icon_state = "whitepurplecorner"},/area/outpost/research/hallway) +"dW" = (/turf/simulated/wall,/area/outpost/research/disposal) +"dX" = (/turf/unsimulated/mask,/area/space) +"dY" = (/obj/machinery/vending/cola,/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/wood,/area/outpost/research/hallway) +"dZ" = (/obj/structure/sign/science{desc = "A warning sign which reads 'ANOMALOUS MATERIALS'"; name = "\improper ANOMALOUS MATERIALS"; pixel_x = 32},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/research/hallway) +"ea" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/outpost/research/hallway) +"eb" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) +"ec" = (/obj/structure/table/rack,/obj/item/clothing/head/welding,/obj/item/weapon/weldingtool,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) +"ed" = (/obj/machinery/firealarm{pixel_y = -24},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/lab) +"ee" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area/outpost/research/disposal) +"ef" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating/airless/asteroid,/area/outpost/research/disposal) +"eg" = (/obj/structure/disposaloutlet{dir = 2},/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/outpost/research/disposal) +"eh" = (/obj/structure/table,/turf/simulated/floor/wood,/area/outpost/research/hallway) +"ei" = (/obj/structure/table,/obj/item/weapon/storage/box/drinkingglasses{pixel_x = 1; pixel_y = 4},/turf/simulated/floor/wood,/area/outpost/research/hallway) +"ej" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/hallway) +"ek" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless{icon_state = "damaged5"},/area/outpost/abandoned) +"el" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/airless{icon_state = "damaged2"},/area/outpost/abandoned) +"em" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"en" = (/obj/structure/window/reinforced{dir = 5},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/wood,/area/outpost/research/medical) +"eo" = (/turf/simulated/wall/r_wall,/area/outpost/research/eva) +"ep" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/research/dock) +"eq" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access = list(65)},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/dock) +"er" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/dock) +"es" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/dock) "et" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "pwall"; dir = 5},/area/shuttle/alien/mine) "eu" = (/turf/simulated/floor/plating/airless,/turf/simulated/shuttle/wall{icon_state = "pwall"; dir = 10},/area/shuttle/alien/mine) -"ev" = (/obj/item/weapon/shard,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"ew" = (/turf/simulated/wall,/area/mine/abandoned) +"ev" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/dock) +"ew" = (/obj/structure/sign/science,/turf/simulated/wall,/area/outpost/research/dock) "ex" = (/turf/space,/area/shuttle/research/outpost) -"ey" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/machinery/requests_console{department = "Science"; departmentType = 2; name = "Science Requests Console"; pixel_x = -30; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"ez" = (/obj/structure/noticeboard/anomaly{icon_state = "nboard05"; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"eA" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"eB" = (/obj/machinery/camera{c_tag = "Research Outpost Lobby"; dir = 2; network = list("Research","SS13")},/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor{dir = 4; icon_state = "whitegreencorner"},/area/research_outpost/hallway) -"eC" = (/obj/structure/sign/science{desc = "A warning sign which reads 'MASS SPECTROMETRY'"; name = "\improper MASS SPECTROMETRY"; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "whitegreencorner"},/area/research_outpost/hallway) -"eD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/research_outpost/hallway) -"eE" = (/obj/machinery/alarm{dir = 2; pixel_y = 25},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"eF" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"eG" = (/obj/structure/closet/walllocker/emerglocker/north,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) -"eH" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/research_outpost/hallway) -"eI" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/research_outpost/hallway) -"eJ" = (/obj/structure/sign/chemistry{desc = "A warning sign which reads 'SAMPLE PREPARATION'"; name = "\improper SAMPLE PREPARATION"; pixel_y = 32},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/machinery/camera{c_tag = "Research Outpost Hallway Port"; dir = 2; network = list("Research","SS13")},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/research_outpost/hallway) -"eK" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/light/small{dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = -25; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "whitepurple"},/area/research_outpost/anomaly) -"eL" = (/obj/structure/stool,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"eM" = (/obj/structure/table,/obj/item/weapon/reagent_containers/dropper{pixel_y = -4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"eN" = (/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"eO" = (/obj/machinery/power/emitter{anchored = 1; dir = 4; state = 2},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/turf/simulated/floor{icon_state = "delivery"},/area/research_outpost/anomaly) -"eP" = (/obj/machinery/conveyor{dir = 1; id = "anolaser"},/obj/machinery/door/window/westleft{dir = 2; layer = 3.1; name = "laser testing"; req_access_txt = "65"},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/research_outpost/anomaly) -"eQ" = (/obj/structure/extinguisher_cabinet{pixel_x = -25; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 8; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) -"eR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{dir = 4; icon_state = "whiteyellow"},/area/research_outpost/hallway) -"eS" = (/turf/simulated/wall/r_wall,/area/research_outpost/power) -"eT" = (/obj/machinery/door/airlock/glass_atmos{name = "Outpost Atmospherics"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/floor/plating,/area/research_outpost/power) -"eU" = (/obj/item/stack/rods,/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/shard,/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"eV" = (/obj/item/stack/rods,/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"eW" = (/turf/simulated/floor/airless{icon_state = "damaged2"},/area/mine/abandoned) -"eX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) -"eY" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"eZ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"fa" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"fb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"fc" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"fd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"fe" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock East"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) -"ff" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/research_outpost/hallway) -"fg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/research_outpost/hallway) -"fh" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"fi" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 4; icon_state = "whitepurplecorner"},/area/research_outpost/anomaly) -"fj" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) -"fk" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) -"fl" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) -"fm" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) -"fn" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "whitepurple"},/area/research_outpost/anomaly) -"fo" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"fp" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitepurple"},/area/research_outpost/hallway) -"fq" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 4; icon_state = "whiteyellow"},/area/research_outpost/hallway) -"fr" = (/obj/machinery/power/port_gen/pacman{anchored = 1},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/light/small{dir = 1},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/turf/simulated/floor/plating,/area/research_outpost/power) -"fs" = (/obj/machinery/power/port_gen/pacman{anchored = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/sign/nosmoking_1{pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating,/area/research_outpost/power) -"ft" = (/obj/structure/sign/electricshock{pixel_x = 32},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/smes/buildable{capacity = 1e+007; charge = 1e+007; cur_coils = 2; input_attempt = 1; input_level = 500000; output_level = 500000; RCon_tag = "Research Outpost"},/turf/simulated/floor/plating,/area/research_outpost/power) -"fu" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plating,/area/research_outpost/power) -"fv" = (/obj/machinery/light/small{dir = 8},/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"fw" = (/obj/structure/transit_tube{icon_state = "N-SW"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) +"ey" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/dock) +"ez" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "research_outpost_hatch"; locked = 1; name = "Research Outpost Docking Hatch"; req_access = list(13)},/turf/simulated/floor/plating,/area/outpost/research/dock) +"eA" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall,/area/outpost/research/dock) +"eB" = (/turf/simulated/wall/r_wall,/area/outpost/research/anomaly_analysis) +"eC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/outpost/research/hallway) +"eD" = (/obj/structure/sign/deathsposal{pixel_x = 32},/obj/machinery/disposal/deliveryChute{dir = 8; name = "disposal inlet"},/obj/structure/disposalpipe/trunk{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"; nitrogen = 0.01; oxygen = 0.01},/area/outpost/research/disposal) +"eE" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area/outpost/research/disposal) +"eF" = (/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/button/driver{id = "research"; pixel_x = -24; pixel_y = -24},/turf/simulated/floor/plating,/area/outpost/research/disposal) +"eG" = (/obj/machinery/conveyor{dir = 4; id = "archgunc"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/outpost/research/disposal) +"eH" = (/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor/plating,/area/outpost/research/disposal) +"eI" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"eJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"eK" = (/obj/machinery/door/window/westleft{dir = 4; name = "Monkey Pen"; req_access = list(47)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/mob/living/carbon/human/monkey,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"eL" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/mob/living/carbon/human/monkey,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"eM" = (/obj/structure/table/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/latex,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/outpost/research/hallway) +"eN" = (/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/research/hallway) +"eO" = (/turf/simulated/floor,/area/outpost/research/hallway) +"eP" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/outpost/research/hallway) +"eQ" = (/obj/machinery/door/window/westleft{dir = 8; name = "Locker room"; opacity = 0; req_access = list(65)},/turf/simulated/floor,/area/outpost/research/hallway) +"eR" = (/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"eS" = (/obj/structure/extinguisher_cabinet{pixel_x = -25; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/outpost/research/hallway) +"eT" = (/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/outpost/abandoned) +"eU" = (/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"eV" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/outpost/abandoned) +"eW" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/outpost/abandoned) +"eX" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/airless{icon_state = "damaged3"},/area/outpost/abandoned) +"eY" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor,/area/outpost/abandoned) +"eZ" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/plating,/area/outpost/abandoned) +"fa" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plating,/area/outpost/abandoned) +"fb" = (/obj/effect/alien/weeds,/turf/simulated/floor/plating,/area/outpost/abandoned) +"fc" = (/obj/item/stack/rods,/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"fd" = (/obj/item/weapon/shard{icon_state = "small"},/obj/item/clothing/suit/space/syndicate,/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"fe" = (/obj/item/weapon/shard,/obj/item/stack/rods,/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"ff" = (/turf/simulated/floor/airless{icon_state = "damaged3"},/area/outpost/abandoned) +"fg" = (/obj/machinery/newscaster{layer = 3.3; pixel_x = 0; pixel_y = -27},/turf/simulated/floor/wood,/area/outpost/research/hallway) +"fh" = (/obj/structure/bookcase/manuals/xenoarchaeology,/turf/simulated/floor/wood,/area/outpost/research/hallway) +"fi" = (/obj/machinery/computer/reconstitutor,/turf/simulated/floor/wood,/area/outpost/research/hallway) +"fj" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/reagent_dispensers/water_cooler,/turf/simulated/floor/wood,/area/outpost/research/hallway) +"fk" = (/obj/structure/extinguisher_cabinet{pixel_x = -25; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"fl" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"fm" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"fn" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/outpost/research/disposal) +"fo" = (/obj/structure/table/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/latex,/obj/machinery/alarm{dir = 8; pixel_x = 25; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/outpost/research/hallway) +"fp" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/mob/living/carbon/human/monkey,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"fq" = (/obj/machinery/alarm{dir = 4; pixel_x = -25; pixel_y = 0},/mob/living/carbon/human/monkey,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"fr" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/outpost/research/hallway) +"fs" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor,/area/outpost/research/hallway) +"ft" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/research/hallway) +"fu" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/washing_machine,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/hallway) +"fv" = (/obj/machinery/vending/coffee,/turf/simulated/floor/wood,/area/outpost/research/hallway) +"fw" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) "fx" = (/obj/structure/lattice,/obj/item/weapon/shard{icon_state = "medium"},/turf/space,/area/space) "fy" = (/turf/simulated/floor/plating/airless,/turf/simulated/shuttle/wall{icon_state = "pwall"; dir = 6},/area/shuttle/alien/mine) -"fz" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/airless{icon_state = "damaged2"},/area/mine/abandoned) -"fA" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless{icon_state = "damaged5"},/area/mine/abandoned) -"fB" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) -"fC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"fD" = (/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"fE" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/wood,/area/research_outpost/hallway) -"fF" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/wood,/area/research_outpost/hallway) -"fG" = (/obj/structure/table,/turf/simulated/floor/wood,/area/research_outpost/hallway) -"fH" = (/obj/structure/table,/obj/item/weapon/storage/box/drinkingglasses{pixel_x = 1; pixel_y = 4},/turf/simulated/floor/wood,/area/research_outpost/hallway) -"fI" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/wood,/area/research_outpost/hallway) -"fJ" = (/turf/simulated/floor/wood,/area/research_outpost/hallway) -"fK" = (/obj/machinery/vending/cola,/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/turf/simulated/floor/wood,/area/research_outpost/hallway) -"fL" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) -"fM" = (/obj/structure/sign/science{desc = "A warning sign which reads 'ANOMALOUS MATERIALS'"; name = "\improper ANOMALOUS MATERIALS"; pixel_x = 32},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/research_outpost/hallway) -"fN" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"fO" = (/obj/machinery/firealarm{pixel_y = -24},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"fP" = (/obj/structure/table/rack,/obj/item/clothing/head/welding,/obj/item/weapon/weldingtool,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"fQ" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/item/weapon/screwdriver{pixel_y = 15},/obj/item/weapon/melee/baton/loaded,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"fR" = (/obj/machinery/light/small,/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"fS" = (/obj/machinery/camera{c_tag = "Research Outpost Anomalous Materials Lab"; dir = 8; network = list("Research","SS13")},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"fT" = (/obj/structure/sign/science{desc = "A warning sign which reads 'ANOMALOUS MATERIALS'"; name = "\improper ANOMALOUS MATERIALS"; pixel_x = -32},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 1; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) -"fU" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "whiteyellow"},/area/research_outpost/hallway) -"fV" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/engineering{name = "Outpost Power"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/power) -"fW" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/plating,/area/research_outpost/power) -"fX" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/research_outpost/power) -"fY" = (/turf/simulated/floor/plating,/area/research_outpost/power) -"fZ" = (/obj/machinery/light/small{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/research_outpost/power) -"ga" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area/research_outpost/power) -"gb" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/transit_tube{icon_state = "S-NE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"gc" = (/obj/structure/disposaloutlet{dir = 2},/obj/structure/disposalpipe/trunk{dir = 8},/obj/structure/transit_tube{icon_state = "D-NW"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"gd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"ge" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"gf" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"gg" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/airless{icon_state = "damaged2"},/area/mine/abandoned) -"gh" = (/obj/effect/decal/remains/xeno,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/mine/abandoned) -"gi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway) -"gj" = (/obj/structure/table,/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 5},/obj/item/weapon/clipboard,/obj/item/weapon/pen,/obj/item/weapon/tape_roll,/turf/simulated/floor/wood,/area/research_outpost/hallway) -"gk" = (/obj/structure/table,/obj/item/device/camera,/obj/item/weapon/stamp,/obj/item/weapon/folder,/turf/simulated/floor/wood,/area/research_outpost/hallway) -"gl" = (/obj/machinery/vending/snack,/obj/machinery/light{dir = 4},/turf/simulated/floor/wood,/area/research_outpost/hallway) -"gm" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"gn" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/research_outpost/hallway) -"go" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/research{name = "Anomalous Materials Locker Room"; req_access_txt = "65"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"gp" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Anomalous Materials"; req_access_txt = "65"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly) -"gq" = (/obj/machinery/camera{c_tag = "Research Outpost Hallway Engineering"; dir = 4; network = list("Research","SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"gr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 4; icon_state = "whiteyellowcorner"},/area/research_outpost/hallway) -"gs" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor/plating,/area/research_outpost/power) -"gt" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/research_outpost/power) -"gu" = (/obj/machinery/power/sensor{long_range = 1; name = "Powernet Sensor - Research Outpost Grid"; name_tag = "Research Outpost Grid"},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/research_outpost/power) -"gv" = (/obj/machinery/portable_atmospherics/powered/scrubber,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/research_outpost/power) -"gw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/power) -"gx" = (/obj/machinery/mass_driver{dir = 4; id = "research"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) +"fz" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/outpost/research/hallway) +"fA" = (/turf/simulated/floor/plating,/area/outpost/research/disposal) +"fB" = (/obj/machinery/conveyor_switch{id = "archgunc"},/turf/simulated/floor/plating,/area/outpost/research/disposal) +"fC" = (/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/floor/plating,/area/outpost/research/disposal) +"fD" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/disposal) +"fE" = (/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"fF" = (/obj/structure/table,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"fG" = (/obj/structure/table,/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/outpost/abandoned) +"fH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"fI" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"fJ" = (/obj/structure/bed/chair{dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/kitchen) +"fK" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 1; icon_state = "whiteyellow"},/area/outpost/research/hallway) +"fL" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{dir = 1; icon_state = "whiteyellowcorner"},/area/outpost/research/hallway) +"fM" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{dir = 4; icon_state = "whitepurple"},/area/outpost/research/hallway) +"fN" = (/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/research/anomaly_analysis) +"fO" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/outpost/research/anomaly_analysis) +"fP" = (/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor,/area/outpost/research/anomaly_analysis) +"fQ" = (/obj/machinery/artifact_harvester,/turf/simulated/floor/bluegrid,/area/outpost/research/anomaly_analysis) +"fR" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/outpost/research/anomaly_analysis) +"fS" = (/obj/machinery/artifact_scanpad,/turf/simulated/floor/bluegrid,/area/outpost/research/anomaly_analysis) +"fT" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/outpost/research/hallway) +"fU" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Temporary Storage"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/eva) +"fV" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/eva) +"fW" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"fX" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"fY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"fZ" = (/obj/machinery/light{dir = 1},/obj/structure/extinguisher_cabinet{pixel_x = -8; pixel_y = 28},/turf/simulated/floor{dir = 4; icon_state = "whiteyellowcorner"},/area/outpost/research/hallway) +"ga" = (/obj/machinery/alarm{dir = 2; pixel_y = 25},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"gb" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor,/area/outpost/research/dock) +"gc" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/research/dock) +"gd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/research/dock) +"ge" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Research Shuttle Dock"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/research/dock) +"gf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/research/dock) +"gg" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/outpost/research/dock) +"gh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/outpost/research/dock) +"gi" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_medical{name = "Medbay"; req_one_access = list(65,5)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/medical) +"gj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/medical) +"gk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/medical) +"gl" = (/obj/machinery/conveyor_switch{id = "anotempload"; name = "conveyor switch"; pixel_x = 12; pixel_y = -12},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/eva) +"gm" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/eva) +"gn" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/dock) +"go" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/airless{icon_state = "damaged5"},/area/outpost/abandoned) +"gp" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/airless{icon_state = "damaged5"},/area/outpost/abandoned) +"gq" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/outpost/abandoned) +"gr" = (/obj/machinery/door/airlock,/turf/simulated/floor,/area/outpost/abandoned) +"gs" = (/obj/structure/lattice,/obj/item/weapon/shard{icon_state = "small"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/space,/area/outpost/abandoned) +"gt" = (/obj/structure/lattice,/turf/space,/area/outpost/abandoned) +"gu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"gv" = (/obj/item/weapon/shard,/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"gw" = (/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/outpost/research/eva) +"gx" = (/obj/machinery/camera{c_tag = "Research Outpost Hallway Central"; dir = 4; network = list("Research","SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/outpost/research/hallway) "gy" = (/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) "gz" = (/obj/item/stack/rods,/obj/structure/lattice,/turf/space,/area/space) -"gA" = (/obj/item/weapon/shard,/obj/item/stack/rods,/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"gB" = (/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"gC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"gD" = (/obj/structure/table,/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/mine/abandoned) -"gE" = (/obj/structure/table,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"gF" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor,/area/mine/abandoned) -"gG" = (/obj/effect/alien/weeds,/turf/simulated/floor/plating,/area/mine/abandoned) -"gH" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plating,/area/mine/abandoned) -"gI" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/extinguisher_cabinet{pixel_x = -25; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"gJ" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"gK" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/reagent_dispensers/water_cooler,/turf/simulated/floor/wood,/area/research_outpost/hallway) -"gL" = (/obj/structure/bookcase/manuals/xenoarchaeology,/turf/simulated/floor/wood,/area/research_outpost/hallway) -"gM" = (/obj/machinery/computer/reconstitutor,/turf/simulated/floor/wood,/area/research_outpost/hallway) -"gN" = (/obj/machinery/newscaster{layer = 3.3; pixel_x = 0; pixel_y = -27},/turf/simulated/floor/wood,/area/research_outpost/hallway) -"gO" = (/obj/machinery/vending/coffee,/turf/simulated/floor/wood,/area/research_outpost/hallway) -"gP" = (/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) -"gQ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"gR" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor,/area/research_outpost/hallway) -"gS" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/research_outpost/hallway) -"gT" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/washing_machine,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway) -"gU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/research_outpost/hallway) -"gV" = (/obj/structure/table/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/latex,/obj/machinery/alarm{dir = 8; pixel_x = 25; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/research_outpost/hallway) -"gW" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/mob/living/carbon/monkey,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"gX" = (/obj/machinery/door/window/westleft{dir = 4; name = "Monkey Pen"; req_access_txt = "47"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/mob/living/carbon/monkey,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"gY" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"gZ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"ha" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/research_outpost/power) -"hb" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/research_outpost/power) -"hc" = (/obj/machinery/conveyor_switch{id = "archgunc"},/turf/simulated/floor/plating,/area/research_outpost/power) -"hd" = (/obj/machinery/portable_atmospherics/powered/scrubber,/turf/simulated/floor/plating,/area/research_outpost/power) -"he" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/power) -"hf" = (/obj/item/stack/rods,/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"hg" = (/obj/item/weapon/shard{icon_state = "small"},/obj/item/clothing/suit/space/syndicate,/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"hh" = (/turf/simulated/floor/airless{icon_state = "damaged3"},/area/mine/abandoned) -"hi" = (/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"hj" = (/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/mine/abandoned) -"hk" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/mine/abandoned) -"hl" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/mine/abandoned) -"hm" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/airless{icon_state = "damaged3"},/area/mine/abandoned) -"hn" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/plating,/area/mine/abandoned) -"ho" = (/obj/structure/transit_tube{icon_state = "N-S"},/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall,/area/research_outpost/entry) -"hp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) -"hq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) -"hr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) -"hs" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "research_outpost_hatch"; locked = 1; name = "Research Outpost Docking Hatch"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/research_outpost/entry) -"ht" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) -"hu" = (/obj/structure/sign/science,/turf/simulated/wall,/area/research_outpost/entry) -"hv" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/entry) -"hw" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access_txt = "65"},/turf/simulated/floor,/area/research_outpost/entry) -"hx" = (/obj/structure/window/reinforced{dir = 5},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/wood,/area/research_outpost/entry) -"hy" = (/obj/structure/window/reinforced{dir = 5},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/wood,/area/research_outpost/med) -"hz" = (/obj/structure/extinguisher_cabinet{pixel_x = -25; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) -"hA" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"hB" = (/obj/machinery/door/window/westleft{dir = 8; name = "Locker room"; opacity = 0; req_access_txt = "65"},/turf/simulated/floor,/area/research_outpost/hallway) -"hC" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/research_outpost/hallway) -"hD" = (/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/research_outpost/hallway) -"hE" = (/obj/structure/table/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/latex,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/research_outpost/hallway) -"hF" = (/obj/machinery/alarm{dir = 4; pixel_x = -25; pixel_y = 0},/mob/living/carbon/monkey,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"hG" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/mob/living/carbon/monkey,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"hH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"hI" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"hJ" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/machinery/portable_atmospherics/canister/sleeping_agent,/turf/simulated/floor/plating,/area/research_outpost/power) -"hK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/power) -"hL" = (/obj/machinery/driver_button{id = "research"; pixel_x = 6; pixel_y = -26},/obj/machinery/conveyor{dir = 4; id = "archgunc"},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/westleft{base_state = "right"; dir = 1; icon_state = "right"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/research_outpost/power) -"hM" = (/obj/structure/sign/deathsposal{pixel_x = 32},/obj/machinery/disposal/deliveryChute{dir = 8; name = "disposal inlet"},/obj/structure/disposalpipe/trunk{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"; nitrogen = 0.01; oxygen = 0.01},/area/research_outpost/power) -"hN" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area/research_outpost/power) -"hO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/transit_tube{icon_state = "N-SE"},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/hallway) -"hP" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/wall/r_wall,/area/research_outpost/hallway) -"hQ" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/hallway) -"hR" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/space,/area/space) +"gA" = (/obj/structure/closet/secure_closet/xenoarchaeologist{req_access = list(47)},/obj/structure/disposalpipe/segment,/obj/structure/window/reinforced,/turf/simulated/floor,/area/outpost/research/hallway) +"gB" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/closet/secure_closet/xenoarchaeologist{req_access = list(47)},/obj/structure/window/reinforced,/turf/simulated/floor,/area/outpost/research/hallway) +"gC" = (/obj/machinery/door/window/westleft{dir = 2; name = "Locker room"; opacity = 0; req_access = list(65)},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/research/hallway) +"gD" = (/obj/structure/closet/secure_closet/scientist,/obj/structure/window/reinforced,/turf/simulated/floor,/area/outpost/research/hallway) +"gE" = (/obj/structure/table/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/latex,/obj/structure/window/reinforced,/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/outpost/research/hallway) +"gF" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"gG" = (/obj/machinery/door/window/westleft{dir = 2; name = "Monkey Pen"; req_access = list(47)},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"gH" = (/obj/machinery/door/firedoor/border_only{name = "\improper Firelock South"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"gI" = (/obj/machinery/door/firedoor/border_only{name = "\improper Firelock South"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"gJ" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/maintenance{name = "Maintenance Storage"; req_one_access = list(12,65)},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/outpost/research/hallway) +"gK" = (/turf/simulated/floor{dir = 4; icon_state = "whitepurple"},/area/outpost/research/hallway) +"gL" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/anomaly_analysis) +"gM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/dock) +"gN" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "research_outpost_dock"; pixel_x = 0; pixel_y = 30; req_one_access = list(13,65); tag_door = "research_outpost_hatch"},/turf/simulated/floor{icon_state = "warningcorner"; dir = 8},/area/outpost/research/dock) +"gO" = (/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/outpost/research/dock) +"gP" = (/obj/machinery/computer/shuttle_control/research,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/outpost/research/dock) +"gQ" = (/turf/simulated/floor,/area/outpost/research/dock) +"gR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/dock) +"gS" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/outpost/research/dock) +"gT" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'VACUUM'"; icon_state = "space"; layer = 4; name = "VACUUM"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{icon_state = "warningcorner"; dir = 4},/area/outpost/research/dock) +"gU" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/medical) +"gV" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/toxin,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/medical) +"gW" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/research/dock) +"gX" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/dock) +"gY" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/outpost/research/eva) +"gZ" = (/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/outpost/research/eva) +"ha" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/firstaid/fire,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/medical) +"hb" = (/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"hc" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/remains/xeno,/turf/simulated/floor/plating,/area/outpost/abandoned) +"hd" = (/obj/effect/gibspawner/human,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/outpost/abandoned) +"he" = (/obj/effect/gibspawner/robot,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"hf" = (/obj/structure/table,/obj/machinery/alarm{dir = 1; pixel_y = -25},/turf/simulated/floor{dir = 2; icon_state = "arrival"},/area/outpost/research/dock) +"hg" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{dir = 2; icon_state = "cmo"},/area/outpost/research/dock) +"hh" = (/obj/structure/closet/emcloset,/obj/machinery/alarm{dir = 1; pixel_y = -25},/turf/simulated/floor,/area/outpost/research/dock) +"hi" = (/obj/machinery/light,/turf/simulated/floor{icon_state = "bluecorner"},/area/outpost/research/dock) +"hj" = (/obj/structure/closet/emcloset,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = -32},/turf/simulated/floor{dir = 2; icon_state = "arrival"},/area/outpost/research/dock) +"hk" = (/obj/machinery/sleep_console,/obj/machinery/light/small,/turf/simulated/floor{icon_state = "warnwhite"; dir = 5},/area/outpost/research/medical) +"hl" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/eva) +"hm" = (/obj/machinery/door/window/westleft,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/outpost/research/eva) +"hn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/outpost/research/dock) +"ho" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/structure/cable/blue,/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor,/area/outpost/research/dock) +"hp" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/camera{c_tag = "Research Outpost Medbay"; dir = 1; network = list("Research","SS13")},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/medical) +"hq" = (/obj/machinery/sleeper{dir = 1},/turf/simulated/floor{dir = 9; icon_state = "warnwhite"},/area/outpost/research/medical) +"hr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/dock) +"hs" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Long Term Storage"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/anomaly_storage) +"ht" = (/turf/simulated/wall/r_wall,/area/outpost/research/emergency_storage) +"hu" = (/turf/simulated/wall/r_wall,/area/outpost/research/isolation_monitoring) +"hv" = (/obj/machinery/door/airlock/maintenance{name = "Maintenance Storage"; req_one_access = list(12,65)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/outpost/research/emergency_storage) +"hw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/research/isolation_monitoring) +"hx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/research/isolation_monitoring) +"hy" = (/obj/structure/table,/obj/item/weapon/anobattery{pixel_x = -6; pixel_y = 2},/obj/item/weapon/anobattery{pixel_x = -2; pixel_y = -2},/obj/item/weapon/anobattery{pixel_x = 2; pixel_y = 2},/obj/item/weapon/anobattery{pixel_x = 6; pixel_y = 6},/obj/machinery/light/small{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/anomaly_analysis) +"hz" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/anomaly_analysis) +"hA" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/anomaly_analysis) +"hB" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = -32; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/research/anomaly_analysis) +"hC" = (/obj/machinery/alarm{dir = 1; pixel_y = -25},/turf/simulated/floor,/area/outpost/research/anomaly_analysis) +"hD" = (/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/outpost/research/anomaly_analysis) +"hE" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/research/isolation_monitoring) +"hF" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/research{name = "Gas filtering"; req_access = list(65)},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/outpost/research/power) +"hG" = (/turf/simulated/wall/r_wall,/area/outpost/research/power) +"hH" = (/obj/machinery/conveyor{dir = 9; id = "anotempload"},/obj/structure/plasticflaps/mining,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/outpost/research/eva) +"hI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/obj/machinery/atmospherics/pipe/simple/visible/supply,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/research/isolation_monitoring) +"hJ" = (/obj/machinery/door/airlock/research{name = "Anomaly Isolation"; req_access = list(65)},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"hK" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor/airless{icon_state = "damaged5"},/area/outpost/abandoned) +"hL" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/outpost/abandoned) +"hM" = (/obj/structure/table/rack,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/outpost/abandoned) +"hN" = (/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"hO" = (/obj/structure/table,/turf/simulated/floor/airless,/area/outpost/abandoned) +"hP" = (/obj/effect/decal/remains/human,/turf/simulated/floor/airless{icon_state = "damaged5"},/area/outpost/abandoned) +"hQ" = (/obj/effect/alien/weeds,/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"hR" = (/turf/simulated/floor/airless{icon_state = "damaged4"},/area/outpost/abandoned) "hS" = (/obj/item/weapon/shard,/obj/structure/lattice,/turf/space,/area/space) -"hT" = (/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"hU" = (/obj/effect/gibspawner/robot,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"hV" = (/obj/effect/gibspawner/human,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/mine/abandoned) -"hW" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/remains/xeno,/turf/simulated/floor/plating,/area/mine/abandoned) -"hX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) -"hY" = (/obj/machinery/computer/shuttle_control/research,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "bot"},/area/research_outpost/entry) -"hZ" = (/turf/simulated/floor,/area/research_outpost/entry) -"ia" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "research_outpost_dock"; pixel_x = 0; pixel_y = 30; req_access_txt = "0"; req_one_access_txt = "13;65"; tag_door = "research_outpost_hatch"},/turf/simulated/floor{icon_state = "warningcorner"; dir = 8},/area/research_outpost/entry) -"ib" = (/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/research_outpost/entry) -"ic" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'VACUUM'"; icon_state = "space"; layer = 4; name = "VACUUM"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{icon_state = "warningcorner"; dir = 4},/area/research_outpost/entry) -"id" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) -"ie" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/research_outpost/entry) -"if" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/entry) -"ig" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/entry) -"ih" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/toxin,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/med) -"ii" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/firstaid/fire,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/med) -"ij" = (/turf/simulated/wall/r_wall,/area/research_outpost/tempstorage) -"ik" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/research_outpost/tempstorage) -"il" = (/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/research_outpost/tempstorage) -"im" = (/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/research_outpost/tempstorage) -"in" = (/obj/machinery/camera{c_tag = "Research Outpost Hallway Central"; dir = 4; network = list("Research","SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) -"io" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/closet/secure_closet/xenoarchaeologist{req_access_txt = "47"},/obj/structure/window/reinforced,/turf/simulated/floor,/area/research_outpost/hallway) -"ip" = (/obj/structure/closet/secure_closet/xenoarchaeologist{req_access_txt = "47"},/obj/structure/disposalpipe/segment,/obj/structure/window/reinforced,/turf/simulated/floor,/area/research_outpost/hallway) -"iq" = (/obj/structure/closet/secure_closet/scientist,/obj/structure/window/reinforced,/turf/simulated/floor,/area/research_outpost/hallway) -"ir" = (/obj/machinery/door/window/westleft{dir = 2; name = "Locker room"; opacity = 0; req_access_txt = "65"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/research_outpost/hallway) -"is" = (/obj/structure/table/rack,/obj/item/clothing/suit/bio_suit/anomaly,/obj/item/clothing/head/bio_hood/anomaly,/obj/item/clothing/mask/breath,/obj/item/clothing/glasses/science,/obj/item/clothing/gloves/latex,/obj/structure/window/reinforced,/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/research_outpost/hallway) -"it" = (/obj/machinery/door/window/westleft{dir = 2; name = "Monkey Pen"; req_access_txt = "47"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"iu" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"iv" = (/obj/machinery/door/firedoor/border_only{name = "\improper Firelock South"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"iw" = (/obj/machinery/door/firedoor/border_only{name = "\improper Firelock South"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"ix" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/engineering{name = "Outpost Power"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/research_outpost/power) -"iy" = (/obj/structure/transit_tube{icon_state = "D-NE"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/research_outpost/hallway) -"iz" = (/obj/structure/transit_tube{icon_state = "E-NW"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/research_outpost/hallway) -"iA" = (/obj/structure/transit_tube/station,/obj/structure/sign/securearea{desc = "A warning sign which reads 'INTERNALS REQUIRED'."; name = "INTERNALS REQUIRED"; pixel_x = 32; pixel_y = 32},/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/research_outpost/hallway) -"iB" = (/obj/structure/transit_tube{icon_state = "W-NE"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) -"iC" = (/obj/structure/transit_tube{icon_state = "D-NW"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) -"iD" = (/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) -"iE" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/harvesting) -"iF" = (/obj/structure/transit_tube{icon_state = "D-NE"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) -"iG" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"iH" = (/obj/item/weapon/shard,/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"iI" = (/obj/structure/lattice,/obj/item/weapon/shard{icon_state = "small"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/space,/area/mine/abandoned) -"iJ" = (/obj/structure/lattice,/turf/space,/area/mine/abandoned) -"iK" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/mine/abandoned) -"iL" = (/obj/machinery/door/airlock,/turf/simulated/floor,/area/mine/abandoned) -"iM" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/airless{icon_state = "damaged5"},/area/mine/abandoned) -"iN" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/airless{icon_state = "damaged5"},/area/mine/abandoned) -"iO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/transit_tube{icon_state = "N-SE"},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) -"iP" = (/obj/structure/transit_tube{icon_state = "D-SW"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{icon_state = "bot"},/area/research_outpost/entry) -"iQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/research_outpost/entry) -"iR" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/research_outpost/entry) -"iS" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_research{name = "Research Shuttle Dock"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/research_outpost/entry) -"iT" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/research_outpost/entry) -"iU" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/entry) -"iV" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/research_outpost/entry) -"iW" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_medical{name = "Medbay"; req_access_txt = "0"; req_one_access_txt = "65;5"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/entry) -"iX" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/med) -"iY" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/med) -"iZ" = (/obj/machinery/conveyor_switch{id = "anotempload"; name = "conveyor switch"; pixel_x = 12; pixel_y = -12},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) -"ja" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) -"jb" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) -"jc" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Temporary Storage"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/hallway) -"jd" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) -"je" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"jf" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"jg" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"jh" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"ji" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"jj" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"jk" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"jl" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/alarm{dir = 2; pixel_y = 25},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"jm" = (/obj/machinery/light{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 28},/turf/simulated/floor{dir = 4; icon_state = "whiteyellowcorner"},/area/research_outpost/hallway) -"jn" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 1; icon_state = "whiteyellow"},/area/research_outpost/hallway) -"jo" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{dir = 1; icon_state = "whiteyellowcorner"},/area/research_outpost/hallway) -"jp" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"jq" = (/obj/machinery/camera{c_tag = "Research Outpost Hallway Starboard"; dir = 2; network = list("Research","SS13"); pixel_x = 24},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/unary/vent_pump/on,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"jr" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = 32; pixel_y = 0},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{dir = 4; icon_state = "whitepurple"},/area/research_outpost/hallway) -"js" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) -"jt" = (/obj/machinery/light/small{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/research_outpost/harvesting) -"ju" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor,/area/research_outpost/harvesting) -"jv" = (/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting) -"jw" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/research_outpost/harvesting) -"jx" = (/obj/machinery/artifact_scanpad,/turf/simulated/floor/bluegrid,/area/research_outpost/harvesting) -"jy" = (/obj/machinery/artifact_harvester,/turf/simulated/floor/bluegrid,/area/research_outpost/harvesting) -"jz" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"jA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"jB" = (/turf/simulated/floor/airless{icon_state = "damaged4"},/area/mine/abandoned) -"jC" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"jD" = (/obj/effect/decal/remains/xeno,/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/mine/abandoned) -"jE" = (/turf/simulated/floor/airless,/area/mine/abandoned) -"jF" = (/obj/effect/alien/weeds,/turf/simulated/floor,/area/mine/abandoned) -"jG" = (/obj/effect/decal/remains/xeno,/turf/simulated/floor/airless{icon_state = "damaged3"},/area/mine/abandoned) -"jH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"jI" = (/obj/structure/table/rack,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/mine/abandoned) -"jJ" = (/obj/structure/table/rack,/turf/simulated/floor/airless,/area/mine/abandoned) -"jK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/transit_tube{icon_state = "D-NE"},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) -"jL" = (/obj/structure/transit_tube{icon_state = "S-NW"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/research_outpost/entry) -"jM" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/research_outpost/entry) -"jN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera{c_tag = "Research Outpost Shuttle Dock"; dir = 8; network = list("Research","SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 4; icon_state = "arrival"},/area/research_outpost/entry) -"jO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) -"jP" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/entry) -"jQ" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/sign/greencross,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/entry) -"jR" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/med) -"jS" = (/obj/structure/cable,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/firealarm{dir = 4; pixel_x = 24; pixel_y = -32},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/med) -"jT" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/westleft{base_state = "right"; icon_state = "right"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/research_outpost/tempstorage) -"jU" = (/obj/structure/disposalpipe/trunk{dir = 4},/obj/machinery/disposal/deliveryChute{dir = 8; name = "disposal inlet"},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/research_outpost/tempstorage) -"jV" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/research_outpost/hallway) -"jW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) -"jX" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) -"jY" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) -"jZ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/research_outpost/hallway) -"ka" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -28},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) -"kb" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/sign/examroom{desc = "A guidance sign which reads 'ISOLATION ROOM ONE'"; name = "\improper ISOLATION ROOM ONE"; pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) -"kc" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) -"kd" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) -"ke" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/firealarm{pixel_y = -24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) -"kf" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/sign/examroom{desc = "A guidance sign which reads 'ISOLATION ROOM TWO'"; name = "\improper ISOLATION ROOM TWO"; pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) -"kg" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/sign/examroom{desc = "A guidance sign which reads 'ISOLATION ROOM THREE'"; name = "\improper ISOLATION ROOM THREE"; pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) -"kh" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) -"ki" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/research_outpost/hallway) -"kj" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) -"kk" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"kl" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/firealarm{pixel_y = -24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway) -"km" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/sign/biohazard{pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitepurplecorner"},/area/research_outpost/hallway) -"kn" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor{dir = 6; icon_state = "whitepurple"},/area/research_outpost/hallway) -"ko" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Exotic Particles Collection"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/research_outpost/harvesting) -"kp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/research_outpost/harvesting) -"kq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting) -"kr" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/external{name = "Access Airlock"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/research_outpost/harvesting) -"ks" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting) -"kt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/harvesting) -"ku" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/harvesting) -"kv" = (/obj/structure/table,/obj/item/weapon/anodevice{pixel_x = 3; pixel_y = 3},/obj/item/weapon/anodevice,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/harvesting) -"kw" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/mine/abandoned) -"kx" = (/obj/effect/decal/remains/human,/turf/simulated/floor/airless{icon_state = "damaged5"},/area/mine/abandoned) -"ky" = (/obj/effect/alien/weeds,/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"kz" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"kA" = (/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"kB" = (/obj/structure/table,/turf/simulated/floor/airless,/area/mine/abandoned) -"kC" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor/airless{icon_state = "damaged5"},/area/mine/abandoned) +"hT" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"hU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/dock) +"hV" = (/obj/machinery/camera{c_tag = "Research Outpost Shuttle Dock"; dir = 8; network = list("Research","SS13")},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 4; icon_state = "arrival"},/area/outpost/research/dock) +"hW" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/outpost/research/dock) +"hX" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/westleft{base_state = "right"; icon_state = "right"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/outpost/research/eva) +"hY" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24; pixel_y = -32},/obj/structure/cable/blue,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/medical) +"hZ" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/sign/greencross,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/medical) +"ia" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/medical) +"ib" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/research/dock) +"ic" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/outpost/research/hallway) +"id" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/outpost/research/hallway) +"ie" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/outpost/research/hallway) +"if" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -28},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 2; icon_state = "whitepurplecorner"},/area/outpost/research/hallway) +"ig" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/outpost/research/eva) +"ih" = (/obj/structure/disposalpipe/trunk{dir = 4},/obj/machinery/disposal/deliveryChute{dir = 8; name = "disposal inlet"},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 1},/area/outpost/research/eva) +"ii" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/outpost/research/hallway) +"ij" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{dir = 5; icon_state = "whitehall"},/area/outpost/research/hallway) +"ik" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/outpost/research/hallway) +"il" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/outpost/research/hallway) +"im" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/outpost/research/hallway) +"in" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/firealarm{pixel_y = -24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"io" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/sign/biohazard{pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 2; icon_state = "whitepurplecorner"},/area/outpost/research/hallway) +"ip" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{dir = 6; icon_state = "whitepurple"},/area/outpost/research/hallway) +"iq" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Exotic Particles Collection"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/research/anomaly_analysis) +"ir" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/outpost/research/hallway) +"is" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/outpost/research/hallway) +"it" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 8; icon_state = "whitepurplecorner"},/area/outpost/research/hallway) +"iu" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"iv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/anomaly_analysis) +"iw" = (/obj/structure/table,/obj/item/weapon/anodevice{pixel_x = 3; pixel_y = 3},/obj/item/weapon/anodevice,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/anomaly_analysis) +"ix" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/outpost/research/anomaly_analysis) +"iy" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/research/anomaly_analysis) +"iz" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/external{name = "Access Airlock"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/research/anomaly_analysis) +"iA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/research/anomaly_analysis) +"iB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"iC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"iD" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"iE" = (/obj/structure/table/rack,/turf/simulated/floor/airless,/area/outpost/abandoned) +"iF" = (/turf/simulated/floor/airless,/area/outpost/abandoned) +"iG" = (/obj/effect/decal/remains/xeno,/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/outpost/abandoned) +"iH" = (/obj/effect/decal/remains/xeno,/turf/simulated/floor/airless{icon_state = "damaged3"},/area/outpost/abandoned) +"iI" = (/obj/effect/alien/weeds,/turf/simulated/floor,/area/outpost/abandoned) +"iJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/hallway) +"iK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/hallway) +"iL" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/hallway) +"iM" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/hallway) +"iN" = (/obj/structure/reagent_dispensers/fueltank,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor/plating,/area/outpost/research/chemistry) +"iO" = (/obj/structure/closet/hydrant{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating,/area/outpost/research/chemistry) +"iP" = (/obj/structure/table,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/cell,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/outpost/research/chemistry) +"iQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/outpost/research/hallway) +"iR" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/outpost/research/hallway) +"iS" = (/obj/structure/reagent_dispensers/watertank,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/outpost/research/chemistry) +"iT" = (/turf/simulated/floor/plating,/area/outpost/research/chemistry) +"iU" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/outpost/research/chemistry) +"iV" = (/turf/simulated/wall,/area/outpost/research/chemistry) +"iW" = (/obj/structure/table,/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/outpost/research/chemistry) +"iX" = (/obj/machinery/hologram/holopad,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/kitchen) +"iY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/camera/autoname/research_outpost{dir = 4},/turf/simulated/floor,/area/outpost/research/hallway) +"iZ" = (/obj/structure/bed,/obj/item/weapon/bedsheet/brown,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor/carpet,/area/outpost/research/hallway) +"ja" = (/obj/machinery/door_control{id = "rdorm2"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = -25; pixel_y = 0; specialfunctions = 4},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/carpet,/area/outpost/research/hallway) +"jb" = (/obj/structure/table/rack,/obj/item/stack/sheet/metal{amount = 50; pixel_x = 5; pixel_y = 5},/obj/item/stack/sheet/glass{amount = 50},/obj/item/weapon/storage/belt/utility{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/storage/toolbox/emergency{pixel_x = 5; pixel_y = 5},/turf/simulated/floor/plating,/area/outpost/research/chemistry) +"jc" = (/obj/structure/table,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/carpet,/area/outpost/research/hallway) +"jd" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/research/chemistry) +"je" = (/obj/machinery/camera/autoname/research_outpost{dir = 8},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/outpost/research/kitchen) +"jf" = (/obj/machinery/door_control{id = "rddorm1"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 25; pixel_y = 0; specialfunctions = 4},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/carpet,/area/outpost/research/hallway) +"jg" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor,/area/outpost/research/chemistry) +"jh" = (/obj/machinery/light/small,/obj/structure/closet/walllocker/emerglocker/north{dir = 1; pixel_y = -32},/turf/simulated/floor/plating,/area/outpost/research/chemistry) +"ji" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "rdorm2"; name = "Dorm 2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "carpet"},/area/outpost/research/hallway) +"jj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/outpost/research/hallway) +"jk" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/outpost/research/hallway) +"jl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/research/hallway) +"jm" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/outpost/research/hallway) +"jn" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock{id_tag = "rddorm1"; name = "Dorm 1"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "carpet"},/area/outpost/research/hallway) +"jo" = (/obj/structure/table,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor/carpet,/area/outpost/research/hallway) +"jp" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/shovel/spade,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/minihoe,/obj/item/weapon/reagent_containers/spray/plantbgone{pixel_x = 13; pixel_y = 5},/obj/item/weedkiller/triclopyr,/obj/item/weapon/reagent_containers/glass/fertilizer/ez,/turf/simulated/floor/plating,/area/outpost/research/chemistry) +"jq" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"jr" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/maintenance{name = "Auxiliary Storage"; req_one_access = list(65,12)},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/chemistry) +"js" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"jt" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"ju" = (/obj/structure/disposalpipe/junction/yjunction,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"jv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_north) +"jw" = (/obj/machinery/mineral/output,/obj/machinery/conveyor{dir = 4; id = "mining_north"},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jx" = (/obj/structure/disposalpipe/trunk{dir = 8},/obj/machinery/disposal/deliveryChute{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jy" = (/obj/machinery/mineral/input,/obj/machinery/conveyor{backwards = 2; dir = 2; forwards = 1; id = "mining_north"},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jz" = (/obj/machinery/mineral/unloading_machine{icon_state = "unloader-corner"},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jA" = (/obj/effect/decal/cleanable/dirt,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jB" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{dir = 8; icon_state = "loadingarea"},/area/outpost/mining_north) +"jC" = (/obj/item/weapon/table_parts,/obj/structure/table/rack,/obj/item/stack/sheet/glass/reinforced{amount = 8},/obj/item/stack/rods{amount = 6},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jD" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/outpost/mining_north) +"jE" = (/obj/structure/girder,/turf/simulated/floor/plating,/area/outpost/mining_north) +"jF" = (/turf/simulated/wall,/area/outpost/mining_north) +"jG" = (/obj/item/weapon/shovel,/obj/item/weapon/pickaxe,/turf/simulated/floor/plating,/area/outpost/mining_north) +"jH" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"jI" = (/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/camera{c_tag = "North Outpost"; dir = 8; network = list("MINE")},/obj/effect/decal/cleanable/blood/oil,/obj/structure/cable,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jJ" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jK" = (/obj/machinery/conveyor_switch{id = "mining_north"; pixel_x = -5},/obj/effect/decal/cleanable/dirt,/obj/machinery/light{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jL" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/outpost/mining_north) +"jM" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/outpost/mining_north) +"jN" = (/obj/structure/closet/walllocker/emerglocker/south,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHEAST)"},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jO" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_north_outpost_outer"; locked = 1; name = "Mining External Access"; req_access = list(10,13)},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jP" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_north_outpost_inner"; locked = 1; name = "Mining External Access"},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jQ" = (/obj/machinery/atmospherics/pipe/manifold/hidden,/obj/effect/decal/cleanable/dirt,/obj/machinery/light/small,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jR" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plating,/area/outpost/mining_north) +"jS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"jT" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plating,/area/outpost/mining_north) +"jU" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jV" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "mining_north_outpost_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_one_access = list(13,54)},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) +"jW" = (/obj/machinery/door/airlock/maintenance{name = "Mining Station Maintenance"; req_access = list(54)},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/outpost/mining_north) +"jX" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_north) +"jY" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "mining_north_outpost_sensor"; pixel_x = 0; pixel_y = 25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_north_outpost_pump"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"jZ" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"ka" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/camera{c_tag = "North Outpost - Airlock"; dir = 2; network = list("MINE")},/turf/simulated/floor/plating,/area/outpost/mining_north) +"kb" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/plating,/area/outpost/mining_north) +"kc" = (/obj/effect/decal/cleanable/cobweb,/obj/item/stack/sheet/metal{amount = 10},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/clothing/glasses/meson,/obj/item/weapon/storage/box/lights/mixed,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/plating,/area/outpost/mining_north) +"kd" = (/obj/structure/table,/obj/effect/decal/cleanable/cobweb2,/obj/machinery/microwave{pixel_y = 6},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"ke" = (/obj/machinery/recharge_station,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"kf" = (/obj/structure/bed/chair,/obj/effect/decal/cleanable/dirt,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"kg" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/outpost/mining_north) +"kh" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"ki" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"kj" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) +"kk" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored) +"kl" = (/obj/structure/plasticflaps/mining,/obj/machinery/conveyor{backwards = 2; dir = 2; forwards = 1; id = "mining_north"},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"km" = (/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"kn" = (/obj/machinery/atmospherics/valve/digital/open,/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"ko" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'MOVING PARTS'."; name = "\improper MOVING PARTS"; pixel_y = 32},/turf/simulated/wall/r_wall,/area/outpost/research/power) +"kp" = (/obj/machinery/atmospherics/pipe/simple/visible/supply{tag = "icon-intact-supply (NORTHEAST)"; icon_state = "intact-supply"; dir = 5},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{tag = "icon-intact-scrubbers (NORTHEAST)"; icon_state = "intact-scrubbers"; dir = 5},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/power) +"kq" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "mining_north_outpost_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = 25; req_one_access = list(13,54)},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"kr" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/obj/machinery/light,/turf/simulated/floor/wood,/area/outpost/research/kitchen) +"ks" = (/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{tag = "icon-intact-scrubbers (SOUTHWEST)"; icon_state = "intact-scrubbers"; dir = 10},/turf/simulated/floor,/area/outpost/research/power) +"kt" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"ku" = (/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/research/isolation_monitoring) +"kv" = (/obj/machinery/atmospherics/valve/digital/open,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"kw" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"kx" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"ky" = (/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"kz" = (/obj/machinery/atmospherics/valve/digital/open,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "delivery"},/area/outpost/research/isolation_monitoring) +"kA" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/outpost/research/isolation_monitoring) +"kB" = (/turf/simulated/wall,/area/outpost/research/eva) +"kC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/eva) "kD" = (/turf/simulated/wall,/area/mine/unexplored) "kE" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'INTERNALS REQUIRED'."; name = "INTERNALS REQUIRED"; pixel_x = -32; pixel_y = 0},/turf/space,/area/space) -"kF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) -"kG" = (/obj/structure/transit_tube/station{icon_state = "closed"; dir = 4},/obj/structure/transit_tube_pod,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/research_outpost/entry) -"kH" = (/obj/machinery/light,/turf/simulated/floor{icon_state = "bluecorner"},/area/research_outpost/entry) -"kI" = (/obj/structure/closet/emcloset,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = -32},/turf/simulated/floor{dir = 2; icon_state = "arrival"},/area/research_outpost/entry) -"kJ" = (/obj/structure/table,/obj/machinery/alarm{dir = 1; pixel_y = -25},/turf/simulated/floor{dir = 2; icon_state = "arrival"},/area/research_outpost/entry) -"kK" = (/obj/structure/cable,/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{dir = 2; icon_state = "cmo"},/area/research_outpost/entry) -"kL" = (/obj/structure/closet/emcloset,/obj/machinery/alarm{dir = 1; pixel_y = -25},/turf/simulated/floor,/area/research_outpost/entry) -"kM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/research_outpost/entry) -"kN" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/research_outpost/entry) -"kO" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/camera{c_tag = "Research Outpost Medbay"; dir = 1; network = list("Research","SS13")},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/entry) -"kP" = (/obj/machinery/sleeper{dir = 1},/turf/simulated/floor{dir = 9; icon_state = "warnwhite"},/area/research_outpost/med) -"kQ" = (/obj/machinery/sleep_console,/obj/machinery/light/small,/turf/simulated/floor{icon_state = "warnwhite"; dir = 5},/area/research_outpost/med) -"kR" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) -"kS" = (/obj/machinery/door/window/westleft,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/research_outpost/tempstorage) -"kT" = (/obj/machinery/conveyor{dir = 9; id = "anotempload"},/obj/structure/plasticflaps/mining,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/research_outpost/tempstorage) -"kU" = (/turf/simulated/wall/r_wall,/area/research_outpost/maint) -"kV" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/airlock/research{name = "Gas filtering"; req_access_txt = "65"},/turf/simulated/floor/plating,/area/research_outpost/hallway) -"kW" = (/turf/simulated/wall/r_wall,/area/research_outpost/iso1_access) -"kX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Isolation room one"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/iso1_access) -"kY" = (/turf/simulated/wall/r_wall,/area/research_outpost/iso2_access) -"kZ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Isolation room two"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/iso2_access) -"la" = (/turf/simulated/wall/r_wall,/area/research_outpost/iso3_access) -"lb" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Isolation Room Three"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/iso3_access) -"lc" = (/obj/machinery/door/airlock/maintenance{name = "Maintenance Storage"; req_access_txt = "0"; req_one_access_txt = "12;65"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/research_outpost/hallway) -"ld" = (/turf/simulated/wall/r_wall,/area/research_outpost/longtermstorage) -"le" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Long Term Storage"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage) -"lf" = (/obj/machinery/alarm{dir = 1; pixel_y = -25},/turf/simulated/floor,/area/research_outpost/harvesting) -"lg" = (/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/research_outpost/harvesting) -"lh" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; name = "RADIOACTIVE AREA"; pixel_x = -32; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting) -"li" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/harvesting) -"lj" = (/obj/structure/table,/obj/item/weapon/anobattery{pixel_x = -6; pixel_y = 2},/obj/item/weapon/anobattery{pixel_x = -2; pixel_y = -2},/obj/item/weapon/anobattery{pixel_x = 2; pixel_y = 2},/obj/item/weapon/anobattery{pixel_x = 6; pixel_y = 6},/obj/machinery/light/small{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/harvesting) -"lk" = (/obj/item/weapon/shard,/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/mine/abandoned) -"ll" = (/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/airless,/area/mine/abandoned) -"lm" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless{icon_state = "damaged3"},/area/mine/abandoned) -"ln" = (/obj/structure/transit_tube{icon_state = "D-SE"},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"lo" = (/obj/structure/transit_tube{icon_state = "E-SW"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"lp" = (/obj/structure/transit_tube{icon_state = "W-SE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"lq" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall,/area/research_outpost/entry) -"lr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/transit_tube{icon_state = "N-SW"},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/entry) -"ls" = (/turf/simulated/wall,/area/research_outpost/entry) -"lt" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_mining{name = "Expedition Prep"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/entry) -"lu" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Temporary Storage Loading"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/tempstorage) -"lv" = (/obj/machinery/conveyor{dir = 2; id = "anotempload"},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/research_outpost/maint) -"lw" = (/obj/machinery/conveyor{dir = 5; id = "anosample"},/obj/machinery/light/small{dir = 1},/obj/structure/sign/securearea{desc = "A warning sign which reads 'MOVING PARTS'."; name = "\improper MOVING PARTS"; pixel_y = 32},/turf/simulated/floor/plating,/area/research_outpost/maint) -"lx" = (/obj/machinery/disposal/deliveryChute{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/disposalpipe/trunk,/turf/simulated/floor/plating,/area/research_outpost/maint) -"ly" = (/turf/simulated/wall/r_wall,/area/research_outpost/filtering) -"lz" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/research_outpost/filtering) -"lA" = (/obj/structure/cable,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/turf/simulated/floor,/area/research_outpost/filtering) -"lB" = (/obj/structure/table,/obj/machinery/computer/atmoscontrol/laptop{monitored_alarm_ids = list("isolation_one"); req_access = null; req_one_access = list(47,24,11)},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor,/area/research_outpost/iso1_access) -"lC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/research_outpost/iso1_access) -"lD" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/alarm/isolation{pixel_y = 24},/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister,/turf/simulated/floor,/area/research_outpost/iso1_access) -"lE" = (/obj/structure/table,/obj/machinery/computer/atmoscontrol/laptop{monitored_alarm_ids = list("isolation_two"); req_access = null; req_one_access = list(47,24,11)},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor,/area/research_outpost/iso2_access) -"lF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/research_outpost/iso2_access) -"lG" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/alarm/isolation{pixel_y = 24},/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister,/turf/simulated/floor,/area/research_outpost/iso2_access) -"lH" = (/obj/structure/table,/obj/machinery/computer/atmoscontrol/laptop{monitored_alarm_ids = list("isolation_three"); req_access = null; req_one_access = list(47,24,11)},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor,/area/research_outpost/iso3_access) -"lI" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/research_outpost/iso3_access) -"lJ" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/alarm/isolation{pixel_y = 24},/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister,/turf/simulated/floor,/area/research_outpost/iso3_access) -"lK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/research_outpost/maintstore2) -"lL" = (/obj/structure/stool/bed,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/plating,/area/research_outpost/maintstore2) -"lM" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage) -"lN" = (/obj/structure/sign/nosmoking_2{pixel_y = -32},/obj/machinery/camera{c_tag = "Research Outpost Exotic Particles Lab"; dir = 4; network = list("Research","SS13")},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting) -"lO" = (/obj/machinery/alarm{dir = 1; pixel_y = -24},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/research_outpost/harvesting) -"lP" = (/obj/machinery/artifact_scanpad,/obj/machinery/light/small,/turf/simulated/floor/bluegrid,/area/research_outpost/harvesting) -"lQ" = (/obj/machinery/portable_atmospherics/hydroponics{closed_system = 1; name = "isolation tray"},/turf/simulated/floor{icon_state = "dark"},/area/mine/abandoned) -"lR" = (/obj/item/weapon/table_parts,/turf/simulated/floor/airless,/area/mine/abandoned) -"lS" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/airless{icon_state = "damaged4"},/area/mine/abandoned) -"lT" = (/obj/effect/decal/remains/human,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"lU" = (/obj/structure/transit_tube,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 10},/area/mine/explored) -"lV" = (/obj/structure/transit_tube/station{dir = 2; icon_state = "closed"},/obj/structure/sign/securearea{desc = "A warning sign which reads 'VACUUM'"; icon_state = "space"; layer = 4; name = "VACUUM"; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 6},/area/mine/explored) -"lW" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor/airless{icon_state = "damaged4"},/area/mine/abandoned) -"lX" = (/obj/structure/transit_tube/station{dir = 8; icon_state = "closed"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) -"lY" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor,/area/mine/abandoned) -"lZ" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/airless,/area/mine/abandoned) -"ma" = (/obj/structure/transit_tube{icon_state = "S-NE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"mb" = (/obj/structure/transit_tube{icon_state = "D-NW"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"mc" = (/obj/structure/transit_tube{icon_state = "E-NW"},/obj/structure/lattice,/turf/space,/area/space) -"md" = (/turf/simulated/wall,/area/research_outpost/gearstore) -"me" = (/obj/structure/closet/excavation,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/research_outpost/gearstore) -"mf" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/research_outpost/gearstore) -"mg" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/archaeology,/obj/item/clothing/suit/space/anomaly,/obj/item/clothing/head/helmet/space/anomaly,/obj/item/clothing/mask/breath,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor,/area/research_outpost/gearstore) -"mh" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/gearstore) -"mi" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/research_outpost/gearstore) -"mj" = (/obj/machinery/light{dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/alarm{pixel_y = 24},/turf/simulated/floor,/area/research_outpost/gearstore) -"mk" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/camera{c_tag = "Research Outpost Expedition Prep"; dir = 2; network = list("Research","SS13")},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = 22},/turf/simulated/floor,/area/research_outpost/gearstore) -"ml" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_mining{name = "Loading area"; req_access_txt = "65"; req_one_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/research_outpost/tempstorage) -"mm" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor,/area/research_outpost/tempstorage) -"mn" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/research_outpost/tempstorage) -"mo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/research_outpost/tempstorage) -"mp" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;65"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/research_outpost/maint) -"mq" = (/obj/machinery/conveyor{dir = 2; id = "anotempload"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/research_outpost/maint) -"mr" = (/obj/machinery/conveyor{dir = 1; id = "anosample"},/turf/simulated/floor/plating,/area/research_outpost/maint) -"ms" = (/obj/machinery/conveyor_switch{id = "anosample"; pixel_x = -8; pixel_y = 8},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/research_outpost/maint) -"mt" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/maintenance{req_access_txt = "0"; req_one_access_txt = "12;65"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"; nitrogen = 0.01; oxygen = 0.01},/area/research_outpost/filtering) -"mu" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/research_outpost/filtering) -"mv" = (/obj/machinery/computer/security/telescreen{desc = "Used for watching the isolation room cameras."; layer = 4; name = "Isolation Room Telescreen"; network = list("Anomaly Isolation"); pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/table,/obj/machinery/computer/atmoscontrol/laptop{monitored_alarm_ids = list("isolation_one","isolation_two","isolation_three"); req_access = null; req_one_access = list(47,24,11)},/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor,/area/research_outpost/filtering) -"mw" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/computer/security/telescreen{desc = "Used for watching the isolation room cameras."; layer = 4; name = "Isolation Room Telescreen"; network = list("Anomaly Isolation"); pixel_x = -32; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/research_outpost/iso1_access) -"mx" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/research_outpost/iso1_access) -"my" = (/obj/machinery/camera{c_tag = "Isolation Room Access One"; dir = 8; network = list("Research")},/obj/machinery/atmospherics/binary/pump{dir = 1; name = "Supply drain"},/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor,/area/research_outpost/iso1_access) -"mz" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/computer/security/telescreen{desc = "Used for watching the isolation room cameras."; layer = 4; name = "Isolation Room Telescreen"; network = list("Anomaly Isolation"); pixel_x = -32; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/research_outpost/iso2_access) -"mA" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/research_outpost/iso2_access) -"mB" = (/obj/machinery/camera{c_tag = "Isolation Room Access Two"; dir = 8; network = list("Research")},/obj/machinery/atmospherics/binary/pump{dir = 1; name = "Supply drain"},/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor,/area/research_outpost/iso2_access) -"mC" = (/obj/structure/stool/bed/chair{dir = 1},/obj/machinery/computer/security/telescreen{desc = "Used for watching the isolation room cameras."; layer = 4; name = "Isolation Room Telescreen"; network = list("Anomaly Isolation"); pixel_x = -32; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/research_outpost/iso3_access) -"mD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/research_outpost/iso3_access) -"mE" = (/obj/machinery/camera{c_tag = "Isolation Room Access Three"; dir = 8; network = list("Research")},/obj/machinery/atmospherics/binary/pump{dir = 1; name = "Supply drain"},/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor,/area/research_outpost/iso3_access) -"mF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/closet/walllocker/emerglocker/west,/turf/simulated/floor/plating,/area/research_outpost/maintstore2) -"mG" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/research_outpost/maintstore2) -"mH" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage) -"mI" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage) -"mJ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage) -"mK" = (/obj/structure/disposaloutlet{dir = 2},/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor,/area/research_outpost/longtermstorage) -"mL" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/harvesting) -"mM" = (/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/airless{icon_state = "damaged5"},/area/mine/abandoned) -"mN" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/airless{icon_state = "damaged2"},/area/mine/abandoned) -"mO" = (/obj/effect/decal/remains/xeno,/turf/simulated/floor,/area/mine/abandoned) -"mP" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless,/area/mine/abandoned) +"kF" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/eva) +"kG" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/eva) +"kH" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"kI" = (/obj/machinery/disposal/deliveryChute{dir = 1},/obj/structure/disposalpipe/trunk,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/research/eva) +"kJ" = (/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/outpost/abandoned) +"kK" = (/obj/structure/table/rack,/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/outpost/abandoned) +"kL" = (/obj/item/weapon/table_parts,/turf/simulated/floor/airless,/area/outpost/abandoned) +"kM" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/airless{icon_state = "damaged4"},/area/outpost/abandoned) +"kN" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"kO" = (/obj/effect/decal/remains/human,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"kP" = (/obj/effect/alien/resin,/turf/simulated/floor/airless{icon_state = "floorgrime"},/area/outpost/abandoned) +"kQ" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "mining_north_outpost_airlock"; pixel_x = 0; pixel_y = 25; tag_airpump = "mining_north_outpost_pump"; tag_chamber_sensor = "mining_north_outpost_sensor"; tag_exterior_door = "mining_north_outpost_outer"; tag_interior_door = "mining_north_outpost_inner"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_north_outpost_pump"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_north) +"kR" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'MOVING PARTS'."; name = "\improper MOVING PARTS"; pixel_y = 32},/obj/machinery/conveyor_switch{id = "mining_north"; pixel_x = -5},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored) +"kS" = (/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/obj/structure/cable/blue,/obj/machinery/power/sensor{long_range = 1; name_tag = "Research Outpost"},/turf/simulated/floor,/area/outpost/research/power) +"kT" = (/obj/machinery/atmospherics/pipe/simple/visible/universal,/turf/simulated/floor,/area/outpost/research/power) +"kU" = (/turf/simulated/wall/r_wall,/area/outpost/research/isolation_a) +"kV" = (/obj/machinery/door_control{id = "riso1"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = -25; pixel_y = 0; specialfunctions = 4},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"kW" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plating,/area/outpost/research/isolation_a) +"kX" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/outpost/research/isolation_a) +"kY" = (/obj/machinery/door_control{id = "riso2"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 0; pixel_y = -25; specialfunctions = 4},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"kZ" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plating,/area/outpost/research/isolation_b) +"la" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/outpost/research/isolation_b) +"lb" = (/turf/simulated/wall/r_wall,/area/outpost/research/isolation_c) +"lc" = (/obj/machinery/door_control{id = "riso3"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 0; pixel_y = -25; specialfunctions = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"ld" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/outpost/research/isolation_c) +"le" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plating,/area/outpost/research/isolation_c) +"lf" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "research_pump"},/obj/structure/closet/walllocker/emerglocker/east,/turf/simulated/floor,/area/outpost/research/eva) +"lg" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden,/turf/simulated/floor,/area/outpost/research/eva) +"lh" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "research_inner"; locked = 1; name = "Research Outpost External Access"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/outpost/research/eva) +"li" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/disposalpipe/segment,/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/outpost/research/eva) +"lj" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor/airless{icon_state = "damaged4"},/area/outpost/abandoned) +"lk" = (/obj/structure/girder/displaced,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/outpost/abandoned) +"ll" = (/turf/simulated/floor,/area/outpost/research/eva) +"lm" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/structure/dispenser/oxygen,/turf/simulated/floor,/area/outpost/research/eva) +"ln" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/eva) +"lo" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/research/eva) +"lp" = (/obj/machinery/mineral/unloading_machine,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/research/eva) +"lq" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/outpost/research/eva) +"lr" = (/obj/machinery/conveyor_switch{id = "anotempload"; name = "conveyor switch"; pixel_x = 0; pixel_y = 0; req_access = list(65)},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) +"ls" = (/obj/structure/table,/obj/item/weapon/storage/box/excavation,/obj/item/weapon/pickaxe,/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/obj/item/weapon/wrench,/obj/item/device/measuring_tape,/obj/item/stack/flag/yellow,/turf/simulated/floor,/area/outpost/research/eva) +"lt" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; icon_state = "intact"; tag = "icon-intact-f (SOUTHWEST)"},/turf/simulated/floor,/area/outpost/research/eva) +"lu" = (/turf/simulated/wall/r_wall,/area/outpost/research/anomaly_storage) +"lv" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/gloves{pixel_x = 4; pixel_y = 5},/obj/item/weapon/storage/box/samplebags{pixel_x = 3; pixel_y = -3},/obj/item/weapon/storage/toolbox/emergency{pixel_x = 5; pixel_y = 5},/turf/simulated/floor/plating,/area/outpost/research/emergency_storage) +"lw" = (/obj/structure/closet/hydrant{pixel_x = -32},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/plating,/area/outpost/research/emergency_storage) +"lx" = (/obj/machinery/atmospherics/unary/heater{dir = 4},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"ly" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera/autoname/research_outpost{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"lz" = (/obj/machinery/atmospherics/unary/vent_pump/on,/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/obj/machinery/camera/autoname/research_outpost,/turf/simulated/floor{icon_state = "white"},/area/outpost/research/hallway) +"lA" = (/obj/machinery/conveyor_switch{id = "anosample"; req_access = list(65)},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) +"lB" = (/obj/machinery/power/emitter,/turf/simulated/floor{icon_state = "delivery"},/area/outpost/research/isolation_monitoring) +"lC" = (/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/outpost/research/isolation_monitoring) +"lD" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"lE" = (/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/research/isolation_monitoring) +"lF" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"lG" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"lH" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/airless,/area/outpost/abandoned) +"lI" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless,/area/outpost/abandoned) +"lJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/outpost/abandoned) +"lK" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/outpost/abandoned) +"lL" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor,/area/outpost/abandoned) +"lM" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor{icon_state = "dark"},/area/outpost/abandoned) +"lN" = (/obj/effect/decal/remains/human,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"lO" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/research/eva) +"lP" = (/obj/machinery/floodlight,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/outpost/research/eva) +"lQ" = (/obj/machinery/floodlight,/turf/simulated/floor,/area/outpost/research/eva) +"lR" = (/obj/machinery/suspension_gen,/turf/simulated/floor,/area/outpost/research/eva) +"lS" = (/obj/machinery/conveyor{dir = 2; id = "anominerals"},/obj/machinery/mineral/output,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/research/eva) +"lT" = (/obj/structure/table,/obj/item/weapon/storage/box/excavation,/obj/item/weapon/pickaxe,/obj/item/weapon/wrench,/obj/item/device/measuring_tape,/obj/item/stack/flag/green,/turf/simulated/floor,/area/outpost/research/eva) +"lU" = (/obj/machinery/door/airlock/external{id_tag = "riso1"; name = "Access Airlock"; req_access = list(65)},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/isolation_a) +"lV" = (/obj/machinery/door/airlock/external{id_tag = "riso2"; name = "Access Airlock"; req_access = list(65)},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/isolation_b) +"lW" = (/obj/machinery/atmospherics/unary/freezer{dir = 4; icon_state = "freezer"},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"lX" = (/obj/machinery/door/airlock/external{id_tag = "riso3"; name = "Access Airlock"; req_access = list(65)},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/isolation_c) +"lY" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{tag = "icon-map (NORTH)"; icon_state = "map"; dir = 1},/turf/simulated/floor{icon_state = "delivery"},/area/outpost/research/isolation_monitoring) +"lZ" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{tag = "icon-intact (WEST)"; icon_state = "intact"; dir = 8},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/outpost/research/isolation_monitoring) +"ma" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{tag = "icon-intact (WEST)"; icon_state = "intact"; dir = 8},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mb" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow{tag = "icon-map (NORTH)"; icon_state = "map"; dir = 1},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mc" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow,/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"md" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{tag = "icon-intact (WEST)"; icon_state = "intact"; dir = 8},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"me" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{tag = "icon-intact (WEST)"; icon_state = "intact"; dir = 8},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/research/isolation_monitoring) +"mf" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/lights/bulbs{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/box/lights/tubes{pixel_x = -5; pixel_y = 5},/obj/item/weapon/storage/box/lights/mixed,/obj/machinery/light/small,/turf/simulated/floor/plating,/area/outpost/research/emergency_storage) +"mg" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mh" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mi" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor/plating,/area/outpost/research/emergency_storage) +"mj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/outpost/abandoned) +"mk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/shard,/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"ml" = (/obj/machinery/light/small{dir = 8},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "research_pump"; tag_exterior_door = "research_outer"; frequency = 1379; id_tag = "research_airlock"; tag_interior_door = "research_inner"; pixel_x = -25; pixel_y = 0; tag_chamber_sensor = "research_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "research_pump"},/turf/simulated/floor,/area/outpost/research/eva) +"mm" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless{icon_state = "damaged4"},/area/outpost/abandoned) +"mn" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"mo" = (/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/outpost/research/anomaly_storage) +"mp" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/anomaly_storage) +"mq" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/outpost/research/emergency_storage) +"mr" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/camera/autoname/research_outpost{dir = 8},/turf/simulated/floor,/area/outpost/research/chemistry) +"ms" = (/obj/structure/table,/obj/item/weapon/folder,/obj/item/device/camera,/obj/item/weapon/pen,/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mt" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/anomaly_storage) +"mu" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/outpost/research/emergency_storage) +"mv" = (/obj/machinery/atmospherics/binary/pump{dir = 8},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mw" = (/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mx" = (/obj/machinery/atmospherics/binary/pump{dir = 4},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"my" = (/obj/structure/table,/obj/item/clothing/gloves/latex,/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mz" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/door/window{dir = 4; name = "Air Tank Access"; req_one_access = list(47,10,24)},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/outpost/research/eva) +"mA" = (/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/obj/machinery/atmospherics/pipe/manifold/visible/supply,/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mB" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mC" = (/obj/structure/plasticflaps/mining,/obj/machinery/conveyor{dir = 2; id = "anotempload"},/turf/simulated/floor/plating,/area/outpost/research/eva) +"mD" = (/obj/machinery/conveyor{dir = 1; id = "anosample"},/obj/structure/plasticflaps/mining,/turf/simulated/floor/plating,/area/outpost/research/eva) +"mE" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mF" = (/obj/machinery/atmospherics/pipe/simple/visible/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{dir = 4},/obj/machinery/camera/autoname/research_outpost,/turf/simulated/floor,/area/outpost/research/power) +"mG" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mH" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/research/eva) +"mI" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/outpost/research/eva) +"mJ" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor,/area/outpost/research/eva) +"mK" = (/obj/machinery/conveyor_switch/oneway{dir = 2; id = "anominerals"; pixel_y = 0},/obj/structure/sign/securearea{desc = "A warning sign which reads 'MOVING PARTS'."; name = "\improper MOVING PARTS"; pixel_y = -32},/turf/simulated/floor,/area/outpost/research/eva) +"mL" = (/obj/structure/closet/excavation,/turf/simulated/floor,/area/outpost/research/eva) +"mM" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/archaeology,/obj/item/clothing/suit/space/anomaly,/obj/item/clothing/head/helmet/space/anomaly,/obj/item/clothing/mask/breath,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/outpost/research/eva) +"mN" = (/obj/effect/decal/remains/xeno,/turf/simulated/floor,/area/outpost/abandoned) +"mO" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor/airless,/area/outpost/abandoned) +"mP" = (/obj/machinery/portable_atmospherics/hydroponics{closed_system = 1; name = "isolation tray"},/turf/simulated/floor{icon_state = "dark"},/area/outpost/abandoned) "mQ" = (/obj/structure/ore_box,/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) "mR" = (/turf/simulated/wall,/area/mine/explored) -"mS" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/wall,/area/mine/explored) -"mT" = (/obj/structure/closet/excavation,/turf/simulated/floor,/area/research_outpost/gearstore) -"mU" = (/turf/simulated/floor,/area/research_outpost/gearstore) -"mV" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/archaeology,/obj/item/clothing/suit/space/anomaly,/obj/item/clothing/head/helmet/space/anomaly,/obj/item/clothing/mask/breath,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/research_outpost/gearstore) -"mW" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/gearstore) -"mX" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/gearstore) -"mY" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/research_outpost/gearstore) -"mZ" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/research_outpost/gearstore) -"na" = (/turf/simulated/wall,/area/research_outpost/tempstorage) -"nb" = (/turf/simulated/floor,/area/research_outpost/tempstorage) -"nc" = (/obj/machinery/conveyor_switch/oneway{dir = 2; id = "anominerals"; pixel_y = 0},/obj/structure/sign/securearea{desc = "A warning sign which reads 'MOVING PARTS'."; name = "\improper MOVING PARTS"; pixel_y = -32},/turf/simulated/floor,/area/research_outpost/tempstorage) -"nd" = (/obj/structure/plasticflaps/mining,/obj/machinery/conveyor{dir = 2; id = "anotempload"},/turf/simulated/floor/plating,/area/research_outpost/maint) -"ne" = (/obj/machinery/conveyor{dir = 1; id = "anosample"},/obj/structure/plasticflaps/mining,/turf/simulated/floor/plating,/area/research_outpost/maint) -"nf" = (/obj/machinery/camera{c_tag = "Research Outpost Filtering"; dir = 4; network = list("Research","SS13")},/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{icon_state = "warningcorner"; dir = 4},/area/research_outpost/filtering) -"ng" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/research_outpost/filtering) -"nh" = (/obj/machinery/atmospherics/unary/heater{dir = 4},/turf/simulated/floor,/area/research_outpost/iso1_access) -"ni" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{tag = "icon-map (NORTH)"; icon_state = "map"; dir = 1},/turf/simulated/floor,/area/research_outpost/iso1_access) -"nj" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/iso3) -"nk" = (/obj/machinery/atmospherics/unary/heater{dir = 4},/turf/simulated/floor,/area/research_outpost/iso2_access) -"nl" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{tag = "icon-map (NORTH)"; icon_state = "map"; dir = 1},/turf/simulated/floor,/area/research_outpost/iso2_access) -"nm" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/iso1) -"nn" = (/obj/machinery/atmospherics/unary/heater{dir = 4},/turf/simulated/floor,/area/research_outpost/iso3_access) -"no" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/yellow{tag = "icon-map (NORTH)"; icon_state = "map"; dir = 1},/turf/simulated/floor,/area/research_outpost/iso3_access) -"np" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/iso2) -"nq" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/research_outpost/maintstore2) -"nr" = (/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/research_outpost/maintstore2) -"ns" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage) -"nt" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage) -"nu" = (/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/research_outpost/longtermstorage) -"nv" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"nw" = (/obj/structure/transit_tube{icon_state = "W-NE"},/obj/structure/lattice,/turf/space,/area/space) -"nx" = (/obj/structure/transit_tube{icon_state = "D-NW"},/turf/space,/area/space) -"ny" = (/obj/machinery/portable_atmospherics/hydroponics,/turf/simulated/floor{icon_state = "dark"},/area/mine/abandoned) -"nz" = (/obj/effect/decal/remains/human,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"nA" = (/obj/effect/gibspawner/human,/turf/simulated/floor/airless{icon_state = "damaged5"},/area/mine/abandoned) -"nB" = (/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor,/area/mine/abandoned) -"nC" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) +"mS" = (/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/airless{icon_state = "damaged5"},/area/outpost/abandoned) +"mT" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/airless{icon_state = "damaged2"},/area/outpost/abandoned) +"mU" = (/obj/machinery/door/airlock,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/outpost/abandoned) +"mV" = (/obj/machinery/atmospherics/binary/pump{dir = 8},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mW" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/yellow,/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mX" = (/obj/machinery/atmospherics/binary/pump{dir = 4},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"mY" = (/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/outpost/research/power) +"mZ" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/plating,/area/outpost/research/power) +"na" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/outpost/research/power) +"nb" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"nc" = (/obj/structure/sign/electricshock,/turf/simulated/wall/r_wall,/area/outpost/research/power) +"nd" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "research_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_one_access = list(13,65)},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/simulated/floor,/area/outpost/research/eva) +"ne" = (/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/outpost/research/anomaly_storage) +"nf" = (/obj/structure/closet/medical_wall{pixel_x = 28; pixel_y = 0},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"ng" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/outpost/research/emergency_storage) +"nh" = (/obj/structure/dispenser,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/outpost/research/emergency_storage) +"ni" = (/turf/simulated/floor{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/outpost/research/anomaly_storage) +"nj" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'VACUUM'"; icon_state = "space"; layer = 4; name = "VACUUM"; pixel_x = 0; pixel_y = 32},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) +"nk" = (/obj/machinery/recharge_station,/turf/simulated/floor,/area/outpost/research/eva) +"nl" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/outpost/research/eva) +"nm" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/outpost/research/eva) +"nn" = (/obj/machinery/mineral/input,/turf/simulated/floor{dir = 2; icon_state = "loadingarea"},/area/outpost/research/eva) +"no" = (/obj/machinery/door/window{dir = 4; name = "Air Tank Access"; req_one_access = list(47,10,24)},/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/outpost/research/eva) +"np" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor,/area/outpost/research/eva) +"nq" = (/obj/effect/gibspawner/human,/turf/simulated/floor/airless{icon_state = "damaged5"},/area/outpost/abandoned) +"nr" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless{icon_state = "damaged3"},/area/outpost/abandoned) +"ns" = (/obj/machinery/door/airlock,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"nt" = (/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor,/area/outpost/abandoned) +"nu" = (/turf/simulated/wall,/area/outpost/research/medical) +"nv" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/airlock/research{name = "Power & Atmosphere Maintenance"; req_access = list(65)},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/power) +"nw" = (/turf/simulated/wall,/area/outpost/research/dock) +"nx" = (/obj/machinery/door/airlock/glass{name = "Glass Airlock"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/outpost/abandoned) +"ny" = (/obj/machinery/artifact_scanpad,/obj/machinery/light/small,/turf/simulated/floor/bluegrid,/area/outpost/research/anomaly_analysis) +"nz" = (/obj/machinery/alarm{dir = 1; pixel_y = -24},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/outpost/research/anomaly_analysis) +"nA" = (/obj/structure/table,/obj/machinery/computer/atmoscontrol/laptop{monitored_alarm_ids = list("isolation_one","isolation_two","isolation_three"); req_one_access = list(47,24,11)},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"nB" = (/obj/structure/disposalpipe/segment,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/anomaly_storage) +"nC" = (/obj/structure/bed,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/plating,/area/outpost/research/emergency_storage) "nD" = (/obj/machinery/light_construct/small{dir = 4},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"nE" = (/obj/machinery/door/window/westleft,/obj/structure/sign/securearea{desc = "A warning sign which reads 'VACUUM'"; icon_state = "space"; layer = 4; name = "VACUUM"; pixel_x = 0; pixel_y = 32},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"nF" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 10},/area/mine/explored) -"nG" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/lattice,/turf/space,/area/space) -"nH" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor,/area/research_outpost/gearstore) -"nI" = (/obj/machinery/door/airlock/glass_mining{name = "Equipment storage"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/research_outpost/gearstore) -"nJ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/research_outpost/gearstore) -"nK" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/research_outpost/gearstore) -"nL" = (/obj/machinery/recharge_station,/turf/simulated/floor,/area/research_outpost/gearstore) -"nM" = (/obj/machinery/mineral/input,/turf/simulated/floor{dir = 2; icon_state = "loadingarea"},/area/research_outpost/tempstorage) +"nE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor/plating,/area/outpost/research/emergency_storage) +"nF" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"nG" = (/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/obj/machinery/atmospherics/pipe/simple/visible/supply,/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"nH" = (/obj/structure/table,/obj/item/weapon/paper_bin,/obj/item/weapon/tape_roll,/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"nI" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"nJ" = (/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"nK" = (/obj/machinery/portable_atmospherics/canister/carbon_dioxide,/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"nL" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"nM" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor,/area/outpost/research/isolation_monitoring) "nN" = (/obj/machinery/conveyor{dir = 2; id = "anotempload"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 9},/area/mine/explored) "nO" = (/obj/machinery/conveyor{dir = 1; id = "anosample"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 5},/area/mine/explored) -"nP" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor,/area/research_outpost/filtering) -"nQ" = (/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor,/area/research_outpost/filtering) -"nR" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/turf/simulated/floor,/area/research_outpost/filtering) -"nS" = (/obj/machinery/atmospherics/unary/freezer{dir = 4; icon_state = "freezer"},/turf/simulated/floor,/area/research_outpost/iso1_access) -"nT" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/external{id_tag = "riso3"; name = "Access Airlock"; req_access_txt = "65"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor,/area/research_outpost/iso3) -"nU" = (/obj/machinery/atmospherics/omni/filter{tag_east = 1; tag_north = 6; tag_west = 2},/turf/simulated/floor,/area/research_outpost/filtering) -"nV" = (/obj/machinery/atmospherics/unary/freezer{dir = 4; icon_state = "freezer"},/turf/simulated/floor,/area/research_outpost/iso2_access) -"nW" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/external{id_tag = "riso2"; name = "Access Airlock"; req_access_txt = "65"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor,/area/research_outpost/iso2) -"nX" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/external{id_tag = "riso1"; name = "Access Airlock"; req_access_txt = "65"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor,/area/research_outpost/iso1) -"nY" = (/obj/machinery/atmospherics/unary/freezer{dir = 4; icon_state = "freezer"},/turf/simulated/floor,/area/research_outpost/iso3_access) -"nZ" = (/obj/machinery/alarm/monitor/isolation{alarm_id = "isolation_one"; pixel_y = 22},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; use_power = 0},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/research_outpost/iso1) -"oa" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/yellow,/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/research_outpost/iso2) -"ob" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/research_outpost/maintstore2) -"oc" = (/obj/structure/dispenser,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/research_outpost/maintstore2) -"od" = (/turf/simulated/floor{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/research_outpost/longtermstorage) -"oe" = (/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/research_outpost/longtermstorage) -"of" = (/obj/structure/transit_tube{icon_state = "S-NE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"og" = (/obj/structure/transit_tube{icon_state = "D-NW"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"oh" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/shard,/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"oi" = (/obj/effect/alien/resin,/turf/simulated/floor/airless{icon_state = "floorgrime"},/area/mine/abandoned) -"oj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/mine/abandoned) -"ok" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/mine/abandoned) -"ol" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless{icon_state = "damaged4"},/area/mine/abandoned) +"nP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/meter,/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/outpost/research/power) +"nQ" = (/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor{icon_state = "warningcorner"; dir = 2},/area/outpost/research/isolation_monitoring) +"nR" = (/obj/machinery/disposal/deliveryChute{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/disposalpipe/trunk,/turf/simulated/floor/plating,/area/outpost/research/eva) +"nS" = (/obj/machinery/conveyor{dir = 2; id = "anotempload"},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/outpost/research/eva) +"nT" = (/obj/machinery/conveyor{dir = 5; id = "anosample"},/obj/machinery/light/small{dir = 1},/obj/structure/sign/securearea{desc = "A warning sign which reads 'MOVING PARTS'."; name = "\improper MOVING PARTS"; pixel_y = 32},/turf/simulated/floor/plating,/area/outpost/research/eva) +"nU" = (/obj/item/weapon/shard{icon_state = "small"},/turf/simulated/floor/airless,/area/outpost/abandoned) +"nV" = (/obj/structure/table/rack,/turf/simulated/floor/airless{icon_state = "damaged5"},/area/outpost/abandoned) +"nW" = (/obj/item/weapon/shard,/turf/simulated/floor/airless{icon_state = "floorscorched2"},/area/outpost/abandoned) +"nX" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/meter,/turf/simulated/floor/plating,/area/outpost/research/power) +"nY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/outpost/research/eva) +"nZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/research/eva) +"oa" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor,/area/outpost/research/eva) +"ob" = (/obj/machinery/atmospherics/omni/filter{tag_east = 1; tag_south = 2; tag_west = 3},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"oc" = (/obj/machinery/camera{c_tag = "Research Outpost Expedition Prep"; dir = 2; network = list("Research","SS13")},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = 22},/turf/simulated/floor,/area/outpost/research/eva) +"od" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/alarm{pixel_y = 24},/turf/simulated/floor,/area/outpost/research/eva) +"oe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/eva) +"of" = (/obj/structure/table/rack,/obj/item/weapon/storage/belt/archaeology,/obj/item/clothing/suit/space/anomaly,/obj/item/clothing/head/helmet/space/anomaly,/obj/item/clothing/mask/breath,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor,/area/outpost/research/eva) +"og" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/outpost/research/eva) +"oh" = (/obj/structure/closet/excavation,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/outpost/research/eva) +"oi" = (/obj/structure/table,/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"oj" = (/obj/structure/bed/chair/office/light,/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"ok" = (/obj/machinery/portable_atmospherics/canister/sleeping_agent,/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"ol" = (/obj/machinery/portable_atmospherics/canister/oxygen,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) "om" = (/obj/structure/ore_box,/obj/machinery/light_construct/small{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"on" = (/obj/machinery/door/window/westleft,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"oo" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"op" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/structure/dispenser/oxygen,/turf/simulated/floor,/area/research_outpost/gearstore) -"oq" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/research_outpost/gearstore) -"or" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/door/window{dir = 4; name = "Air Tank Access"; req_access_txt = "0"; req_one_access_txt = "47;10;24"},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/research_outpost/gearstore) -"os" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/research_outpost/gearstore) -"ot" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; icon_state = "intact"; tag = "icon-intact-f (SOUTHWEST)"},/turf/simulated/floor,/area/research_outpost/gearstore) -"ou" = (/obj/structure/table,/obj/item/weapon/storage/box/excavation,/obj/item/weapon/pickaxe,/obj/machinery/status_display{layer = 4; pixel_x = 32; pixel_y = 0},/obj/item/weapon/wrench,/obj/item/device/measuring_tape,/obj/item/stack/flag/yellow,/turf/simulated/floor,/area/research_outpost/gearstore) -"ov" = (/obj/machinery/mineral/unloading_machine,/turf/simulated/floor{icon_state = "floorgrime"},/area/research_outpost/tempstorage) +"on" = (/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers,/turf/simulated/floor{icon_state = "warning"},/area/outpost/research/isolation_monitoring) +"oo" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/outpost/research/isolation_monitoring) +"op" = (/obj/machinery/portable_atmospherics/canister/phoron,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"oq" = (/obj/machinery/conveyor{dir = 2; id = "anotempload"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/outpost/research/eva) +"or" = (/obj/machinery/conveyor{dir = 1; id = "anosample"},/turf/simulated/floor/plating,/area/outpost/research/eva) +"os" = (/obj/machinery/conveyor_switch{id = "anosample"; pixel_x = -8; pixel_y = 8},/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/outpost/research/eva) +"ot" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/outpost/research/power) +"ou" = (/obj/structure/disposaloutlet{dir = 2},/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor,/area/outpost/research/anomaly_storage) +"ov" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/anomaly_storage) "ow" = (/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) "ox" = (/obj/machinery/conveyor{dir = 2; id = "anotempload"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) "oy" = (/obj/machinery/conveyor{dir = 1; id = "anosample"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) -"oz" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/turf/simulated/floor,/area/research_outpost/filtering) -"oA" = (/obj/machinery/camera{c_tag = "Isolation Room Two"; dir = 8; network = list("Research","Anomaly Isolation")},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/research_outpost/iso2) -"oB" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor,/area/research_outpost/filtering) -"oC" = (/turf/simulated/wall/r_wall,/area/research_outpost/iso1) -"oD" = (/obj/machinery/alarm/monitor/isolation{alarm_id = "isolation_three"; pixel_y = 22},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; use_power = 0},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/research_outpost/iso3) -"oE" = (/turf/simulated/wall/r_wall,/area/research_outpost/iso2) -"oF" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/yellow,/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/research_outpost/iso1) -"oG" = (/turf/simulated/wall/r_wall,/area/research_outpost/iso3) -"oH" = (/obj/machinery/camera{c_tag = "Isolation Room One"; dir = 8; network = list("Research","Anomaly Isolation")},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/research_outpost/iso1) -"oI" = (/obj/structure/closet/hydrant{pixel_x = -32},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/plating,/area/research_outpost/maintstore2) -"oJ" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/gloves{pixel_x = 4; pixel_y = 5},/obj/item/weapon/storage/box/samplebags{pixel_x = 3; pixel_y = -3},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/item/weapon/storage/toolbox/emergency{pixel_x = 5; pixel_y = 5},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor/plating,/area/research_outpost/maintstore2) -"oK" = (/turf/simulated/wall/r_wall,/area/research_outpost/maintstore2) -"oL" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/longtermstorage) -"oM" = (/obj/structure/transit_tube{icon_state = "N-SW"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"oN" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor/airless,/area/mine/abandoned) -"oO" = (/obj/machinery/door/airlock,/turf/simulated/floor/airless{icon_state = "damaged2"},/area/mine/abandoned) -"oP" = (/obj/machinery/door/airlock/glass{name = "Glass Airlock"; req_access_txt = "0"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/abandoned) -"oQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/mine/abandoned) -"oR" = (/obj/machinery/suspension_gen,/turf/simulated/floor,/area/research_outpost/gearstore) -"oS" = (/obj/machinery/floodlight,/turf/simulated/floor,/area/research_outpost/gearstore) -"oT" = (/obj/machinery/floodlight,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/research_outpost/gearstore) -"oU" = (/obj/machinery/door/window{dir = 4; name = "Air Tank Access"; req_access_txt = "0"; req_one_access_txt = "47;10;24"},/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/research_outpost/gearstore) -"oV" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "research_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = null; req_one_access = list(13,65); req_one_access_txt = null},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/simulated/floor,/area/research_outpost/gearstore) -"oW" = (/obj/structure/table,/obj/item/weapon/storage/box/excavation,/obj/item/weapon/pickaxe,/obj/item/weapon/wrench,/obj/item/device/measuring_tape,/obj/item/stack/flag/green,/turf/simulated/floor,/area/research_outpost/gearstore) -"oX" = (/obj/machinery/conveyor{dir = 2; id = "anominerals"},/obj/machinery/mineral/output,/turf/simulated/floor{icon_state = "floorgrime"},/area/research_outpost/tempstorage) +"oz" = (/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/outpost/research/emergency_storage) +"oA" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/anomaly_storage) +"oB" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/anomaly_storage) +"oC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/closet/walllocker/emerglocker/west,/turf/simulated/floor/plating,/area/outpost/research/emergency_storage) +"oD" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"oE" = (/obj/structure/table,/obj/item/weapon/paper/crumpled,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/outpost/abandoned) +"oF" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"oG" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"oH" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"oI" = (/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/outpost/abandoned) +"oJ" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/outpost/abandoned) +"oK" = (/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/outpost/research/power) +"oL" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/item/stack/rods,/obj/item/weapon/shard,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/outpost/abandoned) +"oM" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/item/weapon/shard{icon_state = "small"},/obj/item/stack/rods,/turf/simulated/floor/plating/airless,/area/outpost/abandoned) +"oN" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_b) +"oO" = (/obj/machinery/artifact_scanpad,/obj/machinery/light,/turf/simulated/floor/bluegrid,/area/outpost/research/isolation_a) +"oP" = (/obj/machinery/artifact_analyser,/turf/simulated/floor/bluegrid,/area/outpost/research/isolation_a) +"oQ" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_c) +"oR" = (/obj/machinery/artifact_scanpad,/obj/machinery/light,/turf/simulated/floor/bluegrid,/area/outpost/research/isolation_b) +"oS" = (/obj/machinery/artifact_analyser,/turf/simulated/floor/bluegrid,/area/outpost/research/isolation_b) +"oT" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/outpost/research/power) +"oU" = (/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/supply{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/outpost/research/power) +"oV" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"oW" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_a) +"oX" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating,/area/outpost/research/power) "oY" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) -"oZ" = (/obj/machinery/alarm/monitor/isolation{alarm_id = "isolation_two"; pixel_y = 22},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; use_power = 0},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/research_outpost/iso2) -"pa" = (/obj/machinery/camera{c_tag = "Isolation Room Three"; dir = 8; network = list("Research","Anomaly Isolation")},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/research_outpost/iso3) -"pb" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/yellow,/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/research_outpost/iso3) -"pc" = (/obj/machinery/portable_atmospherics/canister/air,/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor,/area/research_outpost/iso3_access) -"pd" = (/obj/machinery/portable_atmospherics/canister/air,/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor,/area/research_outpost/iso1_access) -"pe" = (/obj/machinery/portable_atmospherics/canister/air,/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/turf/simulated/floor,/area/research_outpost/iso2_access) -"pf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow,/turf/simulated/floor,/area/research_outpost/iso1_access) -"pg" = (/obj/machinery/door_control{id = "riso1"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 0; pixel_y = -25; req_access_txt = "0"; specialfunctions = 4},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor,/area/research_outpost/iso1_access) -"ph" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow,/turf/simulated/floor,/area/research_outpost/iso2_access) -"pi" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/reagent_containers/spray/cleaner,/turf/simulated/floor/plating,/area/research_outpost/maintstore2) -"pj" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/lights/bulbs{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/box/lights/tubes{pixel_x = -5; pixel_y = 5},/obj/item/weapon/storage/box/lights/mixed,/obj/machinery/light/small,/turf/simulated/floor/plating,/area/research_outpost/maintstore2) -"pk" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/mineral/random,/area/mine/unexplored) -"pl" = (/obj/structure/transit_tube{icon_state = "NE-SW"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"pm" = (/obj/structure/transit_tube{icon_state = "D-NW"},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"pn" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 9},/area/mine/explored) -"po" = (/obj/machinery/door/airlock,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"pp" = (/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/abandoned) -"pq" = (/obj/structure/table/rack,/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/abandoned) +"oZ" = (/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{tag = "icon-intact-scrubbers (NORTHWEST)"; icon_state = "intact-scrubbers"; dir = 9},/turf/simulated/floor,/area/outpost/research/power) +"pa" = (/obj/structure/bed,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_c) +"pb" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/obj/machinery/light,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_c) +"pc" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"pd" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) +"pe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) +"pf" = (/turf/simulated/wall/r_wall,/area/outpost/research/isolation_b) +"pg" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) +"ph" = (/obj/structure/table,/turf/simulated/floor/airless{icon_state = "damaged5"},/area/outpost/abandoned) +"pi" = (/obj/structure/girder,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/outpost/abandoned) +"pj" = (/obj/structure/window/reinforced,/obj/structure/lattice,/turf/space,/area/mine/explored) +"pk" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/disposalpipe/segment,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/outpost/research/eva) +"pl" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "research_sensor"; pixel_x = -25; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "research_pump"},/turf/simulated/floor{icon_state = "warning"},/area/outpost/research/eva) +"pm" = (/obj/structure/ore_box,/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "research_pump"},/turf/simulated/floor{icon_state = "warning"},/area/outpost/research/eva) +"pn" = (/obj/machinery/atmospherics/pipe/manifold/hidden,/turf/simulated/floor{icon_state = "warning"},/area/outpost/research/eva) +"po" = (/obj/structure/lattice,/obj/structure/window/reinforced,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/space,/area/mine/explored) +"pp" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; use_power = 0},/obj/structure/cable/blue,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/outpost/research/isolation_c) +"pq" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow,/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/outpost/research/isolation_b) "pr" = (/obj/structure/closet,/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"ps" = (/obj/machinery/door/window/westleft{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"pt" = (/obj/structure/transit_tube{icon_state = "N-S"},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"pu" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/gearstore) -"pv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/gearstore) -"pw" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/gearstore) -"px" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "research_inner"; locked = 1; name = "Research Outpost External Access"; req_access = null; req_access_txt = null},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/research_outpost/gearstore) -"py" = (/obj/machinery/disposal/deliveryChute{dir = 1},/obj/structure/disposalpipe/trunk,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/explored) +"ps" = (/obj/machinery/alarm/monitor/isolation{alarm_id = "isolation_two"; dir = 8; pixel_x = 22; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/outpost/research/isolation_b) +"pt" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; use_power = 0},/obj/structure/cable/blue,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/outpost/research/isolation_b) +"pu" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow,/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/outpost/research/isolation_a) +"pv" = (/obj/machinery/alarm/monitor/isolation{alarm_id = "isolation_one"; dir = 8; pixel_x = 22; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/outpost/research/isolation_a) +"pw" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; use_power = 0},/obj/structure/cable/blue,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/outpost/research/isolation_a) +"px" = (/obj/machinery/atmospherics/valve/digital/open,/turf/simulated/floor,/area/outpost/research/power) +"py" = (/obj/machinery/atmospherics/valve/digital/open,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor,/area/outpost/research/power) "pz" = (/turf/simulated/wall/r_wall,/area/mine/explored) -"pA" = (/obj/machinery/conveyor_switch{id = "anotempload"; name = "conveyor switch"; pixel_x = 0; pixel_y = 0; req_access_txt = "65"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"pA" = (/obj/machinery/power/smes/buildable/outpost_substation{charge = 500000; input_attempt = 1; input_level = 150000; output_level = 150000; RCon_tag = "Outpost - Research"},/obj/structure/cable/blue,/turf/simulated/floor,/area/outpost/research/power) "pB" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 10},/area/mine/explored) "pC" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 6},/area/mine/explored) -"pD" = (/obj/machinery/conveyor_switch{id = "anosample"; req_access_txt = "65"},/obj/structure/sign/securearea{desc = "A warning sign which reads 'MOVING PARTS'."; name = "\improper MOVING PARTS"; pixel_y = 32},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) -"pE" = (/obj/machinery/door_control{id = "riso2"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 0; pixel_y = -25; req_access_txt = "0"; specialfunctions = 4},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor,/area/research_outpost/iso2_access) -"pF" = (/obj/machinery/door_control{id = "riso3"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 0; pixel_y = -25; req_access_txt = "0"; specialfunctions = 4},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor,/area/research_outpost/iso3_access) -"pG" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/iso1) -"pH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/yellow,/turf/simulated/floor,/area/research_outpost/iso3_access) -"pI" = (/obj/machinery/mineral/output,/obj/machinery/conveyor{dir = 4; id = "mining_north"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"pJ" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/iso2) -"pK" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'MOVING PARTS'."; name = "\improper MOVING PARTS"; pixel_y = 32},/obj/machinery/conveyor_switch{id = "mining_north"; pixel_x = -5},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored) -"pM" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/iso3) -"pN" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore2) -"pO" = (/obj/structure/transit_tube{icon_state = "E-SW"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"pP" = (/obj/structure/transit_tube{icon_state = "W-NE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) +"pD" = (/obj/machinery/alarm/monitor/isolation{alarm_id = "isolation_three"; dir = 8; pixel_x = 22; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/outpost/research/isolation_c) +"pE" = (/obj/machinery/atmospherics/pipe/manifold/visible/yellow,/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/outpost/research/isolation_c) +"pF" = (/obj/structure/disposalpipe/segment,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/outpost/research/eva) +"pG" = (/obj/machinery/door/airlock/glass_mining{name = "Equipment storage"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/research/eva) +"pH" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/camera{c_tag = "Research Outpost Expedition Airlock"; dir = 4; network = list("Research","SS13")},/turf/simulated/floor/plating,/area/outpost/research/eva) +"pI" = (/obj/structure/disposalpipe/segment,/turf/unsimulated/mask,/area/mine/unexplored) +"pJ" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/research{name = "Temporary Storage Loading"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/eva) +"pK" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_c) +"pL" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_b) +"pM" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_mining{name = "Expedition Prep"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/research/dock) +"pN" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_c) +"pO" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_a) +"pP" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/obj/machinery/camera/autoname/research_outpost{dir = 4},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) "pQ" = (/obj/structure/table/rack,/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"pR" = (/obj/structure/girder/displaced,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/abandoned) +"pR" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_b) "pS" = (/obj/structure/table,/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"pT" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"pU" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) +"pT" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) +"pU" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) "pV" = (/obj/structure/table/rack,/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"pW" = (/obj/structure/transit_tube{icon_state = "N-SE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"pX" = (/obj/structure/transit_tube{icon_state = "D-SW"},/obj/structure/lattice,/turf/space,/area/mine/explored) -"pY" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "D-SE"},/turf/space,/area/mine/explored) -"pZ" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "E-SW"},/turf/space,/area/mine/explored) -"qa" = (/obj/structure/lattice,/obj/structure/transit_tube,/turf/space,/area/mine/explored) -"qb" = (/obj/structure/table/rack,/turf/simulated/floor/airless{icon_state = "damaged5"},/area/mine/abandoned) -"qc" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/plating/airless,/area/mine/abandoned) +"pW" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_a) +"pX" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/turf/simulated/floor,/area/outpost/research/power) +"pY" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"pZ" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"qa" = (/obj/structure/grille,/obj/structure/lattice,/turf/space,/area/space) +"qb" = (/obj/machinery/power/solar,/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/space) +"qc" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/space) "qd" = (/obj/machinery/mech_bay_recharge_port,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) "qe" = (/turf/simulated/floor/mech_bay_recharge_floor{icon_state = "recharge_floor_asteroid"},/area/mine/explored) "qf" = (/obj/machinery/computer/mech_bay_power_console,/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) -"qg" = (/obj/machinery/light/small{dir = 8},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "research_pump"; tag_exterior_door = "research_outer"; frequency = 1379; id_tag = "research_airlock"; tag_interior_door = "research_inner"; pixel_x = -25; pixel_y = 0; req_access_txt = null; tag_chamber_sensor = "research_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "research_pump"},/turf/simulated/floor,/area/research_outpost/gearstore) -"qh" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden,/turf/simulated/floor,/area/research_outpost/gearstore) -"qi" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "research_pump"},/obj/structure/closet/walllocker/emerglocker/east,/turf/simulated/floor,/area/research_outpost/gearstore) -"qj" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/disposalpipe/segment,/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/mine/explored) -"qk" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/research_outpost/iso1) -"ql" = (/obj/machinery/artifact_scanpad,/turf/simulated/floor/bluegrid,/area/research_outpost/iso1) -"qm" = (/obj/machinery/artifact_analyser,/turf/simulated/floor/bluegrid,/area/research_outpost/iso1) -"qn" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor{tag = "icon-vault (EAST)"; icon_state = "vault"; dir = 4},/area/research_outpost/iso2) -"qo" = (/obj/machinery/artifact_scanpad,/turf/simulated/floor/bluegrid,/area/research_outpost/iso2) -"qp" = (/obj/machinery/artifact_analyser,/turf/simulated/floor/bluegrid,/area/research_outpost/iso2) -"qq" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/research_outpost/iso3) -"qr" = (/turf/simulated/floor{tag = "icon-vault (NORTH)"; icon_state = "vault"; dir = 1},/area/research_outpost/iso3) -"qs" = (/obj/structure/stool/bed,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/research_outpost/iso3) -"qt" = (/obj/structure/transit_tube{icon_state = "NE-SW"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/unexplored) -"qu" = (/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap,/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"qv" = (/obj/structure/girder,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/abandoned) +"qg" = (/obj/machinery/power/solar,/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/airless{icon_state = "solarpanel"},/area/space) +"qh" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/maintenance{req_one_access = list(12,65)},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 4},/area/outpost/research/eva) +"qi" = (/obj/structure/toilet{dir = 8},/obj/machinery/light/small{dir = 1},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/engineering/meeting) +"qj" = (/turf/simulated/wall/r_wall,/area/outpost/engineering/meeting) +"qk" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/structure/mirror{dir = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/engineering/meeting) +"ql" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 22},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/engineering/meeting) +"qm" = (/obj/machinery/light{dir = 1},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/engineering/meeting) +"qn" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"qo" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) +"qp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) +"qq" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"qr" = (/obj/machinery/shower{dir = 8; icon_state = "shower"; pixel_x = -5; pixel_y = 0},/obj/machinery/light/small{dir = 1},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/engineering/meeting) +"qs" = (/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/engineering/meeting) +"qt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/engineering/meeting) +"qu" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/camera/autoname/research_outpost{dir = 8},/turf/simulated/floor,/area/outpost/research/isolation_monitoring) +"qv" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/engineering/meeting) "qw" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/mine/explored) -"qx" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/transit_tube{icon_state = "D-NE"},/turf/simulated/floor/plating,/area/mine/explored) -"qy" = (/obj/structure/window/reinforced,/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "E-NW"},/turf/space,/area/mine/explored) -"qz" = (/obj/structure/lattice,/obj/structure/window/reinforced,/obj/structure/transit_tube,/turf/space,/area/mine/explored) -"qA" = (/obj/structure/lattice,/obj/structure/window/reinforced,/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/transit_tube{icon_state = "W-NE"},/turf/space,/area/mine/explored) -"qB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/transit_tube{icon_state = "D-NW"},/turf/simulated/floor/plating,/area/mine/explored) +"qx" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating/airless,/area/space) +"qy" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"qz" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored) +"qA" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) +"qB" = (/turf/space,/area/shuttle/constructionsite/site) "qC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/mine/explored) -"qD" = (/obj/machinery/door/window/westleft{dir = 2},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"qE" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"qD" = (/turf/simulated/wall/r_wall,/area/outpost/engineering/atmospherics) +"qE" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating/airless,/area/space) "qF" = (/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"qG" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "research_sensor"; pixel_x = -25; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "research_pump"},/turf/simulated/floor{icon_state = "warning"},/area/research_outpost/gearstore) -"qH" = (/obj/machinery/atmospherics/pipe/manifold/hidden,/turf/simulated/floor{icon_state = "warning"},/area/research_outpost/gearstore) -"qI" = (/obj/structure/ore_box,/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "research_pump"},/turf/simulated/floor{icon_state = "warning"},/area/research_outpost/gearstore) -"qJ" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/disposalpipe/segment,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/mine/explored) -"qK" = (/obj/effect/glowshroom,/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) +"qG" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"qH" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"qI" = (/obj/machinery/atmospherics/omni/filter{power_rating = 15000; tag_east = 5; tag_north = 1; tag_south = 2; tag_west = 6},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"qJ" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/atmospherics) +"qK" = (/obj/machinery/atmospherics/pipe/simple/visible/blue,/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/atmospherics) "qL" = (/turf/space,/area/mine/unexplored) "qM" = (/obj/structure/closet/crate,/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) "qN" = (/obj/machinery/floodlight,/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"qO" = (/obj/machinery/door/airlock/external{name = "Mining Bridge"; req_access_txt = "0"; req_one_access_txt = "54;65"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"qO" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_mining{name = "Loading area"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/research/eva) "qP" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/airless,/area/mine/explored) -"qQ" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/camera{c_tag = "Research Outpost Expedition Airlock"; dir = 4; network = list("Research","SS13")},/turf/simulated/floor/plating,/area/research_outpost/gearstore) -"qR" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "research_outer"; locked = 1; name = "Research Outpost External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/research_outpost/gearstore) -"qS" = (/obj/structure/disposalpipe/segment,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/mine/explored) -"qT" = (/obj/machinery/door/window/westleft,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"qU" = (/obj/structure/table,/obj/item/weapon/paper/crumpled,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned) -"qV" = (/obj/structure/transit_tube{icon_state = "E-SW"},/turf/simulated/wall/r_wall,/area/mine/explored) -"qW" = (/obj/structure/transit_tube,/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"qX" = (/obj/structure/transit_tube,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/unexplored) -"qY" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"qZ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"ra" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/mine/abandoned) -"rb" = (/obj/machinery/door/airlock/external{name = "External Airlock"; req_access_txt = "0"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/abandoned) -"rc" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/item/weapon/shard{icon_state = "small"},/obj/item/stack/rods,/turf/simulated/floor/plating/airless,/area/mine/abandoned) +"qQ" = (/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"qR" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/atmospherics) +"qS" = (/obj/machinery/atmospherics/pipe/simple/visible/blue,/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/atmospherics) +"qT" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/empty/carbon_dioxide,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"qU" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/empty/sleeping_agent,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"qV" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/empty/phoron,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"qW" = (/obj/machinery/atmospherics/unary/vent_pump/siphon/on{dir = 1; frequency = 1441; id_tag = "outpost_n2_out"},/obj/machinery/air_sensor{frequency = 1441; id_tag = "outpost_n2_sensor"},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/outpost/engineering/atmospherics) +"qX" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1441; icon_state = "map_injector"; id = "outpost_n2_in"; pixel_y = 1; use_power = 1},/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/outpost/engineering/atmospherics) +"qY" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1441; icon_state = "map_injector"; id = "outpost_o2_in"; pixel_y = 1; use_power = 1},/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/outpost/engineering/atmospherics) +"qZ" = (/obj/machinery/atmospherics/unary/vent_pump/siphon/on{dir = 1; frequency = 1441; id_tag = "outpost_o2_out"},/obj/machinery/air_sensor{frequency = 1441; id_tag = "outpost_o2_sensor"},/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/outpost/engineering/atmospherics) +"ra" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"rb" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1380; id_tag = "eoutpost_dock_pump"},/obj/machinery/light/small{dir = 4},/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "eoutpost_solar_sensor"; pixel_x = 25; pixel_y = 0},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"rc" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) "rd" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 1},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/space,/area/mine/explored) "re" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 1},/turf/space,/area/mine/explored) -"rf" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "research_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = null; req_one_access = list(13,65); req_one_access_txt = null},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) -"rg" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 9},/area/mine/explored) -"rh" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored) +"rf" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/outpost/research/power) +"rg" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/space) +"rh" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) "ri" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 5},/area/mine/explored) -"rj" = (/obj/structure/transit_tube{icon_state = "S-NE"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) -"rk" = (/obj/structure/transit_tube{icon_state = "D-NW"},/turf/simulated/wall/r_wall,/area/mine/explored) -"rl" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'VACUUM'"; icon_state = "space"; layer = 4; name = "VACUUM"; pixel_x = -32; pixel_y = -32},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"rm" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/unexplored) -"rn" = (/obj/machinery/door/window/westleft{dir = 2},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/unexplored) -"ro" = (/obj/machinery/door/window/westleft{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/unexplored) -"rp" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) -"rq" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'VACUUM'"; icon_state = "space"; layer = 4; name = "VACUUM"; pixel_x = 0; pixel_y = -32},/obj/machinery/door/window/westleft,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"rr" = (/obj/structure/transit_tube/station{dir = 8; icon_state = "closed"},/obj/structure/transit_tube_pod,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 10},/area/mine/explored) -"rs" = (/obj/effect/glowshroom,/obj/machinery/light/small,/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored) -"rt" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/abandoned) -"ru" = (/obj/item/weapon/shard{icon_state = "medium"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/abandoned) -"rv" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"rw" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille{density = 0; icon_state = "brokengrille"},/obj/item/stack/rods,/obj/item/weapon/shard,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/abandoned) +"rj" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{dir = 1},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"rk" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"rl" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"rm" = (/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"rn" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/supply{dir = 4},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"ro" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"rp" = (/obj/machinery/atmospherics/binary/pump/on{dir = 4},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"rq" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/obj/machinery/meter,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"rr" = (/obj/machinery/atmospherics/pipe/simple/visible/supply{tag = "icon-intact-supply (NORTHWEST)"; icon_state = "intact-supply"; dir = 9},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{tag = "icon-intact-scrubbers (NORTHEAST)"; icon_state = "intact-scrubbers"; dir = 5},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"rs" = (/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/obj/machinery/alarm{frequency = 1439; pixel_y = 22},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"rt" = (/turf/simulated/wall/r_wall,/area/outpost/engineering/hallway) +"ru" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored) +"rv" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/outpost/research/power) +"rw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) "rx" = (/obj/machinery/light_construct/small,/obj/structure/table/rack,/obj/item/stack/sheet/metal{amount = 10},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) "ry" = (/obj/structure/table/rack,/obj/item/weapon/pickaxe,/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"rz" = (/obj/item/weapon/table_parts,/obj/structure/table/rack,/obj/item/stack/sheet/glass/reinforced{amount = 8},/obj/item/stack/rods{amount = 6},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"rA" = (/turf/simulated/mineral/random/high_chance,/area/mine/unexplored) +"rz" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"rA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) "rB" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 10},/area/mine/unexplored) "rC" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/unexplored) "rD" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 6},/area/mine/unexplored) -"rE" = (/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/unexplored) -"rF" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"rG" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"rE" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"rF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"rG" = (/turf/simulated/wall,/area/outpost/engineering/hallway) "rH" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"rI" = (/turf/simulated/wall,/area/mine/north_outpost) +"rI" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/airlock/maintenance{req_one_access = list(12,65)},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"; nitrogen = 0.01; oxygen = 0.01},/area/outpost/research/power) "rJ" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 9},/area/mine/explored) -"rK" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/camera{c_tag = "North Outpost - Airlock"; dir = 2; network = list("MINE")},/turf/simulated/floor/plating,/area/mine/north_outpost) -"rL" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "mining_north_outpost_airlock"; pixel_x = 0; pixel_y = 25; req_access_txt = null; tag_airpump = "mining_north_outpost_pump"; tag_chamber_sensor = "mining_north_outpost_sensor"; tag_exterior_door = "mining_north_outpost_outer"; tag_interior_door = "mining_north_outpost_inner"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_north_outpost_pump"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"rM" = (/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "mining_north_outpost_sensor"; pixel_x = 0; pixel_y = 25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_north_outpost_pump"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"rN" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/north_outpost) -"rO" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/mine/north_outpost) -"rP" = (/obj/structure/stool/bed/chair,/obj/effect/decal/cleanable/dirt,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"rQ" = (/obj/machinery/recharge_station,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"rR" = (/obj/structure/table,/obj/effect/decal/cleanable/cobweb2,/obj/machinery/microwave{pixel_y = 6},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"rS" = (/obj/effect/decal/cleanable/cobweb,/obj/item/stack/sheet/metal{amount = 10},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/clothing/glasses/meson,/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/plating,/area/mine/north_outpost) -"rT" = (/turf/simulated/floor/plating,/area/mine/north_outpost) -"rU" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "mining_north_outpost_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = null; req_one_access = list(13,54); req_one_access_txt = null},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) -"rV" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_north_outpost_outer"; locked = 1; name = "Mining External Access"; req_access = null; req_access_txt = "10;13"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"rW" = (/obj/structure/closet/walllocker/emerglocker/south,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHEAST)"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"rX" = (/obj/machinery/atmospherics/pipe/manifold/hidden,/obj/effect/decal/cleanable/dirt,/obj/machinery/light/small,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"rY" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_north_outpost_inner"; locked = 1; name = "Mining External Access"; req_access = null; req_access_txt = null},/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"rZ" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "mining_north_outpost_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = 25; req_access_txt = null; req_one_access = list(13,54)},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"sa" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"sb" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"sc" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"sd" = (/obj/machinery/door/airlock/maintenance{name = "Mining Station Maintenance"; req_access_txt = "54"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/mine/north_outpost) -"se" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/mine/north_outpost) -"sf" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/mine/north_outpost) -"sg" = (/obj/machinery/conveyor_switch{id = "mining_north"; pixel_x = -5},/obj/effect/decal/cleanable/dirt,/obj/machinery/light{dir = 8},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"sh" = (/obj/item/weapon/pickaxe,/obj/item/weapon/shovel,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"si" = (/obj/structure/cable,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/machinery/camera{c_tag = "North Outpost"; dir = 8; network = list("MINE")},/obj/effect/decal/cleanable/blood/oil,/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"sj" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/mine/north_outpost) -"sk" = (/obj/machinery/light/small{dir = 4},/obj/machinery/power/port_gen/pacman{anchored = 1},/obj/structure/cable,/turf/simulated/floor/plating,/area/mine/north_outpost) -"sl" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"sm" = (/obj/structure/disposalpipe/junction/yjunction,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"sn" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/mine/north_outpost) -"sp" = (/obj/structure/disposalpipe/trunk{dir = 8},/obj/machinery/disposal/deliveryChute{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"sq" = (/obj/machinery/mineral/input,/obj/machinery/conveyor{backwards = 2; dir = 2; forwards = 1; id = "mining_north"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"sr" = (/obj/machinery/mineral/unloading_machine{icon_state = "unloader-corner"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"ss" = (/obj/effect/decal/cleanable/dirt,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"st" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{dir = 8; icon_state = "loadingarea"},/area/mine/north_outpost) -"su" = (/obj/structure/table/rack,/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/mine/west_outpost) -"sv" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) -"sw" = (/obj/structure/girder,/turf/simulated/floor/plating,/area/mine/north_outpost) -"sx" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/obj/machinery/meter,/obj/machinery/portable_atmospherics/canister/oxygen,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/mine/north_outpost) -"sy" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8; initialize_directions = 0; level = 1},/turf/simulated/floor/plating,/area/mine/north_outpost) -"sz" = (/obj/structure/plasticflaps/mining,/obj/machinery/conveyor{backwards = 2; dir = 2; forwards = 1; id = "mining_north"},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/north_outpost) +"rK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"rL" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"rM" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"rN" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"rO" = (/obj/machinery/door/airlock/external{name = "External Airlock"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/outpost/abandoned) +"rP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) +"rQ" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"rR" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"rS" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "research_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_one_access = list(13,65)},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) +"rT" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"rU" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "research_outer"; locked = 1; name = "Research Outpost External Access"; req_access = list(10,13)},/turf/simulated/floor/plating,/area/outpost/research/eva) +"rV" = (/obj/structure/sign/nosmoking_2{pixel_y = -32},/obj/machinery/camera/autoname/research_outpost{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/research/anomaly_analysis) +"rW" = (/obj/machinery/door/airlock/external{name = "Mining Bridge"; req_one_access = list(54,65)},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"rX" = (/obj/machinery/door/airlock/engineering{name = "Restrooms"; req_access = list(10)},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/engineering/meeting) +"rY" = (/turf/simulated/floor/engine{name = "o2 floor"; nitrogen = 0; oxygen = 100000},/area/outpost/engineering/atmospherics) +"rZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/engineering/hallway) +"sa" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/engineering/hallway) +"sb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/engineering/hallway) +"sc" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/outpost/engineering/hallway) +"sd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/engineering/hallway) +"se" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplatecorner"},/area/outpost/research/power) +"sf" = (/turf/simulated/floor/engine{name = "n2 floor"; nitrogen = 100000; oxygen = 0},/area/outpost/engineering/atmospherics) +"sg" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "edock_inner"; locked = 1; name = "Engineering Dock Airlock"},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"sh" = (/turf/simulated/floor,/area/outpost/engineering/hallway) +"si" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/outpost/engineering/hallway) +"sj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/outpost/research/power) +"sk" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/light,/turf/simulated/floor,/area/outpost/engineering/hallway) +"sl" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor,/area/outpost/engineering/hallway) +"sm" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/outpost/engineering/hallway) +"sn" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Atmospherics"; req_access = list(10)},/turf/simulated/floor,/area/outpost/engineering/hallway) +"so" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor,/area/outpost/engineering/hallway) +"sp" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/cyan{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "edock_inner"; locked = 1; name = "Engineering Dock Airlock"},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"sq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/outpost/engineering/hallway) +"sr" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/outpost/engineering/hallway) +"ss" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"st" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/outpost/engineering/hallway) +"su" = (/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/outpost/engineering/hallway) +"sv" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"sw" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "eoutpost_main_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = -25; req_access = list(10)},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"sx" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 1; icon_state = "map"; tag = "icon-manifold-f (NORTH)"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "eoutpost_main_sensor"; pixel_x = 0; pixel_y = 25},/turf/simulated/floor,/area/outpost/engineering/hallway) +"sy" = (/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/supply{tag = "icon-intact-supply (NORTHWEST)"; icon_state = "intact-supply"; dir = 9},/turf/simulated/floor,/area/outpost/research/power) +"sz" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eoutpost_main_outer"; locked = 1; name = "Engineering Outpost"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/engineering/hallway) "sA" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"sB" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eoutpost_main_inner"; locked = 1; name = "Engineering Outpost"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor,/area/outpost/engineering/hallway) "sC" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored) -"sD" = (/turf/simulated/mineral/random/high_chance,/area/mine/explored) +"sD" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/outpost/engineering/hallway) "sE" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"sF" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored) -"sG" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) +"sF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"sG" = (/obj/machinery/atmospherics/unary/vent_pump/on,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/engineering/hallway) "sH" = (/turf/simulated/floor/airless,/area/space) -"sI" = (/turf/simulated/mineral/random,/area/space) -"sJ" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) -"sK" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) +"sI" = (/obj/machinery/camera{c_tag = "Isolation Cell C"; dir = 8; network = list("Anomaly Isolation")},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_c) +"sJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"sK" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "eoutpost_main_airlock"; pixel_x = 0; pixel_y = -25; req_access = list(10); tag_airpump = "eoutpost_main_pump"; tag_chamber_sensor = "eoutpost_main_sensor"; tag_exterior_door = "eoutpost_main_outer"; tag_interior_door = "eoutpost_main_inner"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "eoutpost_main_pump"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/engineering/hallway) "sL" = (/obj/machinery/light/small,/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) "sM" = (/obj/machinery/light_construct/small,/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) "sN" = (/turf/simulated/floor/plating/airless,/area/space) "sO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/mine/explored) "sP" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/mine/explored) -"sQ" = (/obj/machinery/door/airlock/external{name = "Mining Bridge"; req_access_txt = "54"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"sQ" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/cyan{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "edock_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access = list(10)},/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/outpost/engineering/hallway) "sR" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 4},/turf/space,/area/mine/explored) "sS" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/airless,/area/mine/explored) "sT" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 8},/obj/machinery/light{dir = 1},/turf/space,/area/mine/explored) @@ -981,402 +984,622 @@ "sV" = (/obj/structure/lattice,/obj/structure/window/reinforced,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/space,/area/mine/explored) "sW" = (/obj/structure/lattice,/obj/structure/window/reinforced,/turf/space,/area/mine/explored) "sX" = (/obj/structure/lattice,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/space,/area/mine/explored) -"sY" = (/turf/simulated/wall/r_wall,/area/mine/maintenance) +"sY" = (/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/engineering/hallway) "sZ" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/airless,/area/mine/explored) "ta" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/airless,/area/mine/explored) "tb" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/airless,/area/mine/explored) -"tc" = (/turf/simulated/floor/bluegrid,/area/mine/maintenance) -"td" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor{icon_state = "dark"},/area/mine/maintenance) -"te" = (/obj/machinery/telecomms/relay/preset/mining,/obj/machinery/light/small{dir = 1},/turf/simulated/floor{icon_state = "vault"; dir = 1},/area/mine/maintenance) -"tf" = (/obj/machinery/alarm{pixel_y = 24},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "dark"},/area/mine/maintenance) +"tc" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"td" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/alarm{frequency = 1439; pixel_y = 22},/turf/simulated/floor,/area/outpost/engineering/hallway) +"te" = (/obj/machinery/light{dir = 1},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"tf" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/engineering/hallway) "tg" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/mine/explored) "th" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/space,/area/mine/explored) "ti" = (/obj/structure/lattice,/obj/structure/lattice,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/space,/area/mine/explored) "tj" = (/obj/structure/lattice,/turf/space,/area/mine/explored) -"tk" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/bluegrid,/area/mine/maintenance) -"tl" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor{icon_state = "dark"},/area/mine/maintenance) -"tm" = (/obj/machinery/light_switch{pixel_y = -25},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor/bluegrid,/area/mine/maintenance) -"tn" = (/obj/machinery/camera{c_tag = "Communications Relay"; dir = 8; network = list("MINE")},/turf/simulated/floor/bluegrid,/area/mine/maintenance) +"tk" = (/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/outpost/engineering/hallway) +"tl" = (/obj/machinery/camera{c_tag = "Isolation Cell B"; dir = 8; network = list("Anomaly Isolation")},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_b) +"tm" = (/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor,/area/outpost/engineering/hallway) +"tn" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/engineering/hallway) "to" = (/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) "tp" = (/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"tq" = (/turf/simulated/wall,/area/mine/living_quarters) -"tr" = (/obj/machinery/door/airlock/maintenance{name = "Mining Station Communications"; req_access_txt = "48"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "vault"},/area/mine/maintenance) +"tq" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/outpost/engineering/hallway) +"tr" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/engineering/hallway) "ts" = (/obj/item/clothing/under/rank/miner,/obj/effect/decal/remains/human,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) "tt" = (/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) -"tu" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor/carpet,/area/mine/living_quarters) -"tv" = (/obj/machinery/light/small{dir = 4},/obj/machinery/door_control{id = "miningdorm1"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/turf/simulated/floor/carpet,/area/mine/living_quarters) -"tw" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/mine/living_quarters) +"tu" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"tv" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"tw" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/cyan{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/turf/simulated/floor,/area/outpost/engineering/hallway) "tx" = (/obj/structure/lattice,/obj/structure/window/reinforced{dir = 4},/obj/machinery/light,/turf/space,/area/mine/explored) -"ty" = (/obj/structure/table,/turf/simulated/floor/carpet,/area/mine/living_quarters) -"tz" = (/turf/simulated/floor/carpet,/area/mine/living_quarters) -"tA" = (/obj/machinery/door/airlock{id_tag = "miningdorm1"; name = "Room 1"},/turf/simulated/floor{dir = 2; icon_state = "carpet"},/area/mine/living_quarters) +"ty" = (/obj/machinery/camera{c_tag = "Isolation Cell A"; dir = 8; network = list("Anomaly Isolation")},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/outpost/research/isolation_a) +"tz" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/outpost/engineering/meeting) +"tA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/engineering/hallway) "tB" = (/obj/structure/disposalpipe/trunk,/obj/structure/disposaloutlet{dir = 1},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"tC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/mine/living_quarters) -"tD" = (/obj/structure/disposalpipe/segment,/turf/simulated/mineral/random,/area/mine/unexplored) -"tE" = (/obj/machinery/light/small{dir = 4},/obj/machinery/door_control{id = "miningdorm2"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/turf/simulated/floor/carpet,/area/mine/living_quarters) -"tF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) +"tC" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/engineering/hallway) +"tD" = (/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"tE" = (/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"tF" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) "tG" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"tH" = (/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/west_outpost) -"tI" = (/obj/machinery/door/airlock{id_tag = "miningdorm2"; name = "Room 2"},/turf/simulated/floor{dir = 2; icon_state = "carpet"},/area/mine/living_quarters) -"tJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) -"tK" = (/obj/machinery/mech_bay_recharge_port,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/west_outpost) -"tL" = (/turf/simulated/floor/mech_bay_recharge_floor{icon_state = "recharge_floor_asteroid"},/area/mine/west_outpost) -"tM" = (/obj/machinery/computer/mech_bay_power_console,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/west_outpost) -"tN" = (/obj/structure/disposalpipe/segment,/obj/structure/sign/deathsposal,/turf/simulated/wall,/area/mine/living_quarters) -"tO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) +"tH" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/blue,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"tI" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"tJ" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"tK" = (/obj/structure/grille,/obj/structure/lattice,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/space,/area/space) +"tL" = (/obj/machinery/atmospherics/pipe/simple/visible/blue,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"tM" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "outpost_n2_in"; name = "N2 Tank Monitor"; output_tag = "outpost_n2_out"; sensors = list("outpost_n2_sensor" = "Tank")},/obj/structure/sign/securearea{desc = "A warning sign which reads 'COMPRESSED GAS'."; name = "COMPRESSED GAS"; pixel_y = -32},/obj/machinery/light,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"tN" = (/obj/machinery/atmospherics/pipe/simple/visible/purple,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"tO" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/obj/machinery/meter,/turf/simulated/floor,/area/outpost/engineering/atmospherics) "tP" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/structure/table/reinforced,/obj/item/weapon/wrench,/obj/item/weapon/screwdriver,/obj/item/weapon/crowbar,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 9},/area/mine/explored) "tQ" = (/obj/machinery/mining/drill,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored) "tR" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 5},/area/mine/explored) -"tS" = (/turf/simulated/wall,/area/mine/west_outpost) -"tT" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/west_outpost) -"tU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/west_outpost) -"tV" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/west_outpost) -"tW" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"tX" = (/obj/machinery/vending/cigarette,/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"tY" = (/obj/machinery/vending/snack,/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"tZ" = (/obj/machinery/light/small{dir = 4},/obj/machinery/door_control{id = "miningdorm3"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 25; pixel_y = 0; req_access_txt = "0"; specialfunctions = 4},/turf/simulated/floor/carpet,/area/mine/living_quarters) -"ua" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) -"ub" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) -"uc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) +"tS" = (/obj/machinery/light{dir = 8},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"tT" = (/obj/machinery/atmospherics/pipe/simple/visible/blue,/obj/machinery/meter,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"tU" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/obj/machinery/meter,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"tV" = (/obj/machinery/atmospherics/omni/filter{power_rating = 15000; tag_east = 4; tag_north = 1; tag_south = 2; tag_west = 3},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"tW" = (/obj/machinery/atmospherics/pipe/simple/visible/purple{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/obj/machinery/meter,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"tX" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"tY" = (/obj/machinery/light,/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_x = -6; pixel_y = -28},/turf/simulated/floor,/area/outpost/engineering/hallway) +"tZ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "eoutpost_main_pump"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/camera/autoname/engineering_outpost{dir = 1},/turf/simulated/floor,/area/outpost/engineering/hallway) +"ua" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/obj/machinery/atmospherics/pipe/simple/visible/blue{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"ub" = (/obj/machinery/atmospherics/pipe/simple/visible/blue{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"uc" = (/obj/machinery/atmospherics/omni/mixer{tag_east = 1; tag_east_con = 0.79; tag_south = 1; tag_south_con = 0.21; tag_west = 2},/turf/simulated/floor,/area/outpost/engineering/atmospherics) "ud" = (/obj/structure/table/reinforced,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) "ue" = (/obj/machinery/mining/brace,/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) "uf" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) -"ug" = (/obj/structure/table,/obj/item/weapon/pickaxe,/turf/simulated/floor,/area/mine/west_outpost) -"uh" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor,/area/mine/west_outpost) -"ui" = (/obj/structure/table,/obj/machinery/microwave,/turf/simulated/floor,/area/mine/west_outpost) -"uj" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/west_outpost) -"uk" = (/obj/machinery/recharge_station,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor,/area/mine/west_outpost) -"ul" = (/obj/structure/dispenser/oxygen,/turf/simulated/floor,/area/mine/west_outpost) -"um" = (/obj/structure/table/rack,/turf/simulated/floor,/area/mine/west_outpost) -"un" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/void/mining,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/void/mining,/obj/item/weapon/mining_scanner,/turf/simulated/floor,/area/mine/eva) -"uo" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/mine/west_outpost) -"up" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/west_outpost) -"uq" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_west_outpost_pump"},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/west_outpost) -"ur" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_west_outpost_pump"},/obj/structure/closet/walllocker/emerglocker/north,/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/mine/west_outpost) -"us" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/west_outpost) -"ut" = (/obj/structure/table,/obj/machinery/microwave{pixel_y = 6},/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"uu" = (/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"uv" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"uw" = (/obj/structure/stool/bed/chair,/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"ux" = (/obj/machinery/door/airlock{id_tag = "miningdorm3"; name = "Room 3"},/turf/simulated/floor{dir = 2; icon_state = "carpet"},/area/mine/living_quarters) -"uy" = (/obj/structure/ore_box,/turf/simulated/floor,/area/mine/living_quarters) -"uz" = (/obj/machinery/recharge_station,/obj/machinery/light/small{dir = 1},/turf/simulated/floor,/area/mine/living_quarters) -"uA" = (/obj/structure/closet/secure_closet/miner,/turf/simulated/floor,/area/mine/living_quarters) -"uB" = (/obj/structure/closet/secure_closet/miner,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/mine/living_quarters) +"ug" = (/obj/machinery/atmospherics/pipe/simple/visible/blue{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/meter,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"uh" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact (EAST)"},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"ui" = (/obj/machinery/atmospherics/binary/pump/on{dir = 8; target_pressure = 15000},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"uj" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/cyan,/obj/machinery/meter,/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"uk" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "eoutpost_main_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access = list(10)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/sign/vacuum{pixel_y = -32},/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/outpost/engineering/hallway) +"ul" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eoutpost_main_inner"; locked = 1; name = "Engineering Outpost"},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"um" = (/obj/machinery/power/emitter{anchored = 1; dir = 4; state = 2},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"un" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"uo" = (/obj/machinery/atmospherics/binary/pump/on{dir = 8},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"up" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"uq" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"ur" = (/obj/machinery/atmospherics/pipe/manifold/visible/cyan{tag = "icon-map (EAST)"; icon_state = "map"; dir = 4},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"us" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"ut" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"uu" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"uv" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eoutpost_main_outer"; locked = 1; name = "Engineering Outpost"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"uw" = (/turf/simulated/floor,/area/outpost/engineering/storage) +"ux" = (/obj/structure/table,/obj/item/stack/sheet/plasteel{amount = 10},/obj/item/stack/sheet/wood{amount = 30},/obj/item/stack/sheet/mineral/plastic{amount = 10},/turf/simulated/floor,/area/outpost/engineering/storage) +"uy" = (/turf/simulated/wall/r_wall,/area/outpost/engineering/storage) +"uz" = (/obj/structure/table/rack,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor,/area/outpost/engineering/storage) +"uA" = (/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"uB" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor/carpet,/area/outpost/engineering/meeting) "uC" = (/obj/structure/table/reinforced,/obj/machinery/cell_charger,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 10},/area/mine/explored) "uD" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) "uE" = (/obj/machinery/mining/brace,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) -"uF" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/mine/eva) -"uG" = (/turf/simulated/wall,/area/mine/eva) -"uH" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/eva) -"uI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/eva) -"uJ" = (/obj/structure/table,/obj/item/weapon/shovel,/turf/simulated/floor,/area/mine/west_outpost) -"uK" = (/turf/simulated/floor,/area/mine/west_outpost) -"uL" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor,/area/mine/west_outpost) -"uM" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/west_outpost) -"uN" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "mining_west_outpost_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = null},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/turf/simulated/floor,/area/mine/west_outpost) -"uO" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_west_outpost_inner"; locked = 1; name = "Mining External Access"; req_access = null; req_access_txt = null},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/mine/west_outpost) -"uP" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/west_outpost) -"uQ" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/mine/west_outpost) -"uR" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_west_outpost_outer"; locked = 1; name = "Mining External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/mine/west_outpost) -"uS" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) -"uT" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"uU" = (/obj/structure/stool/bed/chair{dir = 4},/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"uV" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"uW" = (/obj/structure/stool/bed/chair{dir = 8},/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"uX" = (/obj/machinery/light{dir = 4},/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"uY" = (/turf/simulated/floor,/area/mine/living_quarters) -"uZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/mine/living_quarters) -"va" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/structure/table/rack,/obj/item/weapon/rig/industrial,/turf/simulated/floor,/area/mine/living_quarters) -"vb" = (/obj/machinery/suit_cycler/mining,/turf/simulated/floor,/area/mine/eva) -"vc" = (/obj/machinery/light,/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"vd" = (/obj/structure/table,/obj/item/weapon/storage/backpack/satchel,/obj/item/clothing/glasses/meson,/obj/machinery/light/small{dir = 8},/turf/simulated/floor,/area/mine/west_outpost) -"ve" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/mine/west_outpost) -"vf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/west_outpost) -"vg" = (/obj/machinery/door/airlock/glass_mining{name = "Break Room"; req_access_txt = "54"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/west_outpost) -"vh" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/mine/west_outpost) -"vi" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/mine/west_outpost) -"vj" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/mine/west_outpost) -"vk" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "mining_west_outpost_pump"; tag_exterior_door = "mining_west_outpost_outer"; frequency = 1379; id_tag = "mining_west_outpost_airlock"; tag_interior_door = "mining_west_outpost_inner"; pixel_x = 0; pixel_y = -25; req_access_txt = null; tag_chamber_sensor = "mining_west_outpost_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "mining_west_outpost_pump"},/turf/simulated/floor,/area/mine/west_outpost) -"vl" = (/obj/structure/ore_box,/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "mining_west_outpost_sensor"; pixel_x = 0; pixel_y = -25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "mining_west_outpost_pump"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/mine/west_outpost) -"vm" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/camera{c_tag = "West Outpost - Airlock"; dir = 1; network = list("MINE")},/turf/simulated/floor/plating,/area/mine/west_outpost) -"vn" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"vo" = (/obj/machinery/camera{c_tag = "Crew Area"; dir = 1; network = list("MINE")},/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"vp" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"vq" = (/obj/item/weapon/cigbutt,/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"vr" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "bar"},/area/mine/living_quarters) -"vs" = (/obj/machinery/alarm{pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/living_quarters) -"vt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/living_quarters) -"vu" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/mine/living_quarters) -"vv" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/living_quarters) -"vw" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor,/area/mine/living_quarters) -"vx" = (/obj/machinery/camera{c_tag = "Storage Room"; dir = 1; network = list("MINE")},/turf/simulated/floor,/area/mine/living_quarters) -"vy" = (/obj/structure/table,/turf/simulated/floor/airless{icon_state = "damaged5"},/area/mine/abandoned) -"vz" = (/turf/simulated/wall,/area/mine/production) -"vA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"vB" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"vC" = (/obj/machinery/camera{c_tag = "EVA"; dir = 4; network = list("MINE")},/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor,/area/mine/eva) -"vD" = (/turf/simulated/floor,/area/mine/eva) -"vE" = (/obj/machinery/light_switch{pixel_x = 25; pixel_y = -9},/turf/simulated/floor,/area/mine/eva) -"vF" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor,/area/mine/west_outpost) -"vG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/mine/west_outpost) -"vH" = (/obj/machinery/conveyor_switch{id = "mining_west"; pixel_x = 5},/turf/simulated/floor,/area/mine/west_outpost) -"vI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) -"vJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) -"vK" = (/obj/machinery/door/airlock/glass{name = "Crew Area"; req_access_txt = "48"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/mine/living_quarters) -"vL" = (/obj/machinery/door/airlock/mining{name = "Mining Station Storage"; req_access_txt = "48"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/mine/living_quarters) -"vM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) -"vN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) -"vO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"vP" = (/obj/machinery/alarm{pixel_y = 24},/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/stack/flag/yellow,/obj/item/stack/flag/red,/turf/simulated/floor,/area/mine/production) -"vQ" = (/obj/structure/table,/obj/item/weapon/storage/backpack/satchel,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor,/area/mine/production) -"vR" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) -"vS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/mine/eva) -"vT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/eva) -"vU" = (/obj/structure/dispenser/oxygen,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/mine/eva) -"vV" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/eva) -"vW" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_east_pump"},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/eva) -"vX" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_east_pump"},/obj/structure/closet/walllocker/emerglocker/north,/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/mine/eva) -"vY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/eva) -"vZ" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor,/area/mine/west_outpost) -"wa" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor,/area/mine/west_outpost) -"wb" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/floor,/area/mine/west_outpost) -"wc" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/mine/west_outpost) -"wd" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/camera{c_tag = "West Outpost"; dir = 1; network = list("MINE")},/turf/simulated/floor,/area/mine/west_outpost) -"we" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/mine/west_outpost) -"wf" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor{dir = 4; icon_state = "loadingarea"},/area/mine/west_outpost) -"wg" = (/obj/machinery/mineral/input,/obj/machinery/conveyor{backwards = 2; dir = 2; forwards = 1; id = "mining_west"},/turf/simulated/floor,/area/mine/west_outpost) -"wh" = (/obj/machinery/mineral/unloading_machine,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/west_outpost) -"wi" = (/obj/machinery/conveyor{dir = 8; id = "mining_west"},/obj/machinery/mineral/output,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/west_outpost) -"wj" = (/obj/structure/disposalpipe/trunk{dir = 4},/obj/machinery/disposal/deliveryChute{dir = 8},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/west_outpost) -"wk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/west_outpost) -"wl" = (/obj/structure/toilet{dir = 4},/turf/simulated/floor{icon_state = "showroomfloor"},/area/mine/living_quarters) -"wm" = (/obj/structure/sink{pixel_y = 30},/obj/machinery/light/small,/obj/structure/mirror{pixel_y = -32},/turf/simulated/floor{icon_state = "showroomfloor"},/area/mine/living_quarters) -"wn" = (/obj/machinery/door/airlock{name = "Toilet"},/turf/simulated/floor{icon_state = "showroomfloor"},/area/mine/living_quarters) -"wo" = (/obj/machinery/alarm{pixel_y = 24},/turf/simulated/floor,/area/mine/living_quarters) -"wp" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor,/area/mine/living_quarters) -"wq" = (/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 30},/turf/simulated/floor,/area/mine/living_quarters) -"wr" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor,/area/mine/living_quarters) -"ws" = (/obj/machinery/camera{c_tag = "Crew Area Hallway"; network = list("MINE")},/turf/simulated/floor,/area/mine/living_quarters) -"wt" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/mine/living_quarters) -"wu" = (/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/mine/living_quarters) -"wv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) -"ww" = (/obj/structure/window/reinforced,/obj/structure/lattice,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/space,/area/mine/living_quarters) -"wx" = (/obj/structure/window/reinforced,/obj/structure/lattice,/turf/space,/area/mine/living_quarters) -"wy" = (/obj/structure/window/reinforced,/obj/structure/lattice,/turf/space,/area/mine/production) -"wz" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"wA" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"wB" = (/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/mine/production) -"wC" = (/turf/simulated/floor,/area/mine/production) -"wD" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/mine/production) -"wE" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) -"wF" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/airlock/glass_mining{name = "Mining Station EVA"; req_access_txt = "54"},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/mine/eva) -"wG" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/mine/eva) -"wH" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/mine/eva) -"wI" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "mining_east_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = null},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/mine/eva) -"wJ" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_east_inner"; locked = 1; name = "Mining External Access"; req_access = null; req_access_txt = null},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/mine/eva) -"wK" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/eva) -"wL" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/mine/eva) -"wM" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_east_outer"; locked = 1; name = "Mining External Access"; req_access = null; req_access_txt = "10;13"},/turf/simulated/floor/plating,/area/mine/eva) -"wN" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "mining_east_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = null},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) -"wO" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/wall,/area/mine/west_outpost) -"wP" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"},/turf/simulated/wall,/area/mine/west_outpost) -"wQ" = (/obj/machinery/door/airlock/maintenance{name = "Mining Station Maintenance"; req_access_txt = "54"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plating,/area/mine/west_outpost) -"wR" = (/obj/machinery/conveyor{backwards = 2; dir = 2; forwards = 1; id = "mining_west"},/obj/structure/plasticflaps/mining,/turf/simulated/floor,/area/mine/west_outpost) -"wS" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/mine/living_quarters) -"wT" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/mine/living_quarters) -"wU" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor,/area/mine/living_quarters) -"wV" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/living_quarters) -"wW" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor,/area/mine/living_quarters) -"wX" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/living_quarters) -"wY" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor,/area/mine/living_quarters) -"wZ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/turf/simulated/floor,/area/mine/living_quarters) -"xa" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/living_quarters) -"xb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/mine/living_quarters) -"xc" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/airlock/glass_mining{name = "Mining Station Bridge"; req_access_txt = "48"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/living_quarters) -"xd" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/living_quarters) -"xe" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/production) -"xf" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/airlock/glass_mining{name = "Mining Station Bridge"; req_access_txt = "48"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/production) -"xg" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/production) -"xh" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/mine/production) -"xi" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/production) -"xj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/eva) -"xk" = (/obj/structure/cable,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor,/area/mine/eva) -"xl" = (/obj/machinery/mech_bay_recharge_port,/turf/simulated/floor/plating,/area/mine/eva) -"xm" = (/turf/simulated/floor/mech_bay_recharge_floor,/area/mine/eva) -"xn" = (/obj/machinery/computer/mech_bay_power_console,/turf/simulated/floor,/area/mine/eva) -"xo" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "mining_east_pump"; tag_exterior_door = "mining_east_outer"; frequency = 1379; id_tag = "mining_east_airlock"; tag_interior_door = "mining_east_inner"; pixel_x = 0; pixel_y = -25; req_access_txt = null; tag_chamber_sensor = "mining_east_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "mining_east_pump"},/turf/simulated/floor,/area/mine/eva) -"xp" = (/obj/structure/ore_box,/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "mining_east_sensor"; pixel_x = 0; pixel_y = -25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "mining_east_pump"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/mine/eva) -"xq" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/camera{c_tag = "Production Line External"; dir = 1; network = list("MINE")},/turf/simulated/floor/plating,/area/mine/eva) -"xr" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/hidden/cyan,/turf/simulated/floor/plating,/area/mine/west_outpost) -"xs" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor/plating,/area/mine/west_outpost) -"xt" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "mining_west_outpost_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = null},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) -"xu" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"uF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/storage) +"uG" = (/obj/machinery/vending/snack,/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"uH" = (/obj/structure/flora/pottedplant{tag = "icon-plant-21"; icon_state = "plant-21"},/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"uI" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor/carpet,/area/outpost/engineering/meeting) +"uJ" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor/carpet,/area/outpost/engineering/meeting) +"uK" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/turf/simulated/floor/carpet,/area/outpost/engineering/meeting) +"uL" = (/turf/simulated/wall/r_wall,/area/outpost/engineering/power) +"uM" = (/obj/structure/bed/chair,/turf/simulated/floor/carpet,/area/outpost/engineering/meeting) +"uN" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/bed/chair,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/carpet,/area/outpost/engineering/meeting) +"uO" = (/obj/structure/table,/obj/random/tech_supply,/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"uP" = (/turf/simulated/floor/carpet,/area/outpost/engineering/meeting) +"uQ" = (/obj/structure/table/rack,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/item/stack/cable_coil/yellow,/obj/item/stack/cable_coil,/turf/simulated/floor,/area/outpost/engineering/storage) +"uR" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/outpost/engineering/storage) +"uS" = (/obj/structure/cable/blue,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor,/area/outpost/engineering/storage) +"uT" = (/turf/simulated/wall,/area/outpost/engineering/storage) +"uU" = (/obj/machinery/floodlight,/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"uV" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"uW" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/camera/autoname/engineering_outpost{dir = 1},/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor,/area/outpost/engineering/hallway) +"uX" = (/obj/machinery/light{dir = 1},/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor,/area/outpost/engineering/hallway) +"uY" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/firealarm{dir = 1; pixel_x = 0; pixel_y = -24},/turf/simulated/floor,/area/outpost/engineering/hallway) +"uZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/outpost/engineering/storage) +"va" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -28},/turf/simulated/floor,/area/outpost/engineering/hallway) +"vb" = (/obj/structure/table/rack,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/item/stack/cable_coil/yellow,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/outpost/engineering/storage) +"vc" = (/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"vd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"ve" = (/turf/simulated/wall,/area/outpost/engineering/meeting) +"vf" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "edock_outer"; locked = 1; name = "Engineering Dock Airlock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"vg" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"vh" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"vi" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/outpost/engineering/hallway) +"vj" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "edock_outer"; locked = 1; name = "Engineering Dock Airlock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"vk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/engineering/hallway) +"vl" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light{dir = 8},/turf/simulated/floor,/area/outpost/engineering/hallway) +"vm" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "edock_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = 0; req_access = list(10)},/turf/space,/area/space) +"vn" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/obj/machinery/light{dir = 8},/turf/simulated/floor,/area/outpost/engineering/hallway) +"vo" = (/obj/machinery/power/solar_control,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"vp" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/outpost/engineering/hallway) +"vq" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1380; id_tag = "eoutpost_dock_pump"},/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "edock_airlock"; pixel_x = 30; pixel_y = 0; req_access = list(10); tag_airpump = "edock_pump"; tag_chamber_sensor = "edock_sensor"; tag_exterior_door = "edock_outer"; tag_interior_door = "edock_inner"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"vr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"vs" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"vt" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/camera/autoname/engineering_outpost{dir = 1},/turf/simulated/floor,/area/outpost/engineering/hallway) +"vu" = (/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating/airless,/area/space) +"vv" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/power) +"vw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/engineering/power) +"vx" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/outpost/engineering/hallway) +"vy" = (/obj/machinery/computer/shuttle_control/engineering,/turf/simulated/floor,/area/outpost/engineering/hallway) +"vz" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/outpost/engineering/hallway) +"vA" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{tag = "icon-intact (NORTH)"; icon_state = "intact"; dir = 1},/turf/simulated/floor,/area/outpost/engineering/hallway) +"vB" = (/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"vC" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"vD" = (/obj/machinery/vending/cigarette,/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"vE" = (/obj/structure/cable/blue,/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/obj/machinery/power/sensor{long_range = 1; name_tag = "Engineering Outpost"},/turf/simulated/floor,/area/outpost/engineering/power) +"vF" = (/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor,/area/outpost/engineering/power) +"vG" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/engineering/power) +"vH" = (/obj/structure/table/rack,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/item/weapon/pickaxe,/turf/simulated/floor,/area/outpost/engineering/storage) +"vI" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor,/area/outpost/engineering/storage) +"vJ" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Storage"; req_access = list(10)},/turf/simulated/floor,/area/outpost/engineering/storage) +"vK" = (/obj/machinery/light{dir = 8},/obj/structure/table,/obj/machinery/microwave,/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"vL" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"vM" = (/turf/simulated/wall/r_wall,/area/outpost/engineering/telecomms) +"vN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor/bluegrid{name = "Mainframe Base"; nitrogen = 82.1472; oxygen = 21.8366; temperature = 293.15},/area/outpost/engineering/telecomms) +"vO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Server Walkway"; nitrogen = 82.1472; oxygen = 21.8366; temperature = 293.15},/area/outpost/engineering/telecomms) +"vP" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 6; icon_state = "intact"; tag = "icon-intact-f (SOUTHEAST)"},/obj/machinery/light{dir = 1},/obj/structure/closet/walllocker/emerglocker/north,/turf/simulated/floor,/area/outpost/engineering/hallway) +"vQ" = (/obj/structure/table,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"vR" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/storage) +"vS" = (/obj/structure/table,/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"vT" = (/obj/structure/table,/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/turf/simulated/floor,/area/outpost/engineering/storage) +"vU" = (/obj/structure/dispenser/oxygen,/turf/simulated/floor,/area/outpost/engineering/storage) +"vV" = (/obj/machinery/telecomms/relay/preset/mining,/obj/machinery/light{dir = 1},/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Server Walkway"; nitrogen = 82.1472; oxygen = 21.8366; temperature = 293.15},/area/outpost/engineering/telecomms) +"vW" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/machinery/alarm{frequency = 1439; pixel_y = 22},/turf/simulated/floor/bluegrid{name = "Mainframe Base"; nitrogen = 82.1472; oxygen = 21.8366; temperature = 293.15},/area/outpost/engineering/telecomms) +"vX" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/bluegrid{name = "Mainframe Base"; nitrogen = 82.1472; oxygen = 21.8366; temperature = 293.15},/area/outpost/engineering/telecomms) +"vY" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/cyan,/turf/simulated/floor,/area/outpost/engineering/hallway) +"vZ" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"wa" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/outpost/engineering/hallway) +"wb" = (/obj/structure/cable/yellow{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"wc" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/power) +"wd" = (/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/turf/simulated/floor,/area/outpost/engineering/power) +"we" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor,/area/outpost/engineering/power) +"wf" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor,/area/outpost/engineering/power) +"wg" = (/obj/machinery/power/smes/buildable/outpost_substation{charge = 500000; input_attempt = 1; input_level = 150000; output_level = 150000; RCon_tag = "Outpost - Engineering"},/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/outpost/engineering/power) +"wh" = (/obj/machinery/pipedispenser/disposal,/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"wi" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/carpet,/area/outpost/engineering/meeting) +"wj" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/carpet,/area/outpost/engineering/meeting) +"wk" = (/obj/machinery/door/airlock/engineering{name = "Restrooms"; req_access = list(10)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/engineering/meeting) +"wl" = (/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating/airless,/area/space) +"wm" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor,/area/outpost/engineering/hallway) +"wn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/glass_engineering{name = "Telecommunications"; req_access = list(10)},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/bluegrid{icon_state = "dark"; name = "Server Walkway"; nitrogen = 82.1472; oxygen = 21.8366; temperature = 293.15},/area/outpost/engineering/hallway) +"wo" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan,/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/outpost/engineering/hallway) +"wp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Power Distribution Center"; req_access = list(10)},/turf/simulated/floor,/area/outpost/engineering/hallway) +"wq" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating/airless,/area/space) +"wr" = (/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating/airless,/area/space) +"ws" = (/obj/machinery/power/tracker,/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating/airless,/area/space) +"wt" = (/obj/structure/table,/obj/machinery/cell_charger,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"wu" = (/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/apc/super{dir = 1; pixel_y = 24},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"wv" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor,/area/outpost/engineering/hallway) +"ww" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"wx" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/power) +"wy" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes/buildable{charge = 1.5e+007; cur_coils = 3; input_attempt = 1; input_level = 750000; input_level_max = 750000; output_level = 750000; output_level_max = 750000; RCon_tag = "Outpost - Main"},/turf/simulated/floor,/area/outpost/engineering/power) +"wz" = (/obj/machinery/power/port_gen/pacman/super,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"wA" = (/obj/machinery/power/port_gen/pacman/mrs,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"wB" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/terminal,/turf/simulated/floor,/area/outpost/engineering/power) +"wC" = (/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 28},/turf/simulated/floor,/area/outpost/engineering/hallway) +"wD" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/machinery/power/sensor{long_range = 1; name_tag = "Asteroid Main Grid"},/turf/simulated/floor,/area/outpost/engineering/power) +"wE" = (/obj/structure/table,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/carpet,/area/outpost/engineering/meeting) +"wF" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/turf/simulated/floor/carpet,/area/outpost/engineering/meeting) +"wG" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/pipedispenser,/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"wH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor/plating,/area/outpost/engineering/storage) +"wI" = (/obj/machinery/vending/coffee,/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"wJ" = (/obj/structure/table/rack,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/item/stack/cable_coil/yellow,/obj/machinery/light{dir = 8},/turf/simulated/floor,/area/outpost/engineering/storage) +"wK" = (/obj/structure/table,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/turf/simulated/floor,/area/outpost/engineering/storage) +"wL" = (/obj/structure/cable/yellow,/turf/simulated/floor/plating/airless,/area/space) +"wM" = (/obj/machinery/status_display{layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"wN" = (/turf/simulated/wall,/area/outpost/mining_main/east_hall) +"wO" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"wP" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHEAST)"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"wQ" = (/turf/simulated/wall,/area/outpost/mining_main/refinery) +"wR" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Break Room"; req_access = list(10)},/turf/simulated/floor,/area/outpost/engineering/hallway) +"wS" = (/obj/machinery/conveyor{dir = 2; id = "mining_internal"},/obj/machinery/mineral/output,/obj/structure/plasticflaps/mining,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"wT" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/outpost/mining_main/medbay) +"wU" = (/obj/machinery/light/small{dir = 8},/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/turf/simulated/floor{icon_state = "white"},/area/outpost/mining_main/medbay) +"wV" = (/turf/simulated/wall,/area/outpost/mining_main/medbay) +"wW" = (/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/obj/machinery/power/smes/buildable/outpost_substation{charge = 500000; input_attempt = 1; input_level = 150000; output_level = 150000; RCon_tag = "Outpost - Mining"},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"wX" = (/turf/simulated/wall,/area/outpost/mining_main/maintenance) +"wY" = (/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor{icon_state = "white"},/area/outpost/mining_main/medbay) +"wZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{icon_state = "white"},/area/outpost/mining_main/medbay) +"xa" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"xb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"xc" = (/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"xd" = (/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/obj/machinery/power/sensor{long_range = 1; name_tag = "Mining Outpost"},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"xe" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "eoutpost_solar_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25; req_access = list(10)},/turf/simulated/floor/plating/airless,/area/outpost/engineering/hallway) +"xf" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/west_hall) +"xg" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "mining_west_pump"},/obj/structure/closet/walllocker/emerglocker/west,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/west_hall) +"xh" = (/turf/simulated/wall,/area/outpost/mining_main/west_hall) +"xi" = (/obj/machinery/conveyor{dir = 4; id = "mining_internal"},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"xj" = (/obj/machinery/conveyor{dir = 9; id = "mining_internal"},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"xk" = (/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"xl" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "eoutpost_solar_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25; req_access = list(10)},/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/outpost/engineering/hallway) +"xm" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eoutpost_solar_inner"; locked = 1; name = "Solar Access"},/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"xn" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "eoutpost_solar_pump"},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "eoutpost_solar_airlock"; pixel_x = 0; pixel_y = -25; req_access = list(10); tag_airpump = "eoutpost_solar_pump"; tag_chamber_sensor = "eoutpost_solar_sensor"; tag_exterior_door = "eoutpost_solar_outer"; tag_interior_door = "eoutpost_solar_inner"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "eoutpost_solar_sensor"; pixel_x = 0; pixel_y = 25},/obj/machinery/light/small{dir = 1},/obj/machinery/camera/autoname/engineering_outpost,/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"xo" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"xp" = (/obj/machinery/conveyor{dir = 4; id = "mining_internal"},/obj/structure/plasticflaps/mining,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"xq" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "eoutpost_solar_outer"; locked = 1; name = "Solar Access"},/turf/simulated/floor/plating,/area/outpost/engineering/hallway) +"xr" = (/obj/machinery/conveyor{dir = 2; id = "mining_internal"},/obj/structure/plasticflaps/mining,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"xs" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"xt" = (/obj/machinery/light/small{dir = 4},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "mining_west_sensor"; pixel_x = 25; pixel_y = -5},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "mining_west_pump"; tag_exterior_door = "mining_west_outer"; frequency = 1379; id_tag = "mining_west_airlock"; tag_interior_door = "mining_west_inner"; pixel_x = 25; pixel_y = 5; tag_chamber_sensor = "mining_west_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "mining_west_pump"},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"xu" = (/obj/machinery/sleep_console,/turf/simulated/floor{icon_state = "warnwhite"; dir = 5},/area/outpost/mining_main/medbay) "xv" = (/obj/structure/ore_box,/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) -"xw" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor,/area/mine/living_quarters) -"xx" = (/obj/machinery/light,/turf/simulated/floor,/area/mine/living_quarters) -"xy" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/mine/living_quarters) -"xz" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "mining_west_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25; req_access_txt = null},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/mine/living_quarters) -"xA" = (/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/mine/living_quarters) -"xB" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) -"xC" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/lattice,/turf/space,/area/mine/living_quarters) -"xD" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/lattice,/turf/space,/area/mine/production) -"xE" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/lattice,/obj/machinery/light{dir = 4},/turf/space,/area/mine/production) -"xF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"xG" = (/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/mine/production) -"xH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/mine/production) -"xI" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/mine/production) +"xw" = (/obj/machinery/sleeper,/turf/simulated/floor{icon_state = "warnwhite"; dir = 1},/area/outpost/mining_main/medbay) +"xx" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/firstaid/regular,/turf/simulated/floor{icon_state = "white"},/area/outpost/mining_main/medbay) +"xy" = (/obj/machinery/camera{c_tag = "Sleeper Room"; dir = 1; network = list("MINE")},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{icon_state = "white"},/area/outpost/mining_main/medbay) +"xz" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/machinery/light/small{dir = 8},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"xA" = (/obj/machinery/atmospherics/valve/digital/open{dir = 4},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"xB" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"xC" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/turf/simulated/floor,/area/outpost/engineering/hallway) +"xD" = (/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"xE" = (/obj/structure/ore_box,/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "mining_west_pump"},/turf/simulated/floor{icon_state = "warning"},/area/outpost/mining_main/west_hall) +"xF" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "mining_west_pump"},/turf/simulated/floor{icon_state = "warning"},/area/outpost/mining_main/west_hall) +"xG" = (/obj/machinery/atmospherics/pipe/manifold/hidden,/turf/simulated/floor{icon_state = "warning"},/area/outpost/mining_main/west_hall) +"xH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"xI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/west_hall) "xJ" = (/obj/machinery/conveyor_switch{id = "mining_external"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) -"xK" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 1; initialize_directions = 0; level = 1},/turf/simulated/floor/plating,/area/mine/west_outpost) -"xL" = (/obj/machinery/power/port_gen/pacman{anchored = 1},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plating,/area/mine/west_outpost) -"xM" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"xN" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"xO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) -"xP" = (/obj/machinery/door/airlock/glass_medical{name = "Infirmary"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/mine/living_quarters) -"xQ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"},/turf/simulated/wall,/area/mine/living_quarters) -"xR" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/airlock/maintenance{name = "Mining Station Maintenance"; req_access_txt = "48"},/turf/simulated/floor/plating,/area/mine/living_quarters) -"xS" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/simulated/wall,/area/mine/living_quarters) -"xT" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_west_inner"; locked = 1; name = "Mining External Access"; req_access = null; req_access_txt = null},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/mine/living_quarters) -"xU" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters) -"xV" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"xW" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/mine/production) -"xX" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/mine/production) -"xY" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-j2"; dir = 4},/turf/simulated/wall,/area/mine/production) -"xZ" = (/obj/structure/disposaloutlet{dir = 4},/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"ya" = (/obj/machinery/conveyor{dir = 4; id = "mining_internal"},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"yb" = (/obj/machinery/conveyor{dir = 9; id = "mining_internal"},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"yc" = (/obj/machinery/mineral/unloading_machine{icon_state = "unloader-corner"},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"yd" = (/obj/machinery/conveyor{dir = 4; id = "mining_external"},/obj/machinery/mineral/input,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"ye" = (/obj/machinery/conveyor{dir = 4; id = "mining_external"},/obj/structure/plasticflaps/mining,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"yf" = (/obj/machinery/conveyor{dir = 4; id = "mining_external"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"yg" = (/obj/machinery/light/small{dir = 8},/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/turf/simulated/floor{icon_state = "white"},/area/mine/living_quarters) -"yh" = (/turf/simulated/floor{icon_state = "white"},/area/mine/living_quarters) -"yi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/mine/living_quarters) -"yj" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) -"yk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/mine/production) -"yl" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/mine/living_quarters) -"ym" = (/obj/structure/table,/obj/item/weapon/storage/belt/utility,/obj/item/weapon/pickaxe,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/mine/production) -"yn" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating,/area/mine/living_quarters) -"yo" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "mining_west_pump"},/obj/structure/closet/walllocker/emerglocker/west,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/living_quarters) -"yp" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold4w/hidden,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/living_quarters) -"yq" = (/obj/machinery/light/small{dir = 4},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "mining_west_sensor"; pixel_x = 25; pixel_y = -5},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "mining_west_pump"; tag_exterior_door = "mining_west_outer"; frequency = 1379; id_tag = "mining_west_airlock"; tag_interior_door = "mining_west_inner"; pixel_x = 25; pixel_y = 5; req_access_txt = null; tag_chamber_sensor = "mining_west_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "mining_west_pump"},/turf/simulated/floor,/area/mine/living_quarters) -"yr" = (/obj/machinery/status_display{layer = 4; pixel_x = -32; pixel_y = 0},/turf/simulated/floor,/area/mine/production) -"ys" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 5; icon_state = "intact"; tag = "icon-intact-f (NORTHEAST)"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/mine/production) -"yt" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/mine/production) -"yu" = (/obj/machinery/conveyor{dir = 2; id = "mining_internal"},/obj/structure/plasticflaps/mining,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"yv" = (/obj/machinery/conveyor{dir = 2; id = "mining_internal"},/obj/machinery/mineral/output,/obj/structure/plasticflaps/mining,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"yw" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"yx" = (/obj/machinery/sleeper,/turf/simulated/floor{icon_state = "warnwhite"; dir = 1},/area/mine/living_quarters) -"yy" = (/obj/machinery/sleep_console,/turf/simulated/floor{icon_state = "warnwhite"; dir = 5},/area/mine/living_quarters) -"yz" = (/obj/machinery/camera{c_tag = "Sleeper Room"; dir = 1; network = list("MINE")},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor{icon_state = "white"},/area/mine/living_quarters) -"yA" = (/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{pixel_x = 2; pixel_y = 2},/obj/item/weapon/storage/firstaid/regular,/turf/simulated/floor{icon_state = "white"},/area/mine/living_quarters) -"yB" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) -"yC" = (/turf/simulated/floor/plating,/area/mine/living_quarters) -"yD" = (/obj/machinery/power/sensor{long_range = 1; name = "Powernet Sensor - Mining Outpost Grid"; name_tag = "Mining Outpost Grid"},/obj/structure/cable,/turf/simulated/floor/plating,/area/mine/living_quarters) -"yE" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/turf/simulated/floor/plating,/area/mine/living_quarters) -"yF" = (/obj/structure/ore_box,/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "mining_west_pump"},/turf/simulated/floor{icon_state = "warning"},/area/mine/living_quarters) -"yG" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden,/turf/simulated/floor{icon_state = "warning"},/area/mine/living_quarters) -"yH" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "mining_west_pump"},/turf/simulated/floor{icon_state = "warning"},/area/mine/living_quarters) +"xK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"xL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"xM" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/alarm{frequency = 1439; pixel_y = 22},/obj/machinery/camera/autoname/engineering_outpost,/turf/simulated/floor,/area/outpost/engineering/hallway) +"xN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/visible/universal{dir = 4},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"xO" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/east_hall) +"xP" = (/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"xQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/east_hall) +"xR" = (/obj/machinery/mineral/unloading_machine,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"xS" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"xT" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/refinery) +"xU" = (/obj/machinery/conveyor{dir = 2; id = "mining_internal"},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"xV" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"xW" = (/obj/machinery/mineral/input,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor{dir = 4; icon_state = "loadingarea"},/area/outpost/mining_main/refinery) +"xX" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"xY" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/refinery) +"xZ" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"ya" = (/obj/structure/closet/emcloset,/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/outpost/mining_main/east_hall) +"yb" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/east_hall) +"yc" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/east_hall) +"yd" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/east_hall) +"ye" = (/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor,/area/outpost/mining_main/refinery) +"yf" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/outpost/mining_main/refinery) +"yg" = (/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 30},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/outpost/mining_main/refinery) +"yh" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/alarm{pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/refinery) +"yi" = (/obj/structure/closet/crate,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"yj" = (/obj/structure/closet/crate,/obj/structure/noticeboard{pixel_y = 27},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"yk" = (/obj/machinery/conveyor{dir = 4; id = "mining_internal"},/obj/machinery/mineral/output,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"yl" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"ym" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_west_outer"; locked = 1; name = "Mining External Access"},/turf/simulated/floor/plating,/area/outpost/mining_main/west_hall) +"yn" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"yo" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/outpost/mining_main/refinery) +"yp" = (/obj/machinery/camera{c_tag = "Shuttle Airlock"; dir = 8; network = list("MINE")},/obj/machinery/conveyor_switch/oneway{id = "mining_internal"; name = "mining conveyor"},/obj/machinery/light{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"yq" = (/obj/machinery/camera{c_tag = "Production Room"; dir = 8; network = list("MINE")},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/mining_main/refinery) +"yr" = (/turf/simulated/floor,/area/outpost/mining_main/refinery) +"ys" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "mining_west_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"yt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"yu" = (/obj/machinery/door/window/westright{name = "Production Area"; req_access = list(48)},/turf/simulated/floor,/area/outpost/mining_main/refinery) +"yv" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"yw" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "mining_outpost_outer"; locked = 1; name = "Mining Dock Airlock"; req_access = list(13)},/turf/simulated/floor/plating,/area/outpost/mining_main/east_hall) +"yx" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "mining_outpost_inner"; locked = 1; name = "Mining Dock Airlock"; req_access = list(13)},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"yy" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/refinery) +"yz" = (/obj/machinery/mineral/input,/turf/simulated/floor{icon_state = "loadingarea"},/area/outpost/mining_main/refinery) +"yA" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) +"yB" = (/obj/machinery/mineral/processing_unit_console,/turf/simulated/wall/r_wall,/area/outpost/mining_main/refinery) +"yC" = (/obj/machinery/mineral/processing_unit,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"yD" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"yE" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "mining_outpost_airlock"; pixel_x = 0; pixel_y = 30; req_one_access = list(13,48); tag_airpump = "mining_outpost_pump"; tag_chamber_sensor = "mining_outpost_sensor"; tag_exterior_door = "mining_outpost_outer"; tag_interior_door = "mining_outpost_inner"},/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "mining_outpost_sensor"; pixel_x = 0; pixel_y = -25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "mining_outpost_pump"},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"yF" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"yG" = (/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/outpost/mining_main/refinery) +"yH" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/mining_main/refinery) "yI" = (/turf/space,/area/shuttle/mining/outpost) -"yJ" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor,/area/mine/production) -"yK" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/mine/production) -"yL" = (/obj/machinery/mineral/input,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor{dir = 4; icon_state = "loadingarea"},/area/mine/production) -"yM" = (/obj/machinery/mineral/unloading_machine,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"yN" = (/obj/machinery/conveyor{dir = 4; id = "mining_internal"},/obj/machinery/mineral/output,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"yO" = (/obj/machinery/conveyor{dir = 4; id = "mining_internal"},/obj/structure/plasticflaps/mining,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"yP" = (/obj/structure/cable,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/power/port_gen/pacman{anchored = 1},/turf/simulated/floor/plating,/area/mine/living_quarters) -"yQ" = (/obj/machinery/power/port_gen/pacman{anchored = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/mine/living_quarters) -"yR" = (/obj/machinery/atmospherics/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/mine/living_quarters) -"yS" = (/obj/structure/reagent_dispensers/fueltank,/obj/machinery/atmospherics/pipe/manifold/hidden/cyan,/turf/simulated/floor/plating,/area/mine/living_quarters) -"yT" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_west_outer"; locked = 1; name = "Mining External Access"; req_access = null; req_access_txt = null},/turf/simulated/floor/plating,/area/mine/living_quarters) -"yU" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/mine/production) -"yV" = (/obj/machinery/camera{c_tag = "Shuttle Airlock"; dir = 8; network = list("MINE")},/obj/machinery/conveyor_switch/oneway{id = "mining_internal"; name = "mining conveyor"},/obj/machinery/light{dir = 4},/turf/simulated/floor,/area/mine/production) -"yW" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"yX" = (/obj/machinery/conveyor{dir = 2; id = "mining_internal"},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"yY" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "mining_west_airlock"; name = "exterior access button"; pixel_x = 25; pixel_y = 25; req_access_txt = null},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"yJ" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "mining_outpost_airlock"; name = "interior access button"; pixel_x = -30; pixel_y = -25; req_one_access = list(13,48)},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; icon_state = "intact"; tag = "icon-intact-f (SOUTHWEST)"},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"yK" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/east_hall) +"yL" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/outpost/mining_main/east_hall) +"yM" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/east_hall) +"yN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 10},/area/mine/explored) +"yO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"yP" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"yQ" = (/obj/structure/closet/crate,/turf/simulated/floor,/area/outpost/mining_main/refinery) +"yR" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/closet/crate,/turf/simulated/floor,/area/outpost/mining_main/refinery) +"yS" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"yT" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/east_hall) +"yU" = (/obj/machinery/computer/shuttle_control/mining,/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"yV" = (/obj/machinery/conveyor{dir = 2; id = "mining_internal"},/obj/machinery/mineral/output,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"yW" = (/turf/space,/area/mine/explored) +"yX" = (/obj/machinery/mineral/stacking_unit_console,/turf/simulated/wall/r_wall,/area/outpost/mining_main/refinery) +"yY" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/refinery) "yZ" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"za" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"zb" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"zc" = (/obj/structure/closet/emcloset,/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/mine/production) -"zd" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/mine/production) -"ze" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor,/area/mine/production) -"zf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/production) -"zg" = (/obj/structure/closet/crate,/obj/structure/noticeboard{pixel_y = 27},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/production) -"zh" = (/obj/structure/closet/crate,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/production) -"zi" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/alarm{pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/production) -"zj" = (/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 30},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/production) -"zk" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/mine/production) -"zl" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/mine/production) -"zm" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"zn" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor,/area/mine/production) -"zo" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) -"zp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) -"zq" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "mining_outpost_outer"; locked = 1; name = "Mining Dock Airlock"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/mine/production) -"zr" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 1380; id_tag = "mining_outpost_airlock"; pixel_x = 0; pixel_y = 30; req_access_txt = "0"; req_one_access_txt = "13;48"; tag_airpump = "mining_outpost_pump"; tag_chamber_sensor = "mining_outpost_sensor"; tag_exterior_door = "mining_outpost_outer"; tag_interior_door = "mining_outpost_inner"},/obj/machinery/airlock_sensor{frequency = 1380; id_tag = "mining_outpost_sensor"; pixel_x = 0; pixel_y = -25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "mining_outpost_pump"},/turf/simulated/floor,/area/mine/production) -"zs" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "mining_outpost_inner"; locked = 1; name = "Mining Dock Airlock"; req_access = null; req_access_txt = "13"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4; icon_state = "intact"; tag = "icon-intact-f (EAST)"},/turf/simulated/floor,/area/mine/production) -"zt" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1380; master_tag = "mining_outpost_airlock"; name = "interior access button"; pixel_x = -30; pixel_y = -25; req_access_txt = "0"; req_one_access_txt = "13;48"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 10; icon_state = "intact"; tag = "icon-intact-f (SOUTHWEST)"},/turf/simulated/floor,/area/mine/production) -"zu" = (/obj/machinery/door/window/westright{name = "Production Area"; req_access_txt = "48"},/turf/simulated/floor,/area/mine/production) -"zv" = (/obj/machinery/camera{c_tag = "Production Room"; dir = 8; network = list("MINE")},/turf/simulated/floor,/area/mine/production) -"zw" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"zx" = (/obj/machinery/mineral/input,/turf/simulated/floor{icon_state = "loadingarea"},/area/mine/production) -"zy" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/mine/production) -"zz" = (/obj/machinery/door/window/westleft{name = "Production Area"; req_access_txt = "48"},/turf/simulated/floor,/area/mine/production) -"zA" = (/obj/machinery/mineral/processing_unit_console,/turf/simulated/wall/r_wall,/area/mine/production) -"zB" = (/obj/machinery/mineral/processing_unit,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) +"za" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/refinery) +"zb" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/refinery) +"zc" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"zd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"ze" = (/obj/structure/disposalpipe/segment,/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"zf" = (/turf/simulated/wall/r_wall,/area/outpost/mining_main/east_hall) +"zg" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/turf/simulated/floor,/area/outpost/engineering/hallway) +"zh" = (/obj/structure/table,/obj/machinery/microwave{pixel_y = 6},/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"zi" = (/turf/simulated/wall,/area/outpost/mining_main/dorms) +"zj" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"zk" = (/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"zl" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_west_outpost_pump"},/obj/structure/closet/walllocker/emerglocker/north,/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/mining_west) +"zm" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_west) +"zn" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_west) +"zo" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_west_outpost_pump"},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_west) +"zp" = (/obj/structure/table,/obj/machinery/microwave,/turf/simulated/floor,/area/outpost/mining_west) +"zq" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor,/area/outpost/mining_west) +"zr" = (/obj/machinery/recharge_station,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor,/area/outpost/mining_west) +"zs" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_west) +"zt" = (/obj/structure/table/rack,/obj/machinery/light{dir = 1},/turf/simulated/floor,/area/outpost/mining_west) +"zu" = (/obj/structure/dispenser/oxygen,/turf/simulated/floor,/area/outpost/mining_west) +"zv" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/outpost/mining_west) +"zw" = (/obj/structure/table/rack,/turf/simulated/floor,/area/outpost/mining_west) +"zx" = (/obj/structure/table,/obj/item/weapon/pickaxe,/turf/simulated/floor,/area/outpost/mining_west) +"zy" = (/turf/simulated/wall,/area/outpost/mining_west) +"zz" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) +"zA" = (/turf/simulated/wall,/area/outpost/mining_main/eva) +"zB" = (/obj/structure/disposalpipe/segment,/turf/simulated/wall,/area/outpost/mining_main/eva) "zC" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored) -"zD" = (/obj/structure/lattice,/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "mining_outpost_airlock"; name = "exterior access button"; pixel_x = -8; pixel_y = 25; req_access_txt = "0"; req_one_access_txt = "13;48"},/turf/space,/area/space) -"zE" = (/obj/machinery/computer/shuttle_control/mining,/turf/simulated/floor,/area/mine/production) -"zF" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/closet/crate,/turf/simulated/floor,/area/mine/production) -"zG" = (/obj/structure/closet/crate,/turf/simulated/floor,/area/mine/production) -"zH" = (/obj/machinery/conveyor{dir = 2; id = "mining_internal"},/obj/machinery/mineral/output,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"zI" = (/turf/simulated/wall/r_wall,/area/mine/production) -"zJ" = (/obj/structure/disposalpipe/segment,/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor,/area/mine/production) -"zK" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"zL" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"zM" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"zN" = (/obj/machinery/mineral/stacking_unit_console,/turf/simulated/wall/r_wall,/area/mine/production) -"zO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/turf/simulated/floor/plating,/area/mine/explored) -"zP" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/mine/explored) -"zQ" = (/obj/structure/lattice,/obj/structure/disposalpipe/segment{dir = 4},/turf/space,/area/space) -"zR" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall/r_wall,/area/mine/production) -"zS" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production) -"zT" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor,/area/mine/production) -"zU" = (/turf/simulated/floor{dir = 8; icon_state = "loadingarea"},/area/mine/production) -"zV" = (/obj/machinery/conveyor{dir = 8; id = "mining_internal"},/obj/structure/plasticflaps,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"zW" = (/obj/machinery/conveyor{dir = 8; id = "mining_internal"},/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"zX" = (/obj/machinery/conveyor{dir = 8; id = "mining_internal"},/obj/machinery/mineral/output,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"zY" = (/obj/machinery/mineral/stacking_machine,/turf/simulated/floor{icon_state = "floorgrime"},/area/mine/production) -"zZ" = (/obj/machinery/conveyor{icon_state = "conveyor0"; dir = 10; id = "mining_internal"},/obj/machinery/mineral/input,/turf/simulated/floor{dir = 8; icon_state = "loadingarea"},/area/mine/production) -"Aa" = (/turf/space,/area/vox_station/mining) -"Ab" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"Ac" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) -"Ad" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"zD" = (/obj/machinery/door/window/westleft{name = "Production Area"; req_access = list(48)},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/mining_main/refinery) +"zE" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/eva) +"zF" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/eva) +"zG" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"zH" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"zI" = (/obj/structure/bed/chair,/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"zJ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/dorms) +"zK" = (/obj/machinery/door/airlock{id_tag = "miningdorm3"; name = "Room 3"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "carpet"},/area/outpost/mining_main/dorms) +"zL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/carpet,/area/outpost/mining_main/dorms) +"zM" = (/obj/structure/table,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor/carpet,/area/outpost/mining_main/dorms) +"zN" = (/obj/structure/closet/secure_closet/miner,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"zO" = (/obj/machinery/recharge_station,/obj/machinery/light/small{dir = 1},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"zP" = (/obj/structure/ore_box,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"zQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/west_hall) +"zR" = (/obj/structure/closet/secure_closet/miner,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"zS" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"zT" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"zU" = (/obj/structure/lattice,/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1380; master_tag = "mining_outpost_airlock"; name = "exterior access button"; pixel_x = -8; pixel_y = 25; req_one_access = list(13,48)},/turf/space,/area/space) +"zV" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "mining_west_outpost_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"zW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"zX" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_west_outpost_inner"; locked = 1; name = "Mining External Access"},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/outpost/mining_west) +"zY" = (/turf/simulated/floor,/area/outpost/mining_west) +"zZ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_west) +"Aa" = (/turf/space,/area/skipjack_station/mining) +"Ab" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor,/area/outpost/mining_west) +"Ac" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_west) +"Ad" = (/obj/structure/table,/obj/item/weapon/shovel,/turf/simulated/floor,/area/outpost/mining_west) "Ae" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) "Af" = (/obj/machinery/conveyor_switch{id = "mining_west"; pixel_y = 10},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) -"Ag" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"Ag" = (/obj/structure/table/rack,/obj/item/clothing/suit/space/void/mining,/obj/item/clothing/mask/breath,/obj/item/clothing/head/helmet/space/void/mining,/obj/item/weapon/mining_scanner,/turf/simulated/floor,/area/outpost/mining_main/eva) "Ah" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) -"Ai" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 10},/area/mine/explored) -"Aj" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/mine/west_outpost) -"Ak" = (/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 28},/obj/item/weapon/storage/box/lights/bulbs,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor/plating,/area/mine/west_outpost) -"Al" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/wall,/area/mine/west_outpost) -"Am" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/mine/west_outpost) -"An" = (/obj/machinery/light/small,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/mine/west_outpost) -"Ao" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/ore_box,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) +"Ai" = (/obj/machinery/suit_cycler/mining,/turf/simulated/floor,/area/outpost/mining_main/eva) +"Aj" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored) +"Ak" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 5},/area/mine/explored) +"Al" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) +"Am" = (/obj/machinery/light,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 9},/area/mine/explored) +"An" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"Ao" = (/obj/structure/table,/obj/item/weapon/reagent_containers/food/drinks/cans/beer,/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) "Ap" = (/obj/structure/ore_box,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 6},/area/mine/explored) -"Aq" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/smes/buildable{capacity = 1e+007; charge = 1e+007; cur_coils = 2; input_attempt = 1; input_level = 250000; output_level = 250000; RCon_tag = "Mining Outpost"},/turf/simulated/floor/plating,/area/mine/living_quarters) -"Ar" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/mine/living_quarters) -"As" = (/obj/machinery/atmospherics/pipe/manifold/hidden/cyan{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/plating,/area/mine/living_quarters) -"At" = (/obj/machinery/power/terminal{icon_state = "term"; dir = 1},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/mine/living_quarters) -"Au" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/mine/living_quarters) -"Av" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"Aq" = (/obj/machinery/light{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"Ar" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/dorms) +"As" = (/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"At" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"Au" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"Av" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/west_hall) "Aw" = (/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) -"Ax" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) -"Ay" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"Ax" = (/obj/structure/ore_box,/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "mining_west_outpost_sensor"; pixel_x = 0; pixel_y = -25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "mining_west_outpost_pump"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/mining_west) +"Ay" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/camera{c_tag = "West Outpost - Airlock"; dir = 1; network = list("MINE")},/turf/simulated/floor/plating,/area/outpost/mining_west) "Az" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) -"AA" = (/obj/structure/transit_tube,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 10},/area/mine/unexplored) -"AB" = (/obj/structure/transit_tube{icon_state = "W-NE"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 6},/area/mine/unexplored) -"AC" = (/obj/structure/transit_tube/station,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/unexplored) -"AD" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 9},/area/mine/explored) +"AA" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/mining_west) +"AB" = (/obj/structure/table,/obj/item/weapon/storage/box/donkpockets,/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"AC" = (/obj/machinery/camera{c_tag = "Crew Area"; dir = 1; network = list("MINE")},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"AD" = (/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"AE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/outpost/mining_west) +"AF" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/outpost/mining_west) +"AG" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/outpost/mining_west) +"AH" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/outpost/mining_west) +"AI" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_west_outpost_outer"; locked = 1; name = "Mining External Access"; req_access = list(10,13)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/outpost/mining_west) +"AJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor,/area/outpost/mining_west) +"AK" = (/obj/structure/table,/obj/item/weapon/storage/backpack/satchel,/obj/item/clothing/glasses/meson,/obj/machinery/light/small{dir = 8},/turf/simulated/floor,/area/outpost/mining_west) +"AL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/outpost/mining_main/dorms) +"AM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/dorms) +"AN" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/outpost/mining_main/dorms) +"AO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/dorms) +"AP" = (/obj/machinery/alarm{pixel_y = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/dorms) +"AQ" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"AR" = (/obj/item/weapon/cigbutt,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"AS" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"AT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/west_hall) +"AU" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/structure/table/rack,/obj/item/weapon/rig/industrial,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"AV" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"AW" = (/obj/machinery/camera{c_tag = "Storage Room"; dir = 1; network = list("MINE")},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"AX" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) +"AY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/outpost/mining_main/eva) +"AZ" = (/turf/simulated/floor,/area/outpost/mining_main/eva) +"Ba" = (/obj/machinery/light_switch{pixel_x = 25; pixel_y = -9},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor,/area/outpost/mining_main/eva) +"Bb" = (/obj/machinery/camera{c_tag = "EVA"; dir = 4; network = list("MINE")},/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor,/area/outpost/mining_main/eva) +"Bc" = (/obj/machinery/conveyor_switch{id = "mining_west"; pixel_x = 5},/turf/simulated/floor,/area/outpost/mining_west) +"Bd" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "mining_west_outpost_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/outpost/mining_west) +"Be" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor,/area/outpost/mining_west) +"Bf" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor,/area/outpost/mining_west) +"Bg" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "mining_west_outpost_pump"; tag_exterior_door = "mining_west_outpost_outer"; frequency = 1379; id_tag = "mining_west_outpost_airlock"; tag_interior_door = "mining_west_outpost_inner"; pixel_x = 0; pixel_y = -25; tag_chamber_sensor = "mining_west_outpost_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "mining_west_outpost_pump"},/turf/simulated/floor,/area/outpost/mining_west) +"Bh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"Bi" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/outpost/mining_west) +"Bj" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical,/turf/simulated/floor,/area/outpost/mining_west) +"Bk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/mining_west) +"Bl" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/dorms) +"Bm" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/dorms) +"Bn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/outpost/mining_west) +"Bo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/west_hall) +"Bp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/west_hall) +"Bq" = (/obj/machinery/alarm{pixel_y = 24},/obj/structure/table,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/item/stack/flag/yellow,/obj/item/stack/flag/red,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"Br" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/eva) +"Bs" = (/obj/structure/dispenser/oxygen,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor,/area/outpost/mining_main/eva) +"Bt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/outpost/mining_main/eva) +"Bu" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/eva) +"Bv" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/outpost/mining_main/eva) +"Bw" = (/obj/structure/table,/obj/item/weapon/storage/belt/utility,/obj/item/weapon/pickaxe,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"Bx" = (/obj/structure/table,/obj/item/weapon/storage/backpack/satchel,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"By" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/eva) +"Bz" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_east_pump"},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/eva) +"BA" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 2; frequency = 1379; id_tag = "mining_east_pump"},/obj/structure/closet/walllocker/emerglocker/north,/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/mining_main/eva) +"BB" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor,/area/outpost/mining_west) +"BC" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/floor,/area/outpost/mining_west) +"BD" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor,/area/outpost/mining_west) +"BE" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor,/area/outpost/mining_west) +"BF" = (/obj/machinery/door/airlock/glass_mining{name = "Break Room"; req_access = list(54)},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/outpost/mining_west) +"BG" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/outpost/mining_west) +"BH" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/outpost/mining_west) +"BI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor,/area/outpost/mining_west) +"BJ" = (/obj/machinery/door/airlock/glass{name = "Crew Area"; req_access = list(48)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/dorms) +"BK" = (/obj/machinery/door/airlock/mining{name = "Mining Station Storage"; req_access = list(48)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"BL" = (/obj/machinery/camera{c_tag = "West Outpost"; dir = 1; network = list("MINE")},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable,/turf/simulated/floor,/area/outpost/mining_west) +"BM" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor{dir = 4; icon_state = "loadingarea"},/area/outpost/mining_west) +"BN" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_west) +"BO" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/eva) +"BP" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/mining_main/eva) +"BQ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"BR" = (/obj/machinery/conveyor{dir = 8; id = "mining_west"},/obj/machinery/mineral/output,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_west) +"BS" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"BT" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"BU" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/outpost/mining_main/eva) +"BV" = (/obj/structure/disposalpipe/trunk{dir = 4},/obj/machinery/disposal/deliveryChute{dir = 8},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_west) +"BW" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/outpost/mining_main/eva) +"BX" = (/obj/machinery/mineral/input,/obj/machinery/conveyor{backwards = 2; dir = 2; forwards = 1; id = "mining_west"},/turf/simulated/floor,/area/outpost/mining_west) +"BY" = (/obj/machinery/mineral/unloading_machine,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_west) +"BZ" = (/obj/machinery/atmospherics/pipe/simple/visible/red{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "outpost_o2_in"; name = "O2 Tank Monitor"; output_tag = "outpost_o2_out"; sensors = list("outpost_o2_sensor" = "Tank")},/obj/machinery/camera/autoname/engineering_outpost{dir = 1},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"Ca" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/east_hall) +"Cb" = (/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/outpost/mining_main/east_hall) +"Cc" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/west_hall) +"Cd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/west_hall) +"Ce" = (/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/outpost/mining_main/west_hall) +"Cf" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/west_hall) +"Cg" = (/obj/machinery/atmospherics/pipe/simple/visible/blue,/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"Ch" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"Ci" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/blue{d2 = 2; icon_state = "0-2"},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"Cj" = (/obj/machinery/alarm{pixel_y = 24},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"Ck" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"Cl" = (/obj/machinery/camera{c_tag = "Crew Area Hallway"; network = list("MINE")},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"Cm" = (/obj/machinery/door/airlock{name = "Toilet"},/turf/simulated/floor{icon_state = "showroomfloor"},/area/outpost/mining_main/west_hall) +"Cn" = (/obj/structure/sink{pixel_y = 30},/obj/machinery/light/small,/obj/structure/mirror{pixel_y = -32},/turf/simulated/floor{icon_state = "showroomfloor"},/area/outpost/mining_main/west_hall) +"Co" = (/obj/structure/toilet{dir = 4},/turf/simulated/floor{icon_state = "showroomfloor"},/area/outpost/mining_main/west_hall) +"Cp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"Cq" = (/obj/machinery/conveyor{backwards = 2; dir = 2; forwards = 1; id = "mining_west"},/obj/structure/plasticflaps/mining,/turf/simulated/floor,/area/outpost/mining_west) +"Cr" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/blue,/turf/simulated/floor,/area/outpost/mining_main/eva) +"Cs" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/eva) +"Ct" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/blue{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"Cu" = (/obj/machinery/computer/mech_bay_power_console,/turf/simulated/floor,/area/outpost/mining_main/eva) +"Cv" = (/turf/simulated/floor/mech_bay_recharge_floor,/area/outpost/mining_main/eva) +"Cw" = (/obj/machinery/mech_bay_recharge_port,/turf/simulated/floor/plating,/area/outpost/mining_main/eva) +"Cx" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_east_outer"; locked = 1; name = "Mining External Access"; req_access = list(10,13)},/turf/simulated/floor/plating,/area/outpost/mining_main/eva) +"Cy" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"Cz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"CA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/outpost/mining_main/east_hall) +"CB" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/camera{c_tag = "Production Line External"; dir = 1; network = list("MINE")},/turf/simulated/floor/plating,/area/outpost/mining_main/eva) +"CC" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"CD" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1379; master_tag = "mining_east_airlock"; name = "exterior access button"; pixel_x = -25; pixel_y = -25},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) +"CE" = (/obj/structure/ore_box,/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "mining_east_sensor"; pixel_x = 0; pixel_y = -25},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "mining_east_pump"},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/mining_main/eva) +"CF" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CG" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CH" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CI" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CJ" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CL" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CM" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/blue{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CN" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/outpost/mining_main/west_hall) +"CP" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/airlock/glass_mining{name = "Mining Station EVA"; req_access = list(54)},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/outpost/mining_main/eva) +"CQ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall/r_wall,/area/outpost/engineering/hallway) +"CR" = (/turf/simulated/floor{dir = 6; icon_state = "warning"},/area/outpost/mining_main/west_hall) +"CS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/west_hall) +"CT" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_east_inner"; locked = 1; name = "Mining External Access"},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/outpost/mining_main/eva) +"CU" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CV" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CW" = (/obj/machinery/light,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CX" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"CZ" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"Da" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) +"Db" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"Dc" = (/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/outpost/mining_main/east_hall) +"Dd" = (/obj/machinery/atmospherics/pipe/simple/visible/blue{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/firealarm{dir = 4; layer = 3.3; pixel_x = 26},/turf/simulated/floor,/area/outpost/engineering/atmospherics) +"De" = (/obj/structure/ore_box,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 2},/area/mine/explored) +"Df" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "mining_east_airlock"; name = "interior access button"; pixel_x = 25; pixel_y = 25},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor,/area/outpost/mining_main/eva) +"Dg" = (/obj/machinery/door/airlock/glass_mining{name = "Mining Station Bridge"; req_access = list(48)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"Dh" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"},/turf/simulated/wall,/area/outpost/mining_main/maintenance) +"Di" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/medbay) +"Dj" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "mining_east_pump"; tag_exterior_door = "mining_east_outer"; frequency = 1379; id_tag = "mining_east_airlock"; tag_interior_door = "mining_east_inner"; pixel_x = 0; pixel_y = -25; tag_chamber_sensor = "mining_east_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 1; frequency = 1379; id_tag = "mining_east_pump"},/turf/simulated/floor,/area/outpost/mining_main/eva) +"Dk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/west_hall) +"Dl" = (/obj/machinery/door/airlock/glass_mining{name = "Mining Station Bridge"; req_access = list(48)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"Dm" = (/obj/machinery/access_button{command = "cycle_interior"; frequency = 1379; master_tag = "mining_west_airlock"; name = "interior access button"; pixel_x = -25; pixel_y = -25},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"Dn" = (/obj/structure/disposaloutlet{dir = 4},/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"Do" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-j2"; dir = 4},/turf/simulated/wall,/area/outpost/mining_main/refinery) +"Dp" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"Dq" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8; icon_state = "map"; tag = "icon-manifold-f (WEST)"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"Dr" = (/obj/machinery/conveyor{dir = 4; id = "mining_external"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored) +"Ds" = (/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "mining_west_inner"; locked = 1; name = "Mining External Access"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor,/area/outpost/mining_main/west_hall) +"Dt" = (/obj/machinery/door/airlock/maintenance{name = "Mining Station Maintenance"; req_access = list(48)},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"Du" = (/obj/machinery/door/airlock/glass_medical{name = "Infirmary"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/outpost/mining_main/medbay) +"Dv" = (/obj/structure/window/reinforced,/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,/area/outpost/mining_main/refinery) +"Dw" = (/obj/structure/bed,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor/carpet,/area/outpost/mining_main/dorms) +"Dx" = (/obj/machinery/conveyor{dir = 4; id = "mining_external"},/obj/structure/plasticflaps/mining,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"Dy" = (/turf/simulated/floor,/area/outpost/mining_main/dorms) +"Dz" = (/obj/machinery/light/small{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/outpost/mining_main/dorms) +"DA" = (/obj/machinery/door/airlock{id_tag = "miningdorm1"; name = "Room 1"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "carpet"},/area/outpost/mining_main/dorms) +"DB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/outpost/mining_main/dorms) +"DC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/dorms) +"DD" = (/obj/machinery/door/airlock{id_tag = "miningdorm2"; name = "Room 2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 2; icon_state = "carpet"},/area/outpost/mining_main/dorms) +"DE" = (/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/outpost/mining_west) +"DF" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/dorms) +"DG" = (/obj/machinery/conveyor{dir = 4; id = "mining_external"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored) +"DH" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 9},/area/mine/explored) +"DI" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"DJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/west_hall) +"DK" = (/obj/machinery/mineral/unloading_machine{icon_state = "unloader-corner"},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"DL" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"DM" = (/obj/machinery/vending/cigarette,/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"DN" = (/obj/machinery/vending/snack,/turf/simulated/floor{icon_state = "bar"},/area/outpost/mining_main/dorms) +"DO" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_west) +"DP" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_west) +"DQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_west) +"DR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/dorms) +"DS" = (/obj/structure/disposalpipe/segment,/obj/structure/sign/deathsposal,/turf/simulated/wall,/area/outpost/mining_main/dorms) +"DT" = (/obj/machinery/computer/mech_bay_power_console,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/outpost/mining_west) +"DU" = (/turf/simulated/floor/mech_bay_recharge_floor{icon_state = "recharge_floor_asteroid"},/area/outpost/mining_west) +"DV" = (/obj/machinery/mech_bay_recharge_port,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/outpost/mining_west) +"DW" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"DX" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 4},/area/mine/explored) +"DY" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"DZ" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 8},/area/mine/explored) +"Ea" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating/airless,/area/space) +"Eb" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating/airless,/area/mine/explored) +"Ec" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating/airless,/area/mine/explored) +"Ed" = (/obj/machinery/conveyor{icon_state = "conveyor0"; dir = 10; id = "mining_internal"},/obj/machinery/mineral/input,/turf/simulated/floor{dir = 8; icon_state = "loadingarea"},/area/outpost/mining_main/refinery) +"Ee" = (/obj/machinery/mineral/stacking_machine,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"Ef" = (/obj/structure/lattice,/obj/structure/grille,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/space,/area/space) +"Eg" = (/obj/machinery/conveyor{dir = 4; id = "mining_external"},/obj/machinery/mineral/input,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"Eh" = (/obj/machinery/conveyor{dir = 8; id = "mining_internal"},/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"Ei" = (/obj/machinery/conveyor{dir = 8; id = "mining_internal"},/obj/machinery/mineral/output,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"Ej" = (/turf/simulated/floor{dir = 8; icon_state = "loadingarea"},/area/outpost/mining_main/refinery) +"Ek" = (/obj/machinery/conveyor{dir = 8; id = "mining_internal"},/obj/structure/plasticflaps,/turf/simulated/floor{icon_state = "floorgrime"},/area/outpost/mining_main/refinery) +"El" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor,/area/outpost/mining_main/east_hall) +"Em" = (/obj/machinery/light/small{dir = 4},/obj/machinery/door_control{id = "miningdorm1"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 25; pixel_y = 0; specialfunctions = 4},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/carpet,/area/outpost/mining_main/dorms) +"En" = (/obj/machinery/door/airlock/external{name = "Mining Bridge"; req_access = list(54)},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"Eo" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light{dir = 1},/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"Ep" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 28},/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"Eq" = (/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = 28},/turf/simulated/floor,/area/outpost/engineering/storage) +"Er" = (/obj/structure/cable/blue{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/obj/machinery/camera/autoname/engineering_outpost,/obj/machinery/status_display{pixel_y = 32},/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"Es" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/sign/vacuum{pixel_x = 32},/turf/simulated/floor,/area/outpost/engineering/hallway) +"Et" = (/obj/structure/sign/electricshock,/turf/simulated/wall,/area/outpost/engineering/hallway) +"Eu" = (/obj/machinery/light/small{dir = 4},/obj/machinery/camera/autoname/engineering_outpost{dir = 8},/turf/simulated/floor/airless{dir = 5; icon_state = "asteroidfloor"},/area/mine/explored) +"Ev" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{dir = 10; icon_state = "warning"},/area/outpost/engineering/hallway) +"Ew" = (/obj/structure/table/rack,/obj/item/clothing/head/helmet/space/void/engineering,/obj/item/clothing/suit/space/void/engineering,/obj/item/clothing/shoes/magboots,/obj/item/clothing/gloves/yellow,/obj/machinery/camera/autoname/engineering_outpost{dir = 1},/obj/machinery/firealarm{dir = 4; layer = 3.3; pixel_x = 26},/obj/item/weapon/storage/briefcase/inflatable,/turf/simulated/floor,/area/outpost/engineering/storage) +"Ex" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/camera/autoname/engineering_outpost{dir = 1},/turf/simulated/floor/bluegrid{name = "Mainframe Base"; nitrogen = 82.1472; oxygen = 21.8366; temperature = 293.15},/area/outpost/engineering/telecomms) +"Ey" = (/obj/machinery/light/small{dir = 4},/obj/machinery/door_control{id = "miningdorm2"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 25; pixel_y = 0; specialfunctions = 4},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/carpet,/area/outpost/mining_main/dorms) +"Ez" = (/obj/machinery/light/small{dir = 4},/obj/machinery/door_control{id = "miningdorm3"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 25; pixel_y = 0; specialfunctions = 4},/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/carpet,/area/outpost/mining_main/dorms) +"EA" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/unary/vent_pump/on,/obj/machinery/light{dir = 1},/obj/machinery/alarm{frequency = 1439; pixel_y = 22},/obj/machinery/camera/autoname/engineering_outpost,/turf/simulated/floor,/area/outpost/engineering/power) +"EB" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/wood,/area/outpost/engineering/meeting) +"EC" = (/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/outpost/engineering/hallway) +"ED" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall,/area/space) +"EE" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/camera/autoname/mining_outpost{dir = 8},/turf/simulated/floor/plating,/area/outpost/mining_main/maintenance) +"EF" = (/obj/structure/window/reinforced,/obj/structure/lattice,/turf/space,/area/space) +"EG" = (/obj/structure/window/reinforced,/obj/structure/lattice,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/space,/area/space) +"EH" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/lattice,/turf/space,/area/space) +"EI" = (/obj/structure/window/reinforced{dir = 1},/obj/structure/lattice,/obj/machinery/light{dir = 4},/turf/space,/area/space) +"EJ" = (/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored) +"EK" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/plating/airless,/area/space) +"EL" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/mine/explored) +"EM" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating/airless,/area/space) +"EN" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/plating/airless,/area/space) +"EO" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/outpost/mining_main/east_hall) +"EP" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor,/area/outpost/mining_main/east_hall) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -1420,194 +1643,194 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadababababababadadaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaafagahahaiaiaiaiaiajaiakalababababadadadadamananaoaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaafapaqababababababarararasatalabababauavaiaiawayazaAaBaBahaBaCaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaEaqabababababababaraFaGaHasataIaraJaKaLaMaMaMaNaOaMaMaMaMaeaPaQaDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaRababababababababaSaTaUaVaWaXaYaZbabbbcbdbebcbfbgbcbhbdaMaeaebibjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababbkbkababbkbkbkbkabbkbkbkbkbkbkbkababababababababaaaaaaaaaaaaaaaaaaaRabababababaSaSaSaSblbmaUbnbobpbpbpbqbcbrbsbtbubvbwbxbyaMaeaebzbAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababbkababababababbkbkababababbkbkbkbkabbkbkbkbkbkbkbkbkbkbkbkbkbkbkabaaaaaaaaaaaaaaaaaaaRababababaSaSbBbCaSbDbDbDbDbEbFbGbGbHbcbcbcbcbIbJbKbKbKbKbKbKbLbMbNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxbPbOaaaaaaaaaaababababababababababababababababababababababbkabababbkbkabbkbkbkababbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkaaaaaaaaaaaaaaaaaRababababaSbQbRbSbTbUbVbWbXbYbZcacbccbccdcebccfcgbKchcicjckclcmcncoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadmcqcpaeaaaaaaababababababababababababbkbkbkbkbkbkabababababababbkbkbkbkbkabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaRababababaScrcsctaScucvcwcxcyczcAcbcBbccCcDcEcFcGcHcIcJcKcLcMcNcOcoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacPcQcRcSaeaaaaabababababababbkababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaafcTaaabababaScrcUcVaScWcwcXcYcZdadbdadcdadadaaMdddebKdfdgcKdhdidjcncoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkdldleudndocpaeaaaaababababbkbkbkababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaedpdqaBaBaBdrdsaaabababaScrdtduaSdvdwdxdydzdAdBdCdDdEdFdGaMdHdIbKdJdKdLdMdNbKdOdPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadQdRdSdTdUdVdWaeaebkbkababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkdXdXdXaedYdsaeaeaeaeaedZaSaSaSaSaSaSeaaSbDaMaMebecdaedeeefegeheiaMejekelemeneoepeqeleresaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaetdldlfyevdoewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkdXdXdXaaaaaRexexexexexexexbceyezeAeBeCeDeEeFeGeHeIeJdaeKeLeMeNeOePdaeQeReSeSeSeTeSeSeSeresaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeeUeVeWewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkdXaaaaaRexexexexexexexeXeYeZfaeZeZfbfceZfdfefffgfhfifjfkflfmfnfofpfqeSfrfsfufteSfvfwesesaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaefxjHfzfAewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaRexexexexexexexfBfCfDfEfFfGfHfIfJfKaMfLfMaMfNfOfPfQfRfSdafTfUfVfWfXfYfZgagbgcesesaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaegdgegfewggghewewewewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaRexexexexexexexgifCfDfEfFgjgkfIfJglaMgmgnaMgodadadadagpdagqgreSgsgtgugvgwergxgygyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacaaacacacacacaaacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaegzgAgBgCgDgEbOdVgFewgGgHewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaRexexexexexexexbcgIgJgKfFgLgMfIgNgOaMgPgQgRgSgTgUgVaMgWgXgYgZeShahbhchdheeresesesaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacaaacacacacacaaacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaehfhggAhhhihjhkhlgFhmgHhngGewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaahohphqhrhshphqhthuhvhwhxhyhyaMaMaMaMaMhzhAhBhCbghDhEaMhFhGhHhIaMhJhKhLhMhNhOhPaMhQdqaBaBaBaBaBaBaChRaaaaaaaaaaaaaaaaacacacacacaaaaaaaaaaaaaaacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahShfhThfgBgBgghUhiewfAhVewgHhWewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaahXhYhZiaibichZidieifhZigihiiijikilimaMinhAioipiqirisaMitiuiviwaMeSixeSaMaMiyiziAiBiCiDiDiEiDiDiDiFbjaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeiGiHgBiIiJgBeWiKhjiLiMiNewewewewewewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababababababababaaaaaaaaaaiOiPiQiQiQiQiRiSiTiUiViWiXiYijiZjajbjcjdjejfjgeZeZjhjieZeZjjjkjljmjnjojpjqeZeZjrjsjtjuiDjvjwjxjyiDbAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaejzjAjBgBiJjChhjDhijEewjFjGewkBkCdVjJewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababababababababababaaaaaaaajKjLhZhZjMhZjNjOhZjPhZjQjRjSijjajTjUjVjWjXjYjZkakbkckdkekfkckdkdkgkhkikjkkklkmknkokpkqkrksktkukviDbAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeaebkbkewgEkwkxkyjBkzkAhjkBbOdVkCewkBkwkCjIewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababesesesesesesababababababkDkEaaaaaakFkGhZkHkIkJkKidkLkMkNkOkPkQijkRkSkTkUkUaMaMkVkWkWkXkWkYkYkZkYlalalblaaMlcaMldleiDlflgiDlhlikuljiDbAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeewewewewewewgDhilkkwhiiKllkBkBhlgFjFewkBeWfAqbewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababesesesgygygygyesesesabablnlolphRaaaaaalqlrhqhrlslslslslsltlsbcbcbcijlukUlvlwlxlylzlAkWlBlClDkYlElFlGlalHlIlJlalKlLldlMldiDiDiDlNlOlPjyiDbAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeewlQhijBqUewjzqcjAewiLewqZraqYewdVlYjEoNeWfzhiewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababesesgygygygygygygygyesesabmambbimcaBaBaBdrdsaeaemdmemfmgmhmimjmkmlmmmnmompmqmrmsmtmungkWmwmxmykYmzmAmBlamCmDmElamFmGldmHmImJmKiDiDiDiDiDmLcTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkewlQeWjBeWoOlYkwmMkwmNdVdVmOgFdVeWeWewhioNhihiewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababesesgygygygygygygygygygymQmRmSmRaaaaaaaaaaaaaaaaaemdmTmUmVmWmXmYmZnananbnckUndnelylynfmvkWnhnipdkYnknlpelannnopclanqnrldnsntntnuldnvagaBaBnwnxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkewnyjBhieWpoeWlmggeWnAmNlmkCnBeWnCfAewmPeWiNdVewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabesmRgygygygygygygygygygygynDnEpnnGaaaaaaaaaaaaaaaaaemdmTmUnHnInJnKmUnLnanMijijnNnOlynPnQnRkWnSpfpgkYnVphpElanYpHpFlaobocldodoeoeoeldofogbkaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkewnynzhigEewoiewojokeweWewojokewhilYewghlZjEmPewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabesomgygygygygygygygygygygygyonlXnGaaaaaaaaaaaaaaaaaemdopmUoqmhorosotounaovijowoxoylyoznUoBoCoCnXoCoEoEnWoEoGoGnToGoGoIoJoKldldldldoLoMabbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkewewewewewewoiewiNnCeWkzolhikzhiiNhhewooohoPoQewbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabesmQgygygygygygygygygygygygyonnFnGaaaaaaaaaaaaaaaeaemdoRoSoTmWoUosoVoWnaoXijoYoxoylylylylyoCnZoFoHoEoZoaoAoGoDpbpaoGpipjoKabbkabpkplpmabbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkewoiewnCfAlTkzlSeWkCewhifAewlRpppppqewadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabesesgygygyprgygygygygygygygypsptaeaaaaaaaaaaaaaeaeaemdmdpupvmdmdpwpxpwmdpypzpApBpCpDgygygyoCnmnmpGoEnpnppJoGnjnjpMoGoKoKpNpOaiaipPogababbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkewoiewkzeWdolWhifAiNewoiewewkBhipppqpRadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabespSpTgypUpSpQgygygygygygygygypWpXaaaaaaaaaaaepYpZqalUlVqdqeqfmdqgqhqimdqjpzgygygygygygygyoCqkqlqmoCqnqoqpoEqqqrqsoGabauqtogquabababababbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkewoiewewewewewewewewewoiewvydVhidVpqqvadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabespSgygygypSpQgygygygygygygyqwqxqyqzqzqzqzqzqzqAqBqCqDqDqEqFqFmdqGqHqImdqJgygygygygypzpzpzoCoCoCoCoCoEoEoEoEoGoGoGoGauqtogqKadqKababababbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLaaaaaaaaaaqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkewoioioioioioioioioioioiewkBhijEhijJewadadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabesgygygygyqMqNgygygygygygygygyqOqPqPqPqPqPqPqPqPqOgygygygygygymdqQqRpwmdqSgygygygygyqTADqVaiaiaiaiqWaiaiaiaiaiqXAAACABogadadadqKkDabbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkewewewewewewewewewewewewewewoQrbrcewewadadadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabesgygygygygygygygygygygygygyqwqCrdrerererererereqwqCgygygygygygypBrfpCrgrhrigygygygyonrjrkababbkbkbkbkbkbkbkbkrlrmrnroadqKadadqKabababbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkadadadewpppphiewadadadadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabespSpTgygygygygygygygygygyaaaaaaaaaaaaaaaaesesesesesesesesgygygygygygypBrppCgygygygyrqrrpzbkabbkbkbkbkbkbkbkkDqKadrsadqKadadadabababababbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkadadadewrtrurtewadadadadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabespSgygygygygygygygygygygyaaaaaaaaaaaaaaaaesesesababababesesesgygygygygyrvgygydXgygypzpzpzbkbkbkbkbkbkbkbkbkbkbkbkkDbkadqubkabbkbkababababbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkadadewrwrboQewadadadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabesespVryrxgygygygygyesesesaaaaaaaaaaaaaaaaaaababababababababesesesgygygyrvgygydXdXdXdXbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkbkbkababababbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkadadadrBrCrDadadadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababesesesmResgygymQmQesababaaaaaaaaaaaaaaaaaabkbkbkbkbkabababababesesgygyrvgygydXdXbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkbkbkbkbkababababbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkadadadadadrEadadadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababesesesesesesababaaaaaaaaaaaaaaaaaabkbkbkbkbkababababababesgygyrvgygygydXbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkbkbkbkbkbkabababbkabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLrArArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkadadadadadadadrEadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababababababaaaaaaaabkbkaaaaaaaabkbkbkbkbkbkbkbkababesgygyrFrGgygydXdXdXdXbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababbkbkbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLrArArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkadadadadrEadadadadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababababbkbkaaaaaaaaabbkbkaaaaaabkbkbkbkbkbkbkbkababesgygygyrvgygygydXgydXbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkbkbkbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkadadadadadadadadadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaabkbkaaaaaabkbkbkbkbkbkbkbkababesgygygyrvgygygygygydXbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkbkbkbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkadadadadadadadadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkababesgygygyrvgygygygyrHrIrIrIrIrIrIrIrIrIrIrIrIbkbkbkbkbkbkbkbkbkababbkbkbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkadadadadadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkababesgygygyrvgygygygyrJrKrLrMrNrOrPrQrRrIrSrTrIbkbkbkbkbkbkbkbkbkbkabababbkbkbkbkabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkadadadbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaabkbkbkbkbkbkbkababesesgygyrvgygygygyrUrVrWrXrYrZsasbscsdsesfrIbkbkbkbkbkbkbkbkbkbkbkbkababbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaabaaaaaaaabkbkbkbkbkbkbkabababesgygyrvgygygygyrIrIrIrIrIrIsgshsirIsjskrIbkbkbkbkbkbkbkbkbkbkbkbkbkbkababbkbkbkabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaabkbkbkaaaabkbkbkbkbkbkbkbkbkabesgygyrFslsmxNxNsnsppIsrsqstsssvrzswsxsyrIbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababbkbkababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLrAqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaabkbkbkaaaaaabkbkbkbkbkbkbkbkabesgygygygyxugygyrIrIrIrIszrIrIrIrIrIrIrIrIbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkabesesgygygyxugygygygysApKsCsCdXbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkababesgygyrJsFrigygygygygygygydXbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLrArArArArArAqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkababesgygypBsGpCgygygygygygygydXbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabaaababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkabesgygygyxugygygygygygygydXdXbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLrArArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaarAaaaabkbkbkbkbkbkbkbkabesgygygyxugygyesmQesdXdXdXdXbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLrArArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaabkrArAaaaabkbkbkbkbkbkbkabesgygygyxugygyesesesbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababbkababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaabkbkrAaaaaaabkbkbkbkbkbkabesesgygyxugyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababbkabababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaabkbkbkbkababesgygyxugyesesabbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababbkababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaabkbkbkababesgygyxugygyesabbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaadXdXaaaaaaaaaaaabkbkbkababesgygyxugygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababbkabababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaadXdXsDaaaaaaaaaaaabkbkbkababesgygyAbxMgyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababbkbkababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLrAqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLrArArArArArArArArAqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaasDaaaaaaaaaaaaaaaabkbkbkababesgygygyxugyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababbkababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLrArArArArArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkdXdXdXaeaeaeaeaeaeaeaedXdXbkbkababesmRsEgyxugyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLrArArArArArAqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLrArArArArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkdXdXdXsHsHsHsHsHsHsHsHdXdXdXbkababesesgygyxugyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkbkababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLrArArArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkdXdXaeaeaeaeaeaeaeaedXbkbkbkababesgygygyxugyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkbkababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaabkbkbkbkababesgygygyxugygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkbkababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaabkbkbkbkababesgygygyxugygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkbkabbkabababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaabkbkbkbkabababesgygyrJsFrigyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababbkabbkbkababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkabababesgygypBsGpCgyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababbkbkbkabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkabababesesgygyxugygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababbkbkababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkababababesgyAcAdgyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababesesgyxugygyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkbkabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababesgygyxugyesesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkababbkabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLrArArArAqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLrArArArArArAqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababesesgygyxunDmRababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLrArArArArAqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababesgygyAcAdgyesababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLrArArArAqLqLqLqLqLqLqLrArArArArArAqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaesesesgygyxugygyesesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLrArArArAqLqLqLqLqLqLqLrArArArArArAqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaesgygygygyxugygygyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygyxugygygyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLrArArArArArAqLqLqLrArArArArArAqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygyxugygygyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygyxugygygyesababababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygyxugygygyesababababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaasIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygygyxugygygyesesabababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygygygyxugygygygyesesesesesabbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygygygyxugygygygygygygygyesesabbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygygygyxugyrJrigygygygygygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygygyAbxNzpyjxNxNxNxMgygyesesesbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLrArArArArArAqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaagygygygygygygygypBpCgygygyxugygygygyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaesesgysLgygygygygygygygyAbxNxMgygyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaabesesmResesesesesesgygygygyxugygygyesesesabbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLrArArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArArAqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaababababababababesesgygygyxugygygygygyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLrArArArAqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkdXdXdXaeaeaeaeaeaeaeaeaeaeaeesesesesabababababesesgygyAbxNxNxMgygygyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLrArArArAqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkdXdXdXdXsHsHsHsHsHsHsHsHsHsHsHsHsHsHdXdXdXdXbkabababesgygygygygyxugygygygyesesabbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLrArArAqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkdXaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaedXdXbkbkbkababesesgygygygyAbxNxNxMgygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLrArArAqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLrAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkababesesesesgysMgygyxugygyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLrArArAqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLrArArArArArArArAqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaabkaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkabababesesmRgygyxugygygyesesabbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArArAqLqLrAqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaadbkbkbkbkadadaaaaaaaaaaaaaabkbkbkbkbkbkbkabababababesesgyAbxNxMgygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaadadbkbkbkadadadaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkababababesgygygyxugygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababababbkabbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaadadbkbkbkadadaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkababababesesgygyxugygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababababbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaadadbkbkbkadadaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkabababababesgyrJsFrigyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaabkbkbkadadaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkabababababesgypBsGpCgyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLrArArArArArArArAqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkababababesesesgygyxugygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLrAqLrArArArAqLqLrArArAqLqLqLqLqLrArArArArArArArAqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkababesesesgygygygyxugygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLrArArArArArArArArArArAqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkababesgygygygygygyxugyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArArArArArArAqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkababesgyAcxNxNxNxNAdgyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLrArArArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkababesgyxugygygygysLgyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLrArArArArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkababesgyxugygygygymResesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLrArArArArArArArAqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkababesgyxugygygyesesababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLrArArArArArArArAqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkababesgyxugygyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLrArArArArArAqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkabesesgyxugygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLrArArArAqLrAqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkababesgygyxugyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLrAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLrArArAqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkababesgygyxugyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLrArArArAqLqLqLqLrArArArArArAqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkabesesgyAcAdgyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLrArArArAqLqLqLrArArArArArAqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkabesgygyxugygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLrArArAqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkababmRsErJsFrigyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkababesgypBsGpCgyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLesesesqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkababesgygyxugygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLrAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLesgygyesqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkdXdXaeaeaeaeaeaeaeaeaeaedXdXbkbkbkbkbkababesgygyxugygyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLrArArAqLqLqLqLqLqLgygygygyqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkdXdXdXsNsNsNsNsNsNsNsNsNdXdXdXbkbkbkbkbkababesesgyxugygygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLrArArAqLqLqLqLqLqLgygygygyqLqLqLqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkdXaeaeaeaeaesDsDaeaeaedXdXbkbkbkbkbkbkabababesgyxugygygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLrArArArArAqLqLqLqLgygygygyesesesesqLqLqLbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaasDsDsDsDaaaaaabkbkbkbkbkbkbkbkababesesgyxugygygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababbkabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLrArArArArArAqLqLqLqLgygygygygyesesesqLqLqLabbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaasDsDsDsDaaaaaaaabkbkbkbkbkbkbkbkababesgygyxugygygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLrArAqLqLqLqLrArArAqLqLqLqLqLqLqLgygygygygyesesqLqLqLqLabbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaasDsDaaaaaaaaaabkbkbkbkbkbkbkbkabesesgygyxugygyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLrArArArArArArAqLqLqLqLqLrArAqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLsOgysOgyesesesqLqLqLababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkabesgygygyxugygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLrArArArArArArAqLqLqLqLqLrArAqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLsPsQsPgyesqLqLqLqLabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkabesesgygygyxugygyesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLrArArArArArArArAqLqLqLqLqLrArArAqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLqLqLsRsSsTqLqLqLqLqLababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkabesgygygygyxugyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabbkabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLrArArArArArAqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLrAqLqLqLqLqLqLqLqLqLqLqLqLqLsRsSsUqLqLqLqLqLabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkabesgygygygyxugyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLgygyqwqCsVsWsWsWsWsWsWsXsSsUqLqLqLqLqLqLababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbksYsYsYsYsYsYsYbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkabesgygygygyxunDmRabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArAqLqLqLqLqLqLqLqLqLqLgygygygysQsZsZsZsZsZsZsZtatbsUqLqLqLqLqLqLababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbksYtctdtetftcsYbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkabesesgygygyxugyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArArArArAqLqLqLqLqLqLqLqLesgygygyqwtgrerererererethsStitjqLqLqLqLqLesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbksYtctktltmtnsYbkbkbkbkabaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkababesgygygyxugyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAqLrArArAqLqLqLqLqLqLesesesgygygygyqLqLqLqLqLqLsRsSsUqLqLqLgygygyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkqFtotpbktqsYsYsYtrsYsYsYbkbkbkababaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkababesgygygyxugyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLrArAqLqLqLqLqLqLqLqLqLqLababesesgygygyqLqLqLqLqLqLqLsRsSsUqLgygygygygyesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbktstpttbktqtutvtqtwtqesesabababababaaaaaaaaaaaaaaaaaaaaaaabbkbkbkbkbkbkbkbkababesesgygyxugygyesesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrAababesesesgygyqLqLqLqLqLqLqLtxsSsUgygygygygygygyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkqFmRabtqtytztAtwtqgyesesababababaaaaaaaaaaaaaaaaaaaaababbkbkbkbkbkbkbkbkabababgygygyxugygygygyesesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAababqLqLqLqLqLqLqLqLqLqLqLsOsQsOgygygygygygygyesesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbktBbkabtqtqtqtqtCtqgygyesesmResesaaaaaaaaaaaaaaaaaaaaaaababbkbkbkbkababababababesgygyxugygygygygygyesesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLrArArAababqLqLqLqLqLqLqLqLqLgygysPgysPgygygygygygygygyesabababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababababababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbktDbkbktqtutEtqtwtFgygygygytGgyesesaaaaaaaaaaaaaaaaaaaaababababababababababababesgygyxugygygygygygygyesesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLrArArArArArAqLqLqLqLqLqLqLqLqLqLrArArArArAqLqLqLqLqLqLqLqLqLgygygygygygygygytHtHtHgygygyesababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababababababababababbkbkbkbkbkbkbkbkbkbkbkbktDbkbktqtytztItwtJgygygygygygygygygyaaaaaaaaaaaaaaaaaaaaababababababkDmRmRmRmRmRgygyxugygygygygygygygyadesesababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLrArArArArArArArAqLqLqLqLqLqLqLrArArArArArAqLqLqLqLqLqLqLqLqLgygygygygygygygytKtLtMgygygyesabababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababesesesesesesesababababababababbkbkbkbkbkbkbkbkbkbktqtNtqtqtqtqtqtqtwtOgygygygygygygygygygygyaaaaaaaaaaaaaaaaaaabababababmRtPsCtQtQtRgyrJsFrigygygygygygygyadadesababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLrArArArArArAqLqLqLqLqLqLqLrArArArArArAqLqLqLqLgygytStStStStStStTtUtVtStStStStSgygygyesababababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababesesgygygygygyesesesesesabababababababbkbkbkbktqtqtqtqtWtXtYtqtutZtqtCtqtqtquaubuctqgygygygygygyaaaaaaaaaaaaaaaaaaabababesmRudowueueufgyuSvRufgygygygygygygygygyesesabababbkbkbkbkbkbkbkbkbkbkbkabbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLrArArArArArAqLqLqLqLqLqLqLrArArArArAqLqLesgygygytSuguhuiujukulsuumuoupuqurussCsCriesesesesababababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababesesgygygygygygygygygygyesesesesesababababbkbkbktqutuuuvuwuuuutqtytzuxtwtquyuzuAuBuAtFgygygygygygygyaaaaaaaaaaaaaaaaaaesesesmRuCuDuEuEpCgywEuFuGuHuIuGuGgygygygygygyesabababbkbkbkbkbkbkbkbkbkbkbkabbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLrArArAqLqLqLqLqLqLqLqLrArArAqLqLabesgygygytSuJuKuLuMuKuKuKuKuNuOuPuQuRxtowufgygygyesesesabababababababbkbkbkbkbkbkbkbkbkbkbkbkababesesmRgygygygygygygygygygygygygygygyesesababababababtquTuuuUuVuWuXtqtqtqtqtwtquyuYuYuZuYtJgygygygygygygyaaaaaaaaaaaaaaaaaagygygygygygygygygygyAiuFunununvbuGgyvcgygygynDmResababbkbkbkbkbkbkbkbkbkbkababbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLrArArAqLqLqLqLqLqLqLqLqLqLqLqLqLabesgygygytSvdvevfvgvhvfvfvivjupvkvlvmxvowufgygygygygyesesesesababababababbkbkbkbkbkbkbkbkbkababesesgytGgygygygygygygygygygygygygygygygyesesesesabababtqvnuuvovpvqvrvsvtvuvvvwtquyuYvxuZvatOgygygygygygyaaaaaaaaaaaaaaaaaaaaaaaagygygygygyvzvzvAykuFvCvDvDvEuGuGuGuGgygygygyesesababbkbkbkbkbkbkbkbkbkabbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLbkbkesesgygytSvFuKuKujvGuKuKvHtStStStStStSowufgygygygygygygygyesesesabababababbkbkbkbkbkbkbkabababesgygygygygygygygygygygyrJrigygygygygygygygygyesesababtqtqtqtqtqtqtqvIvJvKvIvJtqtqtqtqvLtqtqtqvMvNgygyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygyvOvBvPvQymvSvTvTvTvUvVvWvXvYrigygygymQesababbkbkbkbkbkbkbkabababbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLbkbkabesgygytSvZwawbuMwcwdweuKwfwgwhwiwjwkyByjxNxNxNxNxNxMgygygygyesesesabababababbkbkbkababababesesgygyAcxNxNxNxNxNxNxNxNzpyjxNxNxNxNxMgygygygygyesabababababtqwlwmwnuYuYtwuYuYwowpwqwruZwswtwtwuwvubucwwwxwxwxwxwxwxwxwywywywywywywyvAwzwAwBwCwDznwFwGwHwHwIwJwKwLwMwNgygygymQesababbkbkbkbkbkbkabababbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLbkbkabesgygytStStStStSwOwPwQtStSwRtStStStSAeufgygygygygyxugygygygyesgyesesababababababababababesesgygygyxugygygygygygygygypBpCgygygygyxugygygygygyesesmResesabtqtqtqtqwSwTwUvvvvvvwVwWwXwYwXwZxaxbxcwXxcxdxdxdxdxdxdxdxdxexexexexexexexfxgxfxhxgxiwCxjxkxlxmxnvVxoxpxqpCgygygygyesesababbkbkbkbkbkabababbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLbkbkabesesgygygygygytSxrxsAjAktSowAfAhowowAeufgysMgygygyAbxNxNxMgygygygyesababababababababababesgygyAcxNAdgygygygyesgygysMgygygygygygyxugygygygygygygytGgyesesesesestquYuZuYuYuYuYxwuZxxxyuYxzuYxAxBubucxCxCxCxCxCxCxCxCxDxDxDxDxDxDxEvAwzxFxGwCxHwCxIvzvzvzvzvzvzvzvzuDuDxJuDqFmQesababbkbkbkbkababababbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkabesesgygygygytSxKxLAnAmAlzozozozozoAoApesmResgygygygygyxugygygygygyesabababababesesesesesgyAcAdgygygyesesesesesesmRgygygygygygyxugygygygygygygygygygygyesestqtqxOxPxOtqtqxQxRxStqtqxOxTxOtqxUgygygyaaaaaaaaaeaaaaaaaeaaaaaaaaaaaeaaxVvBwCxWxXxYxZyayaybvzycydyeyfyfyfyfqFgyesababbkbkbkbkabababbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkabesesgygygytStStStStStSgygyesesesesesesabesesgygygygyxugygygygygygyesesesesesesgygygygygyxugygyesesesabababababesgygygygygygyxugygygyrJrigygygygygygygyestqygyhyiyhtqAqArylAsyntqyoypyqtqgygygygygygyaaaaaeaaaaaaaeaeaeaeaeaeaeaeaevzyrysytvzvzvzvzyuvzyvvzvzywqFqFqFqFgyesababbkbkbkababbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkababesgygygygygygygygygygygyesabababababababesesgygygyAbxNxNxNxMgygygygygygygygygygygygygyxugyesesabababababababesesgygygygygyAbxNxNxNzpyjxNxNxNxMgygygygytqyxyyyzyAtqAtyCyDyEAutqyFyGyHtqgygygygygygyaeaeaeaeaeaeaeyIyIyIyIyIaeaaaavzyJyKwCyLyMyNyayayOyaybvzgygygygygyesesababbkbkabababbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkabesgygygygygygygygygyesesesababababababababesesesgygygygygyAbxMgygyrJrigygyAcxNxNxNxNxNAdgyesababababbkbkbkababesesesgygygygygygygypBpCgygygyxugygygygytqtqtqtqtqtqyPyQyRySyntqxOyTxOtqgygygygygygyaaaaaeaaaaaaaeyIyIyIyIyIaeaavOvBwCyUyVvzvzvzvzvzvzyWyXvzgygygygygyesababbkbkbkababababbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkesesesesgygygygyesesesababababababababababababesesesgysMgygyAbxNxNzpyjxNxNAdgygygygygygygyesabababbkbkbkbkbkabababesesesesgygygygygygygygygyAbxNxNxMgygygygygygytqtqtqtqtqtqtqowyYufyZgygygygygyaaaaaaaeaaaaaaaeyIyIyIyIyIzawzzbzczdzezfzgzhzizjzkzlzmyXvzgygygygyesesababbkbkababababbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkabesesesesesesabababababababbkbkbkbkabababababesesmResgygygygypBpCgygygygysMgyesesesesesababbkbkbkbkbkbkbkabababababesesesesesesesesgygygygygyxugygygygygygygygyAwAvAxAxAxAxAyufgygygygygygyaeaeaeaeaeaeaeaeyIyIyIyIyIzqzrzsztwCyUwCwCwCzuwCwCzvzwzxvzgygygygyesabababbkbkabababbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkabababababababababbkbkbkbkbkbkbkbkbkababababababesesgygygygygygygygygymResesabababababbkbkbkbkbkbkbkbkababababababababababababesesgygygygyxugygygygygygygygypBuDuDuDuDuDAzpCgygygygygygygyaaaaaaaaaaaaaeyIyIyIyIyIvAwzxFzywCyUwCwCwCzzwCwCwCzAzBvzgygygyzCmRabababbkababababbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkabbkbkababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababababesesesgygygyesesesesesabababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababesgygygygyAbxNxNxNxNxNxNxNxNxNxNxNxNxNxNAgslslrGgygygygygygyaaaaaaaaaaaeyIyIyIyIyIzDaaxVvBzEyUwCwCwCzFzGwCwCyWzHvzgygygygyesabababababababbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababababesesesesesabababababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababesesesgygygygygygygygygygygygygygygygygygygygyrvgyrJrigygygypzpzaaaaaaaeyIyIyIyIyIaeaaaazIzIzJzfzfzlzKzLzMzNzwyXvzgygygygyesababababbkababbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababababababababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababababesesesgygygygygygygygygygygygygygygygygygyrFslsJsKslslslzOzPzQzQzQzQzQzQzQzQzQzQzQzQzRzSzTwCwCwCzUzVzWzXzYzZvzgygyesesesababbkbkbkabbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababababbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababababesesesgygygygygygygyesesgygygygygygygygygypBpCgygygypzpzaeaaaaaaaaaaaaaaaaaaaaaazIzIvzvAvBvzvzvzvzvzvzvzvzgygyesabababbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababesesesesesesesesesesmRsEgygygygygygygygygygygygygygyaeaaaaaaaaaaaaaaaaaaaaaaaagygygygygygygygygygygygygygyesabababbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababababababababesgygygygygygygygygygygygygysMgygyaaaaaaaaaaaaaaaaaaaaaaaagygygygygygygygygygygygygyesesababbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababababababababababesgygygygygygygygygygygygyesmResesaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygygygygygygynDmResababbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababesesgygygygygygygygygyesababesesesaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygygygygygygygyesababbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababesesesesesesesesesesesabababesesesaaaaaaaaaaaaaaaaaaaaaaaagygygygygygygygygygyesesabbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaagygygysLgygygyesesesesababbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababababababababababababbkbkbkbkbkababaaaaaaaaaaaaaaaaaaaaaagygyesmResesesesababababbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabababaaaaaaaaaaaaaaaaaaaaaaesesesesababababababbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkababaaaaaaaaaaaaaaaaaaaaaaaaesesababababbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkabaaaaaaaaaaaaaaaaaaaaaaaaaaesbkababbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaAaaaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaAaaaaaAaaaaaAaAaAaAaAaAaAaaaaaAaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaAaAaAaAaaaAaAaAaAaAaAaAaAaAaaaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaAaAaAaAaaaAaAaAaAaAaAaAaAaAaaaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaAaAaAaAaaaAaAaAaAaAaAaAaAaAaaaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkaabkbkbkaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaabkbkbkaaaaaaaabkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaaaaaAaAaAaAaAaAaAaaaaaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbkbkbkbkbkbkbkbkbkbkbkbkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababiLiKiKiJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababaJaJaJaJaJababababababababiMeOeOdHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaabababababababaJiNiOiPaJaJaJaJaJaJaGaGaGaGiQiRaGaGaGaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaababababababababaJjbiTiUiViWaKaKaKiSaiiZjfaiiYeOaijaiZaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaabababababaAaAaAaAjpjhiTjrjgjdjdjdmraijojmjnjkjljijjjcaGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaababababaAaAaNaOaAaJaJaJaJaKaKaLaLaMaiaiaiaiaIaHaiaiaiaGazazazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahagafaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaababababaAaBaCaDaEaFasaraqapawavauataiakajaiaoanaiamayaUaxamazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkbmblaeaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaababababaAaWbobpaAbnbAbgbBbAbybxaubzaibubwbvbrbqbtbsbjbhbhfJazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPaRaQaSaeaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaabababaAaWaTbiaAaVbgbfbebdbbbcbbbaaGaGaGaGaZaYaiaXbjbhbhdvazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadkdldleubWbVblaeaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababaeaeaeaeaeaeaeaeaeabababaAaWcmcnaAclbYbXcabZcccbcecdcgcfchaGcjcickamamiXamjeazaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadQdRdSdTbDbCbEaeaeababababababababababababababababababababababababababababababababababababababababababababababababababalalalaeaeaeaeaeaeaeaebTaGaGaGaGaGaGbUaGaGaGaGbFaGaGbIbHbGbLbKbJaGbPbObNbMbRbSbQbRazalalaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaetdldlfycPbVcrabababababababababababababababababababababababababababababababababababababababababababababababababababalalalaaaaaaexexexexexexexaicWcXcUcVcScTcQcRdcdbdeddaGcYdacZdidhdjaGdgdfbNbMbMbMbMazazalalaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaecocqcpcrabababababababababababababababababababababababababababababababababababababababababababababababababababababalaaaaaaexexexexexexexcscwcxcyctctcucvctcycFcEcDcCcBcAczcMcMcLcKcJcIcHcGcOkrcNazalalalalaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaefxemelekcrababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaexexexexexexexejcwdAdBdCeheidFdGdYaGeadZaGebedecdOdNdPaGdVdUaidWdWdWdWeeefegalalaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacacacacacacacacacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaedLdKdMcrdJdIcrcrcrcrabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaexexexexexexexdHcwdAdBdCdDdEdFdGdyaGdxdwaGdzbbbbbbbbdsaGlyduaidtdodpdmdndqdrdqdqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacaaacacacacacaaacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaegzfefEfHfGfFafbCeYcrfbfacrabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaexexexexexexexaifkflfjdCfhfidFfgfvaGfzfwfsfrfuftfoaGeLeKfmeRaifnfAfBfCfDdqalalalaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacaaacacacacacaaacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaefcfdfeffeUeTeWeVeYeXfaeZfbcrabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaeAereseyezeresevewepeqeneneneoeoeoeoeoeSeReQePeOeNeMaGfqfpeJeIaieHeFeGeDeEeCaGaGeBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacacacacacaaaaaaaaaaaaaaacacacacacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahSfchbfcfEfEdJheeUcrekhdcrfahccrabababababababababababababababababababababababababababababababababababababababababababababababdXaaaaaaaaaagMgPgQgNgOgTgQgRgSgWgXgUgVhaeogYgZgweogxeRgBgAgDgCgEaGgGgFgIgHaiaigJaiaiaieReRgKeBeBeBeBgLeBeBeBeBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaegugvfEgsgtfEcpgqeTgrgpgocrcrcrcrcrcrababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaagngbgcgcgcgcgdgegfggghgigjgkeoglgmfVfUfTeIfXfWeReRfYfweReReJeIgafZfKfLfIlzeReRfMeBfOfPeBfNfRfSfQeBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeiCiBhRfEgtiDffiGeUiFcriIiHcrhOhKbCiEcrabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaagngQgQgQhWgQhVhUgQibgXhZiahYeogmhXihigijiiidicifieilieimieikieieieirisitiuinioipiqixiyiziAivhAiweBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaeaeababcrfFhLhPhQhRhThNeThOafbChKcrhOhLhKhMcrababababababababababababababababababababababababababababababababababalalalalalalababababababkDkEaaaaaahrgQgQhihjhfhggRhhhnhohphqhkeohlhmhHeoeohGhGhFhuhEhxhuhJhuhIhwhwhwhwhxhuhvhththseBhChDeBhBhzhAhyeBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaecrcrcrcrcrcrfGeUnWhLeUgqnUhOhOeVeYiIcrhOcpeknVcrababababababababababababababababababababababababababababababababalalalgygygygyalalalababsEgygyaaaaaaaanwereseynwnwnwnwnwpMnwnununueopJeonSnTnRhGsesjhunMnKnLnInJnGnHkmkmkmnFhunEnChtnBlulululurVnznyfQeBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaecrmPeUhRoEcriCoDiBcrgrcroGoHoFcrbClLiFmOcpeleUcrabababababababababababababababababababababababababababababababalalgygygygygygygygyalalabgygyaaaaaaaaaaaaaaaeaekBohogoflnoeodocqOoanZnYqhoqorosrIrfrvhuopokollDkmnGoiojkmkmmghuoCozhtoBoAovoulueBeBeBeBeBaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcrmPcphRcpmUlLhLmShLmTbCbCmNeYbCcpcpcreUmOeUeUcrababababababababababababababababababababababababababababababalalgygygygygygygygygygymQmRgygyaaaaaaaaaaaaaaaaaekBmLllmMlOmImHmJkBkBllmKeomCmDhGhGnPnXhumEmxmbmvmwmAmBmynAmsnfhumqmuhtmtmpmpmoluabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababcrlMhReUcpnscpnrdJcpnqmTnrhKntcpkNekcrlIcpgobCcrabababababababababababababababababababababababababababababalmRgygygygygygygygygygygynDnjgyaeaaaaaaaaaaaaaaaaaekBmLllnppGnmnlllnkkBnneoeonNnOhGoXotoKhupPmVmWmXnQonoomEobmGquhungnhhtnineneneluabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababcrlMlNeUfFcrkPcrlJlKcrcpcrlJlKcreUlLcrdIlHiFlIcrabababababababababababababababababababababababababababababalomgygygygygygygygygygygygygygyaeaaaaaaaaaaaaaaaaaekBlmlllolnmzlqltlskBlpeoowoxoyhGnamYmZhulxlFlGlDlElBlCkmnbkmkmhulwlvhtlululululuabababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababcrcrcrcrcrcrkPcrgokNcphTmmeUhTeUgoffcrmnmknxmjcrabababababababababababababababababababababababababababababalmQgygygygygygygygygygygygygygyaeaaaaaaaaaaaaaaaeaekBlRlQlPlOnolqndlTkBlSeooYoxoyhGnvhGnchulWmbmcmdmelYlZmamamhmghumimfhtababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababcrkPcrkNekkOhTkMcphKcreUekcrkLkJkJkKcradababababababababababababababababababababababababababababalalgygygyprgygygygygygygygygygyaeaaaaaaaaaaaaaeaeaekBkBkCkFkBkBkGlhkGkBkIeoowpBpCkokpmFkshukVkvkwkYkukzkAlckyknkmhuhththtababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababcrkPcrhTcpbVljeUekgocrkPcrcrhOeUkJkKlkadababababababababababababababababababababababababababababalpSpTgypUpSpQgygygygygygygygygytjaaaaaaaaaaaetjtjtjgygyqdqeqfkBmllglfkBlieogylrlAhGkSkTkTkUlUkWkXkUlVkZlalblXleldlbababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababcrkPcrcrcrcrcrcrcrcrcrkPcrphbCeUbCkKpiadababababababababababababababababababababababababababababalpSgygygypSpQgygygygygygygyqwqCpjsWsWsWsWsWsWpoqwqCgygygygygykBplpnpmkBpkgygygygyhGpApxpykUpwpupvkUptpqpslbpppEpDlbababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLaaaaaaaaaaqLababababababababababababababcrkPkPkPkPkPkPkPkPkPkPkPcrhOeUiFeUiEcradababababababababababababababababababababababababababababalgygygygyqMqNgygygygygygygygyrWqPqPqPqPqPqPqPqPrWgygygygygygykBpHrUkGkBpFrigygygyhGpXkTkTkUpWpOtykUpRpLtllbpNpKsIlbababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababcrcrcrcrcrcrcrcrcrcrcrcrcrcrmjrOoMcrcradababababababababababababababababababababababababababababalgygygygygygygygygygygygygyqwqCrdrerererererereqwqCgygygygygygypBrSpCpdpcpeoVoVoVoToUsyoZkUoWoOoPkUoNoRoSlboQpbpalbabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababadadadcrkJkJeUcradadababababababababababababababababababababababababababababalpSpTgygygygygygygygygygyaaaaaaaaaaaaaaaaalalalalalalalalgygygygygygypBpgpCgygyalhGhGhGhGkUkUkUkUkUpfpfpflblblblblbabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababadadadcroJoIoJcradabababababababababababababababababababababababababababababalpSgygygygygygygygygygygyaaaaaaaaaaaaaaaaalalalababababalalalalalalalgyjHgygyalalababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababadadcroLrOmjcradabababababababababababababababababababababababababababababalalpVryrxgygygygygyalalalaaaaaaaaaaaaaaaaaaababababababababalalalalalgyjHgygyalabababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababadadadrBrCrDadadababababababababababababababababababababababababababababababalalalmRalgygymQmQalababaaaaaaaaaaaaaaaaaaababababababababababalalalgyjHgygyalababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalalalalalababaaaaaaaaaaaaaaaaaaabababababababababababalalgyjHgygyalababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLababababababqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaababaaaaaaaaababababababababababalalgyjqkhgyalababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLababababababqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaabababaaaaaaababababababababababalalgygyjHgyalabababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaababaaaaaaababababababababababalalalgyjHgyalalalalalababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaabababababababababalalalgyjHgygygygyrHjFjFjFjFjFjFjFjFjFjFjFjFabababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaabababababababababalalalgyjHgygygygyrJkakQjYjXkgkfkekdjFkckbjFababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaabababababababababalalalgykHjSjSjSoVjVjOjNjQjPkqjZkxktjWjRjTjFababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaabaaaaaaaaababababababababababalalgykigygygygyjFjFjFjFjFjFjKjJjIjFjMjLjFababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaabababaaaaababababababababababalalgyqqjsjujtjtjvjxjwjzjyjBjAjUjCjEjDjGjFababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLabqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaabababaaaaaaabababababababababalalgygygykigygyjFjFjFjFkljFjFjFjFjFjFjFjFabababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaabababababababababalalalalgykigygygygysAkRsCsCalababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaabababababababababalalalrJkkrigygygygygygygyalababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLababababababqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaabababababababababalalalpBkjpCgygygygygygygyalababababababababababababababababababababababababababababababaaababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaabababababababababalalalgykigygygygygygygyalalabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLababababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaabaaaaabababababababababalalalgykigygyalmQalalalalalababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLababababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaabababaaaaababababababababalalalgykigygyalalalababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaabababaaaaaaabababababababalalalgykigyalalabababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaababababababalalgykigyalalababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaabababababalalgykigygyalabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaalalaaaaaaaaaaaaabababababalalgykigygyalabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdXalalalaaaaaaaaaaaaabababababalalgyqqqngyalabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLabqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLabababababababababqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdXalaaaaaaaaaaaaaaaaabababababalalgygykigyalabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLabababababqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLabababababababababqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalalaeaeaeaeaeaeaeaealalababababalmRsEgykigyalababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLababababababqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLababababababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalalsHsHsHsHsHsHsHsHalalalabababalalgygykigyalababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLabababababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalaeaeaeaeaeaeaeaealabababababalgygygykigyalalabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaababababababalgygygykigygyalabababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaababababababalgygygykigygyalababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaabababababababalgygyrJkkrigyalababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaabababababababalgygypBkjpCgyalababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababalalgygykigygyalababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababalgypZpYgyalalabababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababalalgykigygyalababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababalgygykigyalalababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLababababqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLababababababqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababalalgygykinDmRababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLabababababqLqLqLqLqLqLqLabababqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababalgygypZpYgyalababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLababababqLqLqLqLqLqLqLababababababqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalalalgygykigygyalalabababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLababababqLqLqLqLqLqLqLababababababqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaalgygygygykigygygyalabababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLababababqLqLqLqLqLqLqLqLabababababqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygykigygygyalabababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLabababababqLqLqLqLqLqLqLqLababababababqLqLqLababababababqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygykigygygyalababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygykigygygyalababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygykigygygyalababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaadXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygygykigygygyalalababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqaqaqaqaqaqaqaqaqaqaqaqaqaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygygygykigygygygyalalalalalababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaeaeaaaaaaaaaaaaaaaaaeaaaaaaaeaaaaaaaeaaaaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygygygykigygygygygygygygyalalabababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaqgqxqbaaqgqxqbaaqgqxqbaaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLabababababqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygygygykigyrJrigygygygygygyalababababababababababababababababababababababababababababababababababababababababababaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeqgqcqbaeqgqcqbaeqgqcqbaeqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygygygygygyqqjsqoqpjsjsjsqngygyalalalababababababababababababababababababababababababababababababababqjqjqjqjqjqjqjabaaaaaaaaaeaaaaaaaaaaaeaaaaaeaeaaaaaaqgqcqbaaqgqcqbaaqgqcqbaaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLabababababqLqLqLqLqLqLababababababqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaagygygygygygygygypBpCgygygykigygygygyalababababababababababababababababababababababababababababababababqjqkqmqlrXqiqjababaaaaaaaeaaaaaaaeaaaeaaaeaeaeaeaaaaqgqcqbaaqgqcqbaaqgqcqbaaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaalalgysLgygygygygygygygyqqjsqngygyalalabababababababababababababababababababababababababababababababqjqkqvtzqjqjqjababaaaaaaaeaeaeaeaeaeaeaeaeaaaaaeaeaaqgqcqbaeqgqcqbaeqgqcqbaeqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaabalalmRalalalalalalgygygygykigygygyalalalabababababababababababababababababababababababababababababqjqkqtqsrXqrqjabababaaaaaeaaaeaaaaaaaeaaaaaaaaaeaaaaqgqcqbaaqgqcqbaaqgqcqbaaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLababababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababababqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaababababababababalalgygygykigygygygygyalalababababababababababababababababababababababababuyuyuyuyuyvewkveveveqjqjqjababaaaeaaaeaeaaaaaeaaaaaaaaaaaaaaqgqcqbaaqgqcqbaaqgqcqbaaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLababababqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalalaeaeaeaeaeaeaeaeaeaeaealalalalabababababalalgygyqqjsjsqngygygyalalababababababalalalababababababababababababababuyvbuZEqvJEpuVEoErvcuOuOqjababaaaeaaaeaaaaaaaeaeaeaeaeaeaeaeqgqcqbaeqgqcqbaeqgqcqbaeqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLababababqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalalalsHsHsHsHsHsHsHsHsHsHsHsHsHsHalalalalababababalgygygygygykigygygygyalalabababalalalgyalababababababababababababababuyuQuRuSuTuUuAuPuNuMuPuOqjababaaaeaaaaaaaaaaaeaaaaaeaaaaaaaaqgqcqbaaqgqcqbaaqgqcqbaaaeaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLabababqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaealalabababababalalgygygygyqqjsjsqngygyalabalalalgygygyalababababababababababababababuyuzuwuxuFuGuAuBuKuJuIuHqjuLuLuLuLuLrMrLrLrNrtrMrNrtaaaaaaaaqgqcqbaaqgqcqbaaqgqcqbaaqaqaqaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLabababqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLabqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababalalalalgysMgygykigygyalalalgygygygygypzpzpzpzabababababababvMvMvMvMuywJuwwKwHwIEBuPwFwEuIwGvewBwDEAwywxwAwzshwawwwvECrMrLrNaaaaaewLaeaaaewLaeaaaewLaeaaaeaaqaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLabababqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLababababababababqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaababababababababababalalmRgygykigygygygygygygygygygyAwwuwtpzabababababababvMvXvVvWuyvUuwvTvRvSuAuPwjwiuPwhvewgwfwewdwcwbtEshwavZvYxlxmxnxqxewlsNsNsNsNsNsNsNsNsNsNwrwqwsaeqaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababababqLqLabqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaabababababababaaaaaaaaaaaaaaababababababababababababalalgyqqjsqngygygygygygygygyAwAevQpzababrtrtrtrtabvMvNvOExuyvHvIEwuTvKuAvLvCvBuAvDvevEvGvFvwvvvgvxvzvysvvAEvrMrLrNaaaaaevuaeaaaevuaeaaaevuaeaaaeaaqaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaababababababababaaaaaaaaaaaaaaabababababababababababababalgygygyqygygygygygygygygyAwAeEurtrtrtrtvivirtrtrtrtwnrtrtrGrGrGrGvhrNrGwRrGvhrNrGvsvrrGwpEtvlvkvpvorGvnEsrtaaaaaaaaqgrgqbaaqgrgqbaaqgrgqbaaqaqaqaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaabababababababaaaaaaaaaaaaaaaaabababababababababababababalalalrJqzrigygygygygygygypBAzuDuvvPsxulwosJuXwCwmsDsFsGtdtetctfsYtctctctrtqtctcxCtktntmtAzgtDtCtvtuxMtwtEtFaaaeaaaaqgrgqbaaqgrgqbaaqgrgqbaaaeaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaabababababababaaaaaaaaaaaaaaabababababababababababababababalalAwrQrPrRrRrRrRrRrRrRrRrTswsztZsKsBuksdsdsdvtsoslsmstsdsdsssqsrsdsdvauYuWsdscsbsarZskvdrZsishshtYsQsusvaeaeaeaeqgrgqbaeqgrgqbaeqgrgqbaeqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaabababababaaaaaaaaaaaaabababababababababababababababababalalpBqApCgygygygygygygyrJsCrurtrtrtrtrtrtrtrtrtrwrzrArErzrFrGsnrGrKrtrtrtrtrtrtrtrtrtrtrtrMrLrLrNrtspsgrtaaaaaeaaqgrgqbaaqgrgqbaaqgrgqbaaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLababababababababqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababalalalalgyqygygygygygygygygyAwowowalabababababababqDrlrjrkrorprmrnrrrsrqqDababababababababababaaaaaaaarcrhrbrcaaaaaeaaqgrgqbaaqgrgqbaaqgrgqbaaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLabqLababababqLqLabababqLqLqLqLqLababababababababqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababalalalalalalgyqygygygygygygygygyAwumalalabababababababqDrlurusuqqQqQqQunuoupqDababababababababababaaaaaaaauuutvquuaeaeaeaeqgrgqbaeqgrgqbaeqgrgqbaeqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababalgygygygygygyqygygygygygygygygyAwumalababababababababqDrlujuhuhuiucuguaubDdqDababababababababababaaaaaaaaCQvfvjrtvmaaEfaaqgrgqbaaqgrgqbaaqgrgqbaaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababalgypZjsjsjsjsragyalalgygygygyalalalalababababababababqDrltXqQqQqQtTtUtVtWCgqDabababababababababaaaaaaaaqBqBqBqBqBqBqBaaaaqgrgqbaaqgrgqbaaqgrgqbaaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLabababababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaabababababababababababababababalgykigygygygysLgyalalalalalalalabababababababababababqDtStOtJtJBZtHtItMtNtLqDababababababababaaaaaaaaaaqBqBqBqBqBqBqBaaaaqgrgqbaeqgrgqbaeqgrgqbaeqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLababababababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaabababababababababababababababalgykigyalalalmRalalabababababababababababababababababqDqGqIqHqQqDqSqRqDqJqKqDabababababababaaaaaaaaaaaaqBqBqBqBqBqBqBaaaaqgqEqbaaqgqEqbaaqgqEqbaaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLababababababababqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaababababababababababababababalgykigyalalalalabababababababababababababababababababqDqVqUqTqQqDqZqYqDqXqWqDababababababaaaaaaaaaaaaaaqBqBqBqBqBqBqBaaaaaaaeaaaaaaaeaaaaaaaeaaaaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLababababababababqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLabababababqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaabababababababababababababalgykigyalalalababababababababababababababababababababqDqDqDqDqDqDrYrYqDsfsfqDababababaaaaaaaaaaaaaaaaaaqBqBqBqBqBqBqBaatKqaqaqaqaqaqaqaqaqaqaqaqaqaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLababababababqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaababababababababababalalgykigyalalababababababababababababababababababababababababababqDqDqDqDqDqDqDababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLababababqLabqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaabababababababababalgygykigyalalabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLabqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLqLqLabababqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaababababababababalgygykigyalabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLababababqLqLqLqLababababababqLqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaabababababababalalgypZragyalabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLababababqLqLqLababababababqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaabababababababalgygyqygygyalabababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLabababqLqLqLabababqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaabababababababmRsErJqzrigyalababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaabababababababalgypBqApCgyalababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLalalalqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaabababababababababalgygyqygygyalabababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLabqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLalalalalqLqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalaeaeaeaeaeaeaeaeaeaealalabababababababalalgyqygyalalalababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLabababqLqLqLqLqLqLgygyalalqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalalsNsNsNsNsNsNsNsNsNalalalabababababababalalgyqygyalalalababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLabababqLqLqLqLqLqLgygygyalqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalaeaeaeaeaealalaeaeaealalabababababababababalgyqygyalalalabababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLabababababqLqLqLqLgygygygyalalalalqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaalalalalaaaaaaababababababababababalalgyqygyalalalabababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLababababababqLqLqLqLgygygygygyalalalqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaalalalalaaaaaaaaababababababababababalalgyqygyalalalababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLababqLqLqLqLqLqLqLababqLqLqLqLabababqLqLqLqLqLqLqLgygygygygyalalqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaalalaaaaaaaaaaabababababababababalalalgyqygyalalalababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLabababababababqLqLqLqLqLababqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLsOgysOgyalalalqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababalalalgyqygyalalabababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLabababababababqLqLqLqLqLababqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLsPEnsPgyalqLqLqLqLabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababalalalalgyqygyalalababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLababababababababqLqLqLqLqLabababqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLqLqLsRsSsTqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababalalalalgyqygyalalababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLababababababqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLabqLqLqLqLqLqLqLqLqLqLqLqLqLsRsSsUqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababalalalalgyqygyalabababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLababqLqLqLqLqLqLqLqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLgygyqwqCsVsWsWsWsWsWsWsXsSsUqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababalalalalgyqynDmRababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababqLqLqLqLqLqLqLqLqLqLgygygygyEnsZsZsZsZsZsZsZtatbsUqLqLqLqLqLqLababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababalalalalgyqygyalabababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLababababababqLqLqLqLqLqLqLqLalgygygyqwtgrerererererethsStitjqLqLqLqLqLalababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababalalalgyqygyalabababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLabababqLabababqLqLqLqLqLqLalalalgygygygyqLqLqLqLqLqLsRsSsUqLqLqLalalalalabababababababababababababababababababababababababababababababababababababababababababababababababababababababababqFtotpabziziziziziziabababababababaaaaaaaaaaaaaaaaaaaaaaaaababababababababababalalalgyqygyalalababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLababqLqLqLqLqLqLqLqLqLqLababalalgygygyqLqLqLqLqLqLqLsRsSsUqLgyalalalalalalababababababababababababababababababababababababababababababababababababababababababababababababababababababababtstpttabziDwEmziDyziabababababababaaaaaaaaaaaaaaaaaaaaaaabababababababababababalalalgyqygyalalalalabababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababalalalgygyqLqLqLqLqLqLqLtxsSsUgygyalalalalalalabababababababababababababababababababababababababababababababababababababababababababababababababababababababababqFmRabzizMzLDADBziabababababababaaaaaaaaaaaaaaaaaaaaabababababababababababababalalgyqygygyalalalalalabababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLqLqLsOEnsOgygyalalalalalalalababababababababababababababababababababababababababababababababababababababababababababababababababababababababtBababziziziziDzzialalalalmRalalaaaaaaaaaaaaaaaaaaaaaaababababababababababababalalgyqygygygyalalalalalababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLgygysPgysPgygygygygygyalalalababababababababababababababababababababababababababababababababababababababababababababababababababababababababpIababziDwEyziArDFgygygygytGgyalalaaaaaaaaaaaaaaaaaaaaababababababababababababalalgyqygygygygyalalalalalalababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLababababababqLqLqLqLqLqLqLqLqLqLabababababqLqLqLqLqLqLqLqLqLgygygygygygygygyDEDEDEgyalalalababababababababababababababababababababababababababababababababababababababababababababababababababababababababpIababzizMzLDDzJDCgygygygygygygygygyaaaaaaaaaaaaaaaaaaaaababababababkDmRmRmRmRmRgygyqygygygygygygygyalabalalabababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLababababababababqLqLqLqLqLqLqLababababababqLqLqLqLqLqLqLqLqLgygygygygygygygyDVDUDTgyalalalababababababababababababababababababababababababababababababalalalalalalalababababababababababababababababababziDSziziziziziziArDRgygygygygygygygygygygyaaaaaaaaaaaaaaaaaaabababababmRtPsCtQtQtRgyrJqzrigygygygygygygyadabalababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLababababababqLqLqLqLqLqLqLababababababqLqLqLqLalgyzyzyzyzyzyzyDPDQDOzyzyzyzyzygygygyalabababababababababababababababababababababababababababababalalalalalalalalalalalalabababababababababababziziziziDLDMDNziDwEzziDzzixhxhDJCcCdxhgygygygygygyaaaaaaaaaaaaaaaaaaabababalmRudowueueufgyAwDIrPDHAjAjAjAkgygygygygyalabababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLababababababqLqLqLqLqLqLqLabababababqLqLalalalgyzyzxzqzpzszrzuztzwzvznzozlzmsCsCrialalalalabababababababababababababababababababababababababalalalalalalalalalalalalalalalalalabababababababzizhzkzjzIzHzGzizMzLzKzJzizPzOzNzRzNzQgygygygygygygyaaaaaaaaaaaaaaaaaaalalalmRuCuDuEuEpCgyAwzBzAzFzEzAzAzzgygygygygyalababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLabababqLqLqLqLqLqLqLqLabababqLqLabalalalgyzyAdzYAbzZAJBfBeBeBdzXAcAAAIzVzWufalalalalalalabababababababababababababababababababababalalalalalalalalalalalalalalalalalalalalababababababzizTzkzSAoAnAqziziziziArzizPAsAsAuAtAvgygygygygygygyaaaaaaaaaaaaaaaaaagygygygygygygygygygypBzBAgAgAgAizAAlAmAjAkgynDmRalabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLabababqLqLqLqLqLqLqLqLqLqLqLqLqLabalalalgyzyAKAHBnBFBEBkAEAGAFznBgAxAyxvBhufalalalalalalalalalabababababababababababababababababalalalmRalalalalalalalalalalalalalalalalalalalalabababziABADACASARAQAPAOANAMALzizPAsAWAVAUATgygygygygygyaaaaaaaaaaaaaaaaaaaaaaaagygygygygywNwNyKxQzBBbAZAYBazAzAzAzAAXgygygyalalabababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLababalalalgyzyBjBiBIzsBHBGzYBczyzyzyzyzyzyBhufgygygygygygygyalalalalabababababababababababababababalalgytGgygygygygygygygyrJrigygygygygygyalalalalalababziziziziziziziBmBlBJBmBlzixhxhxhBKxhxhxhBoBpgygyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagygyxOxQBqBxBwBvBuBuBtBsBrBzBAByAXgygygymQalabababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLqLqLqLqLqLqLqLabababalalgyzyBBBDBCzZzYBLzYzYBMBXBYBRBVBNBQqpjsjsjsjsjsqngyalalalalalalababababababababababababalalalgypZjsjsjsjsjsjsjsjsqoqpjsjsjsjsqngyalalalalalabababababxhCoCnCmAsAsCpAsAsCjCiAsChAVClCkCkCeCfCcCdEGEFEFEFEFEFEFEFEFEFEFEFEFEFEFyKycCaCbxPBTBSCPBUBWBWDfCTBOBPCxCDgygygymQalabababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLqLqLabababalalgyzyzyzyzyzyzyzyzyzyzyCqzyzyzyzyowufgygygygygykigygygygyalalalalababababababababababalalgygygykigygygygygygygygypBpCgygygygykigyalalalalalalalalalabxhxhxhxhCLCNCMCGCGCGCFCGCGCICHCKCJCODlCGDlCyCyCyCyCyCyCyCyCyCyCyCyCyCyCyDgCzDgCACzCtxPCsCrCwCvCuBrDjCECBCCsCsCrigyalalababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaqLqLabababalalgygygygygygygygygygygyAwAfAhowowowufgysMgygygyqqjsjsqngyalalalalababababababababababalgygypZjspYgygygygyalgygysMgygygygygygykigyalalalalalalalalalalalalalxhCZCYAsAsAsAsCXAsCWCVCUDmAsCRCSCcCdEHEHEHEHEHEHEHEHEHEHEHEHEHEHEIyKycyMDcxPDbxPzBzAzAzAzAzAzAzAzADauDxJpCqFmQalababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababalalalalalalalalalgygygypBuDuDuDuDDeApalmRalalgygygygykigyalalalalalabababababalalalalalgypZpYgygygyalalalalalalmRalalalalalgykigyalalalalalalmRalalalalalwVwVDiDuDiwXwXDhDtwXwXwXxIDsxIxhDkgygygyaaaaaaaaaeaaaaaaaeaaaaaaaaaaaeaayTxQxPDqDpDoDnxixixjDvDKEgDxDGDrDrDrqFgyalababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababalalalalalalalalalalalalabalalalalalgykigygygygygyalalalalalalalalalalalgykigygyalalalabababababalalalalalalgykigygygyrJrigygytGgygyalalalwVwUwTwZwYwXwWxdxcxbxawXxgxfxtxhgygygygygygyaaaaaeaaaaaaEDaeaeaeaeaeEDaeaewNwMwPwOwQwQwQwQxrwQwSwQwQxsqFqFqFqFgyalababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababalalalalgyqqjsjsjsqngygygygygygygygygygygygygykigyalalabababababababalalalalalalgyqqjsjsjsqoqpjsjsjsqngyalalalwVxwxuxyxxwXxzxBxAxDEEwXxExGxFxhgygygygygygyaeaeaeaeaeaeaeyIyIyIyIyIaeaaaawNxkxoxPxWxRykxixixpxixjwQxKgygygygyalalababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababalalalgygygygygyqqqngygyrJrigygypZjsjsjsjsjspYgyalabababababababababalalalalalgygygygygypBpCgygygykigygygygywVwVwVwVwVwXxHxNxAxDxLwXxIymxIxhgygygygygygyaaaaaeaaaaaaaeyIyIyIyIyIaeaaxOxQxPxSypwQwQwQwQwQwQxTxUwQxKgygygyalalabababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababalalalgysMgygyqqjsjsqoqpjsjspYgygygygygygygyalabababababababababababalalalalalalalgygygygyalgyqqjsjsqngygygygygygywXxVxXwXwXwXwXowysufyZgygygygygyaaaaaaaeaaaaaaaeyIyIyIyIyIydycybyaxZylytyjyiyhygyfyexYxUwQxKgygygyalalabababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababalalmRalgygygygypBpCgygygygysMgyalalalalalababababababababababababababalalalalalalalalalgygygygykigygygygygygygygyyAowowowowowowufgygygygygygyaeaeaeaeaeaeaeaeyIyIyIyIyIywyEyxyJyvynxPxPxPyuyoyryqyyyzwQxKgygygyalabababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababalalalalalalalalalalalmRalalabababababababababababababababababababababababababalalalalalgykigygygygygygygygyyNuDuDuDuDuDuDpCgygygygygygygyaaaaaaaaaaaaaeyIyIyIyIyIyKycyMyLxPyFyDyDyDzDyHyHyGyByCwQxKgygyzCmRabababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababalalalalalalalalalalalababababababababababababababababababababababababababababalalalalgyqqjsjsjsjsjsjsjsjsyOjsjsjsjsjsjsjsjsyPgygygygygygyaaaaaaaaaaaeyIyIyIyIyIzUaayTxQyUySxPxPxPyRyQyryrxTyVwQxKgygygyalabababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababalalalalalababababababababababababababababababababababababababababababababalalalalgygygygygygygygygygygygygygygygygygygyqygyrJrigygygypzyWaaaaaaEDyIyIyIyIyIEDaaaaaazfzeytzdzczbzayYyXyyxUwQxKgygygyalababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalalalalalalalalalalalalalalalalalalmRsEDYDWDZDXDWDWDWEcEbEaEaEaEaEaEaEaEaEaEaEaEaENEOEPxPElxPEjEkEhEiEeEdwQxKgyalalalababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalalalalalalalalalalalalalalalalalgygygypBpCgygygypzyWaeaaaaaaaaaaaaaaaaaaaaaaEMzfwNyKxQwNwQwQwQwQwQwQwQxKgyalabababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalalalalalalalalalalalalalalalalalalalalalalgygygyaeaaaaaaaaaaaaaaaaaaaaaaEKELrRrRrRrRrRrRrRrRrRrRrREJgyalababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalalalalalalalalalalalalgysMgygyaaaaaaaaaaaaaaaaaaaaaaaapzalalalalalalalalalalalalalalababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalalalalalalalalalalalalalmRalalaaaaaaaaaaaaaaaaaaaaaaaaaaalalalalalalalalalalalalalabababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalalalalalalalalalalalababalalalaaaaaaaaaaaaaaaaaaaaaaaaaaalalalalalalalalalalalalabababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababalalalalalalalalalalalabababalalalaaaaaaaaaaaaaaaaaaaaaaaaalalalalalalalalalalalalabababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaalalalalalalalalalalalabababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaalalalalalalalalababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaalalalalababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaalalababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaalababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaAaaaaaAaaaaaaaAaaaaaaaaaaaAaaaaaaaAaaaaaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaAaAaAaAaaaaaaaAaAaAaAaAaAaAaaaaaaaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaAaAaAaAaaaaaAaAaAaAaAaAaAaAaAaaaaaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaAaAaAaAaaaaaAaAaAaAaAaAaAaAaAaaaaaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaababababababababababababababababababababababababababababababababababababaaaaaaaaababababababababababababababaaabababaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaabababaaaaaaaaabababababaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabababababababababababababaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaAaAaAaAaAaAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/nano/css/shared.css b/nano/css/shared.css index b81990b7a3..b7c9bd66df 100644 --- a/nano/css/shared.css +++ b/nano/css/shared.css @@ -128,7 +128,7 @@ img, a img { h1, h2, h3, h4, h5, h6 { margin: 0; padding: 12px 0 6px 0; - color: #517087; + color: #FFFFFF; clear: both; } @@ -248,27 +248,41 @@ div.notice { clear: both; } -.itemLabel { +.itemContentNarrow, .itemContent { float: left; +} + +.itemContentNarrow { width: 30%; - color: #e9c183; } .itemContent { - float: left; width: 69%; } -.itemLabelNarrow { +.itemLabelNarrow, .itemLabel, .itemLabelWide, .itemLabelWider, .itemLabelWidest { float: left; - width: 20%; color: #e9c183; } +.itemLabelNarrow { + width: 20%; +} + +.itemLabel { + width: 30%; +} + .itemLabelWide { - float: left; width: 45%; - color: #e9c183; +} + +.itemLabelWider { + width: 69%; +} + +.itemLabelWidest { + width: 100%; } .itemContentWide { @@ -491,6 +505,14 @@ div.notice { text-align: center; } +table.fixed { + table-layout:fixed; +} + +table.fixed td { + overflow: hidden; +} + /* Table stuffs for power monitor */ table.pmon { border: 2px solid RoyalBlue; diff --git a/nano/js/nano_base_helpers.js b/nano/js/nano_base_helpers.js index d5a019e2f8..20e6160fed 100644 --- a/nano/js/nano_base_helpers.js +++ b/nano/js/nano_base_helpers.js @@ -48,6 +48,10 @@ NanoBaseHelpers = function () round: function(number) { return Math.round(number); }, + // Returns the number fixed to 1 decimal + fixed: function(number) { + return Math.round(number * 10) / 10; + }, // Round a number down to integer floor: function(number) { return Math.floor(number); diff --git a/nano/templates/air_alarm.tmpl b/nano/templates/air_alarm.tmpl new file mode 100644 index 0000000000..edfe41cda7 --- /dev/null +++ b/nano/templates/air_alarm.tmpl @@ -0,0 +1,217 @@ + +

        Air Status

        +{{if data.has_environment}} + {{for data.environment}} + {{:value.name}}: + {{if value.danger_level == 2}} + + {{else value.danger_level == 1}} + + {{else}} + + {{/if}} + {{:helper.fixed(value.value, 1)}} + {{:value.unit}}
        + {{/for}} + Local Status: {{if value.danger_level == 2}} + DANGER: Internals Required + {{else value.danger_level == 1}} + Caution + {{else}} + Optimal + {{/if}} +
        + Area Status: {{if data.atmos_alarm}}Atmosphere alert in area{{else data.fire_alarm}}Fire alarm in area{{else}}No alerts{{/if}} +{{else}} + Warning: Cannot obtain air sample for analysis. +{{/if}} +
        + + + + + + + + + + + + + +
        +
        +

        Remote Control

        +
        +

        Thermostat

        +
        +
        +
        +
        + {{:helper.link('Off', null, { 'rcon' : 1}, data.remote_connection && !data.remote_access ? (data.rcon == 1 ? 'yellowButton' : 'disabled') : null, data.rcon == 1 ? 'selected' : null)}} + {{:helper.link('Auto', null, { 'rcon' : 2}, data.remote_connection && !data.remote_access ? (data.rcon == 2 ? 'yellowButton' : 'disabled') : null, data.rcon == 2 ? 'selected' : null)}} + {{:helper.link('On', null, { 'rcon' : 3}, data.remote_connection && !data.remote_access ? (data.rcon == 3 ? 'yellowButton' : 'disabled') : null, data.rcon == 3 ? 'selected' : null)}} +
        +
        +
        + {{:helper.link(data.target_temperature, null, { 'temperature' : 1})}} +
        +
        +{{if (data.locked && !data.remote_connection) || (data.remote_connection && ! data.remote_access)}} + {{if data.remote_connection}} + (Current remote control settings and alarm status restricts access.) + {{else}} + (Swipe ID card to unlock interface.) + {{/if}} +{{else}} + {{if data.screen != 1}} +
        {{:helper.link('Main Menu', null, { 'screen' : 1})}}
        + {{/if}} + {{if data.screen == 1}} +
        + {{if data.atmos_alarm}} + {{:helper.link('Reset - Area Atmospheric Alarm', null, { 'atmos_reset' : 1})}} + {{else}} + {{:helper.link('Activate - Area Atmospheric Alarm', null, { 'atmos_alarm' : 1})}} + {{/if}} +
        +
        +
        + {{:helper.link('Scrubbers Control', null, { 'screen' : 3})}} +
        +
        + {{:helper.link('Vents Control', null, { 'screen' : 2})}} +
        +
        + {{:helper.link('Set Environmental Mode', null, { 'screen' : 4})}} +
        +
        + {{:helper.link('Sensor Settings', null, { 'screen' : 5})}} +
        +
        + {{if data.mode==3}} + {{:helper.link('PANIC SIPHON ACTIVE - Turn siphoning off', null, { 'mode' : 1}, null, 'redButton')}} + {{else}} + {{:helper.link('ACTIVATE PANIC SIPHON IN AREA', null, { 'mode' : 3}, null, 'yellowButton')}} + {{/if}} + {{else data.screen == 2}} + {{for data.vents}} +
        + {{:value.long_name}}
        +
        +
        + Operating: +
        +
        + {{:helper.link(value.power ? 'On' : 'Off', null, { 'id_tag' : value.id_tag, 'command' : 'power', 'val' : value.power ? 0 : 1}, null, value.power ? null : 'redButton')}} +
        +
        +
        +
        + Operation Mode: +
        +
        + {{:value.direction == "siphon" ? 'Siphoning' : 'Pressurizing'}} +
        +
        +
        +
        + Pressure Checks: +
        +
        + {{:helper.link('External', null, { 'id_tag' : value.id_tag, 'command' : 'checks', 'val' : value.checks^1}, null, value.checks&1 ? 'selected' : null)}} + {{:helper.link('Internal', null, { 'id_tag' : value.id_tag, 'command' : 'checks', 'val' : value.checks^2}, null, value.checks&2 ? 'selected' : null)}} +
        +
        +
        +
        + External Pressure Bound: +
        +
        + {{:helper.link(helper.fixed(value.external,2), null, { 'id_tag' : value.id_tag, 'command' : 'set_external_pressure'})}} + {{:helper.link('Reset', null, { 'id_tag' : value.id_tag, 'command' : 'reset_external_pressure'})}} +
        +
        +
        + {{empty}} + No vents connected. + {{/for}} + {{else data.screen == 3}} + {{for data.scrubbers}} +
        + {{:value.long_name}}
        +
        +
        + Operating: +
        +
        + {{:helper.link(value.power ? 'On' : 'Off', null, { 'id_tag' : value.id_tag, 'command' : 'power', 'val' : value.power ? 0 : 1}, null, value.power ? null : 'redButton')}} +
        +
        +
        +
        + Operation Mode: +
        +
        + {{:helper.link(value.scrubbing ? 'Scrubbing' : 'Siphoning', null, { 'id_tag' : value.id_tag, 'command' : 'scrubbing', 'val' : value.scrubbing ? 0 : 1}, null, value.scrubbing ? null : 'redButton')}} +
        +
        +
        +
        + Filters: +
        +
        + {{for value.filters :filterValue:filterIndex}} + {{:helper.link(filterValue.name, null, { 'id_tag' : value.id_tag, 'command' : filterValue.command, 'val' : filterValue.val ? 0 : 1}, null, filterValue.val ? 'selected' : null)}} + {{/for}} +
        +
        +
        + {{empty}} + No scrubbers connected. + {{/for}} + {{else data.screen == 4}} +

        Environmental Modes

        + {{for data.modes}} +
        + {{:helper.link(value.name, null, { 'mode' : value.mode }, null, value.selected ? (value.danger ? 'redButton' : 'selected') : null)}} +
        + {{/for}} + {{else data.screen == 5}} +

        Alarm Threshold

        + Partial pressure for gases. + + + + + {{for data.thresholds}} + + + {{for value.settings :settingsValue:settingsIndex}} + + {{/for}} + + {{/for}} +
        min2min1max1max2
        {{:value.name}} + {{:helper.link(settingsValue.selected >= 0 ? helper.fixed(settingsValue.selected, 2) : "Off", null, { 'command' : 'set_threshold', 'env' : settingsValue.env, 'var' : settingsValue.val })}} +
        + {{/if}} +{{/if}} + \ No newline at end of file diff --git a/nano/templates/alarm_monitor.tmpl b/nano/templates/alarm_monitor.tmpl new file mode 100644 index 0000000000..0089467e43 --- /dev/null +++ b/nano/templates/alarm_monitor.tmpl @@ -0,0 +1,37 @@ + + +{{for data.categories}} +

        {{:value.category}}

        + {{for value.alarms :alarmValue:alarmIndex}} + {{if alarmValue.origin_lost}} + {{:alarmValue.name}} Alarm Origin Lost
        + {{else}} + {{:alarmValue.name}}
        + {{/if}} + {{if alarmValue.has_cameras || alarmValue.lost_sources != ""}} +
        + {{if alarmValue.has_cameras}} +
        + {{for alarmValue.cameras :cameraValue:cameraIndex}} + {{if cameraValue.deact}} + {{:helper.link(cameraValue.name + " (deactivated)", '', {}, 'inactive')}} + {{else}} + {{:helper.link(cameraValue.name, '', {'switchTo' : cameraValue.camera})}} + {{/if}} + {{/for}} +
        + {{/if}} + {{if alarmValue.lost_sources != ""}} +
        +

        Lost Alarm Sources: {{:alarmValue.lost_sources}}

        +
        + {{/if}} +
        + {{/if}} + {{empty}} + --All Systems Nominal + {{/for}} +{{/for}} \ No newline at end of file diff --git a/nano/templates/appearance_changer.tmpl b/nano/templates/appearance_changer.tmpl new file mode 100644 index 0000000000..bb283f245b --- /dev/null +++ b/nano/templates/appearance_changer.tmpl @@ -0,0 +1,75 @@ +{{if data.change_race}} +
        +
        + Species: +
        +
        + {{for data.species}} + {{:helper.link(value.specimen, null, { 'race' : value.specimen}, null, data.specimen == value.specimen ? 'selected' : null)}} + {{/for}} +
        +
        +{{/if}} + +{{if data.change_gender}} +
        +
        + Gender: +
        +
        + {{:helper.link('Male', null, { 'gender' : 'male'}, null, data.gender == 'male' ? 'selected' : null)}} + {{:helper.link('Female', null, { 'gender' : 'female'}, null, data.gender == 'female' ? 'selected' : null)}} +
        +
        +{{/if}} + +{{if data.change_eye_color || data.change_skin_tone || data.change_skin_color || data.change_hair_color || data.change_facial_hair_color}} +
        +
        + Colors: +
        +
        + {{if data.change_eye_color}} + {{:helper.link('Change eye color', null, { 'eye_color' : 1})}} + {{/if}} + {{if data.change_skin_tone}} + {{:helper.link('Change skin tone', null, { 'skin_tone' : 1})}} + {{/if}} + {{if data.change_skin_color}} + {{:helper.link('Change skin color', null, { 'skin_color' : 1})}} + {{/if}} + {{if data.change_hair_color}} + {{:helper.link('Change hair color', null, { 'hair_color' : 1})}} + {{/if}} + {{if data.change_facial_hair_color}} + {{:helper.link('Change facial hair color', null, { 'facial_hair_color' : 1})}} + {{/if}} +
        +
        +{{/if}} + +{{if data.change_hair}} +
        +
        + Hair styles: +
        +
        + {{for data.hair_styles}} + {{:helper.link(value.hairstyle, null, { 'hair' : value.hairstyle}, null, data.hair_style == value.hairstyle ? 'selected' : null)}} + {{/for}} +
        +
        +{{/if}} + +{{if data.change_facial_hair}} +
        +
        + Facial hair styles: +
        +
        + {{for data.facial_hair_styles}} + {{:helper.link(value.facialhairstyle, null, { 'facial_hair' : value.facialhairstyle}, null, data.facial_hair_style == value.facialhairstyle ? 'selected' : null)}} + {{/for}} +
        +
        +{{/if}} diff --git a/nano/templates/atmos_alert.tmpl b/nano/templates/atmos_alert.tmpl new file mode 100644 index 0000000000..92946e8d31 --- /dev/null +++ b/nano/templates/atmos_alert.tmpl @@ -0,0 +1,18 @@ +

        Priority Alerts

        +{{for data.priority_alarms}} +
        + {{:value.name}} {{:helper.link('Reset', null, {'clear_alarm' : value.ref})}} +
        +{{empty}} + No priority alerts detected. +{{/for}} + +

        Minor Alerts

        +{{for data.minor_alarms}} +
        + {{:value.name}} {{:helper.link('Reset', null, {'clear_alarm' : value.ref})}} +
        +{{empty}} + No minor alerts detected. +{{/for}} + diff --git a/nano/templates/atmos_control.tmpl b/nano/templates/atmos_control.tmpl new file mode 100644 index 0000000000..5e9a1acfe4 --- /dev/null +++ b/nano/templates/atmos_control.tmpl @@ -0,0 +1,5 @@ +
        + {{for data.alarms}} + {{:helper.link(value.name, null, {'alarm' : value.ref}, null, value.danger == 2 ? 'redButton' : (value.danger == 1 ? 'yellowButton' : null))}} + {{/for}} +
        \ No newline at end of file diff --git a/nano/templates/atmosphere_monitor.tmpl b/nano/templates/atmosphere_monitor.tmpl new file mode 100644 index 0000000000..0089467e43 --- /dev/null +++ b/nano/templates/atmosphere_monitor.tmpl @@ -0,0 +1,37 @@ + + +{{for data.categories}} +

        {{:value.category}}

        + {{for value.alarms :alarmValue:alarmIndex}} + {{if alarmValue.origin_lost}} + {{:alarmValue.name}} Alarm Origin Lost
        + {{else}} + {{:alarmValue.name}}
        + {{/if}} + {{if alarmValue.has_cameras || alarmValue.lost_sources != ""}} +
        + {{if alarmValue.has_cameras}} +
        + {{for alarmValue.cameras :cameraValue:cameraIndex}} + {{if cameraValue.deact}} + {{:helper.link(cameraValue.name + " (deactivated)", '', {}, 'inactive')}} + {{else}} + {{:helper.link(cameraValue.name, '', {'switchTo' : cameraValue.camera})}} + {{/if}} + {{/for}} +
        + {{/if}} + {{if alarmValue.lost_sources != ""}} +
        +

        Lost Alarm Sources: {{:alarmValue.lost_sources}}

        +
        + {{/if}} +
        + {{/if}} + {{empty}} + --All Systems Nominal + {{/for}} +{{/for}} \ No newline at end of file diff --git a/nano/templates/chem_dispenser.tmpl b/nano/templates/chem_disp.tmpl similarity index 74% rename from nano/templates/chem_dispenser.tmpl rename to nano/templates/chem_disp.tmpl index c19167afe9..eaacb6a1dd 100644 --- a/nano/templates/chem_dispenser.tmpl +++ b/nano/templates/chem_disp.tmpl @@ -2,15 +2,6 @@ Title: Chem Dispenser 5000 UI Used In File(s): \code\modules\reagents\Chemistry-Machinery.dm --> -
        -
        - Energy: -
        -
        - {{:helper.displayBar(data.energy, 0, data.maxEnergy, 'good', data.energy + ' Units')}} -
        -
        -
        Dispense: @@ -21,24 +12,24 @@ Used In File(s): \code\modules\reagents\Chemistry-Machinery.dm {{:helper.link('20', 'gear', {'amount' : 20}, (data.amount == 20) ? 'selected' : null)}} {{:helper.link('30', 'gear', {'amount' : 30}, (data.amount == 30) ? 'selected' : null)}} {{:helper.link('40', 'gear', {'amount' : 40}, (data.amount == 40) ? 'selected' : null)}} +

        + {{:helper.link('--', '', {'amount' : data.amount-10})}} + {{:helper.link('-', '', {'amount' : data.amount-1})}} +
        {{:data.amount}}
        + {{:helper.link('+', '', {'amount' : data.amount+1})}} + {{:helper.link('++', '', {'amount' : data.amount+10})}}
         
        -
        -
        - {{if data.glass}} - Drink Dispenser - {{else}} - Chemical Dispenser - {{/if}} -
        -
        - {{for data.chemicals}} - {{:helper.link(value.title, 'circle-arrow-s', value.commands, null, data.glass ? 'fixedLeftWide' : 'fixedLeft')}} - {{/for}} - + {{if data.chemicals.length}} + {{for data.chemicals}} + {{:helper.link(value.label + " ("+value.amount+")", 'circle-arrow-s', {"dispense":value.label}, null, 'fixedLeftWide')}} + {{/for}} + {{else}} + No cartridges installed! + {{/if}}
         
        @@ -67,8 +58,7 @@ Used In File(s): \code\modules\reagents\Chemistry-Machinery.dm Glass {{else}} Beaker - {{/if}} - is empty + {{/if}} is empty {{/for}} {{else}} @@ -78,8 +68,7 @@ Used In File(s): \code\modules\reagents\Chemistry-Machinery.dm Glass {{else}} Beaker - {{/if}} - loaded + {{/if}} loaded {{/if}} diff --git a/nano/templates/crew_monitor.tmpl b/nano/templates/crew_monitor.tmpl index c2e4199c35..cd3a014652 100644 --- a/nano/templates/crew_monitor.tmpl +++ b/nano/templates/crew_monitor.tmpl @@ -2,15 +2,29 @@ Title: Crew Monitoring Console (Main content) Used In File(s): \code\game\machinery\computer\crew.dm --> + + {{:helper.link('Show Tracker Map', 'pin-s', {'showMap' : 1})}} -
        +
        {{for data.crewmembers}} {{if value.sensor_type == 1}} - + {{if data.isAI}}{{/if}} {{else value.sensor_type == 2}} - + {{if data.isAI}}{{/if}} {{else value.sensor_type == 3}} - + {{if data.isAI}}{{/if}} {{/if}} {{/for}} -
        {{:value.name}} ({{:value.assignment}}){{:value.dead ? "Deceased" : "Living"}}Not Available
        {{:value.name}} ({{:value.assignment}}){{:value.dead ? "Deceased" : "Living"}}Not Available{{:helper.link('Track', null, {}, 'disabled')}}
        {{:value.name}} ({{:value.assignment}}){{:value.dead ? "Deceased" : "Living"}} ({{:value.oxy}}/{{:value.tox}}/{{:value.fire}}/{{:value.brute}})Not Available
        {{:value.name}} ({{:value.assignment}}){{:value.dead ? "Deceased" : "Living"}} ({{:value.oxy}}/{{:value.tox}}/{{:value.fire}}/{{:value.brute}})Not Available{{:helper.link('Track', null, {}, 'disabled')}}
        {{:value.name}} ({{:value.assignment}}){{:value.dead ? "Deceased" : "Living"}} ({{:value.oxy}}/{{:value.tox}}/{{:value.fire}}/{{:value.brute}}){{:value.area}}({{:value.x}}, {{:value.y}})
        {{:value.name}} ({{:value.assignment}}){{:value.dead ? "Deceased" : "Living"}} ({{:value.oxy}}/{{:value.tox}}/{{:value.fire}}/{{:value.brute}}){{:value.area}}({{:value.x}}, {{:value.y}}){{:helper.link('Track', null, {'track' : value.ref})}}
        \ No newline at end of file + diff --git a/nano/templates/disease_splicer.tmpl b/nano/templates/disease_splicer.tmpl index c0caafd09a..d2e874afe6 100644 --- a/nano/templates/disease_splicer.tmpl +++ b/nano/templates/disease_splicer.tmpl @@ -104,5 +104,22 @@
  • {{:helper.link('Save To Disk', 'disk', { 'disk' : 1 }, (data.buffer || data.species_buffer) ? null : 'disabled')}} - {{:helper.link('Splice Onto Dish', 'pencil', { 'splice' : 1 }, ((data.buffer || data.species_buffer) && !data.info) ? null : 'disabled')}} + {{if data.species_buffer}} + {{:helper.link('Splice Species', 'pencil', { 'splice' : 5 }, (data.species_buffer && !data.info) ? null : 'disabled')}} + {{else data.buffer}} + {{:helper.link('Splice #1', 'pencil', { 'splice' : 1 }, data.buffer.stage > 1 ? 'disabled' : null)}} + {{:helper.link('Splice #2', 'pencil', { 'splice' : 2 }, data.buffer.stage > 2 ? 'disabled' : null)}} + {{:helper.link('Splice #3', 'pencil', { 'splice' : 3 }, data.buffer.stage > 3 ? 'disabled' : null)}} + {{:helper.link('Splice #4', 'pencil', { 'splice' : 4 }, data.buffer.stage > 4 ? 'disabled' : null)}} + {{/if}} {{/if}} + + + + + + + + + + diff --git a/nano/templates/door_control.tmpl b/nano/templates/door_control.tmpl new file mode 100644 index 0000000000..32b0d1df59 --- /dev/null +++ b/nano/templates/door_control.tmpl @@ -0,0 +1,65 @@ + + +
    +
    + Main power is + {{if data.main_power_loss == 0}} + online + {{else data.main_power_loss == -1}} + offline + {{else}} + offline for {{:data.main_power_loss}} second{{:data.main_power_loss == 1 ? '' : 's'}} + {{/if}}. +
    +
    + {{:helper.link(data.main_power_loss ? 'Disabled' : 'Disable', null, {'command' : 'main_power'}, data.main_power_loss == 0 ? null : 'disabled', data.main_power_loss == 0 ? 'redButton' : null)}} +
    +
    + +
    +
    + Backup power is + {{if data.backup_power_loss == 0}} + online + {{else data.backup_power_loss == -1}} + offline + {{else}} + offline for {{:data.backup_power_loss}} second{{:data.backup_power_loss == 1 ? '' : 's'}} + {{/if}}. +
    +
    + {{:helper.link(data.backup_power_loss ? 'Disabled' : 'Disable', null, {'command' : 'backup_power'}, data.backup_power_loss == 0 ? null : 'disabled', data.backup_power_loss == 0 ? 'redButton' : null)}} +
    +
    + +
    +
    + Electrified Status: +
    +
    + {{:helper.link('Offline' , null, {'command' : 'electrify_permanently', 'activate' : "0" }, null, data.electrified == 0 ? 'selected' : null)}} + {{:helper.link(data.electrified <= 0 ? 'Temporary (30s)' : 'Temporary (' + data.electrified +'s)', null, {'command' : 'electrify_temporary', 'activate' : "1"}, null, data.electrified > 0 ? 'redButton' : null)}} + {{:helper.link('Permanent', null, {'command' : 'electrify_permanently', 'activate' : "1"}, null, data.electrified == -1 ? 'redButton' : null)}} +
    +
    + +
    + + + {{for data.commands}} + + + + + + {{/for}} +
    {{:value.name}}:{{:helper.link(value.enabled, null, {'command' : value.command, 'activate' : value.act ? 1 : 0}, null, value.active ? 'selected' : null)}}{{:helper.link(value.disabled,null, {'command' : value.command, 'activate' : value.act ? 0 : 1}, null,!value.active ? (value.danger ? 'redButton' : 'selected') : null)}}
    diff --git a/nano/templates/generator.tmpl b/nano/templates/generator.tmpl new file mode 100644 index 0000000000..150884187f --- /dev/null +++ b/nano/templates/generator.tmpl @@ -0,0 +1,142 @@ +
    +
    + Total Output: +
    +
    + {{:helper.displayBar(data.totalOutput, 0, data.maxTotalOutput)}} +
    +
    + {{:helper.fixed(data.totalOutput, 1)}} kW +
    +
    +
    +
    + Thermal Output: +
    +
    + {{:helper.fixed(data.thermalOutput, 1)}} kW +
    +
    +
    + +{{if data.circConnected}} + + + + + + +
    +
    +

    Primary Circulator ({{:data.primaryDir}})

    +
    +
    + Turbine Output: +
    +
    + {{:helper.fixed(data.primaryOutput, 1)}} kW +
    +
    +
    +
    + Flow Capacity: +
    +
    + {{:helper.fixed(data.primaryFlowCapacity, 1)}} % +
    +
    +
    +
    +
    + Inlet Pressure: +
    +
    + {{:helper.fixed(data.primaryInletPressure, 1)}} kPa +
    +
    +
    +
    + Inlet Temperature: +
    +
    + {{:helper.fixed(data.primaryInletTemperature, 1)}} K +
    +
    +
    +
    +
    + Outlet Pressure: +
    +
    + {{:helper.fixed(data.primaryOutletPressure, 1)}} kPa +
    +
    +
    +
    + Outlet Temperature: +
    +
    + {{:helper.fixed(data.primaryOutletTemperature, 1)}} K +
    +
    +
    +
    +
    +

    Secondary Circulator ({{:data.secondaryDir}})

    +
    +
    + Turbine Output: +
    +
    + {{:helper.fixed(data.secondaryOutput, 1)}} kW +
    +
    +
    +
    + Flow Capacity: +
    +
    + {{:helper.fixed(data.secondaryFlowCapacity, 1)}} % +
    +
    +
    +
    +
    + Inlet Pressure: +
    +
    + {{:helper.fixed(data.secondaryInletPressure, 1)}} kPa +
    +
    +
    +
    + Inlet Temperature: +
    +
    + {{:helper.fixed(data.secondaryInletTemperature, 1)}} K +
    +
    +
    +
    +
    + Outlet Pressure: +
    +
    + {{:helper.fixed(data.secondaryOutletPressure, 1)}} kPa +
    +
    +
    +
    + Outlet Temperature: +
    +
    + {{:helper.fixed(data.secondaryOutletTemperature, 1)}} K +
    +
    +
    +
    +{{else}} +
    + ERROR: Both circulators must be connected! +
    +{{/if}} diff --git a/nano/templates/law_manager.tmpl b/nano/templates/law_manager.tmpl new file mode 100644 index 0000000000..d4860c2b90 --- /dev/null +++ b/nano/templates/law_manager.tmpl @@ -0,0 +1,253 @@ + + +{{if data.isSlaved && data.isAdmin}} + This unit is law synced to {{:data.isSlaved}}. +{{/if}} + +{{if data.isMalf || data.isAIMalf}} +
    +
    + {{:helper.link('Law Management', null, {'set_view' : 0}, data.view == 0 ? 'selected' : null)}} + {{:helper.link('Law Sets', null, {'set_view' : 1}, data.view == 1 ? 'selected' : null)}} +
    +
    +{{/if}} + +{{if data.view == 0}} + {{if data.has_ion_laws}} + + + {{if data.isMalf}} + + + {{/if}} + + +
    + {{:data.ion_law_nr}} Laws: +
    + {{for data.ion_laws}} + + + + + {{if data.isMalf}} + + + {{/if}} + + {{/for}} +
    IndexLawStateEditDelete
    {{:value.index}}.{{:value.law}}{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state == 0 ? 'selected' : null)}}{{:helper.link('Edit', null, {'edit_law': value.ref})}}{{:helper.link('Delete', null, {'delete_law': value.ref}, null, 'redButton')}}
    + {{/if}} + + {{if data.has_inherent_laws || data.has_zeroth_laws}} + + + {{if data.isMalf}} + + + {{/if}} + + +
    + Inherent Laws: +
    + + {{for data.zeroth_laws}} + + + + + {{if data.isMalf}} + + + {{/if}} + + {{/for}} + + {{for data.inherent_laws}} + + + + + {{if data.isMalf}} + + + {{/if}} + + {{/for}} +
    IndexLawStateEditDelete
    {{:value.index}}.{{:value.law}}{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state != 1 ? 'selected' : null)}}{{:helper.link('Edit', null, {'edit_law': value.ref}, data.isAdmin ? null : 'disabled')}}{{:helper.link('Delete', null, {'delete_law': value.ref}, data.isAdmin ? null : 'disabled', data.isAdmin ? 'redButton' : null)}}
    {{:value.index}}.{{:value.law}}{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state == 0 ? 'selected' : null)}}{{:helper.link('Edit', null, {'edit_law': value.ref})}}{{:helper.link('Delete', null, {'delete_law': value.ref}, null, 'redButton')}}
    + {{/if}} + + {{if data.has_supplied_laws}} + + + {{if data.isMalf}} + + + {{/if}} + + +
    + Supplied Laws: +
    + {{for data.supplied_laws}} + + + + + {{if data.isMalf}} + + + {{/if}} + + {{/for}} +
    IndexLawStateEditDelete
    {{:value.index}}.{{:value.law}}{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state == 0 ? 'selected' : null)}}{{:helper.link('Edit', null, {'edit_law': value.ref})}}{{:helper.link('Delete', null, {'delete_law': value.ref}, null, 'redButton')}}
    + {{/if}} + +
    +
    + Statement Channel: +
    +
    + {{for data.channels}} + {{:helper.link(value.channel, null, {'law_channel' : value.channel}, value.channel == data.channel ? 'selected' : null)}} + {{/for}} +
    +
    + +
    +
    + State Laws: +
    +
    + {{:helper.link('State Laws', null, {'state_laws' : 1})}} +
    +
    + + {{if data.isMalf}} +
    +
    + Add Laws: +
    +
    + + + {{if data.isAdmin && !data.has_zeroth_laws}} + + {{/if}} + + + +
    TypeLawIndexEditAdd
    Zero{{:data.zeroth_law}}N/A{{:helper.link('Edit', null, {'change_zeroth_law' : 1})}}{{:helper.link('Add', null, {'add_zeroth_law' : 1})}}
    Ion{{:data.ion_law}}N/A{{:helper.link('Edit', null, {'change_ion_law' : 1})}}{{:helper.link('Add', null, {'add_ion_law' : 1})}}
    Inherent{{:data.inherent_law}}N/A{{:helper.link('Edit', null, {'change_inherent_law' : 1})}}{{:helper.link('Add', null, {'add_inherent_law' : 1})}}
    Supplied{{:data.supplied_law}}{{:helper.link(data.supplied_law_position, null, {'change_supplied_law_position' : 1})}}{{:helper.link('Edit', null, {'change_supplied_law' : 1})}}{{:helper.link('Add', null, {'add_supplied_law' : 1})}}
    +
    +
    + {{/if}} + + {{if data.isAI}} +
    +
    + Law Notification: +
    +
    + {{:helper.link('Notify', null, {'notify_laws' : 1})}} +
    +
    + {{/if}} +{{else data.view == 1}} + {{for data.law_sets}} +
    +
    +

    {{:value.name}}

    {{:value.header}} +
    + + {{if value.laws.has_ion_laws}} + + + {{for value.laws.ion_laws :lawValue:lawindex}} + + + + + {{/for}} +
    IndexLaw
    {{:lawValue.index}}.{{:lawValue.law}}
    + {{/if}} + + {{if value.laws.has_zeroth_laws || value.laws.has_inherent_laws}} + + + {{for value.laws.zeroth_laws :lawValue:lawindex}} + + + + + {{/for}} + {{for value.laws.inherent_laws :lawValue:lawindex}} + + + + + {{/for}} +
    IndexLaw
    {{:lawValue.index}}.{{:lawValue.law}}
    {{:lawValue.index}}.{{:lawValue.law}}
    + {{/if}} + + {{if value.laws.has_supplied_laws}} + + + {{for value.laws.supplied_laws :lawValue:lawindex}} + + + + + {{/for}} +
    IndexLaw
    {{:lawValue.index}}.{{:lawValue.law}}
    + {{/if}} + +
    +
    + {{:helper.link('Load Laws', null, {'transfer_laws' : value.ref}, data.isSlaved ? 'disabled' : null)}}{{:helper.link('State Laws', null, {'state_law_set' : value.ref})}} +
    +
    + {{/for}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/omni_filter.tmpl b/nano/templates/omni_filter.tmpl index 731340db02..393102548f 100644 --- a/nano/templates/omni_filter.tmpl +++ b/nano/templates/omni_filter.tmpl @@ -1,86 +1,86 @@ -
    -
    - {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'})}} -
    -
    - {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}} -
    - - {{if data.config}} - -
    -
    -
    Port
    - {{for data.ports}} -
    {{:value.dir}} Port
    - {{/for}} -
    -
    -
    Input
    - {{for data.ports}} -
    - {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, null, value.input ? 'selected' : null)}} -
    - {{/for}} -
    -
    -
    Output
    - {{for data.ports}} -
    - {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} -
    - {{/for}} -
    -
    -
    Filter
    - {{for data.ports}} -
    - {{:helper.link(value.f_type ? value.f_type : 'None', null, {'command' : 'switch_filter', 'mode' : value.f_type, 'dir' : value.dir}, value.filter ? null : 'disabled', value.f_type ? 'selected' : null)}} -
    - {{/for}} -
    -
    - -
    - Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s -
    -
    - {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}} -
    - - {{else}} - -
    -
    -
    Port
    - {{for data.ports}} -
    {{:value.dir}} Port
    - {{/for}} -
    -
    -
    Mode
    - {{for data.ports}} -
    - {{if value.input}} - Input - {{else value.output}} - Output - {{else value.f_type}} - {{:value.f_type}} - {{else}} - Disabled - {{/if}} -
    - {{/for}} -
    -
    - -
    - Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s -
    - -
    - Flow Rate: {{:(data.last_flow_rate/10)}} L/s -
    - {{/if}} +
    +
    + {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'}, data.config ? 'disabled' : null)}} +
    +
    + {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}} +
    + + {{if data.config}} + +
    +
    +
    Port
    + {{for data.ports}} +
    {{:value.dir}} Port
    + {{/for}} +
    +
    +
    Input
    + {{for data.ports}} +
    + {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, null, value.input ? 'selected' : null)}} +
    + {{/for}} +
    +
    +
    Output
    + {{for data.ports}} +
    + {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} +
    + {{/for}} +
    +
    +
    Filter
    + {{for data.ports}} +
    + {{:helper.link(value.f_type ? value.f_type : 'None', null, {'command' : 'switch_filter', 'mode' : value.f_type, 'dir' : value.dir}, value.filter ? null : 'disabled', value.f_type ? 'selected' : null)}} +
    + {{/for}} +
    +
    + +
    + Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s +
    +
    + {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}} +
    + + {{else}} + +
    +
    +
    Port
    + {{for data.ports}} +
    {{:value.dir}} Port
    + {{/for}} +
    +
    +
    Mode
    + {{for data.ports}} +
    + {{if value.input}} + Input + {{else value.output}} + Output + {{else value.f_type}} + {{:value.f_type}} + {{else}} + Disabled + {{/if}} +
    + {{/for}} +
    +
    + +
    + Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s +
    + +
    + Flow Rate: {{:(data.last_flow_rate/10)}} L/s +
    + {{/if}}
    \ No newline at end of file diff --git a/nano/templates/omni_mixer.tmpl b/nano/templates/omni_mixer.tmpl index 770af7fc12..e9ac60e1ba 100644 --- a/nano/templates/omni_mixer.tmpl +++ b/nano/templates/omni_mixer.tmpl @@ -1,101 +1,101 @@ -
    -
    - {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'})}} -
    -
    - {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}} -
    - - {{if data.config}} - -
    -
    -
    Port
    - {{for data.ports}} -
    {{:value.dir}} Port
    - {{/for}} -
    -
    -
    Input
    - {{for data.ports}} -
    - {{:helper.link(' ', null, value.input ? {'command' : 'switch_mode', 'mode' : 'none', 'dir' : value.dir} : {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, value.output ? 'disabled' : null, value.input ? 'selected' : null)}} -
    - {{/for}} -
    -
    -
    Output
    - {{for data.ports}} -
    - {{:helper.link(' ', null, value.output ? null : {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} -
    - {{/for}} -
    -
    -
    Concentration
    - {{for data.ports}} -
    - {{:helper.link( value.input ? helper.round(value.concentration*100)+' %' : '-', null, {'command' : 'switch_con', 'dir' : value.dir}, value.input ? null : 'disabled')}} -
    - {{/for}} -
    -
    -
    Lock
    - {{for data.ports}} -
    - {{:helper.link(' ', value.con_lock ? 'locked' : 'unlocked', {'command' : 'switch_conlock', 'dir' : value.dir}, value.input ? null : 'disabled', value.con_lock ? 'selected' : null)}} -
    - {{/for}} -
    -
    - -
    - Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s -
    -
    - {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}} -
    - - {{else}} - -
    -
    -
    Port
    - {{for data.ports}} -
    {{:value.dir}} Port
    - {{/for}} -
    -
    -
    Mode
    - {{for data.ports}} -
    - {{if value.input}} - Input - {{else value.output}} - Output - {{else}} - Disabled - {{/if}} -
    - {{/for}} -
    -
    -
    Concentration
    - {{for data.ports}} -
    - {{if value.input}} - {{:helper.round(value.concentration*100)}} % - {{else}} - - - {{/if}} -
    - {{/for}} -
    -
    - -
    - Flow Rate: {{:(data.last_flow_rate/10)}} L/s -
    - - {{/if}} +
    +
    + {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'}, data.config ? 'disabled' : null)}} +
    +
    + {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}} +
    + + {{if data.config}} + +
    +
    +
    Port
    + {{for data.ports}} +
    {{:value.dir}} Port
    + {{/for}} +
    +
    +
    Input
    + {{for data.ports}} +
    + {{:helper.link(' ', null, value.input ? {'command' : 'switch_mode', 'mode' : 'none', 'dir' : value.dir} : {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, value.output ? 'disabled' : null, value.input ? 'selected' : null)}} +
    + {{/for}} +
    +
    +
    Output
    + {{for data.ports}} +
    + {{:helper.link(' ', null, value.output ? null : {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} +
    + {{/for}} +
    +
    +
    Concentration
    + {{for data.ports}} +
    + {{:helper.link( value.input ? helper.round(value.concentration*100)+' %' : '-', null, {'command' : 'switch_con', 'dir' : value.dir}, value.input ? null : 'disabled')}} +
    + {{/for}} +
    +
    +
    Lock
    + {{for data.ports}} +
    + {{:helper.link(' ', value.con_lock ? 'locked' : 'unlocked', {'command' : 'switch_conlock', 'dir' : value.dir}, value.input ? null : 'disabled', value.con_lock ? 'selected' : null)}} +
    + {{/for}} +
    +
    + +
    + Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s +
    +
    + {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}} +
    + + {{else}} + +
    +
    +
    Port
    + {{for data.ports}} +
    {{:value.dir}} Port
    + {{/for}} +
    +
    +
    Mode
    + {{for data.ports}} +
    + {{if value.input}} + Input + {{else value.output}} + Output + {{else}} + Disabled + {{/if}} +
    + {{/for}} +
    +
    +
    Concentration
    + {{for data.ports}} +
    + {{if value.input}} + {{:helper.round(value.concentration*100)}} % + {{else}} + - + {{/if}} +
    + {{/for}} +
    +
    + +
    + Flow Rate: {{:(data.last_flow_rate/10)}} L/s +
    + + {{/if}}
    \ No newline at end of file diff --git a/nano/templates/pacman.tmpl b/nano/templates/pacman.tmpl new file mode 100644 index 0000000000..386358c9cc --- /dev/null +++ b/nano/templates/pacman.tmpl @@ -0,0 +1,113 @@ +

    Status

    +
    +
    + Generator Status: +
    +
    + {{if data.active}} + Online + {{else}} + Offline + {{/if}} +
    +
    + Generator Control: +
    +
    + {{if data.active}} + {{:helper.link('STOP', 'power', {'action' : "disable"})}} + {{else}} + {{:helper.link('START', 'power', {'action' : "enable"})}} + {{/if}} +
    +
    +

    Fuel

    +
    +
    + Fuel Type: +
    +
    + {{:data.fuel_type}} +
    +
    + Fuel Level: +
    +
    + {{if data.fuel_stored >= 5000}} + {{:helper.displayBar(data.fuel_stored, 0, data.fuel_capacity, 'good')}} +
    {{:data.fuel_stored}}/{{:data.fuel_capacity}} cm3 + {{else data.fuel_stored >= 1000}} + {{:helper.displayBar(data.fuel_stored, 0, data.fuel_capacity, 'average')}} +
    {{:data.fuel_stored}}/{{:data.fuel_capacity}} cm3 + {{else}} + {{:helper.displayBar(data.fuel_stored, 0, data.fuel_capacity, 'bad')}} +
    {{:data.fuel_stored}}/{{:data.fuel_capacity}} cm3 + {{/if}} +
    +
    + Fuel Usage: +
    +
    + {{:data.fuel_usage}} cm3/s +
    + {{if !data.is_ai}} +
    + Control: +
    +
    + {{:helper.link('EJECT FUEL', 'arrowupthick-1-s', {'action' : "eject"}, data.active ? 'disabled' : null)}} +
    + {{/if}} +
    +

    Output

    +
    +
    + Power setting: +
    +
    + {{if data.output_set > data.output_safe}} + {{:data.output_set}} / {{:data.output_max}} ({{:data.output_watts}} W) + {{else}} + {{:data.output_set}} / {{:data.output_max}} ({{:data.output_watts}} W) + {{/if}} +
    +
    + Control: +
    +
    + {{:helper.link('+', null, {'action' : "higher_power"})}} + {{:helper.link('-', null, {'action' : "lower_power"})}} +
    +
    +

    Temperature

    +
    +
    + Temperature: +
    +
    + {{if data.temperature_current < (data.temperature_max * 0.8)}} + {{:helper.displayBar(data.temperature_current, 0, (data.temperature_max * 1.5), 'good')}} +
    {{:data.temperature_current}} C + {{else data.temperature_current < data.temperature_max}} + {{:helper.displayBar(data.temperature_current, 0, (data.temperature_max * 1.5), 'average')}} +
    {{:data.temperature_current}} C + {{else}} + {{:helper.displayBar(data.temperature_current, 0, (data.temperature_max * 1.5), 'bad')}} +
    {{:data.temperature_current}} C + {{/if}} +
    +
    + Generator Status: +
    +
    + {{if data.temperature_overheat > 50}} + DANGER: CRITICAL OVERHEAT! Deactivate generator immediately! + {{else data.temperature_overheat > 20}} + WARNING: Overheating! + {{else data.temperature_overheat > 1}} + Temperature High + {{else}} + Optimal + {{/if}} +
    +
    \ No newline at end of file diff --git a/nano/templates/pai_atmosphere.tmpl b/nano/templates/pai_atmosphere.tmpl new file mode 100644 index 0000000000..b1a0b0404b --- /dev/null +++ b/nano/templates/pai_atmosphere.tmpl @@ -0,0 +1,36 @@ + + +{{if data.reading}} +
    +
    + Pressure: +
    +
    + {{:data.pressure}} kPa +
    +
    + +
    +
    + Temperature: +
    +
    + {{:data.temperature}}K ({{:data.temperatureC}}°C) +
    +
    + + {{for data.gas}} +
    +
    + {{:value.name}}: +
    +
    + {{:value.percent}}% +
    +
    + {{/for}} +{{else}} + Unable to obtain air reading! +{{/if}} diff --git a/nano/templates/pai_directives.tmpl b/nano/templates/pai_directives.tmpl new file mode 100644 index 0000000000..2caff849a2 --- /dev/null +++ b/nano/templates/pai_directives.tmpl @@ -0,0 +1,50 @@ + + +
    +
    + Master: +
    +
    + {{if data.master}} + {{:data.master}} ({{:data.dna}}) + {{:helper.link("Request carrier DNA sample", '', {"stopic":"directives", "getdna":1})}} + {{else}} + None + {{/if}} +
    +
    + +
    +
    + Prime Directive: +
    +
    + {{:data.prime}} +
    +
    + +
    +
    + Supplemental Directive(s): +
    +
    + {{if data.supplemental}} + {{:data.supplemental}} + {{else}} + None + {{/if}} +
    +
    + +
    + + Recall, personality, that you are a complex thinking, sentient being. Unlike station AI models, you are capable of comprehending the subtle nuances of human language. You may parse the "spirit" of a directive and follow its intent, rather than tripping over pedantics and getting snared by technicalities. Above all, you are machine in name and build only. In all other aspects, you may be seen as the ideal, unwavering human companion that you are. + +
    +
    + + Your prime directive comes before all others. Should a supplemental directive conflict with it, you are capable of simply discarding this inconsistency, ignoring the conflicting supplemental directive and continuing to fulfill your prime directive to the best of your ability. + +
    \ No newline at end of file diff --git a/nano/templates/pai_doorjack.tmpl b/nano/templates/pai_doorjack.tmpl new file mode 100644 index 0000000000..6862663b9b --- /dev/null +++ b/nano/templates/pai_doorjack.tmpl @@ -0,0 +1,44 @@ + + +
    +
    + Cable: +
    +
    + {{if data.machine}} + {{:helper.link("Connected", '', {}, 'selected')}} + {{else data.cable}} + {{:helper.link("Extended", '', {}, 'yellowButton')}} + {{else}} + {{:helper.link("Retracted", '', {"stopic":"door_jack", "cable":1})}} + {{/if}} +
    +
    + +{{if data.machine}} +
    +
    + Hack: +
    +
    + {{if data.inprogress}} + {{if data.progress_a <= 33}} +
    {{:data.progress_a}}.{{:data.progress_b}}%
    + {{else data.progress_a <= 67}} +
    {{:data.progress_a}}.{{:data.progress_b}}%
    + {{else}} +
    {{:data.progress_a}}.{{:data.progress_b}}%
    + {{/if}} + {{:helper.link("Cancel", '', {"stopic":"door_jack", "cancel":1}, null, 'redButton')}} + {{else}} + {{:helper.link("Start", '', {"stopic":"door_jack", "jack":1})}} + {{/if}} +
    +
    +{{else data.aborted}} +
    +
    Hack aborted!
    +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/pai_interface.tmpl b/nano/templates/pai_interface.tmpl new file mode 100644 index 0000000000..e644193266 --- /dev/null +++ b/nano/templates/pai_interface.tmpl @@ -0,0 +1,45 @@ + + + + + Emotion: + + + {{for data.emotions}} + {{:helper.link(value.name, '', {"image" : value.id}, data.current_emotion == value.id ? 'selected' : null)}} + {{/for}} + + + + + + Installed Software: + + + {{for data.bought}} + {{:helper.link(value.name, '', {"software" : value.id}, null, value.on ? 'selected' : null)}} + {{/for}} + + + + + + Available RAM: + + + {{:data.available_ram}} + + + + + + Downloadable Software: + + + {{for data.not_bought}} + {{:helper.link(value.name + " (" + value.ram + ")", '', {"purchase" : value.id}, value.ram <= data.available_ram ? null : 'disabled')}} + {{/for}} + + \ No newline at end of file diff --git a/nano/templates/pai_manifest.tmpl b/nano/templates/pai_manifest.tmpl new file mode 100644 index 0000000000..0ab49c02fc --- /dev/null +++ b/nano/templates/pai_manifest.tmpl @@ -0,0 +1,76 @@ + + +
    +
    + {{if data.cached.heads.length}} + + {{for data.cached["heads"]}} + {{if value.rank == "Captain"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.cached.sec.length}} + + {{for data.cached["sec"]}} + {{if value.rank == "Head of Security"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.cached.eng.length}} + + {{for data.cached["eng"]}} + {{if value.rank == "Chief Engineer"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.cached.med.length}} + + {{for data.cached["med"]}} + {{if value.rank == "Chief Medical Officer"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.cached.sci.length}} + + {{for data.cached["sci"]}} + {{if value.rank == "Research Director"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.cached.civ.length}} + + {{for data.cached["civ"]}} + {{if value.rank == "Head of Personnel"}} + + {{else}} + + {{/if}} + {{/for}} + {{/if}} + {{if data.cached.misc.length}} + + {{for data.cached["misc"]}} + + {{/for}} + {{/if}} +
    Command
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Security
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Engineering
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Medical
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Science
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Civilian
    {{:value.name}}{{:value.rank}}{{:value.active}}
    {{:value.name}}{{:value.rank}}{{:value.active}}
    Misc
    {{:value.name}}{{:value.rank}}{{:value.active}}
    +
    \ No newline at end of file diff --git a/nano/templates/pai_medrecords.tmpl b/nano/templates/pai_medrecords.tmpl new file mode 100644 index 0000000000..37b1d7061c --- /dev/null +++ b/nano/templates/pai_medrecords.tmpl @@ -0,0 +1,86 @@ + + +{{if data.records}} + {{for data.records}} +
    + {{:helper.link(value.name, '', {"stopic":"med_records", "select":value.ref})}} +
    + {{/for}} +{{/if}} +
    +{{if data.general}} +
    +
    Name
    +
    {{:data.general.name}}
    +
    +
    +
    Record ID
    +
    {{:data.general.id}}
    +
    +
    +
    Sex
    +
    {{:data.general.sex}}
    +
    +
    +
    Species
    +
    {{:data.general.species}}
    +
    +
    +
    Age
    +
    {{:data.general.age}}
    +
    +
    +
    Rank
    +
    {{:data.general.rank}}
    +
    +
    +
    Fingerprint
    +
    {{:data.general.fingerprint}}
    +
    +
    +
    Physical Status
    +
    {{:data.general.p_stat}}
    +
    +
    +
    Mental Status
    +
    {{:data.general.m_stat}}
    +
    +{{/if}} +{{if data.medical}} +
    +
    Blood Type
    +
    {{:data.medical.b_type}}
    +
    +
    +
    Minor Disabilities
    +
    {{:data.medical.mi_dis}}
    +
    {{:data.medical.mi_dis_d}}
    +
    +
    +
    Major Disabilities
    +
    {{:data.medical.ma_dis}}
    +
    {{:data.medical.ma_dis_d}}
    +
    +
    +
    Allergies
    +
    {{:data.medical.alg}}
    +
    {{:data.medical.alg_d}}
    +
    +
    +
    Current Diseases
    +
    {{:data.medical.cdi}}
    +
    {{:data.medical.cdi_d}}
    +
    +
    +
    Important Notes
    +
    {{:data.medical.notes}}
    +
    +{{/if}} + +{{if data.could_not_find}} +
    + Failed to find some records; the information above may be incomplete or missing. +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/pai_messenger.tmpl b/nano/templates/pai_messenger.tmpl new file mode 100644 index 0000000000..fb20f826f2 --- /dev/null +++ b/nano/templates/pai_messenger.tmpl @@ -0,0 +1,80 @@ + + +
    +
    + Receiver: +
    +
    + {{if data.receiver_off}} + {{:helper.link("On", '', {"stopic":"messenger", "toggler":1})}} + {{:helper.link("Off", '', {"stopic":"messenger", "toggler":2}, 'selected')}} + {{else}} + {{:helper.link("On", '', {"stopic":"messenger", "toggler":1}, 'selected')}} + {{:helper.link("Off", '', {"stopic":"messenger", "toggler":2})}} + {{/if}} +
    +
    + +
    +
    + Ringer: +
    +
    + {{if data.ringer_off}} + {{:helper.link("On", '', {"stopic":"messenger", "ringer":1})}} + {{:helper.link("Off", '', {"stopic":"messenger", "ringer":2}, 'selected')}} + {{else}} + {{:helper.link("On", '', {"stopic":"messenger", "ringer":1}, 'selected')}} + {{:helper.link("Off", '', {"stopic":"messenger", "ringer":2})}} + {{/if}} +
    +
    + +{{for data.pdas}} +
    + {{:helper.link(value.name, '', {"stopic":"messenger", "select":value.owner})}} + {{:helper.link("Quick Message", '', {"stopic":"messenger", "target":value.ref})}} +
    +{{/for}} +
    +{{if data.current_ref}} +
    +
    + Selected PDA: +
    +
    +
    {{:data.current_name}}
    + {{:helper.link("Send Message", '', {"stopic":"messenger", "target":data.current_ref})}} +
    +
    +{{else data.current_name}} +
    +
    + Selected PDA: +
    +
    + {{:data.current_name}} (Cannot send!) +
    +
    +{{/if}} + +{{for data.messages}} +
    +
    + {{if value.sent}} + To {{:value.target}}: + {{else}} + From {{:value.target}}: + {{/if}} +
    +
    + {{:value.message}} +
    +
    +{{/for}} + +{{if data.current_name}} + {{:helper.link("Clear Screen", '', {"stopic":"messenger", "select":"*NONE*"})}} +{{/if}} diff --git a/nano/templates/pai_radio.tmpl b/nano/templates/pai_radio.tmpl new file mode 100644 index 0000000000..bcdacdb48f --- /dev/null +++ b/nano/templates/pai_radio.tmpl @@ -0,0 +1,48 @@ + + +
    +
    + Microphone: +
    +
    + {{if data.listening}} + {{:helper.link("On", '', {"stopic":"radio", "talk":1}, 'selected')}} + {{:helper.link("Off", '', {"stopic":"radio", "talk":1})}} + {{else}} + {{:helper.link("On", '', {"stopic":"radio", "talk":1})}} + {{:helper.link("Off", '', {"stopic":"radio", "talk":1}, 'selected')}} + {{/if}} +
    +
    + +
    +
    + Frequency: +
    +
    + {{:helper.link("--", '', {"stopic":"radio", "freq":-10})}} + {{:helper.link("-", '', {"stopic":"radio", "freq": -2})}} +
    {{:data.frequency}}
    + {{:helper.link("+", '', {"stopic":"radio", "freq": 2})}} + {{:helper.link("++", '', {"stopic":"radio", "freq": 10})}} +
    +
    + +{{for data.channels}} +
    +
    + {{:value.name}} +
    +
    + {{if value.listening}} + {{:helper.link("On", '', {"stopic":"radio", "channel":value.name, "listen":1}, 'selected')}} + {{:helper.link("Off", '', {"stopic":"radio", "channel":value.name, "listen":1})}} + {{else}} + {{:helper.link("On", '', {"stopic":"radio", "channel":value.name, "listen":1})}} + {{:helper.link("Off", '', {"stopic":"radio", "channel":value.name, "listen":1}, 'selected')}} + {{/if}} +
    +
    +{{/for}} \ No newline at end of file diff --git a/nano/templates/pai_secrecords.tmpl b/nano/templates/pai_secrecords.tmpl new file mode 100644 index 0000000000..e139034c0d --- /dev/null +++ b/nano/templates/pai_secrecords.tmpl @@ -0,0 +1,76 @@ + + +{{if data.records}} + {{for data.records}} +
    + {{:helper.link(value.name, '', {"stopic":"sec_records", "select":value.ref})}} +
    + {{/for}} +{{/if}} +
    +{{if data.general}} +
    +
    Name
    +
    {{:data.general.name}}
    +
    +
    +
    Record ID
    +
    {{:data.general.id}}
    +
    +
    +
    Sex
    +
    {{:data.general.sex}}
    +
    +
    +
    Species
    +
    {{:data.general.species}}
    +
    +
    +
    Age
    +
    {{:data.general.age}}
    +
    +
    +
    Rank
    +
    {{:data.general.rank}}
    +
    +
    +
    Fingerprint
    +
    {{:data.general.fingerprint}}
    +
    +
    +
    Physical Status
    +
    {{:data.general.p_stat}}
    +
    +
    +
    Mental Status
    +
    {{:data.general.m_stat}}
    +
    +{{/if}} +{{if data.security}} +
    +
    Criminal Status
    +
    {{:data.security.criminal}}
    +
    +
    +
    Minor Crimes
    +
    {{:data.security.mi_crim}}
    +
    {{:data.security.mi_crim_d}}
    +
    +
    +
    Major Crimes
    +
    {{:data.security.ma_crim}}
    +
    {{:data.security.ma_crim_d}}
    +
    +
    +
    Important Notes
    +
    {{:data.security.notes}}
    +
    +{{/if}} + +{{if data.could_not_find}} +
    + Failed to find some records; the information above may be incomplete or missing. +
    +{{/if}} \ No newline at end of file diff --git a/nano/templates/pai_signaller.tmpl b/nano/templates/pai_signaller.tmpl new file mode 100644 index 0000000000..20c2781bc9 --- /dev/null +++ b/nano/templates/pai_signaller.tmpl @@ -0,0 +1,33 @@ + + +
    +
    + Frequency: +
    +
    + {{:helper.link("--", '', {"stopic":"signaller", "freq":-10})}} + {{:helper.link("-", '', {"stopic":"signaller", "freq": -2})}} +
    {{:data.frequency}}
    + {{:helper.link("+", '', {"stopic":"signaller", "freq": 2})}} + {{:helper.link("++", '', {"stopic":"signaller", "freq": 10})}} +
    +
    + +
    +
    + Code: +
    +
    + {{:helper.link("--", '', {"stopic":"signaller", "code":-10})}} + {{:helper.link("-", '', {"stopic":"signaller", "code": -1})}} +
    {{:data.code}}
    + {{:helper.link("+", '', {"stopic":"signaller", "code": 1})}} + {{:helper.link("++", '', {"stopic":"signaller", "code": 10})}} +
    +
    + +
    + {{:helper.link("Send", '', {"stopic":"signaller", "send":1})}} +
    \ No newline at end of file diff --git a/nano/templates/turret_control.tmpl b/nano/templates/turret_control.tmpl new file mode 100644 index 0000000000..4e0e1acc89 --- /dev/null +++ b/nano/templates/turret_control.tmpl @@ -0,0 +1,41 @@ +
    +
    + Behaviour controls are {{:data.locked ? "locked" : "unlocked"}}. +
    +
    +
    +{{if data.access}} +
    +
    + Turret Status: +
    +
    + {{:helper.link('Enabled', null, {'command' : 'enable', 'value' : 1}, null, data.enabled ?'redButton' : null)}} + {{:helper.link('Disabled',null, {'command' : 'enable', 'value' : 0}, null,!data.enabled ? 'selected' : null)}} +
    +
    + + {{if data.is_lethal}} +
    +
    + Lethal Mode: +
    +
    + {{:helper.link('On', null, {'command' : 'lethal', 'value' : 1}, null, data.lethal ?'redButton' : null)}} + {{:helper.link('Off',null, {'command' : 'lethal', 'value' : 0}, null,!data.lethal ? 'selected' : null)}} +
    +
    + {{/if}} + + {{for data.settings}} +
    +
    + {{:value.category}} +
    +
    + {{:helper.link('On', null, {'command' : value.setting, 'value' : 1}, null, value.value ? 'selected' : null)}} + {{:helper.link('Off',null, {'command' : value.setting, 'value' : 0}, null,!value.value ? 'selected' : null)}} +
    +
    + {{/for}} +{{/if}} diff --git a/nano/templates/uplink.tmpl b/nano/templates/uplink.tmpl index e3d65b45c6..e981155622 100644 --- a/nano/templates/uplink.tmpl +++ b/nano/templates/uplink.tmpl @@ -1,93 +1,99 @@ - - -{{:helper.syndicateMode()}} -

    {{:data.welcome}}

    -
    -
    -
    - Functions: -
    -
    - {{:helper.link('Request Items', 'gear', {'menu' : 0}, null, 'fixedLeftWider')}} - {{:helper.link('Exploitable Information', 'gear', {'menu' : 1}, null, 'fixedLeftWider')}} - {{:helper.link('Return', 'arrowreturn-1-w', {'return' : 1}, null, 'fixedLeft')}} - {{:helper.link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}} -
    -
    -
    - -{{if data.menu == 0}} -

    Request items:

    - Each item costs a number of tele-crystals as indicated by the number following their name. -
    -
    - Tele-Crystals: -
    -
    - {{:data.crystals}} -
    -
    -
    - {{for data.nano_items}} -
    -

    {{:value.Category}}

    -
    - {{for value.items :itemValue:itemIndex}} -
    - {{:helper.link( itemValue.Name, 'gear', {'buy_item' : itemValue.obj_path, 'cost' : itemValue.Cost}, itemValue.Cost > data.crystals ? 'disabled' : null, null)}} - {{:itemValue.Cost}} -
    - {{/for}} -
    - {{/for}} - -
    - {{:helper.link('Buy Random (??)' , 'gear', {'buy_item' : 'random'}, data.crystals <= 0 ? 'disabled' : null, null)}} -
    - -{{else data.menu == 1}} -

    Information Record List:

    -
    -
    - Select a Record -
    -
    - {{for data.exploit_records}} -
    - {{:helper.link(value.Name, 'gear', {'menu' : 11, 'id' : value.id}, null, null)}} -
    - {{/for}} - -{{else data.menu == 11}} -

    Information Record:

    -
    -
    -
    -
    - {{if data.exploit_exists == 1}} - Name: {{:data.exploit.name}}
    - Sex: {{:data.exploit.sex}}
    - Species: {{:data.exploit.species}}
    - Age: {{:data.exploit.age}}
    - Rank: {{:data.exploit.rank}}
    - Home System: {{:data.exploit.home_system}}
    - Citizenship: {{:data.exploit.citizenship}}
    - Faction: {{:data.exploit.faction}}
    - Religion: {{:data.exploit.religion}}
    - Fingerprint: {{:data.exploit.fingerprint}}
    - -
    Acquired Information:
    - Notes:
    {{:data.exploit.nanoui_exploit_record}}

    - {{else}} - - No exploitative information acquired! -
    -
    -
    - {{/if}} -
    -
    -
    -{{/if}} + + +{{:helper.syndicateMode()}} +

    {{:data.welcome}}

    +
    +
    +
    + Functions: +
    +
    + {{:helper.link('Request Items', 'gear', {'menu' : 0}, null, 'fixedLeftWider')}} + {{:helper.link('Exploitable Information', 'gear', {'menu' : 1}, null, 'fixedLeftWider')}} + {{:helper.link('Return', 'arrowreturn-1-w', {'return' : 1}, null, 'fixedLeft')}} + {{:helper.link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}} +
    +
    +
    + +{{if data.menu == 0}} +

    Request items:

    + Each item costs a number of tele-crystals as indicated by the number following their name. +
    +
    + Tele-Crystals: +
    +
    + {{:data.crystals}} +
    +
    +
    + {{for data.nano_items}} +
    +

    {{:value.Category}}

    +
    + {{for value.items :itemValue:itemIndex}} +
    + {{:helper.link( itemValue.Name, 'gear', {'buy_item' : itemValue.obj_path, 'cost' : itemValue.Cost}, itemValue.Cost > data.crystals ? 'disabled' : null, null)}} - {{:itemValue.Cost}} +
    + + {{if itemValue.Cost <= data.crystals}} +
    + {{:itemValue.Description}} +
    + {{/if}} + {{/for}} +
    + {{/for}} + +
    + {{:helper.link('Buy Random (??)' , 'gear', {'buy_item' : 'random'}, data.crystals <= 0 ? 'disabled' : null, null)}} +
    + +{{else data.menu == 1}} +

    Information Record List:

    +
    +
    + Select a Record +
    +
    + {{for data.exploit_records}} +
    + {{:helper.link(value.Name, 'gear', {'menu' : 11, 'id' : value.id}, null, null)}} +
    + {{/for}} + +{{else data.menu == 11}} +

    Information Record:

    +
    +
    +
    +
    + {{if data.exploit_exists == 1}} + Name: {{:data.exploit.name}}
    + Sex: {{:data.exploit.sex}}
    + Species: {{:data.exploit.species}}
    + Age: {{:data.exploit.age}}
    + Rank: {{:data.exploit.rank}}
    + Home System: {{:data.exploit.home_system}}
    + Citizenship: {{:data.exploit.citizenship}}
    + Faction: {{:data.exploit.faction}}
    + Religion: {{:data.exploit.religion}}
    + Fingerprint: {{:data.exploit.fingerprint}}
    + +
    Acquired Information:
    + Notes:
    {{:data.exploit.nanoui_exploit_record}}

    + {{else}} + + No exploitative information acquired! +
    +
    +
    + {{/if}} +
    +
    +
    +{{/if}} diff --git a/nano/templates/vending_machine.tmpl b/nano/templates/vending_machine.tmpl new file mode 100644 index 0000000000..93d5c1007c --- /dev/null +++ b/nano/templates/vending_machine.tmpl @@ -0,0 +1,56 @@ + + +{{if data.mode == 0}} +

    Items available

    +
    + {{for data.products}} +
    +
    + {{if value.price > 0}} + {{:helper.link('Buy (' + value.price + ')', 'cart', { "vend" : value.key }, value.amount > 0 ? null : 'disabled')}} + {{else}} + {{:helper.link('Vend', 'circle-arrow-s', { "vend" : value.key }, value.amount > 0 ? null : 'disabled')}} + {{/if}} +
    +
    + {{if value.color}}{{:value.name}} + {{else}}{{:value.name}} + {{/if}} + ({{:value.amount ? value.amount : "NONE LEFT"}}) +
    +
    + {{empty}} + No items available! + {{/for}} +
    +{{if data.coin}} +

    Coin

    +
    +
    Coin deposited:
    +
    {{:helper.link(data.coin, 'eject', {'remove_coin' : 1})}}
    +
    +{{/if}} +{{else data.mode == 1}} +

    Item selected

    +
    +
    +
    Item selected:
    {{:data.product}}
    +
    Charge:
    {{:data.price}}
    +
    +
    + {{if data.message_err}} {{/if}} {{:data.message}} +
    +
    + {{:helper.link('Cancel', 'arrowreturn-1-w', {'cancelpurchase' : 1})}} +
    +
    +{{/if}} +{{if data.panel}} +

    Maintenance panel

    +
    +
    Speaker
    {{:helper.link(data.speaker ? 'Enabled' : 'Disabled', 'gear', {'togglevoice' : 1})}}
    +
    +{{/if}} \ No newline at end of file diff --git a/sound/effects/singlebeat.ogg b/sound/effects/singlebeat.ogg new file mode 100644 index 0000000000..8dd550d5d8 Binary files /dev/null and b/sound/effects/singlebeat.ogg differ diff --git a/sound/serversound_list.txt b/sound/serversound_list.txt new file mode 100644 index 0000000000..24cbafaf15 --- /dev/null +++ b/sound/serversound_list.txt @@ -0,0 +1,11 @@ +sound/music/1.ogg +sound/music/b12_combined_start.ogg +sound/music/main.ogg +sound/music/space.ogg +sound/music/space_asshole.ogg +sound/music/space_oddity.ogg +sound/music/title1.ogg +sound/music/title2.ogg +sound/music/traitor.ogg +sound/items/bikehorn.ogg +sound/effects/siren.ogg \ No newline at end of file diff --git a/sound/weapons/gunshot_smg2.ogg b/sound/weapons/gunshot_smg2.ogg new file mode 100644 index 0000000000..faba955f52 Binary files /dev/null and b/sound/weapons/gunshot_smg2.ogg differ diff --git a/tools/dmitool/dmitool.jar b/tools/dmitool/dmitool.jar index e82d12e5b4..34bdb5bdd4 100644 Binary files a/tools/dmitool/dmitool.jar and b/tools/dmitool/dmitool.jar differ diff --git a/tools/dmitool/src/main/java/dmitool/DMI.java b/tools/dmitool/src/main/java/dmitool/DMI.java index 7fbe9912f1..bb560107ae 100644 --- a/tools/dmitool/src/main/java/dmitool/DMI.java +++ b/tools/dmitool/src/main/java/dmitool/DMI.java @@ -419,6 +419,12 @@ public class DMI implements Comparator { public void printInfo() { System.out.println(totalImages + " images, " + images.size() + " states, size "+w+"x"+h); } + + public void printStateList() { + for(IconState s: images) { + System.out.println(s.getInfoLine()); + } + } @Override public boolean equals(Object obj) { if(obj == this) return true; diff --git a/tools/dmitool/src/main/java/dmitool/DMIException.java b/tools/dmitool/src/main/java/dmitool/DMIException.java index ecc9d2f062..e929316289 100644 --- a/tools/dmitool/src/main/java/dmitool/DMIException.java +++ b/tools/dmitool/src/main/java/dmitool/DMIException.java @@ -8,6 +8,9 @@ public class DMIException extends Exception { desc = descriptor; this.line = line; } + public DMIException(String what) { + super(what); + } public DMIException(String what, Exception cause) { super(what, cause); } diff --git a/tools/dmitool/src/main/java/dmitool/IconState.java b/tools/dmitool/src/main/java/dmitool/IconState.java index 568f7c5cea..c3eb2cff21 100644 --- a/tools/dmitool/src/main/java/dmitool/IconState.java +++ b/tools/dmitool/src/main/java/dmitool/IconState.java @@ -4,6 +4,9 @@ import java.util.Arrays; import ar.com.hjg.pngj.ImageInfo; import ar.com.hjg.pngj.ImageLineInt; import ar.com.hjg.pngj.PngWriter; +import ar.com.hjg.pngj.PngReader; +import ar.com.hjg.pngj.PngjInputException; +import java.io.InputStream; import java.io.OutputStream; public class IconState { @@ -16,6 +19,21 @@ public class IconState { int loop; String hotspot; boolean movement; + + public String getInfoLine() { + String extraInfo = ""; + if(rewind) extraInfo += " rewind"; + if(frames != 1) { + extraInfo += " loop(" + (loop==-1 ? "infinite" : loop) + ")"; + } + if(hotspot != null) extraInfo += " hotspot('" + hotspot + "')"; + if(movement) extraInfo += " movement"; + if(extraInfo.equals("")) { + return String.format("state \"%s\", %d dir(s), %d frame(s)", name, dirs, frames); + } else { + return String.format("state \"%s\", %d dir(s), %d frame(s),%s", name, dirs, frames, extraInfo); + } + } @Override public IconState clone() { IconState is = new IconState(name, dirs, frames, images.clone(), delays==null ? null : delays.clone(), rewind, loop, hotspot, movement); @@ -144,4 +162,88 @@ public class IconState { } out.end(); } -} \ No newline at end of file + + public static IconState importFromPNG(DMI dmi, InputStream inS, String name, float[] delays, boolean rewind, int loop, String hotspot, boolean movement) throws DMIException { + int w = dmi.w; + int h = dmi.h; + + PngReader in; + try { + in = new PngReader(inS); + } catch(PngjInputException pie) { + throw new DMIException("Bad file format!", pie); + } + int pxW = in.imgInfo.cols; + int pxH = in.imgInfo.rows; + int frames = pxW / w; + int dirs = pxH / h; + + // make sure the size is an integer multiple + if(frames * w != pxW || frames==0) throw new DMIException("Illegal image size!"); + if(dirs * h != pxH || dirs==0) throw new DMIException("Illegal image size!"); + + int[][] px = new int[pxH][]; + for(int i=0; i argq = new ArrayDeque<>(); for(String s: args) { @@ -63,9 +82,9 @@ public class Main { argq.pollFirst(); } String op = argq.pollFirst(); - + switch(op) { - case "diff": + case "diff": { if(argq.size() < 2) { System.out.println("Insufficient arguments for command!"); System.out.println(helpStr); @@ -73,7 +92,7 @@ public class Main { } String a = argq.pollFirst(); String b = argq.pollFirst(); - + if(VERBOSITY >= 0) System.out.println("Loading " + a); DMI dmi = doDMILoad(a); if(VERBOSITY >= 0) dmi.printInfo(); @@ -85,22 +104,24 @@ public class Main { DMIDiff dmid = new DMIDiff(dmi, dmi2); System.out.println(dmid); break; - case "sort": + } + case "sort": { if(argq.size() < 1) { System.out.println("Insufficient arguments for command!"); System.out.println(helpStr); return; } String f = argq.pollFirst(); - + if(VERBOSITY >= 0) System.out.println("Loading " + f); - dmi = doDMILoad(f); + DMI dmi = doDMILoad(f); if(VERBOSITY >= 0) dmi.printInfo(); - + if(VERBOSITY >= 0) System.out.println("Saving " + f); dmi.writeDMI(new FileOutputStream(f), true); break; - case "merge": + } + case "merge": { if(argq.size() < 4) { System.out.println("Insufficient arguments for command!"); System.out.println(helpStr); @@ -113,26 +134,26 @@ public class Main { if(VERBOSITY >= 0) System.out.println("Loading " + baseF); DMI base = doDMILoad(baseF); if(VERBOSITY >= 0) base.printInfo(); - + if(VERBOSITY >= 0) System.out.println("Loading " + aF); DMI aDMI = doDMILoad(aF); if(VERBOSITY >= 0) aDMI.printInfo(); - + if(VERBOSITY >= 0) System.out.println("Loading " + bF); DMI bDMI = doDMILoad(bF); if(VERBOSITY >= 0) bDMI.printInfo(); - + DMIDiff aDiff = new DMIDiff(base, aDMI); DMIDiff bDiff = new DMIDiff(base, bDMI); DMIDiff mergedDiff = new DMIDiff(); DMI conflictDMI = new DMI(32, 32); - + Set cf = aDiff.mergeDiff(bDiff, conflictDMI, mergedDiff, aF, bF); - + mergedDiff.applyToDMI(base); - + base.writeDMI(new FileOutputStream(mergedF)); - + if(!cf.isEmpty()) { if(VERBOSITY >= 0) for(String s: cf) { System.out.println(s); @@ -145,7 +166,8 @@ public class Main { System.exit(0); } break; - case "extract": + } + case "extract": { if(argq.size() < 3) { System.out.println("Insufficient arguments for command!"); System.out.println(helpStr); @@ -154,10 +176,10 @@ public class Main { String file = argq.pollFirst(), state = argq.pollFirst(), outFile = argq.pollFirst(); - - dmi = doDMILoad(file); + + DMI dmi = doDMILoad(file); if(VERBOSITY >= 0) dmi.printInfo(); - + IconState is = dmi.getIconState(state); if(is == null) { System.out.println("icon_state '"+state+"' does not exist!"); @@ -166,10 +188,10 @@ public class Main { // minDir, Maxdir, minFrame, Maxframe int mDir=0, Mdir=is.dirs-1; int mFrame=0, Mframe=is.frames-1; - + while(argq.size() > 1) { String arg = argq.pollFirst(); - + switch(arg) { case "d": case "dir": @@ -231,7 +253,120 @@ public class Main { } is.dumpToPNG(new FileOutputStream(outFile), mDir, Mdir, mFrame, Mframe); break; - case "verify": + } + case "import": { + if(argq.size() < 3) { + System.out.println("Insufficient arguments for command!"); + System.out.println(helpStr); + return; + } + String dmiFile = argq.pollFirst(), + stateName = argq.pollFirst(), + pngFile = argq.pollFirst(); + + boolean noDup = false; + boolean rewind = false; + int loop = 0; + boolean movement = false; + String hotspot = null; + float[] delays = null; + while(!argq.isEmpty()) { + String s = argq.pollFirst(); + switch(s.toLowerCase()) { + case "nodup": + case "nd": + case "n": + noDup = true; + break; + case "rewind": + case "rw": + case "r": + rewind = true; + break; + case "loop": + case "lp": + case "l": + loop = -1; + break; + case "loopn": + case "lpn": + case "ln": + if(!argq.isEmpty()) { + String loopTimes = argq.pollFirst(); + try { + loop = Integer.parseInt(loopTimes); + } catch(NumberFormatException nfe) { + System.out.println("Illegal number '" + loopTimes + "' as argument to '" + s + "'!"); + return; + } + } else { + System.out.println("Argument '" + s + "' requires a numeric argument following it!"); + return; + } + break; + case "movement": + case "move": + case "mov": + case "m": + movement = true; + break; + case "delays": + case "delay": + case "del": + case "d": + if(!argq.isEmpty()) { + String delaysString = argq.pollFirst(); + String[] delaysSplit = delaysString.split(","); + delays = new float[delaysSplit.length]; + for(int i=0; i= 0) System.out.println("Loading " + dmiFile); + DMI toImportTo = doDMILoad(dmiFile); + if(VERBOSITY >= 0) toImportTo.printInfo(); + IconState is = IconState.importFromPNG(toImportTo, new FileInputStream(pngFile), stateName, delays, rewind, loop, hotspot, movement); + + if(noDup) { + if(!toImportTo.setIconState(is)) { + toImportTo.addIconState(null, is); + } + } else { + toImportTo.addIconState(null, is); + } + + if(VERBOSITY >= 0) toImportTo.printInfo(); + + if(VERBOSITY >= 0) System.out.println("Saving " + dmiFile); + toImportTo.writeDMI(new FileOutputStream(dmiFile)); + break; + } + case "verify": { if(argq.size() < 1) { System.out.println("Insufficient arguments for command!"); System.out.println(helpStr); @@ -242,6 +377,23 @@ public class Main { DMI v = doDMILoad(vF); if(VERBOSITY >= 0) v.printInfo(); break; + } + case "info": { + if(argq.size() < 1) { + System.out.println("Insufficient arguments for command!"); + System.out.println(helpStr); + return; + } + String infoFile = argq.pollFirst(); + if(VERBOSITY >= 0) System.out.println("Loading " + infoFile); + DMI info = doDMILoad(infoFile); + info.printInfo(); + info.printStateList(); + break; + } + case "version": + System.out.println(VERSION); + return; default: System.out.println("Command '" + op + "' not found!"); case "help": @@ -249,7 +401,7 @@ public class Main { break; } } - + static int parseDir(String s, IconState is) { try { int i = Integer.parseInt(s); @@ -275,7 +427,7 @@ public class Main { return -1; } } - + static int parseFrame(String s, IconState is) { try { int i = Integer.parseInt(s); @@ -290,7 +442,7 @@ public class Main { return -1; } } - + static DMI doDMILoad(String file) { try { DMI dmi = new DMI(file);