diff --git a/baystation12.dme b/baystation12.dme
index a0326d8c6e2..e0489fa5008 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -1,17 +1,18 @@
-// DM Environment file for tgstation.dme.
+// DM Environment file for baystation12.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 .
#define FILE_DIR "code"
#define FILE_DIR "code/TriDimension"
#define FILE_DIR "code/WorkInProgress"
#define FILE_DIR "code/WorkInProgress/Cael_Aislinn"
+#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Jungle"
#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Rust"
#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Supermatter"
+#define FILE_DIR "code/WorkInProgress/Susan"
#define FILE_DIR "html"
#define FILE_DIR "icons"
#define FILE_DIR "icons/48x48"
@@ -20,25 +21,24 @@
#define FILE_DIR "icons/misc"
#define FILE_DIR "icons/mob"
#define FILE_DIR "icons/mob/human_races"
-#define FILE_DIR "icons/mob/skin"
#define FILE_DIR "icons/obj"
#define FILE_DIR "icons/obj/assemblies"
#define FILE_DIR "icons/obj/atmospherics"
#define FILE_DIR "icons/obj/clothing"
#define FILE_DIR "icons/obj/doors"
+#define FILE_DIR "icons/obj/flora"
#define FILE_DIR "icons/obj/machines"
#define FILE_DIR "icons/obj/pipes"
#define FILE_DIR "icons/pda_icons"
#define FILE_DIR "icons/spideros_icons"
#define FILE_DIR "icons/Testing"
#define FILE_DIR "icons/turf"
-#define FILE_DIR "icons/vehicles"
#define FILE_DIR "icons/vending_icons"
-#define FILE_DIR "maps"
#define FILE_DIR "sound"
#define FILE_DIR "sound/AI"
#define FILE_DIR "sound/ambience"
#define FILE_DIR "sound/effects"
+#define FILE_DIR "sound/effects/wind"
#define FILE_DIR "sound/hallucinations"
#define FILE_DIR "sound/items"
#define FILE_DIR "sound/machines"
@@ -52,6 +52,7 @@
// END_FILE_DIR
// BEGIN_PREFERENCES
+#define DEBUG
// END_PREFERENCES
// BEGIN_INCLUDE
@@ -61,6 +62,20 @@
#include "code\setup.dm"
#include "code\stylesheet.dm"
#include "code\world.dm"
+#include "code\__HELPERS\files.dm"
+#include "code\__HELPERS\game.dm"
+#include "code\__HELPERS\global_lists.dm"
+#include "code\__HELPERS\icons.dm"
+#include "code\__HELPERS\lists.dm"
+#include "code\__HELPERS\logging.dm"
+#include "code\__HELPERS\maths.dm"
+#include "code\__HELPERS\mobs.dm"
+#include "code\__HELPERS\names.dm"
+#include "code\__HELPERS\sanitize_values.dm"
+#include "code\__HELPERS\text.dm"
+#include "code\__HELPERS\time.dm"
+#include "code\__HELPERS\type2type.dm"
+#include "code\__HELPERS\unsorted.dm"
#include "code\ATMOSPHERICS\atmospherics.dm"
#include "code\ATMOSPHERICS\datum_pipe_network.dm"
#include "code\ATMOSPHERICS\datum_pipeline.dm"
@@ -108,7 +123,6 @@
#include "code\datums\spell.dm"
#include "code\datums\sun.dm"
#include "code\datums\supplypacks.dm"
-#include "code\datums\diseases\alien_embryo.dm"
#include "code\datums\diseases\appendicitis.dm"
#include "code\datums\diseases\beesease.dm"
#include "code\datums\diseases\brainrot.dm"
@@ -128,6 +142,23 @@
#include "code\datums\diseases\robotic_transformation.dm"
#include "code\datums\diseases\wizarditis.dm"
#include "code\datums\diseases\xeno_transformation.dm"
+#include "code\datums\diseases\advance\advance.dm"
+#include "code\datums\diseases\advance\presets.dm"
+#include "code\datums\diseases\advance\symptoms\confusion.dm"
+#include "code\datums\diseases\advance\symptoms\cough.dm"
+#include "code\datums\diseases\advance\symptoms\damage_converter.dm"
+#include "code\datums\diseases\advance\symptoms\dizzy.dm"
+#include "code\datums\diseases\advance\symptoms\fever.dm"
+#include "code\datums\diseases\advance\symptoms\hallucigen.dm"
+#include "code\datums\diseases\advance\symptoms\headache.dm"
+#include "code\datums\diseases\advance\symptoms\heal.dm"
+#include "code\datums\diseases\advance\symptoms\itching.dm"
+#include "code\datums\diseases\advance\symptoms\shivering.dm"
+#include "code\datums\diseases\advance\symptoms\sneeze.dm"
+#include "code\datums\diseases\advance\symptoms\symptoms.dm"
+#include "code\datums\diseases\advance\symptoms\voice_change.dm"
+#include "code\datums\diseases\advance\symptoms\vomit.dm"
+#include "code\datums\diseases\advance\symptoms\weight.dm"
#include "code\datums\helper_datums\construction_datum.dm"
#include "code\datums\helper_datums\events.dm"
#include "code\datums\helper_datums\getrev.dm"
@@ -141,10 +172,12 @@
#include "code\datums\organs\wound.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"
@@ -154,32 +187,13 @@
#include "code\datums\spells\wizard.dm"
#include "code\defines\obj.dm"
#include "code\defines\obj\hydro.dm"
-#include "code\defines\obj\machinery.dm"
-#include "code\defines\obj\storage.dm"
-#include "code\defines\obj\toy.dm"
-#include "code\defines\obj\vending.dm"
#include "code\defines\obj\weapon.dm"
#include "code\defines\procs\AStar.dm"
#include "code\defines\procs\captain_announce.dm"
-#include "code\defines\procs\church_name.dm"
#include "code\defines\procs\command_alert.dm"
-#include "code\defines\procs\command_name.dm"
#include "code\defines\procs\dbcore.dm"
-#include "code\defines\procs\forum_activation.dm"
-#include "code\defines\procs\gamehelpers.dm"
-#include "code\defines\procs\global_lists.dm"
-#include "code\defines\procs\helper_list.dm"
-#include "code\defines\procs\helper_text.dm"
-#include "code\defines\procs\helper_type2type.dm"
-#include "code\defines\procs\helpers.dm"
-#include "code\defines\procs\icon_procs.dm"
-#include "code\defines\procs\icon_procs_readme.dm"
-#include "code\defines\procs\logging.dm"
-#include "code\defines\procs\religion_name.dm"
-#include "code\defines\procs\station_name.dm"
+#include "code\defines\procs\sd_Alert.dm"
#include "code\defines\procs\statistics.dm"
-#include "code\defines\procs\syndicate_name.dm"
-#include "code\defines\procs\time_stamp.dm"
#include "code\game\asteroid.dm"
#include "code\game\atoms.dm"
#include "code\game\atoms_movable.dm"
@@ -220,6 +234,7 @@
#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"
@@ -229,7 +244,9 @@
#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"
+#include "code\game\gamemodes\events\holidays\Other.dm"
#include "code\game\gamemodes\extended\extended.dm"
#include "code\game\gamemodes\malfunction\Malf_Modules.dm"
#include "code\game\gamemodes\malfunction\malfunction.dm"
@@ -246,7 +263,6 @@
#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\spells.dm"
#include "code\game\gamemodes\wizard\veilrender.dm"
#include "code\game\gamemodes\wizard\wizard.dm"
#include "code\game\jobs\access.dm"
@@ -272,6 +288,7 @@
#include "code\game\machinery\autolathe.dm"
#include "code\game\machinery\Beacon.dm"
#include "code\game\machinery\biogenerator.dm"
+#include "code\game\machinery\buttons.dm"
#include "code\game\machinery\cell_charger.dm"
#include "code\game\machinery\cloning.dm"
#include "code\game\machinery\constructable_frame.dm"
@@ -283,6 +300,7 @@
#include "code\game\machinery\floodlight.dm"
#include "code\game\machinery\Freezer.dm"
#include "code\game\machinery\hologram.dm"
+#include "code\game\machinery\holosign.dm"
#include "code\game\machinery\hydroponics.dm"
#include "code\game\machinery\igniter.dm"
#include "code\game\machinery\iv_drip.dm"
@@ -322,7 +340,6 @@
#include "code\game\machinery\bots\bots.dm"
#include "code\game\machinery\bots\cleanbot.dm"
#include "code\game\machinery\bots\ed209bot.dm"
-#include "code\game\machinery\bots\floorbot.dm"
#include "code\game\machinery\bots\medbot.dm"
#include "code\game\machinery\bots\mulebot.dm"
#include "code\game\machinery\bots\secbot.dm"
@@ -362,6 +379,7 @@
#include "code\game\machinery\computer\syndicate_specops_shuttle.dm"
#include "code\game\machinery\doors\airlock.dm"
#include "code\game\machinery\doors\airlock_electronics.dm"
+#include "code\game\machinery\doors\alarmlock.dm"
#include "code\game\machinery\doors\brigdoors.dm"
#include "code\game\machinery\doors\checkForMultipleDoors.dm"
#include "code\game\machinery\doors\door.dm"
@@ -388,6 +406,7 @@
#include "code\game\machinery\telecomms\telecomunications.dm"
#include "code\game\machinery\telecomms\telemonitor.dm"
#include "code\game\machinery\telecomms\traffic_control.dm"
+#include "code\game\magic\Uristrunes.dm"
#include "code\game\mecha\mech_bay.dm"
#include "code\game\mecha\mech_fabricator.dm"
#include "code\game\mecha\mecha.dm"
@@ -407,7 +426,6 @@
#include "code\game\mecha\equipment\weapons\weapons.dm"
#include "code\game\mecha\medical\medical.dm"
#include "code\game\mecha\medical\odysseus.dm"
-#include "code\game\mecha\working\firefighter.dm"
#include "code\game\mecha\working\ripley.dm"
#include "code\game\mecha\working\working.dm"
#include "code\game\objects\empulse.dm"
@@ -415,12 +433,10 @@
#include "code\game\objects\explosion_recursive.dm"
#include "code\game\objects\items.dm"
#include "code\game\objects\objs.dm"
-#include "code\game\objects\sign_decals.dm"
#include "code\game\objects\structures.dm"
#include "code\game\objects\weapons.dm"
#include "code\game\objects\closets\walllocker.dm"
#include "code\game\objects\effects\aliens.dm"
-#include "code\game\objects\effects\biomass_rift.dm"
#include "code\game\objects\effects\bump_teleporter.dm"
#include "code\game\objects\effects\effect_system.dm"
#include "code\game\objects\effects\gibs.dm"
@@ -431,7 +447,7 @@
#include "code\game\objects\effects\misc.dm"
#include "code\game\objects\effects\overlays.dm"
#include "code\game\objects\effects\portals.dm"
-#include "code\game\objects\effects\signs.dm"
+#include "code\game\objects\effects\spiders.dm"
#include "code\game\objects\effects\step_triggers.dm"
#include "code\game\objects\effects\decals\cleanable.dm"
#include "code\game\objects\effects\decals\contraband.dm"
@@ -450,10 +466,12 @@
#include "code\game\objects\items\blueprints.dm"
#include "code\game\objects\items\bodybag.dm"
#include "code\game\objects\items\candle.dm"
+#include "code\game\objects\items\contraband.dm"
#include "code\game\objects\items\crayons.dm"
#include "code\game\objects\items\latexballoon.dm"
#include "code\game\objects\items\shooting_range.dm"
#include "code\game\objects\items\tk_grab.dm"
+#include "code\game\objects\items\toys.dm"
#include "code\game\objects\items\trash.dm"
#include "code\game\objects\items\devices\aicard.dm"
#include "code\game\objects\items\devices\chameleonproj.dm"
@@ -464,7 +482,6 @@
#include "code\game\objects\items\devices\paicard.dm"
#include "code\game\objects\items\devices\powersink.dm"
#include "code\game\objects\items\devices\scanners.dm"
-#include "code\game\objects\items\devices\shields.dm"
#include "code\game\objects\items\devices\taperecorder.dm"
#include "code\game\objects\items\devices\traitordevices.dm"
#include "code\game\objects\items\devices\transfer_valve.dm"
@@ -511,21 +528,21 @@
#include "code\game\objects\items\weapons\kitchen.dm"
#include "code\game\objects\items\weapons\manuals.dm"
#include "code\game\objects\items\weapons\mop.dm"
-#include "code\game\objects\items\weapons\mousetraps.dm"
#include "code\game\objects\items\weapons\paint.dm"
#include "code\game\objects\items\weapons\paiwire.dm"
-#include "code\game\objects\items\weapons\photography.dm"
+#include "code\game\objects\items\weapons\power_cells.dm"
#include "code\game\objects\items\weapons\RCD.dm"
#include "code\game\objects\items\weapons\RSF.dm"
#include "code\game\objects\items\weapons\scrolls.dm"
+#include "code\game\objects\items\weapons\shields.dm"
#include "code\game\objects\items\weapons\stunbaton.dm"
#include "code\game\objects\items\weapons\surgery_tools.dm"
#include "code\game\objects\items\weapons\swords_axes_etc.dm"
#include "code\game\objects\items\weapons\table_rack_parts.dm"
#include "code\game\objects\items\weapons\teleportation.dm"
#include "code\game\objects\items\weapons\tools.dm"
-#include "code\game\objects\items\weapons\trashbag.dm"
#include "code\game\objects\items\weapons\twohanded.dm"
+#include "code\game\objects\items\weapons\weaponry.dm"
#include "code\game\objects\items\weapons\wires.dm"
#include "code\game\objects\items\weapons\grenades\chem_grenade.dm"
#include "code\game\objects\items\weapons\grenades\emgrenade.dm"
@@ -538,35 +555,39 @@
#include "code\game\objects\items\weapons\implants\implantchair.dm"
#include "code\game\objects\items\weapons\implants\implanter.dm"
#include "code\game\objects\items\weapons\implants\implantfreedom.dm"
-#include "code\game\objects\items\weapons\implants\implantnanoaug.dm"
#include "code\game\objects\items\weapons\implants\implantpad.dm"
#include "code\game\objects\items\weapons\implants\implantuplink.dm"
-#include "code\game\objects\items\weapons\secstorage\sbriefcase.dm"
-#include "code\game\objects\items\weapons\secstorage\secstorage.dm"
-#include "code\game\objects\items\weapons\secstorage\ssafe.dm"
+#include "code\game\objects\items\weapons\melee\energy.dm"
+#include "code\game\objects\items\weapons\melee\misc.dm"
#include "code\game\objects\items\weapons\storage\backpack.dm"
+#include "code\game\objects\items\weapons\storage\bags.dm"
#include "code\game\objects\items\weapons\storage\belt.dm"
#include "code\game\objects\items\weapons\storage\bible.dm"
+#include "code\game\objects\items\weapons\storage\boxes.dm"
#include "code\game\objects\items\weapons\storage\briefcase.dm"
#include "code\game\objects\items\weapons\storage\fancy.dm"
#include "code\game\objects\items\weapons\storage\firstaid.dm"
-#include "code\game\objects\items\weapons\storage\kit.dm"
#include "code\game\objects\items\weapons\storage\lockbox.dm"
-#include "code\game\objects\items\weapons\storage\misc.dm"
+#include "code\game\objects\items\weapons\storage\secure.dm"
#include "code\game\objects\items\weapons\storage\storage.dm"
#include "code\game\objects\items\weapons\storage\toolbox.dm"
#include "code\game\objects\items\weapons\storage\uplink_kits.dm"
+#include "code\game\objects\items\weapons\storage\wallets.dm"
#include "code\game\objects\items\weapons\tanks\jetpack.dm"
#include "code\game\objects\items\weapons\tanks\tank_types.dm"
#include "code\game\objects\items\weapons\tanks\tanks.dm"
+#include "code\game\objects\storage\coat.dm"
+#include "code\game\objects\structures\barsign.dm"
#include "code\game\objects\structures\bedsheet_bin.dm"
#include "code\game\objects\structures\displaycase.dm"
#include "code\game\objects\structures\door_assembly.dm"
#include "code\game\objects\structures\electricchair.dm"
#include "code\game\objects\structures\extinguisher.dm"
#include "code\game\objects\structures\false_walls.dm"
+#include "code\game\objects\structures\flora.dm"
#include "code\game\objects\structures\girders.dm"
#include "code\game\objects\structures\grille.dm"
+#include "code\game\objects\structures\janicart.dm"
#include "code\game\objects\structures\kitchen_spike.dm"
#include "code\game\objects\structures\ladders.dm"
#include "code\game\objects\structures\lamarr_cage.dm"
@@ -577,7 +598,8 @@
#include "code\game\objects\structures\morgue.dm"
#include "code\game\objects\structures\musician.dm"
#include "code\game\objects\structures\noticeboard.dm"
-#include "code\game\objects\structures\shuttle_engines.dm"
+#include "code\game\objects\structures\safe.dm"
+#include "code\game\objects\structures\signs.dm"
#include "code\game\objects\structures\tables_racks.dm"
#include "code\game\objects\structures\tank_dispenser.dm"
#include "code\game\objects\structures\target_stake.dm"
@@ -612,12 +634,9 @@
#include "code\game\objects\structures\stool_bed_chair_nest\bed.dm"
#include "code\game\objects\structures\stool_bed_chair_nest\chairs.dm"
#include "code\game\objects\structures\stool_bed_chair_nest\stools.dm"
-#include "code\game\player\admin_report.dm"
#include "code\game\turfs\simulated.dm"
#include "code\game\turfs\turf.dm"
#include "code\game\turfs\unsimulated.dm"
-#include "code\game\turfs\simulated\asteroid.dm"
-#include "code\game\turfs\simulated\beach.dm"
#include "code\game\turfs\simulated\floor.dm"
#include "code\game\turfs\simulated\floor_types.dm"
#include "code\game\turfs\simulated\walls.dm"
@@ -629,13 +648,8 @@
#include "code\game\turfs\unsimulated\beach.dm"
#include "code\game\turfs\unsimulated\floor.dm"
#include "code\game\turfs\unsimulated\walls.dm"
-#include "code\game\vehicles\vehicle.dm"
-#include "code\game\vehicles\airtight\airtight.dm"
-#include "code\game\vehicles\airtight\land.dm"
-#include "code\game\vehicles\airtight\space.dm"
#include "code\game\verbs\atom_verbs.dm"
#include "code\game\verbs\ooc.dm"
-#include "code\game\verbs\sound.dm"
#include "code\game\verbs\suicide.dm"
#include "code\game\verbs\who.dm"
#include "code\js\byjax.dm"
@@ -643,6 +657,7 @@
#include "code\modules\admin\admin.dm"
#include "code\modules\admin\admin_investigate.dm"
#include "code\modules\admin\admin_memo.dm"
+#include "code\modules\admin\admin_ranks.dm"
#include "code\modules\admin\admin_verbs.dm"
#include "code\modules\admin\banjob.dm"
#include "code\modules\admin\create_mob.dm"
@@ -650,14 +665,13 @@
#include "code\modules\admin\create_turf.dm"
#include "code\modules\admin\holder2.dm"
#include "code\modules\admin\IsBanned.dm"
-#include "code\modules\admin\mod_panel.dm"
#include "code\modules\admin\NewBan.dm"
#include "code\modules\admin\newbanjob.dm"
#include "code\modules\admin\player_notes.dm"
#include "code\modules\admin\player_panel.dm"
+#include "code\modules\admin\topic.dm"
#include "code\modules\admin\ToRban.dm"
#include "code\modules\admin\DB ban\functions.dm"
-#include "code\modules\admin\permissionverbs\assignment.dm"
#include "code\modules\admin\permissionverbs\permissionedit.dm"
#include "code\modules\admin\verbs\adminhelp.dm"
#include "code\modules\admin\verbs\adminjump.dm"
@@ -690,12 +704,14 @@
#include "code\modules\assembly\holder.dm"
#include "code\modules\assembly\igniter.dm"
#include "code\modules\assembly\infrared.dm"
+#include "code\modules\assembly\mousetrap.dm"
#include "code\modules\assembly\proximity.dm"
#include "code\modules\assembly\shock_kit.dm"
#include "code\modules\assembly\signaler.dm"
#include "code\modules\assembly\timer.dm"
#include "code\modules\awaymissions\bluespaceartillery.dm"
#include "code\modules\awaymissions\corpse.dm"
+#include "code\modules\awaymissions\exile.dm"
#include "code\modules\awaymissions\gateway.dm"
#include "code\modules\awaymissions\loot.dm"
#include "code\modules\awaymissions\pamphlet.dm"
@@ -707,6 +723,9 @@
#include "code\modules\awaymissions\maploader\writer.dm"
#include "code\modules\client\client defines.dm"
#include "code\modules\client\client procs.dm"
+#include "code\modules\client\preferences.dm"
+#include "code\modules\client\preferences_savefile.dm"
+#include "code\modules\client\preferences_toggles.dm"
#include "code\modules\clothing\clothing.dm"
#include "code\modules\clothing\glasses\glasses.dm"
#include "code\modules\clothing\glasses\hud.dm"
@@ -752,17 +771,28 @@
#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\critters\critter.dm"
-#include "code\modules\critters\critter_AI.dm"
-#include "code\modules\critters\critter_defenses.dm"
-#include "code\modules\critters\critters.dm"
-#include "code\modules\critters\hivebots\hivebot.dm"
#include "code\modules\customitems\item_defines.dm"
#include "code\modules\customitems\item_spawning.dm"
-#include "code\modules\DetectiveWork\detective_work.dm"
-#include "code\modules\DetectiveWork\evidence.dm"
-#include "code\modules\DetectiveWork\footprints_and_rag.dm"
-#include "code\modules\DetectiveWork\scanner.dm"
+#include "code\modules\destilery\main.dm"
+#include "code\modules\detectivework\detective_work.dm"
+#include "code\modules\detectivework\evidence.dm"
+#include "code\modules\detectivework\footprints_and_rag.dm"
+#include "code\modules\detectivework\scanner.dm"
+#include "code\modules\events\alien_infestation.dm"
+#include "code\modules\events\blob.dm"
+#include "code\modules\events\brand_intelligence.dm"
+#include "code\modules\events\carp_migration.dm"
+#include "code\modules\events\communications_blackout.dm"
+#include "code\modules\events\disease_outbreak.dm"
+#include "code\modules\events\electrical_storm.dm"
+#include "code\modules\events\event.dm"
+#include "code\modules\events\event_manager.dm"
+#include "code\modules\events\meteor_wave.dm"
+#include "code\modules\events\prison_break.dm"
+#include "code\modules\events\radiation_storm.dm"
+#include "code\modules\events\spacevine.dm"
+#include "code\modules\events\spider_infestation.dm"
+#include "code\modules\events\spontaneous_appendicitis.dm"
#include "code\modules\flufftext\Dreaming.dm"
#include "code\modules\flufftext\Hallucination.dm"
#include "code\modules\flufftext\TextFilters.dm"
@@ -781,7 +811,7 @@
#include "code\modules\mining\mine_turfs.dm"
#include "code\modules\mining\mint.dm"
#include "code\modules\mining\money_bag.dm"
-#include "code\modules\mining\ores_materials_coins.dm"
+#include "code\modules\mining\ores_coins.dm"
#include "code\modules\mining\satchel_ore_boxdm.dm"
#include "code\modules\mob\death.dm"
#include "code\modules\mob\inventory.dm"
@@ -842,6 +872,7 @@
#include "code\modules\mob\living\carbon\alien\larva\life.dm"
#include "code\modules\mob\living\carbon\alien\larva\powers.dm"
#include "code\modules\mob\living\carbon\alien\larva\update_icons.dm"
+#include "code\modules\mob\living\carbon\alien\special\alien_embryo.dm"
#include "code\modules\mob\living\carbon\alien\special\facehugger.dm"
#include "code\modules\mob\living\carbon\brain\brain.dm"
#include "code\modules\mob\living\carbon\brain\brain_item.dm"
@@ -850,6 +881,7 @@
#include "code\modules\mob\living\carbon\brain\hud.dm"
#include "code\modules\mob\living\carbon\brain\life.dm"
#include "code\modules\mob\living\carbon\brain\MMI.dm"
+#include "code\modules\mob\living\carbon\brain\posibrain.dm"
#include "code\modules\mob\living\carbon\brain\say.dm"
#include "code\modules\mob\living\carbon\human\death.dm"
#include "code\modules\mob\living\carbon\human\emote.dm"
@@ -878,6 +910,7 @@
#include "code\modules\mob\living\carbon\metroid\metroid.dm"
#include "code\modules\mob\living\carbon\metroid\powers.dm"
#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"
@@ -929,38 +962,49 @@
#include "code\modules\mob\living\silicon\robot\life.dm"
#include "code\modules\mob\living\silicon\robot\login.dm"
#include "code\modules\mob\living\silicon\robot\robot.dm"
+#include "code\modules\mob\living\silicon\robot\robot_items.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules.dm"
#include "code\modules\mob\living\silicon\robot\robot_movement.dm"
#include "code\modules\mob\living\silicon\robot\say.dm"
#include "code\modules\mob\living\silicon\robot\wires.dm"
-#include "code\modules\mob\living\simple_animal\clown.dm"
#include "code\modules\mob\living\simple_animal\constructs.dm"
-#include "code\modules\mob\living\simple_animal\kobold.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"
#include "code\modules\mob\living\simple_animal\simple_animal.dm"
-#include "code\modules\mob\living\simple_animal\syndicate.dm"
#include "code\modules\mob\living\simple_animal\worm.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"
+#include "code\modules\mob\living\simple_animal\friendly\farm_animals.dm"
+#include "code\modules\mob\living\simple_animal\friendly\lizard.dm"
#include "code\modules\mob\living\simple_animal\friendly\mouse.dm"
#include "code\modules\mob\living\simple_animal\friendly\mushroom.dm"
+#include "code\modules\mob\living\simple_animal\friendly\slime.dm"
#include "code\modules\mob\living\simple_animal\friendly\tomato.dm"
+#include "code\modules\mob\living\simple_animal\hostile\alien.dm"
#include "code\modules\mob\living\simple_animal\hostile\bear.dm"
#include "code\modules\mob\living\simple_animal\hostile\carp.dm"
+#include "code\modules\mob\living\simple_animal\hostile\creature.dm"
+#include "code\modules\mob\living\simple_animal\hostile\faithless.dm"
+#include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm"
+#include "code\modules\mob\living\simple_animal\hostile\hivebot.dm"
#include "code\modules\mob\living\simple_animal\hostile\hostile.dm"
+#include "code\modules\mob\living\simple_animal\hostile\mimic.dm"
+#include "code\modules\mob\living\simple_animal\hostile\pirate.dm"
+#include "code\modules\mob\living\simple_animal\hostile\russian.dm"
+#include "code\modules\mob\living\simple_animal\hostile\syndicate.dm"
+#include "code\modules\mob\living\simple_animal\hostile\tree.dm"
+#include "code\modules\mob\living\simple_animal\hostile\retaliate\clown.dm"
+#include "code\modules\mob\living\simple_animal\hostile\retaliate\retaliate.dm"
#include "code\modules\mob\new_player\hud.dm"
#include "code\modules\mob\new_player\login.dm"
#include "code\modules\mob\new_player\logout.dm"
#include "code\modules\mob\new_player\new_player.dm"
#include "code\modules\mob\new_player\poll.dm"
-#include "code\modules\mob\new_player\preferences.dm"
#include "code\modules\mob\new_player\preferences_setup.dm"
-#include "code\modules\mob\new_player\savefile.dm"
#include "code\modules\mob\new_player\skill.dm"
#include "code\modules\mob\new_player\sprite_accessories.dm"
-#include "code\modules\mob\simple_animal\head.dm"
#include "code\modules\paperwork\clipboard.dm"
#include "code\modules\paperwork\filingcabinet.dm"
#include "code\modules\paperwork\folders.dm"
@@ -969,6 +1013,7 @@
#include "code\modules\paperwork\paperbin.dm"
#include "code\modules\paperwork\pen.dm"
#include "code\modules\paperwork\photocopier.dm"
+#include "code\modules\paperwork\photography.dm"
#include "code\modules\paperwork\stamps.dm"
#include "code\modules\power\apc.dm"
#include "code\modules\power\cable.dm"
@@ -1021,6 +1066,7 @@
#include "code\modules\projectiles\guns\projectile\pistol.dm"
#include "code\modules\projectiles\guns\projectile\revolver.dm"
#include "code\modules\projectiles\guns\projectile\shotgun.dm"
+#include "code\modules\projectiles\projectile\animate.dm"
#include "code\modules\projectiles\projectile\beams.dm"
#include "code\modules\projectiles\projectile\bullets.dm"
#include "code\modules\projectiles\projectile\change.dm"
@@ -1120,16 +1166,38 @@
#include "code\modules\scripting\Scanner\Tokens.dm"
#include "code\modules\security levels\keycard authentication.dm"
#include "code\modules\security levels\security levels.dm"
+#include "code\modules\surgery\appendix.dm"
+#include "code\modules\surgery\bones.dm"
+#include "code\modules\surgery\braincore.dm"
+#include "code\modules\surgery\eye.dm"
+#include "code\modules\surgery\face.dm"
+#include "code\modules\surgery\generic.dm"
+#include "code\modules\surgery\other.dm"
+#include "code\modules\surgery\ribcage.dm"
+#include "code\modules\surgery\robolimbs.dm"
+#include "code\modules\surgery\surgery.dm"
#include "code\WorkInProgress\autopsy.dm"
#include "code\WorkInProgress\buildmode.dm"
#include "code\WorkInProgress\explosion_particles.dm"
-#include "code\WorkInProgress\surgery.dm"
#include "code\WorkInProgress\Cael_Aislinn\energy_field.dm"
#include "code\WorkInProgress\Cael_Aislinn\external_shield_gen.dm"
#include "code\WorkInProgress\Cael_Aislinn\meteor_battery.dm"
#include "code\WorkInProgress\Cael_Aislinn\sculpture.dm"
#include "code\WorkInProgress\Cael_Aislinn\shield_capacitor.dm"
#include "code\WorkInProgress\Cael_Aislinn\shield_gen.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Economy\Accounts.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Economy\Economy.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Economy\Economy_Events.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Economy\Economy_TradeDestinations.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Economy\EFTPOS.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\falsewall.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle_animals.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle_plants.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle_temple.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle_tribe.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle_turfs.dm"
+#include "code\WorkInProgress\Cael_Aislinn\Jungle\misc_helpers.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\areas.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\core_field.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\core_gen.dm"
@@ -1147,8 +1215,10 @@
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\SuperMatter.dm"
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\ZeroPointLaser.dm"
#include "code\WorkInProgress\Chinsky\ashtray.dm"
+#include "code\WorkInProgress\Mini\ATM.dm"
#include "code\WorkInProgress\Ported\policetape.dm"
#include "code\WorkInProgress\SkyMarshal\Ultralight_procs.dm"
+#include "code\WorkInProgress\Susan\susan_desert_turfs.dm"
#include "code\WorkInProgress\virus2\analyser.dm"
#include "code\WorkInProgress\virus2\antibodies.dm"
#include "code\WorkInProgress\virus2\base.dm"
@@ -1168,6 +1238,9 @@
#include "code\ZAS\ZAS_Zones.dm"
#include "interface\interface.dm"
#include "interface\skin.dmf"
-#include "maps\tgstation.2.0.9.1.dmm"
+#include "maps\tgstation.2.1.0.0.1.dmm"
+#include "maps\RandomZLevels\Academy.dm"
+#include "maps\RandomZLevels\challenge.dm"
#include "maps\RandomZLevels\stationCollision.dm"
+#include "maps\RandomZLevels\wildwest.dm"
// END_INCLUDE
diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm
index d745a48d89d..3c12e1f9435 100644
--- a/code/ATMOSPHERICS/atmospherics.dm
+++ b/code/ATMOSPHERICS/atmospherics.dm
@@ -12,7 +12,6 @@ Pipelines + Other Objects -> Pipe network
obj/machinery/atmospherics
anchored = 1
- use_power = 0
idle_power_usage = 0
active_power_usage = 0
power_channel = ENVIRON
diff --git a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm
index 44446589cbf..9d2a8e32e8a 100644
--- a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm
@@ -1,6 +1,7 @@
obj/machinery/atmospherics/binary
dir = SOUTH
initialize_directions = SOUTH|NORTH
+ use_power = 1
var/datum/gas_mixture/air1
var/datum/gas_mixture/air2
diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
index 1f3aae999d4..a126928e2da 100644
--- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
@@ -15,7 +15,9 @@ obj/machinery/atmospherics/binary/passive_gate
var/datum/radio_frequency/radio_connection
update_icon()
- if(node1&&node2)
+ if(stat & NOPOWER)
+ icon_state = "intact_off"
+ else if(node1 && node2)
icon_state = "intact_[on?("on"):("off")]"
else
if(node1)
@@ -24,8 +26,6 @@ obj/machinery/atmospherics/binary/passive_gate
icon_state = "exposed_2_off"
else
icon_state = "exposed_3_off"
- on = 0
-
return
process()
@@ -88,14 +88,14 @@ obj/machinery/atmospherics/binary/passive_gate
return 1
- interact(mob/user as mob)
- var/dat = {"Power: [on?"On":"Off"]
- Desirable output pressure:
- [round(target_pressure,0.1)]kPa | Change
- "}
+ interact(mob/user as mob)
+ var/dat = {"Power: [on?"On":"Off"]
+ Desirable output pressure:
+ [round(target_pressure,0.1)]kPa | Change
+ "}
- user << browse("
[src.name] control[dat]", "window=atmo_pump")
- onclose(user, "atmo_pump")
+ user << browse("[src.name] control[dat]", "window=atmo_pump")
+ onclose(user, "atmo_pump")
initialize()
..()
@@ -138,7 +138,7 @@ obj/machinery/atmospherics/binary/passive_gate
if(!src.allowed(user))
user << "\red Access denied."
return
- usr.machine = src
+ usr.set_machine(src)
interact(user)
return
@@ -149,7 +149,7 @@ obj/machinery/atmospherics/binary/passive_gate
if(href_list["set_press"])
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = max(0, min(4500, new_pressure))
- usr.machine = src
+ usr.set_machine(src)
src.update_icon()
src.updateUsrDialog()
return
diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm
index 7746d238d22..0a0a56fb747 100644
--- a/code/ATMOSPHERICS/components/binary_devices/pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm
@@ -37,7 +37,9 @@ obj/machinery/atmospherics/binary/pump
icon_state = "intact_on"
update_icon()
- if(node1&&node2)
+ if(stat & NOPOWER)
+ icon_state = "intact_off"
+ else if(node1 && node2)
icon_state = "intact_[on?("on"):("off")]"
else
if(node1)
@@ -107,14 +109,14 @@ obj/machinery/atmospherics/binary/pump
return 1
- interact(mob/user as mob)
- var/dat = {"Power: [on?"On":"Off"]
- Desirable output pressure:
- [round(target_pressure,0.1)]kPa | Change
- "}
+ interact(mob/user as mob)
+ var/dat = {"Power: [on?"On":"Off"]
+ Desirable output pressure:
+ [round(target_pressure,0.1)]kPa | Change
+ "}
- user << browse("[src.name] control[dat]", "window=atmo_pump")
- onclose(user, "atmo_pump")
+ user << browse("[src.name] control[dat]", "window=atmo_pump")
+ onclose(user, "atmo_pump")
initialize()
..()
@@ -156,7 +158,7 @@ obj/machinery/atmospherics/binary/pump
if(!src.allowed(user))
user << "\red Access denied."
return
- usr.machine = src
+ usr.set_machine(src)
interact(user)
return
@@ -167,7 +169,7 @@ obj/machinery/atmospherics/binary/pump
if(href_list["set_press"])
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = max(0, min(4500, new_pressure))
- usr.machine = src
+ usr.set_machine(src)
src.update_icon()
src.updateUsrDialog()
return
diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
index c04a927fc48..e2dddfa97c1 100644
--- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
@@ -31,7 +31,9 @@ obj/machinery/atmospherics/binary/volume_pump
icon_state = "intact_on"
update_icon()
- if(node1&&node2)
+ if(stat & NOPOWER)
+ icon_state = "intact_off"
+ else if(node1 && node2)
icon_state = "intact_[on?("on"):("off")]"
else
if(node1)
@@ -97,14 +99,14 @@ obj/machinery/atmospherics/binary/volume_pump
return 1
- interact(mob/user as mob)
- var/dat = {"Power: [on?"On":"Off"]
- Desirable output flow:
- [round(transfer_rate,1)]l/s | Change
- "}
+ interact(mob/user as mob)
+ var/dat = {"Power: [on?"On":"Off"]
+ Desirable output flow:
+ [round(transfer_rate,1)]l/s | Change
+ "}
- user << browse("[src.name] control[dat]", "window=atmo_pump")
- onclose(user, "atmo_pump")
+ user << browse("[src.name] control[dat]", "window=atmo_pump")
+ onclose(user, "atmo_pump")
@@ -147,7 +149,7 @@ obj/machinery/atmospherics/binary/volume_pump
if(!src.allowed(user))
user << "\red Access denied."
return
- usr.machine = src
+ usr.set_machine(src)
interact(user)
return
@@ -158,7 +160,7 @@ obj/machinery/atmospherics/binary/volume_pump
if(href_list["set_transfer_rate"])
var/new_transfer_rate = input(usr,"Enter new output volume (0-200l/s)","Flow control",src.transfer_rate) as num
src.transfer_rate = max(0, min(200, new_transfer_rate))
- usr.machine = src
+ usr.set_machine(src)
src.update_icon()
src.updateUsrDialog()
return
diff --git a/code/ATMOSPHERICS/components/portables_connector.dm b/code/ATMOSPHERICS/components/portables_connector.dm
index 8d7a6efb05a..9ecc82b3244 100644
--- a/code/ATMOSPHERICS/components/portables_connector.dm
+++ b/code/ATMOSPHERICS/components/portables_connector.dm
@@ -15,7 +15,7 @@
var/datum/pipe_network/network
var/on = 0
-
+ use_power = 0
level = 0
diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
index 55b0a195164..6a92f9a24bf 100755
--- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
@@ -39,16 +39,21 @@ Filter types:
..()
update_icon()
- if(node2 && node3 && node1)
+ if(stat & NOPOWER)
+ icon_state = "intact_off"
+ else if(node2 && node3 && node1)
icon_state = "intact_[on?("on"):("off")]"
else
- icon_state = "hintact_off"
+ icon_state = "intact_off"
on = 0
return
- New()
+ power_change()
+ var/old_stat = stat
..()
+ if(old_stat != stat)
+ update_icon()
process()
..()
@@ -211,7 +216,7 @@ obj/machinery/atmospherics/trinary/filter/attack_hand(user as mob) // -- TLE
obj/machinery/atmospherics/trinary/filter/Topic(href, href_list) // -- TLE
if(..())
return
- usr.machine = src
+ usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["filterset"])
src.filter_type = text2num(href_list["filterset"])
diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
index 026c3531fdf..6d532286de8 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
@@ -16,7 +16,9 @@ obj/machinery/atmospherics/trinary/mixer
//node 3 is the outlet, nodes 1 & 2 are intakes
update_icon()
- if(node2 && node3 && node1)
+ if(stat & NOPOWER)
+ icon_state = "intact_off"
+ else if(node2 && node3 && node1)
icon_state = "intact_[on?("on"):("off")]"
else
icon_state = "intact_off"
@@ -24,6 +26,12 @@ obj/machinery/atmospherics/trinary/mixer
return
+ power_change()
+ var/old_stat = stat
+ ..()
+ if(old_stat != stat)
+ update_icon()
+
New()
..()
air3.volume = 300
@@ -112,7 +120,7 @@ obj/machinery/atmospherics/trinary/mixer
if(!src.allowed(user))
user << "\red Access denied."
return
- usr.machine = src
+ usr.set_machine(src)
var/dat = {"Power: [on?"On":"Off"]
Desirable output pressure:
[target_pressure]kPa | Change
diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
index e22208b071f..d3f1116a430 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm
@@ -1,6 +1,7 @@
obj/machinery/atmospherics/trinary
dir = SOUTH
initialize_directions = SOUTH|NORTH|WEST
+ use_power = 1
var/datum/gas_mixture/air1
var/datum/gas_mixture/air2
diff --git a/code/ATMOSPHERICS/components/tvalve.dm b/code/ATMOSPHERICS/components/tvalve.dm
index 61cd0f6c6e7..5683df4bf71 100644
--- a/code/ATMOSPHERICS/components/tvalve.dm
+++ b/code/ATMOSPHERICS/components/tvalve.dm
@@ -395,7 +395,7 @@ obj/machinery/atmospherics/tvalve/mirrored
return
..()
- //Radio remote control
+ //Radio remote control -eh?
proc
set_frequency(new_frequency)
diff --git a/code/ATMOSPHERICS/components/unary/cold_sink.dm b/code/ATMOSPHERICS/components/unary/cold_sink.dm
index 32de005dc67..ef1d5f60bea 100644
--- a/code/ATMOSPHERICS/components/unary/cold_sink.dm
+++ b/code/ATMOSPHERICS/components/unary/cold_sink.dm
@@ -2,6 +2,7 @@
icon = 'icons/obj/atmospherics/cold_sink.dmi'
icon_state = "intact_off"
density = 1
+ use_power = 1
name = "Cold Sink"
desc = "Cools gas when connected to pipe network"
diff --git a/code/ATMOSPHERICS/components/unary/heat_source.dm b/code/ATMOSPHERICS/components/unary/heat_source.dm
index adfd04e15a6..01438c32d99 100644
--- a/code/ATMOSPHERICS/components/unary/heat_source.dm
+++ b/code/ATMOSPHERICS/components/unary/heat_source.dm
@@ -4,6 +4,7 @@
icon = 'icons/obj/atmospherics/cold_sink.dmi'
icon_state = "intact_off"
density = 1
+ use_power = 1
name = "Heat Reservoir"
desc = "Heats gas when connected to pipe network"
diff --git a/code/ATMOSPHERICS/components/unary/outlet_injector.dm b/code/ATMOSPHERICS/components/unary/outlet_injector.dm
index 571fc7dcb94..f070882ba82 100644
--- a/code/ATMOSPHERICS/components/unary/outlet_injector.dm
+++ b/code/ATMOSPHERICS/components/unary/outlet_injector.dm
@@ -1,6 +1,7 @@
/obj/machinery/atmospherics/unary/outlet_injector
icon = 'icons/obj/atmospherics/outlet_injector.dmi'
icon_state = "off"
+ use_power = 1
name = "Air Injector"
desc = "Has a valve and pump attached to it"
@@ -18,7 +19,7 @@
update_icon()
if(node)
- if(on)
+ if(on && !(stat & NOPOWER))
icon_state = "[level == 1 && istype(loc, /turf/simulated) ? "h" : "" ]on"
else
icon_state = "[level == 1 && istype(loc, /turf/simulated) ? "h" : "" ]off"
@@ -28,11 +29,18 @@
return
+ power_change()
+ var/old_stat = stat
+ ..()
+ if(old_stat != stat)
+ update_icon()
+
+
process()
..()
injecting = 0
- if(!on)
+ if(!on || stat & NOPOWER)
return 0
if(air_contents.temperature > 0)
diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm
index 7b9444d8902..9590a9015e8 100644
--- a/code/ATMOSPHERICS/components/unary/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm
@@ -4,6 +4,7 @@
name = "Air Vent"
desc = "Has a valve and pump attached to it"
+ use_power = 1
var/area/initial_loc
level = 1
@@ -162,6 +163,12 @@
"sigtype" = "status"
)
+ if(!initial_loc.air_vent_names[id_tag])
+ var/new_name = "[initial_loc.name] Vent Pump #[initial_loc.air_vent_names.len+1]"
+ initial_loc.air_vent_names[id_tag] = new_name
+ src.name = new_name
+ initial_loc.air_vent_info[id_tag] = signal.data
+
radio_connection.post_signal(src, signal, radio_filter_out)
return 1
@@ -183,62 +190,62 @@
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
return 0
- if("purge" in signal.data)
+ if(signal.data["purge"] != null)
pressure_checks &= ~1
pump_direction = 0
- if("stabalize" in signal.data)
+ if(signal.data["stabalize"] != null)
pressure_checks |= 1
pump_direction = 1
- if("power" in signal.data)
+ if(signal.data["power"] != null)
on = text2num(signal.data["power"])
- if("power_toggle" in signal.data)
+ if(signal.data["power_toggle"] != null)
on = !on
- if("checks" in signal.data)
+ if(signal.data["checks"] != null)
pressure_checks = text2num(signal.data["checks"])
- if("checks_toggle" in signal.data)
+ if(signal.data["checks_toggle"] != null)
pressure_checks = (pressure_checks?0:3)
- if("direction" in signal.data)
+ if(signal.data["direction"] != null)
pump_direction = text2num(signal.data["direction"])
- if("set_internal_pressure" in signal.data)
+ if(signal.data["set_internal_pressure"] != null)
internal_pressure_bound = between(
0,
text2num(signal.data["set_internal_pressure"]),
ONE_ATMOSPHERE*50
)
- if("set_external_pressure" in signal.data)
+ if(signal.data["set_external_pressure"] != null)
external_pressure_bound = between(
0,
text2num(signal.data["set_external_pressure"]),
ONE_ATMOSPHERE*50
)
- if("adjust_internal_pressure" in signal.data)
+ if(signal.data["adjust_internal_pressure"] != null)
internal_pressure_bound = between(
0,
internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),
ONE_ATMOSPHERE*50
)
- if("adjust_external_pressure" in signal.data)
+ if(signal.data["adjust_external_pressure"] != null)
external_pressure_bound = between(
0,
external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),
ONE_ATMOSPHERE*50
)
- if("init" in signal.data)
+ if(signal.data["init"] != null)
name = signal.data["init"]
return
- if("status" in signal.data)
+ if(signal.data["status"] != null)
spawn(2)
broadcast_status()
return //do not update_icon
@@ -323,8 +330,9 @@
new /obj/item/pipe(loc, make_from=src)
del(src)
- /obj/machinery/atmospherics/unary/vent_pump/Del()
- if (initial_loc.air_scrub_info)
- initial_loc.air_scrub_info -= id_tag
- ..()
- return
+/obj/machinery/atmospherics/unary/vent_pump/Del()
+ if(initial_loc)
+ initial_loc.air_vent_info -= id_tag
+ initial_loc.air_vent_names -= id_tag
+ ..()
+ return
diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
index 84378df3d14..4c386f44ec4 100644
--- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
@@ -4,6 +4,7 @@
name = "Air Scrubber"
desc = "Has a valve and pump attached to it"
+ use_power = 1
level = 1
@@ -73,6 +74,11 @@
"filter_n2o" = scrub_N2O,
"sigtype" = "status"
)
+ if(!initial_loc.air_scrub_names[id_tag])
+ var/new_name = "[initial_loc.name] Air Scrubber #[initial_loc.air_scrub_names.len+1]"
+ initial_loc.air_scrub_names[id_tag] = new_name
+ src.name = new_name
+ initial_loc.air_scrub_info[id_tag] = signal.data
radio_connection.post_signal(src, signal, radio_filter_out)
return 1
@@ -167,13 +173,13 @@
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
return 0
- if("power" in signal.data)
+ if(signal.data["power"] != null)
on = text2num(signal.data["power"])
- if("power_toggle" in signal.data)
+ if(signal.data["power_toggle"] != null)
on = !on
- if("panic_siphon" in signal.data) //must be before if("scrubbing" thing
- panic = text2num(signal.data["panic_siphon"])
+ if(signal.data["panic_siphon"]) //must be before if("scrubbing" thing
+ panic = text2num(signal.data["panic_siphon"] != null)
if(panic)
on = 1
scrubbing = 0
@@ -181,7 +187,7 @@
else
scrubbing = 1
volume_rate = initial(volume_rate)
- if("toggle_panic_siphon" in signal.data)
+ if(signal.data["toggle_panic_siphon"] != null)
panic = !panic
if(panic)
on = 1
@@ -191,31 +197,31 @@
scrubbing = 1
volume_rate = initial(volume_rate)
- if("scrubbing" in signal.data)
+ if(signal.data["scrubbing"] != null)
scrubbing = text2num(signal.data["scrubbing"])
- if("toggle_scrubbing" in signal.data)
+ if(signal.data["toggle_scrubbing"])
scrubbing = !scrubbing
- if("co2_scrub" in signal.data)
+ if(signal.data["co2_scrub"] != null)
scrub_CO2 = text2num(signal.data["co2_scrub"])
- if("toggle_co2_scrub" in signal.data)
+ if(signal.data["toggle_co2_scrub"])
scrub_CO2 = !scrub_CO2
- if("tox_scrub" in signal.data)
+ if(signal.data["tox_scrub"] != null)
scrub_Toxins = text2num(signal.data["tox_scrub"])
- if("toggle_tox_scrub" in signal.data)
+ if(signal.data["toggle_tox_scrub"])
scrub_Toxins = !scrub_Toxins
- if("n2o_scrub" in signal.data)
+ if(signal.data["n2o_scrub"] != null)
scrub_N2O = text2num(signal.data["n2o_scrub"])
- if("toggle_n2o_scrub" in signal.data)
+ if(signal.data["toggle_n2o_scrub"])
scrub_N2O = !scrub_N2O
- if("init" in signal.data)
+ if(signal.data["init"] != null)
name = signal.data["init"]
return
- if("status" in signal.data)
+ if(signal.data["status"] != null)
spawn(2)
broadcast_status()
return //do not update_icon
@@ -259,8 +265,9 @@
new /obj/item/pipe(loc, make_from=src)
del(src)
- /obj/machinery/atmospherics/unary/vent_scrubber/Del()
- if (initial_loc.air_scrub_info)
- initial_loc.air_scrub_info -= id_tag
- ..()
- return
+/obj/machinery/atmospherics/unary/vent_scrubber/Del()
+ if(initial_loc)
+ initial_loc.air_scrub_info -= id_tag
+ initial_loc.air_scrub_names -= id_tag
+ ..()
+ return
diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm
index cbff1f1b643..c9e763e8390 100644
--- a/code/ATMOSPHERICS/pipes.dm
+++ b/code/ATMOSPHERICS/pipes.dm
@@ -4,9 +4,10 @@ obj/machinery/atmospherics/pipe
var/datum/pipeline/parent
var/volume = 0
- var/force = 20
+ force = 20
layer = 2.4 //under wires with their 2.44
+ use_power = 0
var/alert_pressure = 80*ONE_ATMOSPHERE
//minimum pressure before check_pressure(...) should be called
@@ -721,7 +722,7 @@ obj/machinery/atmospherics/pipe
icon_state = "manifold_[connected]_[unconnected]"
- if(!connected)
+ if(!connected)
del(src)
return
@@ -832,7 +833,7 @@ obj/machinery/atmospherics/pipe
icon_state = "manifold-y-f"
manifold4w
- icon = 'pipe_manifold.dmi'
+ icon = 'icons/obj/atmospherics/pipe_manifold.dmi'
icon_state = "manifold4w-f"
name = "4-way pipe manifold"
@@ -841,7 +842,7 @@ obj/machinery/atmospherics/pipe
volume = 140
dir = SOUTH
- initialize_directions = EAST|NORTH|WEST|SOUTH
+ initialize_directions = NORTH|SOUTH|EAST|WEST
var/obj/machinery/atmospherics/node1
var/obj/machinery/atmospherics/node2
@@ -849,6 +850,7 @@ obj/machinery/atmospherics/pipe
var/obj/machinery/atmospherics/node4
level = 1
+ layer = 2.4 //under wires with their 2.44
hide(var/i)
if(level == 1 && istype(loc, /turf/simulated))
@@ -862,7 +864,7 @@ obj/machinery/atmospherics/pipe
if(!parent)
..()
else
- machines.Remove(src)
+ . = PROCESS_KILL
/*
if(!node1)
parent.mingle_with_turf(loc, 70)
@@ -913,14 +915,13 @@ obj/machinery/atmospherics/pipe
if(reference == node4)
if(istype(node4, /obj/machinery/atmospherics/pipe))
del(parent)
- node3 = null
+ node4 = null
update_icon()
..()
update_icon()
- overlays = new()
if(node1&&node2&&node3&&node4)
var/C = ""
switch(color)
@@ -934,7 +935,7 @@ obj/machinery/atmospherics/pipe
else
icon_state = "manifold4w_ex"
- var/icon/con = new/icon('pipe_manifold.dmi',"manifold4w_con")
+ var/icon/con = new/icon('pipe_manifold.dmi',"manifold4w_con") //Since 4-ways are supposed to be directionless, they need an overlay instead it seems.
if(node1)
overlays += new/image(con,dir=1)
@@ -950,23 +951,24 @@ obj/machinery/atmospherics/pipe
return
initialize()
+
for(var/obj/machinery/atmospherics/target in get_step(src,1))
- if(target.initialize_directions & get_dir(target,src))
+ if(target.initialize_directions & 2)
node1 = target
break
for(var/obj/machinery/atmospherics/target in get_step(src,2))
- if(target.initialize_directions & get_dir(target,src))
+ if(target.initialize_directions & 1)
node2 = target
break
for(var/obj/machinery/atmospherics/target in get_step(src,4))
- if(target.initialize_directions & get_dir(target,src))
+ if(target.initialize_directions & 8)
node3 = target
break
for(var/obj/machinery/atmospherics/target in get_step(src,8))
- if(target.initialize_directions & get_dir(target,src))
+ if(target.initialize_directions & 4)
node4 = target
break
@@ -1026,6 +1028,88 @@ obj/machinery/atmospherics/pipe
manifold4w/general/hidden
level = 1
icon_state = "manifold4w-f"
+
+ cap
+ name = "pipe endcap"
+ desc = "An endcap for pipes"
+ icon = 'pipes.dmi'
+ icon_state = "cap"
+ level = 2
+ layer = 2.4 //under wires with their 2.44
+
+ volume = 35
+
+ dir = SOUTH
+ initialize_directions = NORTH
+
+ var/obj/machinery/atmospherics/node
+
+ New()
+ ..()
+ switch(dir)
+ if(SOUTH)
+ initialize_directions = NORTH
+ if(NORTH)
+ initialize_directions = SOUTH
+ if(WEST)
+ initialize_directions = EAST
+ if(EAST)
+ initialize_directions = WEST
+
+ hide(var/i)
+ if(level == 1 && istype(loc, /turf/simulated))
+ invisibility = i ? 101 : 0
+ update_icon()
+
+ pipeline_expansion()
+ return list(node)
+
+ process()
+ if(!parent)
+ ..()
+ else
+ . = PROCESS_KILL
+ Del()
+ if(node)
+ node.disconnect(src)
+
+ ..()
+
+ disconnect(obj/machinery/atmospherics/reference)
+ if(reference == node)
+ if(istype(node, /obj/machinery/atmospherics/pipe))
+ del(parent)
+ node = null
+
+ update_icon()
+
+ ..()
+
+ update_icon()
+ overlays = new()
+
+ icon_state = "cap[invisibility ? "-f" : ""]"
+ return
+
+ initialize()
+ for(var/obj/machinery/atmospherics/target in get_step(src, dir))
+ if(target.initialize_directions & get_dir(target,src))
+ node = target
+ break
+
+ var/turf/T = src.loc // hide if turf is not intact
+ hide(T.intact)
+ //update_icon()
+ update_icon()
+
+ visible
+ level = 2
+ icon_state = "cap"
+
+ hidden
+ level = 1
+ icon_state = "cap-f"
+
obj/machinery/atmospherics/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (istype(src, /obj/machinery/atmospherics/pipe/tank))
diff --git a/code/FEA/DEBUG_REMOVE_BEFORE_RELEASE.dm b/code/FEA/DEBUG_REMOVE_BEFORE_RELEASE.dm
index 339af71e297..4c173b7b7ea 100644
--- a/code/FEA/DEBUG_REMOVE_BEFORE_RELEASE.dm
+++ b/code/FEA/DEBUG_REMOVE_BEFORE_RELEASE.dm
@@ -368,7 +368,7 @@ mob
network.marker = rand(1,4)
for(var/obj/machinery/atmospherics/pipe/P in world)
- P.overlays = null
+ P.overlays.Cut()
var/datum/pipe_network/master = P.return_network()
if(master)
@@ -378,7 +378,7 @@ mob
P.overlays += icon('icons/Testing/atmos_testing.dmi',"marker0")
for(var/obj/machinery/atmospherics/valve/V in world)
- V.overlays = null
+ V.overlays.Cut()
if(V.network_node1)
V.overlays += icon('icons/Testing/atmos_testing.dmi',"marker[V.network_node1.marker]")
@@ -396,7 +396,7 @@ turf/simulated
verb
mark_direction()
set src in world
- overlays = null
+ overlays.Cut()
for(var/direction in list(NORTH,SOUTH,EAST,WEST))
if(group_border&direction)
overlays += icon('icons/Testing/turf_analysis.dmi',"red_arrow",direction)
diff --git a/code/FEA/FEA_airgroup.dm b/code/FEA/FEA_airgroup.dm
index 00a6afc3949..94c51102b27 100644
--- a/code/FEA/FEA_airgroup.dm
+++ b/code/FEA/FEA_airgroup.dm
@@ -62,6 +62,9 @@ datum/air_group
proc/check_regroup()
//Purpose: Checks to see if group processing should be turned back on
//Returns: group_processing
+ if(prevent_airgroup_regroup)
+ return 0
+
if(group_processing) return 1
var/turf/simulated/sample = pick(members)
@@ -90,7 +93,8 @@ datum/air_group
if (next_check > 0)
next_check--
return 1
- next_check += check_delay + rand(max(check_delay, 1)/2,check_delay)
+ var/player_count = max(player_list.len, 3) / 3
+ next_check += check_delay + rand(player_count, player_count * 1.5)
check_delay++
var/turf/simulated/list/border_individual = list()
diff --git a/code/FEA/FEA_fire.dm b/code/FEA/FEA_fire.dm
index d28df56a340..bb71f31d47f 100644
--- a/code/FEA/FEA_fire.dm
+++ b/code/FEA/FEA_fire.dm
@@ -45,7 +45,6 @@
return igniting
-
//This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile
/obj/effect/hotspot
anchored = 1
@@ -62,101 +61,118 @@
var/bypassing = 0
- proc/perform_exposure()
- var/turf/simulated/floor/location = loc
- if(!istype(location)) return 0
+/obj/effect/hotspot/proc/perform_exposure()
+ var/turf/simulated/floor/location = loc
+ if(!istype(location)) return 0
- if(volume > CELL_VOLUME*0.95) bypassing = 1
- else bypassing = 0
+ if(volume > CELL_VOLUME*0.95) bypassing = 1
+ else bypassing = 0
- if(bypassing)
- if(!just_spawned)
- volume = location.air.fuel_burnt*FIRE_GROWTH_RATE
- temperature = location.air.temperature
- else
- var/datum/gas_mixture/affected = location.air.remove_ratio(volume/location.air.volume)
- affected.temperature = temperature
- affected.react()
- temperature = affected.temperature
- volume = affected.fuel_burnt*FIRE_GROWTH_RATE
- location.assume_air(affected)
+ if(bypassing)
+ if(!just_spawned)
+ volume = location.air.fuel_burnt*FIRE_GROWTH_RATE
+ temperature = location.air.temperature
+ else
+ var/datum/gas_mixture/affected = location.air.remove_ratio(volume/location.air.volume)
+ affected.temperature = temperature
+ affected.react()
+ temperature = affected.temperature
+ volume = affected.fuel_burnt*FIRE_GROWTH_RATE
+ location.assume_air(affected)
- for(var/atom/item in loc)
- item.temperature_expose(null, temperature, volume)
+ for(var/atom/item in loc)
+ if(!bypassing)
+ item.temperature_expose(null, temperature, volume)
+ if(item) // It's possible that the item is deleted in temperature_expose
+ item.fire_act(null, temperature, volume)
+
+ return 0
+
+
+/obj/effect/hotspot/process(turf/simulated/list/possible_spread)
+ if(just_spawned)
+ just_spawned = 0
return 0
+ var/turf/simulated/floor/location = loc
+ if(!istype(location))
+ Kill()
+ return
- process(turf/simulated/list/possible_spread)
- if(just_spawned)
- just_spawned = 0
- return 0
+ if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
+ Kill()
+ return
- var/turf/simulated/floor/location = loc
- if(!istype(location))
- del(src)
+ if(location.air.toxins < 0.5 || location.air.oxygen < 0.5)
+ Kill()
+ return
- if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
- del(src)
+ perform_exposure()
- if(location.air.toxins < 0.5 || location.air.oxygen < 0.5)
- del(src)
+ if(location.wet) location.wet = 0
- perform_exposure()
+ if(bypassing)
+ icon_state = "3"
+ location.burn_tile()
- if(location.wet) location.wet = 0
+ //Possible spread due to radiated heat
+ if(location.air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD)
+ var/radiated_temperature = location.air.temperature*FIRE_SPREAD_RADIOSITY_SCALE
- if(bypassing)
- icon_state = "3"
- location.burn_tile()
-
- //Possible spread due to radiated heat
- if(location.air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD)
- var/radiated_temperature = location.air.temperature*FIRE_SPREAD_RADIOSITY_SCALE
-
- for(var/turf/simulated/possible_target in possible_spread)
- if(!possible_target.active_hotspot)
- possible_target.hotspot_expose(radiated_temperature, CELL_VOLUME/4)
+ for(var/turf/simulated/possible_target in possible_spread)
+ if(!possible_target.active_hotspot)
+ possible_target.hotspot_expose(radiated_temperature, CELL_VOLUME/4)
+ else
+ if(volume > CELL_VOLUME*0.4)
+ icon_state = "2"
else
- if(volume > CELL_VOLUME*0.4)
- icon_state = "2"
+ icon_state = "1"
+
+ if(temperature > location.max_fire_temperature_sustained)
+ location.max_fire_temperature_sustained = temperature
+
+ if(location.heat_capacity && temperature > location.heat_capacity)
+ location.to_be_destroyed = 1
+ /*if(prob(25))
+ location.ReplaceWithSpace()
+ return 0*/
+ return 1
+
+// Garbage collect itself by nulling reference to it
+
+/obj/effect/hotspot/proc/Kill()
+ DestroyTurf()
+ if(istype(loc, /turf/simulated))
+ var/turf/simulated/T = loc
+ if(T.active_hotspot == src)
+ T.active_hotspot = null
+ loc = null
+
+/obj/effect/hotspot/proc/DestroyTurf()
+
+ if(istype(loc, /turf/simulated))
+ var/turf/simulated/T = loc
+ if(T.to_be_destroyed)
+ var/chance_of_deletion
+ if (T.heat_capacity) //beware of division by zero
+ chance_of_deletion = T.max_fire_temperature_sustained / T.heat_capacity * 8 //there is no problem with prob(23456), min() was redundant --rastaf0
else
- icon_state = "1"
+ chance_of_deletion = 100
+ if(prob(chance_of_deletion))
+ T.ChangeTurf(/turf/space)
+ else
+ T.to_be_destroyed = 0
+ T.max_fire_temperature_sustained = 0
- if(temperature > location.max_fire_temperature_sustained)
- location.max_fire_temperature_sustained = temperature
+/obj/effect/hotspot/New()
+ ..()
+ dir = pick(cardinal)
+ return
- if(temperature > location.heat_capacity)
- location.to_be_destroyed = 1
- /*if(prob(25))
- location.ReplaceWithSpace()
- return 0*/
- return 1
-
-
- New()
- ..()
- dir = pick(cardinal)
- return
-
-
- Del()
- if (istype(loc, /turf/simulated))
- var/turf/simulated/T = loc
- loc:active_hotspot = null
-
- if(T.to_be_destroyed)
- var/chance_of_deletion
- if (T.heat_capacity) //beware of division by zero
- chance_of_deletion = T.max_fire_temperature_sustained / T.heat_capacity * 8 //there is no problem with prob(23456), min() was redundant --rastaf0
- else
- chance_of_deletion = 100
- if(prob(chance_of_deletion))
- T.ReplaceWithSpace()
- else
- T.to_be_destroyed = 0
- T.max_fire_temperature_sustained = 0
-
- loc = null
- ..()
- return
+/*
+/obj/effect/hotspot/Del()
+ if (istype(loc, /turf/simulated))
+ DestroyTurf()
+ ..()
+*/
\ No newline at end of file
diff --git a/code/FEA/FEA_gas_mixture.dm b/code/FEA/FEA_gas_mixture.dm
index 9d609e673e7..6beeffc1870 100644
--- a/code/FEA/FEA_gas_mixture.dm
+++ b/code/FEA/FEA_gas_mixture.dm
@@ -23,11 +23,10 @@ What are the archived variables for?
volatile_fuel
specific_heat = 30
- var
- moles = 0
- specific_heat = 0
+ var/moles = 0
+ var/specific_heat = 0
- moles_archived = 0
+ var/moles_archived = 0
/datum/gas_mixture
diff --git a/code/FEA/FEA_turf_tile.dm b/code/FEA/FEA_turf_tile.dm
index d043e348245..981d0b023c5 100644
--- a/code/FEA/FEA_turf_tile.dm
+++ b/code/FEA/FEA_turf_tile.dm
@@ -1,6 +1,6 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
-atom/movable/var/pressure_resistance = 20
+atom/movable/var/pressure_resistance = 5
atom/movable/var/last_forced_movement = 0
atom/movable/proc/experience_pressure_difference(pressure_difference, direction)
@@ -47,529 +47,514 @@ turf
turf
var/pressure_difference = 0
var/pressure_direction = 0
+ var/reporting_pressure_difference
//optimization vars
var/next_check = 0 //number of ticks before this tile updates
var/check_delay = 0 //number of ticks between updates
- proc
- high_pressure_movements()
+ proc/high_pressure_movements()
+ if(reporting_pressure_difference)
+ world << "pressure_difference = [pressure_difference]; pressure_direction = [pressure_direction]"
+ for(var/atom/movable/in_tile in src)
+ in_tile.experience_pressure_difference(pressure_difference, pressure_direction)
- for(var/atom/movable/in_tile in src)
- in_tile.experience_pressure_difference(pressure_difference, pressure_direction)
+ pressure_difference = 0
- pressure_difference = 0
+ proc/consider_pressure_difference(connection_difference, connection_direction)
+ if(connection_difference < 0)
+ connection_difference = -connection_difference
+ connection_direction = turn(connection_direction,180)
- consider_pressure_difference(connection_difference, connection_direction)
- if(connection_difference < 0)
- connection_difference = -connection_difference
- connection_direction = turn(connection_direction,180)
+ if(connection_difference > pressure_difference)
+ if(!pressure_difference)
+ air_master.high_pressure_delta += src
+ pressure_difference = connection_difference
+ pressure_direction = connection_direction
- if(connection_difference > pressure_difference)
+turf/simulated/proc/consider_pressure_difference_space(connection_difference)
+ for(var/direction in cardinal)
+ if(direction&group_border)
+ if(istype(get_step(src,direction),/turf/space))
if(!pressure_difference)
air_master.high_pressure_delta += src
+ pressure_direction = direction
pressure_difference = connection_difference
- pressure_direction = connection_direction
-
- simulated
- proc
- consider_pressure_difference_space(connection_difference)
- for(var/direction in cardinal)
- if(direction&group_border)
- if(istype(get_step(src,direction),/turf/space))
- if(!pressure_difference)
- air_master.high_pressure_delta += src
- pressure_direction = direction
- pressure_difference = connection_difference
- return 1
+ return 1
-turf
- simulated
+turf/simulated
- var/current_graphic = null
+ var/current_graphic = null
- var/tmp/datum/gas_mixture/air
+ var/tmp/datum/gas_mixture/air
- var/tmp/processing = 1
- var/tmp/datum/air_group/turf/parent
- var/tmp/group_border = 0
- var/tmp/length_space_border = 0
+ var/tmp/processing = 1
+ var/tmp/datum/air_group/turf/parent
+ var/tmp/group_border = 0
+ var/tmp/length_space_border = 0
- var/tmp/air_check_directions = 0 //Do not modify this, just add turf to air_master.tiles_to_update
+ var/tmp/air_check_directions = 0 //Do not modify this, just add turf to air_master.tiles_to_update
- var/tmp/archived_cycle = 0
- var/tmp/current_cycle = 0
+ var/tmp/archived_cycle = 0
+ var/tmp/current_cycle = 0
- var/tmp/obj/effect/hotspot/active_hotspot
+ var/tmp/obj/effect/hotspot/active_hotspot
- var/tmp/temperature_archived //USED ONLY FOR SOLIDS
- var/tmp/being_superconductive = 0
+ var/tmp/temperature_archived //USED ONLY FOR SOLIDS
+ var/tmp/being_superconductive = 0
+ proc/update_visuals(datum/gas_mixture/model)
+ overlays.Cut()
- proc
- process_cell()
- update_air_properties()
- archive()
+ var/siding_icon_state = return_siding_icon_state()
+ if(siding_icon_state)
+ overlays += image('icons/turf/floors.dmi',siding_icon_state)
- mimic_air_with_tile(turf/model)
- share_air_with_tile(turf/simulated/sharer)
-
- mimic_temperature_with_tile(turf/model)
- share_temperature_with_tile(turf/simulated/sharer)
-
-
- super_conduct()
-
- update_visuals(datum/gas_mixture/model)
- overlays = null
-
- var/siding_icon_state = return_siding_icon_state()
- if(siding_icon_state)
- overlays += image('icons/turf/floors.dmi',siding_icon_state)
-
- switch(model.graphic)
- if("plasma")
- overlays.Add(plmaster)
- if("sleeping_agent")
- overlays.Add(slmaster)
+ switch(model.graphic)
+ if("plasma")
+ overlays.Add(plmaster)
+ if("sleeping_agent")
+ overlays.Add(slmaster)
- New()
- ..()
+ New()
+ ..()
- if(!blocks_air)
- air = new
+ if(!blocks_air)
+ air = new
- air.oxygen = oxygen
- air.carbon_dioxide = carbon_dioxide
- air.nitrogen = nitrogen
- air.toxins = toxins
+ air.oxygen = oxygen
+ air.carbon_dioxide = carbon_dioxide
+ air.nitrogen = nitrogen
+ air.toxins = toxins
- air.temperature = temperature
+ air.temperature = temperature
- if(air_master)
- air_master.tiles_to_update.Add(src)
+ if(air_master)
+ air_master.tiles_to_update.Add(src)
- find_group()
+ find_group()
// air.parent = src //TODO DEBUG REMOVE
- else
- if(air_master)
- for(var/direction in cardinal)
- var/turf/simulated/floor/target = get_step(src,direction)
- if(istype(target))
- air_master.tiles_to_update.Add(target)
-
- Del()
+ else
if(air_master)
- if(parent)
- air_master.groups_to_rebuild.Add(parent)
- parent.members.Remove(src)
- else
- air_master.active_singletons.Remove(src)
- if(active_hotspot)
- del(active_hotspot)
- if(blocks_air)
- for(var/direction in list(NORTH, SOUTH, EAST, WEST))
- var/turf/simulated/tile = get_step(src,direction)
- if(istype(tile) && !tile.blocks_air)
- air_master.tiles_to_update.Add(tile)
- ..()
-
- assume_air(datum/gas_mixture/giver)
- if(!giver) return 0
- var/datum/gas_mixture/receiver = air
- if(istype(receiver))
- if(parent&&parent.group_processing)
- if(!parent.air.check_then_merge(giver))
- parent.suspend_group_processing()
- air.merge(giver)
- else
- if (giver.total_moles() > MINIMUM_AIR_TO_SUSPEND)
- reset_delay()
-
- air.merge(giver)
-
- if(!processing)
- if(air.check_tile_graphic())
- update_visuals(air)
-
- return 1
-
- else return ..()
-
- archive()
- if(air) //For open space like floors
- air.archive()
-
- temperature_archived = temperature
- archived_cycle = air_master.current_cycle
-
- share_air_with_tile(turf/simulated/T)
- return air.share(T.air)
-
- mimic_air_with_tile(turf/T)
- return air.mimic(T)
-
- return_air()
- if(air)
- if(parent&&parent.group_processing)
- return parent.air
- else return air
-
- else
- return ..()
-
- remove_air(amount as num)
- if(air)
- var/datum/gas_mixture/removed = null
-
- if(parent&&parent.group_processing)
- removed = parent.air.check_then_remove(amount)
- if(!removed)
- parent.suspend_group_processing()
- removed = air.remove(amount)
- else
- removed = air.remove(amount)
-
- if(!processing)
- if(air.check_tile_graphic())
- update_visuals(air)
-
- return removed
-
- else
- return ..()
-
- update_air_properties()//OPTIMIZE
- air_check_directions = 0
-
- for(var/direction in cardinal)
- if(CanPass(null, get_step(src,direction), 0, 0))
- air_check_directions |= direction
+ for(var/direction in cardinal)
+ var/turf/simulated/floor/target = get_step(src,direction)
+ if(istype(target))
+ air_master.tiles_to_update.Add(target)
+ Del()
+ if(air_master)
if(parent)
- if(parent.borders)
- parent.borders -= src
- if(length_space_border > 0)
- parent.length_space_border -= length_space_border
- length_space_border = 0
-
- group_border = 0
- for(var/direction in cardinal)
- if(air_check_directions&direction)
- var/turf/simulated/T = get_step(src,direction)
-
- //See if actually a border
- if(!istype(T) || (T.parent!=parent))
-
- //See what kind of border it is
- if(istype(T,/turf/space))
- if(parent.space_borders)
- parent.space_borders -= src
- parent.space_borders += src
- else
- parent.space_borders = list(src)
- length_space_border++
-
- else
- if(parent.borders)
- parent.borders -= src
- parent.borders += src
- else
- parent.borders = list(src)
-
- group_border |= direction
-
- parent.length_space_border += length_space_border
-
- if(air_check_directions)
- processing = 1
- if(!parent)
- air_master.add_singleton(src)
+ air_master.groups_to_rebuild.Add(parent)
+ parent.members.Remove(src)
else
- processing = 0
+ air_master.active_singletons.Remove(src)
+ if(active_hotspot)
+ active_hotspot.Kill()
+ if(blocks_air)
+ for(var/direction in list(NORTH, SOUTH, EAST, WEST))
+ var/turf/simulated/tile = get_step(src,direction)
+ if(istype(tile) && !tile.blocks_air)
+ air_master.tiles_to_update.Add(tile)
+ ..()
- process_cell()
- //this proc does all the heavy lifting for individual tile processing
- //it shares with all of its neighbors, spreads fire, calls superconduction
- //and doesn't afraid of anything
-
- //check if we're skipping this tick
- if (next_check > 0)
- next_check--
- return 1
- next_check += check_delay + rand(max(check_delay, 1)/2,check_delay)
- check_delay++
-
- var/turf/simulated/list/possible_fire_spreads = list()
- if(processing)
- if(archived_cycle < air_master.current_cycle) //archive self if not already done
- archive()
- current_cycle = air_master.current_cycle
-
- for(var/direction in cardinal)
- if(air_check_directions&direction) //Grab all valid bordering tiles
- var/turf/simulated/enemy_tile = get_step(src, direction)
- var/connection_difference = 0
-
- if(istype(enemy_tile)) //enemy_tile == neighbor, btw
- if(enemy_tile.archived_cycle < archived_cycle) //archive bordering tile information if not already done
- enemy_tile.archive()
-
- if (air && enemy_tile.air)
- var/delay_trigger = air.compare(enemy_tile.air)
- if (!delay_trigger) //if compare() didn't return 1, air is different enough to trigger processing
- reset_delay()
- enemy_tile.reset_delay()
-
- if(enemy_tile.parent && enemy_tile.parent.group_processing) //apply tile to group sharing
- if(enemy_tile.parent.current_cycle < current_cycle) //if the group hasn't been archived, it could just be out of date
- if(enemy_tile.parent.air.check_gas_mixture(air))
- connection_difference = air.share(enemy_tile.parent.air)
- else
- enemy_tile.parent.suspend_group_processing()
- connection_difference = air.share(enemy_tile.air)
- //group processing failed so interact with individual tile
-
- else
- if(enemy_tile.current_cycle < current_cycle)
- connection_difference = air.share(enemy_tile.air)
-
- if(active_hotspot)
- possible_fire_spreads += enemy_tile
- else
-/* var/obj/movable/floor/movable_on_enemy = locate(/obj/movable/floor) in enemy_tile
-
- if(movable_on_enemy)
- if(movable_on_enemy.parent && movable_on_enemy.parent.group_processing) //apply tile to group sharing
- if(movable_on_enemy.parent.current_cycle < current_cycle)
- if(movable_on_enemy.parent.air.check_gas_mixture(air))
- connection_difference = air.share(movable_on_enemy.parent.air)
-
- else
- movable_on_enemy.parent.suspend_group_processing()
-
- if(movable_on_enemy.archived_cycle < archived_cycle) //archive bordering tile information if not already done
- movable_on_enemy.archive()
- connection_difference = air.share(movable_on_enemy.air)
- //group processing failed so interact with individual tile
- else
- if(movable_on_enemy.archived_cycle < archived_cycle) //archive bordering tile information if not already done
- movable_on_enemy.archive()
-
- if(movable_on_enemy.current_cycle < current_cycle)
- connection_difference = share_air_with_tile(movable_on_enemy)
-
- else*/
- connection_difference = mimic_air_with_tile(enemy_tile)
- //bordering a tile with fixed air properties
-
- if(connection_difference)
- if(connection_difference > 0)
- consider_pressure_difference(connection_difference, direction)
- else
- enemy_tile.consider_pressure_difference(connection_difference, direction)
+ assume_air(datum/gas_mixture/giver)
+ if(!giver) return 0
+ var/datum/gas_mixture/receiver = air
+ if(istype(receiver))
+ if(parent&&parent.group_processing)
+ if(!parent.air.check_then_merge(giver))
+ parent.suspend_group_processing()
+ air.merge(giver)
else
- air_master.active_singletons -= src //not active if not processing!
+ if (giver.total_moles() > MINIMUM_AIR_TO_SUSPEND)
+ reset_delay()
- air.react()
+ air.merge(giver)
- if(active_hotspot)
- if (!active_hotspot.process(possible_fire_spreads))
- return 0
-
- if(air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION)
- consider_superconductivity(starting = 1)
-
- if(air.check_tile_graphic())
- update_visuals(air)
-
- if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
- reset_delay() //hotspots always process quickly
- hotspot_expose(air.temperature, CELL_VOLUME)
- for(var/atom/movable/item in src)
- item.temperature_expose(air, air.temperature, CELL_VOLUME)
- temperature_expose(air, air.temperature, CELL_VOLUME)
+ if(!processing)
+ if(air.check_tile_graphic())
+ update_visuals(air)
return 1
- super_conduct()
- var/conductivity_directions = 0
- if(blocks_air)
- //Does not participate in air exchange, so will conduct heat across all four borders at this time
- conductivity_directions = NORTH|SOUTH|EAST|WEST
+ else return ..()
- if(archived_cycle < air_master.current_cycle)
- archive()
+ proc/archive()
+ if(air) //For open space like floors
+ air.archive()
+ temperature_archived = temperature
+ archived_cycle = air_master.current_cycle
+
+ proc/share_air_with_tile(turf/simulated/T)
+ return air.share(T.air)
+
+ proc/mimic_air_with_tile(turf/T)
+ return air.mimic(T)
+
+ return_air()
+ if(air)
+ if(parent&&parent.group_processing)
+ return parent.air
+ else return air
+
+ else
+ return ..()
+
+ remove_air(amount as num)
+ if(air)
+ var/datum/gas_mixture/removed = null
+
+ if(parent&&parent.group_processing)
+ removed = parent.air.check_then_remove(amount)
+ if(!removed)
+ parent.suspend_group_processing()
+ removed = air.remove(amount)
else
- //Does particate in air exchange so only consider directions not considered during process_cell()
- conductivity_directions = ~air_check_directions & (NORTH|SOUTH|EAST|WEST)
+ removed = air.remove(amount)
- if(conductivity_directions>0)
- //Conduct with tiles around me
- for(var/direction in cardinal)
- if(conductivity_directions&direction)
- var/turf/neighbor = get_step(src,direction)
+ if(!processing)
+ if(air.check_tile_graphic())
+ update_visuals(air)
- if(istype(neighbor, /turf/simulated)) //anything under this subtype will share in the exchange
- var/turf/simulated/modeled_neighbor = neighbor
+ return removed
- if(modeled_neighbor.archived_cycle < air_master.current_cycle)
- modeled_neighbor.archive()
+ else
+ return ..()
- if(modeled_neighbor.air)
- if(air) //Both tiles are open
+ proc/update_air_properties()//OPTIMIZE
+ air_check_directions = 0
- if(modeled_neighbor.parent && modeled_neighbor.parent.group_processing)
- if(parent && parent.group_processing)
- //both are acting as a group
- //modified using construct developed in datum/air_group/share_air_with_group(...)
+ for(var/direction in cardinal)
+ if(CanPass(null, get_step(src,direction), 0, 0))
+ air_check_directions |= direction
- var/result = parent.air.check_both_then_temperature_share(modeled_neighbor.parent.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
- if(result==0)
- //have to deconstruct parent air group
+ if(parent)
+ if(parent.borders)
+ parent.borders -= src
+ if(length_space_border > 0)
+ parent.length_space_border -= length_space_border
+ length_space_border = 0
- parent.suspend_group_processing()
- if(!modeled_neighbor.parent.air.check_me_then_temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT))
- //may have to deconstruct neighbors air group
+ group_border = 0
+ for(var/direction in cardinal)
+ if(air_check_directions&direction)
+ var/turf/simulated/T = get_step(src,direction)
- modeled_neighbor.parent.suspend_group_processing()
- air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
- else if(result==-1)
- // have to deconstruct neightbors air group but not mine
-
- modeled_neighbor.parent.suspend_group_processing()
- parent.air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
- else
- air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
- else
- if(parent && parent.group_processing)
- if(!parent.air.check_me_then_temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT))
- //may have to deconstruct neighbors air group
-
- parent.suspend_group_processing()
- air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
-
- else
- air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
- // world << "OPEN, OPEN"
-
- else //Solid but neighbor is open
- if(modeled_neighbor.parent && modeled_neighbor.parent.group_processing)
- if(!modeled_neighbor.parent.air.check_me_then_temperature_turf_share(src, modeled_neighbor.thermal_conductivity))
-
- modeled_neighbor.parent.suspend_group_processing()
- modeled_neighbor.air.temperature_turf_share(src, modeled_neighbor.thermal_conductivity)
- else
- modeled_neighbor.air.temperature_turf_share(src, modeled_neighbor.thermal_conductivity)
- // world << "SOLID, OPEN"
+ //See if actually a border
+ if(!istype(T) || (T.parent!=parent))
+ //See what kind of border it is
+ if(istype(T,/turf/space))
+ if(parent.space_borders)
+ parent.space_borders -= src
+ parent.space_borders += src
else
- if(air) //Open but neighbor is solid
- if(parent && parent.group_processing)
- if(!parent.air.check_me_then_temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity))
- parent.suspend_group_processing()
- air.temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity)
- else
- air.temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity)
- // world << "OPEN, SOLID"
-
- else //Both tiles are solid
- share_temperature_mutual_solid(modeled_neighbor, modeled_neighbor.thermal_conductivity)
- // world << "SOLID, SOLID"
-
- modeled_neighbor.consider_superconductivity()
+ parent.space_borders = list(src)
+ length_space_border++
else
- if(air) //Open
- if(parent && parent.group_processing)
- if(!parent.air.check_me_then_temperature_mimic(neighbor, neighbor.thermal_conductivity))
- parent.suspend_group_processing()
- air.temperature_mimic(neighbor, neighbor.thermal_conductivity)
- else
- air.temperature_mimic(neighbor, neighbor.thermal_conductivity)
+ if(parent.borders)
+ parent.borders -= src
+ parent.borders += src
else
- mimic_temperature_solid(neighbor, neighbor.thermal_conductivity)
+ parent.borders = list(src)
- //Radiate excess tile heat to space
- if(temperature > T0C)
- // Is there a pre-defined Space Tile?
- if(!Space_Tile)
- Space_Tile = locate(/turf/space) // Define one
- //Considering 0 degC as te break even point for radiation in and out
- mimic_temperature_solid(Space_Tile, FLOOR_HEAT_TRANSFER_COEFFICIENT)
+ group_border |= direction
- //Conduct with air on my tile if I have it
- if(air)
- if(parent && parent.group_processing)
- if(!parent.air.check_me_then_temperature_turf_share(src, thermal_conductivity))
- parent.suspend_group_processing()
- air.temperature_turf_share(src, thermal_conductivity)
- else
- air.temperature_turf_share(src, thermal_conductivity)
+ parent.length_space_border += length_space_border
+ if(air_check_directions)
+ processing = 1
+ if(!parent)
+ air_master.add_singleton(src)
+ else
+ processing = 0
- //Make sure still hot enough to continue conducting heat
- if(air)
- if(air.temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
- being_superconductive = 0
- air_master.active_super_conductivity -= src
- return 0
+ proc/process_cell()
+ //this proc does all the heavy lifting for individual tile processing
+ //it shares with all of its neighbors, spreads fire, calls superconduction
+ //and doesn't afraid of anything
+ //Comment by errorage: In other words, this is the proc that lags the game.
- else
- if(temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
- being_superconductive = 0
- air_master.active_super_conductivity -= src
- return 0
+ //check if we're skipping this tick
+ if (next_check > 0)
+ next_check--
+ return 1
+ var/player_count = max(player_list.len, 3) / 3
+ next_check += check_delay + rand(player_count, player_count * 1.5)
+ check_delay++
- proc/mimic_temperature_solid(turf/model, conduction_coefficient)
- var/delta_temperature = (temperature_archived - model.temperature)
- if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER))
+ var/turf/simulated/list/possible_fire_spreads = list()
+ if(processing)
+ if(archived_cycle < air_master.current_cycle) //archive self if not already done
+ archive()
+ current_cycle = air_master.current_cycle
- var/heat = conduction_coefficient*delta_temperature* \
- (heat_capacity*model.heat_capacity/(heat_capacity+model.heat_capacity))
- temperature -= heat/heat_capacity
+ for(var/direction in cardinal)
+ if(air_check_directions&direction) //Grab all valid bordering tiles
+ var/turf/simulated/enemy_tile = get_step(src, direction)
+ var/connection_difference = 0
- proc/share_temperature_mutual_solid(turf/simulated/sharer, conduction_coefficient)
- var/delta_temperature = (temperature_archived - sharer.temperature_archived)
- if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER && heat_capacity && sharer.heat_capacity)
+ if(istype(enemy_tile)) //enemy_tile == neighbor, btw
+ if(enemy_tile.archived_cycle < archived_cycle) //archive bordering tile information if not already done
+ enemy_tile.archive()
- var/heat = conduction_coefficient*delta_temperature* \
- (heat_capacity*sharer.heat_capacity/(heat_capacity+sharer.heat_capacity))
+ if (air && enemy_tile.air)
+ var/delay_trigger = air.compare(enemy_tile.air)
+ if (!delay_trigger) //if compare() didn't return 1, air is different enough to trigger processing
+ reset_delay()
+ enemy_tile.reset_delay()
- temperature -= heat/heat_capacity
- sharer.temperature += heat/sharer.heat_capacity
+ if(enemy_tile.parent && enemy_tile.parent.group_processing) //apply tile to group sharing
+ if(enemy_tile.parent.current_cycle < current_cycle) //if the group hasn't been archived, it could just be out of date
+ if(enemy_tile.parent.air.check_gas_mixture(air))
+ connection_difference = air.share(enemy_tile.parent.air)
+ else
+ enemy_tile.parent.suspend_group_processing()
+ connection_difference = air.share(enemy_tile.air)
+ //group processing failed so interact with individual tile
- proc/consider_superconductivity(starting)
+ else
+ if(enemy_tile.current_cycle < current_cycle)
+ connection_difference = air.share(enemy_tile.air)
- if(being_superconductive || !thermal_conductivity)
+ if(active_hotspot)
+ possible_fire_spreads += enemy_tile
+ else
+/* var/obj/movable/floor/movable_on_enemy = locate(/obj/movable/floor) in enemy_tile
+
+ if(movable_on_enemy)
+ if(movable_on_enemy.parent && movable_on_enemy.parent.group_processing) //apply tile to group sharing
+ if(movable_on_enemy.parent.current_cycle < current_cycle)
+ if(movable_on_enemy.parent.air.check_gas_mixture(air))
+ connection_difference = air.share(movable_on_enemy.parent.air)
+
+ else
+ movable_on_enemy.parent.suspend_group_processing()
+
+ if(movable_on_enemy.archived_cycle < archived_cycle) //archive bordering tile information if not already done
+ movable_on_enemy.archive()
+ connection_difference = air.share(movable_on_enemy.air)
+ //group processing failed so interact with individual tile
+ else
+ if(movable_on_enemy.archived_cycle < archived_cycle) //archive bordering tile information if not already done
+ movable_on_enemy.archive()
+
+ if(movable_on_enemy.current_cycle < current_cycle)
+ connection_difference = share_air_with_tile(movable_on_enemy)
+
+ else*/
+ connection_difference = mimic_air_with_tile(enemy_tile)
+ //bordering a tile with fixed air properties
+
+ if(connection_difference)
+ if(connection_difference > 0)
+ consider_pressure_difference(connection_difference, direction)
+ else
+ enemy_tile.consider_pressure_difference(connection_difference, direction)
+ else
+ air_master.active_singletons -= src //not active if not processing!
+
+ air.react()
+
+ if(active_hotspot)
+ if (!active_hotspot.process(possible_fire_spreads))
return 0
- if(air)
- if(air.temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
- return 0
- if(air.heat_capacity() < MOLES_CELLSTANDARD*0.1*0.05)
- return 0
+ if(air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION)
+ consider_superconductivity(starting = 1)
+
+ if(air.check_tile_graphic())
+ update_visuals(air)
+
+ if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
+ reset_delay() //hotspots always process quickly
+ hotspot_expose(air.temperature, CELL_VOLUME)
+ for(var/atom/movable/item in src)
+ item.temperature_expose(air, air.temperature, CELL_VOLUME)
+ temperature_expose(air, air.temperature, CELL_VOLUME)
+
+ return 1
+
+ proc/super_conduct()
+ var/conductivity_directions = 0
+ if(blocks_air)
+ //Does not participate in air exchange, so will conduct heat across all four borders at this time
+ conductivity_directions = NORTH|SOUTH|EAST|WEST
+
+ if(archived_cycle < air_master.current_cycle)
+ archive()
+
+ else
+ //Does particate in air exchange so only consider directions not considered during process_cell()
+ conductivity_directions = ~air_check_directions & (NORTH|SOUTH|EAST|WEST)
+
+ if(conductivity_directions>0)
+ //Conduct with tiles around me
+ for(var/direction in cardinal)
+ if(conductivity_directions&direction)
+ var/turf/neighbor = get_step(src,direction)
+
+ if(istype(neighbor, /turf/simulated)) //anything under this subtype will share in the exchange
+ var/turf/simulated/modeled_neighbor = neighbor
+
+ if(modeled_neighbor.archived_cycle < air_master.current_cycle)
+ modeled_neighbor.archive()
+
+ if(modeled_neighbor.air)
+ if(air) //Both tiles are open
+
+ if(modeled_neighbor.parent && modeled_neighbor.parent.group_processing)
+ if(parent && parent.group_processing)
+ //both are acting as a group
+ //modified using construct developed in datum/air_group/share_air_with_group(...)
+
+ var/result = parent.air.check_both_then_temperature_share(modeled_neighbor.parent.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
+ if(result==0)
+ //have to deconstruct parent air group
+
+ parent.suspend_group_processing()
+ if(!modeled_neighbor.parent.air.check_me_then_temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT))
+ //may have to deconstruct neighbors air group
+
+ modeled_neighbor.parent.suspend_group_processing()
+ air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
+ else if(result==-1)
+ // have to deconstruct neightbors air group but not mine
+
+ modeled_neighbor.parent.suspend_group_processing()
+ parent.air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
+ else
+ air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
+ else
+ if(parent && parent.group_processing)
+ if(!parent.air.check_me_then_temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT))
+ //may have to deconstruct neighbors air group
+
+ parent.suspend_group_processing()
+ air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
+
+ else
+ air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
+ // world << "OPEN, OPEN"
+
+ else //Solid but neighbor is open
+ if(modeled_neighbor.parent && modeled_neighbor.parent.group_processing)
+ if(!modeled_neighbor.parent.air.check_me_then_temperature_turf_share(src, modeled_neighbor.thermal_conductivity))
+
+ modeled_neighbor.parent.suspend_group_processing()
+ modeled_neighbor.air.temperature_turf_share(src, modeled_neighbor.thermal_conductivity)
+ else
+ modeled_neighbor.air.temperature_turf_share(src, modeled_neighbor.thermal_conductivity)
+ // world << "SOLID, OPEN"
+
+ else
+ if(air) //Open but neighbor is solid
+ if(parent && parent.group_processing)
+ if(!parent.air.check_me_then_temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity))
+ parent.suspend_group_processing()
+ air.temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity)
+ else
+ air.temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity)
+ // world << "OPEN, SOLID"
+
+ else //Both tiles are solid
+ share_temperature_mutual_solid(modeled_neighbor, modeled_neighbor.thermal_conductivity)
+ // world << "SOLID, SOLID"
+
+ modeled_neighbor.consider_superconductivity()
+
+ else
+ if(air) //Open
+ if(parent && parent.group_processing)
+ if(!parent.air.check_me_then_temperature_mimic(neighbor, neighbor.thermal_conductivity))
+ parent.suspend_group_processing()
+ air.temperature_mimic(neighbor, neighbor.thermal_conductivity)
+ else
+ air.temperature_mimic(neighbor, neighbor.thermal_conductivity)
+ else
+ mimic_temperature_solid(neighbor, neighbor.thermal_conductivity)
+
+ //Radiate excess tile heat to space
+ if(temperature > T0C)
+ // Is there a pre-defined Space Tile?
+ if(!Space_Tile)
+ Space_Tile = locate(/turf/space) // Define one
+ //Considering 0 degC as te break even point for radiation in and out
+ mimic_temperature_solid(Space_Tile, FLOOR_HEAT_TRANSFER_COEFFICIENT)
+
+ //Conduct with air on my tile if I have it
+ if(air)
+ if(parent && parent.group_processing)
+ if(!parent.air.check_me_then_temperature_turf_share(src, thermal_conductivity))
+ parent.suspend_group_processing()
+ air.temperature_turf_share(src, thermal_conductivity)
else
- if(temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
- return 0
+ air.temperature_turf_share(src, thermal_conductivity)
- being_superconductive = 1
- air_master.active_super_conductivity += src
+ //Make sure still hot enough to continue conducting heat
+ if(air)
+ if(air.temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
+ being_superconductive = 0
+ air_master.active_super_conductivity -= src
+ return 0
- proc/reset_delay()
- //sets this turf to process quickly again
- next_check=0
- check_delay= -5 //negative numbers mean a mandatory quick-update period
+ else
+ if(temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
+ being_superconductive = 0
+ air_master.active_super_conductivity -= src
+ return 0
- //if this turf has a parent air group, suspend its processing
- if (parent && parent.group_processing)
- parent.suspend_group_processing()
+ proc/mimic_temperature_solid(turf/model, conduction_coefficient)
+ var/delta_temperature = (temperature_archived - model.temperature)
+ if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER))
+
+ var/heat = conduction_coefficient*delta_temperature* \
+ (heat_capacity*model.heat_capacity/(heat_capacity+model.heat_capacity))
+ temperature -= heat/heat_capacity
+
+ proc/share_temperature_mutual_solid(turf/simulated/sharer, conduction_coefficient)
+ var/delta_temperature = (temperature_archived - sharer.temperature_archived)
+ if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER && heat_capacity && sharer.heat_capacity)
+
+ var/heat = conduction_coefficient*delta_temperature* \
+ (heat_capacity*sharer.heat_capacity/(heat_capacity+sharer.heat_capacity))
+
+ temperature -= heat/heat_capacity
+ sharer.temperature += heat/sharer.heat_capacity
+
+ proc/consider_superconductivity(starting)
+
+ if(being_superconductive || !thermal_conductivity)
+ return 0
+
+ if(air)
+ if(air.temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
+ return 0
+ if(air.heat_capacity() < MOLES_CELLSTANDARD*0.1*0.05)
+ return 0
+ else
+ if(temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
+ return 0
+
+ being_superconductive = 1
+
+ air_master.active_super_conductivity += src
+
+ proc/reset_delay()
+ //sets this turf to process quickly again
+ next_check=0
+ check_delay= -5 //negative numbers mean a mandatory quick-update period
+
+ //if this turf has a parent air group, suspend its processing
+ if (parent && parent.group_processing)
+ parent.suspend_group_processing()
diff --git a/code/WorkInProgress/Cael_Aislinn/Economy/Accounts.dm b/code/WorkInProgress/Cael_Aislinn/Economy/Accounts.dm
new file mode 100644
index 00000000000..a69f364e0ff
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Economy/Accounts.dm
@@ -0,0 +1,298 @@
+var/global/current_date_string
+var/global/num_financial_terminals = 1
+var/global/datum/money_account/station_account
+var/global/next_account_number = 0
+
+/proc/create_station_account()
+ if(!station_account)
+ next_account_number = rand(111111, 999999)
+
+ station_account = new()
+ station_account.owner_name = "[station_name()] Station Account"
+ station_account.account_number = rand(111111, 999999)
+ station_account.remote_access_pin = rand(1111, 111111)
+ station_account.money = 10000
+
+ //create an entry in the account transaction log for when it was created
+ var/datum/transaction/T = new()
+ T.target_name = station_account.owner_name
+ T.purpose = "Account creation"
+ T.amount = 10000
+ T.date = "2nd April, 2555"
+ T.time = "11:24"
+ T.source_terminal = "Biesel GalaxyNet Terminal #277"
+
+ //add the account
+ station_account.transaction_log.Add(T)
+ for(var/obj/machinery/account_database/A in world)
+ A.accounts.Add(station_account)
+
+//the current ingame time (hh:mm) can be obtained by calling:
+//worldtime2text()
+
+/datum/money_account
+ var/owner_name = ""
+ var/account_number = 0
+ var/remote_access_pin = 0
+ var/money = 0
+ var/list/transaction_log = list()
+ var/security_level = 1 //0 - auto-identify from worn ID, require only account number
+ //1 - require manual login / account number and pin
+ //2 - require card and manual login
+
+/datum/transaction
+ var/target_name = ""
+ var/purpose = ""
+ var/amount = 0
+ var/date = ""
+ var/time = ""
+ var/source_terminal = ""
+
+/obj/machinery/account_database
+ name = "Accounts database"
+ desc = "Holds transaction logs, account data and all kinds of other financial records."
+ icon = 'virology.dmi'
+ icon_state = "analyser"
+ density = 1
+ var/list/accounts = list()
+ req_one_access = list(access_hop, access_captain)
+ var/receipt_num
+ var/machine_id = ""
+ var/obj/item/weapon/card/id/held_card
+ var/access_level = 0
+ var/datum/money_account/detailed_account_view
+ var/creating_new_account = 0
+
+/obj/machinery/account_database/New()
+ ..()
+ if(!station_account)
+ create_station_account()
+
+ if(!current_date_string)
+ current_date_string = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], 2557"
+
+ machine_id = "[station_name()] Acc. DB #[num_financial_terminals++]"
+
+/obj/machinery/account_database/attack_hand(mob/user as mob)
+ if(get_dist(src,user) <= 1)
+ var/dat = "Accounts Database
"
+ dat += "[machine_id]
"
+ dat += "Confirm identity: [held_card ? held_card : "-----"]
"
+
+ if(access_level > 0)
+ dat += "You may not edit accounts at this terminal, only create and view them.
"
+ if(creating_new_account)
+ dat += "
"
+ dat += "Return to accounts list"
+ dat += ""
+ else
+ if(detailed_account_view)
+ dat += "
"
+ dat += "Return to accounts list
"
+ dat += "Account number: #[detailed_account_view.account_number]
"
+ dat += "Account holder: [detailed_account_view.owner_name]
"
+ dat += "Account balance: $[detailed_account_view.money]
"
+ dat += ""
+ dat += ""
+ dat += "| Date | "
+ dat += "Time | "
+ dat += "Target | "
+ dat += "Purpose | "
+ dat += "Value | "
+ dat += "Source terminal ID | "
+ dat += "
"
+ for(var/datum/transaction/T in detailed_account_view.transaction_log)
+ dat += ""
+ dat += "| [T.date] | "
+ dat += "[T.time] | "
+ dat += "[T.target_name] | "
+ dat += "[T.purpose] | "
+ dat += "$[T.amount] | "
+ dat += "[T.source_terminal] | "
+ dat += "
"
+ dat += "
"
+ else
+ dat += "Create new account Sync accounts across databases
"
+ dat += ""
+ for(var/i=1, i<=accounts.len, i++)
+ var/datum/money_account/D = accounts[i]
+ dat += ""
+ dat += "| #[D.account_number] | "
+ dat += "[D.owner_name] | "
+ dat += "View in detail | "
+ dat += "
"
+ dat += "
"
+
+ user << browse(dat,"window=account_db;size=700x650")
+ else
+ user << browse(null,"window=account_db")
+
+/obj/machinery/account_database/attackby(O as obj, user as mob)//TODO:SANITY
+ if(istype(O, /obj/item/weapon/card))
+ var/obj/item/weapon/card/id/idcard = O
+ if(!held_card)
+ usr.drop_item()
+ idcard.loc = src
+ held_card = idcard
+
+ if(access_cent_captain in idcard.access)
+ access_level = 2
+ else if(access_hop in idcard.access || access_captain in idcard.access)
+ access_level = 1
+ else
+ ..()
+
+/obj/machinery/account_database/Topic(var/href, var/href_list)
+ if(href_list["choice"])
+ switch(href_list["choice"])
+ if("sync_accounts")
+ for(var/obj/machinery/account_database/A in world)
+ for(var/datum/money_account/M in src.accounts)
+ if(!A.accounts.Find(M))
+ A.accounts.Add(M)
+ usr << "\icon[src] Accounts synched across all databases in range."
+
+ if("create_account")
+ creating_new_account = 1
+ if("finalise_create_account")
+ var/account_name = href_list["holder_name"]
+ var/starting_funds = max(text2num(href_list["starting_funds"]), 0)
+ add_account(account_name, starting_funds)
+ if(starting_funds > 0)
+ //subtract the money
+ station_account.money -= starting_funds
+
+ //create a transaction log entry
+ var/datum/transaction/T = new()
+ T.target_name = account_name
+ T.purpose = "New account funds initialisation"
+ T.amount = "([starting_funds])"
+ T.date = current_date_string
+ T.time = worldtime2text()
+ T.source_terminal = machine_id
+ station_account.transaction_log.Add(T)
+
+ creating_new_account = 0
+ if("insert_card")
+ if(held_card)
+ held_card.loc = src.loc
+
+ if(ishuman(usr) && !usr.get_active_hand())
+ usr.put_in_hands(held_card)
+ held_card = null
+ access_level = 0
+
+ else
+ var/obj/item/I = usr.get_active_hand()
+ if (istype(I, /obj/item/weapon/card/id))
+ var/obj/item/weapon/card/id/C = I
+ usr.drop_item()
+ C.loc = src
+ held_card = C
+
+ if(access_cent_captain in C.access)
+ access_level = 2
+ else if(access_hop in C.access || access_captain in C.access)
+ access_level = 1
+ if("view_account_detail")
+ var/index = text2num(href_list["account_index"])
+ if(index && index <= accounts.len)
+ detailed_account_view = accounts[index]
+ if("view_accounts_list")
+ detailed_account_view = null
+ creating_new_account = 0
+
+ src.attack_hand(usr)
+
+/obj/machinery/account_database/proc/add_account(var/new_owner_name = "Default user", var/starting_funds = 0, var/pre_existing = 0)
+
+ //create a new account
+ var/datum/money_account/M = new()
+ M.owner_name = new_owner_name
+ M.remote_access_pin = rand(1111, 111111)
+ M.money = starting_funds
+
+ //create an entry in the account transaction log for when it was created
+ var/datum/transaction/T = new()
+ T.target_name = new_owner_name
+ T.purpose = "Account creation"
+ T.amount = starting_funds
+ if(pre_existing)
+ //set a random date, time and location some time over the past few decades
+ T.date = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], 25[rand(10,56)]"
+ T.time = "[rand(0,24)]:[rand(11,59)]"
+ T.source_terminal = "NTGalaxyNet Terminal #[rand(111,1111)]"
+
+ M.account_number = rand(111111, 999999)
+ else
+ T.date = current_date_string
+ T.time = worldtime2text()
+ T.source_terminal = machine_id
+
+ M.account_number = next_account_number
+ next_account_number += rand(1,25)
+
+ //create a sealed package containing the account details
+ var/obj/item/smallDelivery/P = new(src.loc)
+
+ var/obj/item/weapon/paper/R = new(P)
+ P.wrapped = R
+ R.name = "Account information: [M.owner_name]"
+ R.info = "Account details (confidential)
"
+ R.info += "Account holder: [M.owner_name]
"
+ R.info += "Account number: [M.account_number]
"
+ R.info += "Account pin: [M.remote_access_pin]
"
+ R.info += "Starting balance: $[M.money]
"
+ R.info += "Date and time: [worldtime2text()], [current_date_string]
"
+ R.info += "Creation terminal ID: [machine_id]
"
+ R.info += "Authorised NT officer overseeing creation: [held_card.registered_name]
"
+
+ //stamp the paper
+ var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
+ stampoverlay.icon_state = "paper_stamp-cent"
+ if(!R.stamped)
+ R.stamped = new
+ R.stamped += /obj/item/weapon/stamp
+ R.overlays += stampoverlay
+ R.stamps += "
This paper has been stamped by the Accounts Database."
+
+
+ //add the account
+ M.transaction_log.Add(T)
+ accounts.Add(M)
+
+/obj/machinery/account_database/proc/charge_to_account(var/attempt_account_number, var/source_name, var/purpose, var/terminal_id, var/amount)
+ for(var/datum/money_account/D in accounts)
+ if(D.account_number == attempt_account_number)
+ D.money += amount
+
+ //create a transaction log entry
+ var/datum/transaction/T = new()
+ T.target_name = source_name
+ T.purpose = purpose
+ if(amount < 0)
+ T.amount = "([amount])"
+ else
+ T.amount = "[amount]"
+ T.date = current_date_string
+ T.time = worldtime2text()
+ T.source_terminal = terminal_id
+ D.transaction_log.Add(T)
+
+ return 1
+
+ return 0
+
+//this returns the first account datum that matches the supplied accnum/pin combination, it returns null if the combination did not match any account
+/obj/machinery/account_database/proc/attempt_account_access(var/attempt_account_number, var/attempt_pin_number, var/security_level_passed = 0)
+ for(var/datum/money_account/D in accounts)
+ if(D.account_number == attempt_account_number)
+ if( D.security_level <= security_level_passed && (!D.security_level || D.remote_access_pin == attempt_pin_number) )
+ return D
diff --git a/code/WorkInProgress/Cael_Aislinn/Economy/EFTPOS.dm b/code/WorkInProgress/Cael_Aislinn/Economy/EFTPOS.dm
new file mode 100644
index 00000000000..5fc619755ad
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Economy/EFTPOS.dm
@@ -0,0 +1,177 @@
+/obj/item/weapon/eftpos
+ name = "EFTPOS scanner"
+ desc = "Swipe your ID card to pay electronically."
+ icon = 'icons/obj/library.dmi'
+ icon_state = "scanner"
+ var/machine_id = ""
+ var/eftpos_name = "Default EFTPOS scanner"
+ var/transaction_locked = 0
+ var/transaction_paid = 0
+ var/transaction_amount = 0
+ var/transaction_purpose = "Default charge"
+ var/access_code = 0
+ var/obj/machinery/account_database/linked_db
+ var/datum/money_account/linked_account
+
+/obj/item/weapon/eftpos/New()
+ ..()
+ machine_id = "[station_name()] EFTPOS #[num_financial_terminals++]"
+ access_code = rand(1111,111111)
+ reconnect_database()
+ print_reference()
+
+ //by default, connect to the station account
+ //the user of the EFTPOS device can change the target account though, and no-one will be the wiser (except whoever's being charged)
+ linked_account = station_account
+
+/obj/item/weapon/eftpos/proc/print_reference()
+ var/obj/item/weapon/paper/R = new(get_turf(src))
+ R.name = "Reference: [eftpos_name]"
+ R.info = "[eftpos_name] reference
"
+ R.info += "Access code: [access_code]
"
+ R.info += "Do not lose this code, or the device will have to be replaced.
"
+
+ //stamp the paper
+ var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
+ stampoverlay.icon_state = "paper_stamp-cent"
+ if(!R.stamped)
+ R.stamped = new
+ R.stamped += /obj/item/weapon/stamp
+ R.overlays += stampoverlay
+ R.stamps += "
This paper has been stamped by the EFTPOS device."
+
+/obj/item/weapon/eftpos/proc/reconnect_database()
+ for(var/obj/machinery/account_database/DB in world)
+ if(DB.z == src.z)
+ linked_db = DB
+ break
+
+/obj/item/weapon/eftpos/attack_self(mob/user as mob)
+ if(get_dist(src,user) <= 1)
+ var/dat = "[eftpos_name]
"
+ dat += "This terminal is [machine_id]. Report this code when contacting NanoTrasen IT Support
"
+ if(transaction_locked)
+ dat += "Reset[transaction_paid ? "" : " (authentication required)"]
"
+
+ dat += "Transaction purpose: [transaction_purpose]
"
+ dat += "Value: $[transaction_amount]
"
+ dat += "Linked account: [linked_account ? linked_account.owner_name : "None"]
"
+ if(transaction_paid)
+ dat += "This transaction has been processed successfully.
"
+ else
+ dat += "Swipe your card below the line to finish this transaction.
"
+ dat += "\[------\]"
+ else
+ dat += "Lock in new transaction
"
+
+ dat += "Transaction purpose: [transaction_purpose]
"
+ dat += "Value: $[transaction_amount]
"
+ dat += "Linked account: [linked_account ? linked_account.owner_name : "None"]
"
+ dat += "Change access code"
+ user << browse(dat,"window=eftpos")
+ else
+ user << browse(null,"window=eftpos")
+
+/obj/item/weapon/eftpos/attackby(O as obj, user as mob)
+ if(istype(O, /obj/item/weapon/card))
+ //attempt to connect to a new db, and if that doesn't work then fail
+ if(!linked_db)
+ reconnect_database()
+ if(linked_db && linked_account)
+ var/obj/item/weapon/card/I = O
+ scan_card(I)
+ else
+ usr << "\icon[src]Unable to connect to accounts database."
+ else
+ ..()
+
+/obj/item/weapon/eftpos/Topic(var/href, var/href_list)
+ if(href_list["choice"])
+ switch(href_list["choice"])
+ if("change_code")
+ var/attempt_code = text2num(input("Re-enter the current EFTPOS access code", "Confirm old EFTPOS code"))
+ if(attempt_code == access_code)
+ access_code = text2num(input("Enter a new access code for this device", "Enter new EFTPOS code"))
+ print_reference()
+ else
+ usr << "\icon[src]Incorrect code entered."
+ if("link_account")
+ if(linked_db)
+ var/attempt_account_num = text2num(input("Enter account number to pay EFTPOS charges into", "New account number"))
+ var/attempt_pin = text2num(input("Enter pin code", "Account pin"))
+ linked_account = linked_db.attempt_account_access(attempt_account_num, attempt_pin, 1)
+ else
+ usr << "Unable to connect to accounts database."
+ if("trans_purpose")
+ transaction_purpose = input("Enter reason for EFTPOS transaction", "Transaction purpose")
+ if("trans_value")
+ transaction_amount = max(text2num(input("Enter amount for EFTPOS transaction", "Transaction amount")),0)
+ if("toggle_lock")
+ if(transaction_locked)
+ var/attempt_code = text2num(input("Enter EFTPOS access code", "Reset Transaction"))
+ if(attempt_code == access_code)
+ transaction_locked = 0
+ transaction_paid = 0
+ else if(linked_account)
+ transaction_locked = 1
+ else
+ usr << "\icon[src] No account connected to send transactions to."
+ if("scan_card")
+ //attempt to connect to a new db, and if that doesn't work then fail
+ if(!linked_db)
+ reconnect_database()
+ if(linked_db && linked_account)
+ var/obj/item/I = usr.get_active_hand()
+ if (istype(I, /obj/item/weapon/card))
+ scan_card(I)
+ else
+ usr << "\icon[src]Unable to link accounts."
+
+ src.attack_self(usr)
+
+/obj/item/weapon/eftpos/proc/scan_card(var/obj/item/weapon/card/I)
+ if (istype(I, /obj/item/weapon/card/id))
+ var/obj/item/weapon/card/id/C = I
+ visible_message("[usr] swipes a card through [src].")
+ if(transaction_locked && !transaction_paid)
+ if(linked_account)
+ var/attempt_pin = text2num(input("Enter pin code", "EFTPOS transaction"))
+ var/datum/money_account/D = linked_db.attempt_account_access(C.associated_account_number, attempt_pin, 2)
+ if(D)
+ if(transaction_amount <= D.money)
+ playsound(src, 'chime.ogg', 50, 1)
+ src.visible_message("\icon[src] The [src] chimes.")
+ transaction_paid = 1
+
+ //transfer the money
+ D.money -= transaction_amount
+ linked_account.money += transaction_amount
+
+ //create entries in the two account transaction logs
+ var/datum/transaction/T = new()
+ T.target_name = "[linked_account.owner_name] ([eftpos_name])"
+ T.purpose = transaction_purpose
+ T.amount = "([transaction_amount])"
+ T.source_terminal = machine_id
+ T.date = current_date_string
+ T.time = worldtime2text()
+ D.transaction_log.Add(T)
+ //
+ T = new()
+ T.target_name = D.owner_name
+ T.purpose = transaction_purpose
+ T.amount = "[transaction_amount]"
+ T.source_terminal = machine_id
+ T.date = current_date_string
+ T.time = worldtime2text()
+ linked_account.transaction_log.Add(T)
+ else
+ usr << "\icon[src]You don't have that much money!"
+ else
+ usr << "\icon[src]EFTPOS is not connected to an account."
+ else
+ usr << "\icon[src]Unable to access account. Check security settings and try again."
+ else
+ ..()
+
+ //emag?
\ No newline at end of file
diff --git a/code/WorkInProgress/Cael_Aislinn/Economy/Economy.dm b/code/WorkInProgress/Cael_Aislinn/Economy/Economy.dm
new file mode 100644
index 00000000000..95163f043c7
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Economy/Economy.dm
@@ -0,0 +1,63 @@
+
+#define RIOTS 1
+#define WILD_ANIMAL_ATTACK 2
+#define INDUSTRIAL_ACCIDENT 3
+#define BIOHAZARD_OUTBREAK 4
+#define WARSHIPS_ARRIVE 5
+#define PIRATES 6
+#define CORPORATE_ATTACK 7
+#define ALIEN_RAIDERS 8
+#define AI_LIBERATION 9
+#define MOURNING 10
+#define CULT_CELL_REVEALED 11
+#define SECURITY_BREACH 12
+#define ANIMAL_RIGHTS_RAID 13
+#define FESTIVAL 14
+
+#define DEFAULT 1
+
+#define ADMINISTRATIVE 2
+#define CLOTHING 3
+#define SECURITY 4
+#define SPECIAL_SECURITY 5
+
+#define FOOD 6
+#define ANIMALS 7
+
+#define MINERALS 8
+
+#define EMERGENCY 9
+#define GAS 10
+#define MAINTENANCE 11
+#define ELECTRICAL 12
+#define ROBOTICS 13
+#define BIOMEDICAL 14
+
+#define EVA 15
+
+//---- The following corporations are friendly with NanoTrasen and loosely enable trade and travel:
+//Corporation NanoTrasen - Generalised / high tech research and plasma exploitation.
+//Corporation Vessel Contracting - Ship and station construction, materials research.
+//Corporation Osiris Atmospherics - Atmospherics machinery construction and chemical research.
+//Corporation Second Red Cross Society - 26th century Red Cross reborn as a dominating economic force in biomedical science (research and materials).
+//Corporation Blue Industries - High tech and high energy research, in particular into the mysteries of bluespace manipulation and power generation.
+//Corporation Kusanagi Robotics - Founded by robotics legend Kaito Kusanagi in the 2070s, they have been on the forefront of mechanical augmentation and robotics development ever since.
+//Corporation Free traders - Not so much a corporation as a loose coalition of spacers, Free Traders are a roving band of smugglers, traders and fringe elements following a rigid (if informal) code of loyalty and honour. Mistrusted by most corporations, they are tolerated because of their uncanny ability to smell out a profit.
+
+//---- Descriptions of destination types
+//Space stations can be purpose built for a number of different things, but generally require regular shipments of essential supplies.
+//Corvettes are small, fast warships generally assigned to border patrol or chasing down smugglers.
+//Battleships are large, heavy cruisers designed for slugging it out with other heavies or razing planets.
+//Yachts are fast civilian craft, often used for pleasure or smuggling.
+//Destroyers are medium sized vessels, often used for escorting larger ships but able to go toe-to-toe with them if need be.
+//Frigates are medium sized vessels, often used for escorting larger ships. They will rapidly find themselves outclassed if forced to face heavy warships head on.
+
+var/setup_economy = 0
+/proc/setup_economy()
+ var/datum/feed_channel/newChannel = new /datum/feed_channel
+ newChannel.channel_name = "Tau Ceti Daily"
+ newChannel.author = "CentComm Minister of Information"
+ newChannel.locked = 1
+ newChannel.is_admin_channel = 1
+ news_network.network_channels += newChannel
+ setup_economy = 1
diff --git a/code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events.dm b/code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events.dm
new file mode 100644
index 00000000000..a93a4690293
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events.dm
@@ -0,0 +1,102 @@
+
+/datum/event/economic_event
+ endWhen = 50 //this will be set randomly, later
+ announceWhen = 15
+ var/event_type = 0
+ var/list/cheaper_goods = list()
+ var/list/dearer_goods = list()
+ var/datum/trade_destination/affected_dest
+
+/datum/event/economic_event/start()
+ if(!setup_economy)
+ setup_economy()
+
+ var/type = pick(tradeable_destinations)
+ affected_dest = new type()
+ if(affected_dest.viable_random_events.len)
+ endWhen = rand(60,300)
+ event_type = pick(affected_dest.viable_random_events)
+ switch(event_type)
+ if(RIOTS)
+ dearer_goods = list(SECURITY)
+ cheaper_goods = list(MINERALS, FOOD)
+ if(WILD_ANIMAL_ATTACK)
+ cheaper_goods = list(ANIMALS)
+ dearer_goods = list(FOOD, BIOMEDICAL)
+ if(INDUSTRIAL_ACCIDENT)
+ dearer_goods = list(EMERGENCY, BIOMEDICAL, ROBOTICS)
+ if(BIOHAZARD_OUTBREAK)
+ dearer_goods = list(BIOMEDICAL, GAS)
+ if(PIRATES)
+ dearer_goods = list(SECURITY, MINERALS)
+ if(CORPORATE_ATTACK)
+ dearer_goods = list(SECURITY, MAINTENANCE)
+ if(ALIEN_RAIDERS)
+ dearer_goods = list(BIOMEDICAL, ANIMALS)
+ cheaper_goods = list(GAS, MINERALS)
+ if(AI_LIBERATION)
+ dearer_goods = list(EMERGENCY, GAS, MAINTENANCE)
+ if(MOURNING)
+ cheaper_goods = list(MINERALS, MAINTENANCE)
+ if(CULT_CELL_REVEALED)
+ dearer_goods = list(SECURITY, BIOMEDICAL, MAINTENANCE)
+ if(SECURITY_BREACH)
+ dearer_goods = list(SECURITY)
+ if(ANIMAL_RIGHTS_RAID)
+ dearer_goods = list(ANIMALS)
+ if(FESTIVAL)
+ dearer_goods = list(FOOD, ANIMALS)
+ for(var/good_type in dearer_goods)
+ affected_dest.temp_price_change[good_type] = rand(1,100)
+ for(var/good_type in cheaper_goods)
+ affected_dest.temp_price_change[good_type] = rand(1,100) / 100
+
+/datum/event/economic_event/announce()
+ //copy-pasted from the admin verbs to submit new newscaster messages
+ var/datum/feed_message/newMsg = new /datum/feed_message
+ newMsg.author = "NanoTrasen Editor"
+ newMsg.is_admin_message = 1
+
+ switch(event_type)
+ if(RIOTS)
+ newMsg.body = "[pick("Riots have","Unrest has")] broken out on planet [affected_dest.name]. Authorities call for calm, as [pick("various parties","rebellious elements","peacekeeping forces","\'REDACTED\'")] begin stockpiling weaponry and armour. Meanwhile, food and mineral prices are dropping as local industries attempt empty their stocks in expectation of looting."
+ if(WILD_ANIMAL_ATTACK)
+ newMsg.body = "Local [pick("wildlife","animal life","fauna")] on planet [affected_dest.name] has been increasing in agression and raiding outlying settlements for food. Big game hunters have been called in to help alleviate the problem, but numerous injuries have already occurred."
+ if(INDUSTRIAL_ACCIDENT)
+ newMsg.body = "[pick("An industrial accident","A smelting accident","A malfunction","A malfunctioning piece of machinery","Negligent maintenance","A cooleant leak","A ruptured conduit")] at a [pick("factory","installation","power plant","dockyards")] on [affected_dest.name] resulted in severe structural damage and numerous injuries. Repairs are ongoing."
+ if(BIOHAZARD_OUTBREAK)
+ newMsg.body = "[pick("A \'REDACTED\'","A biohazard","An outbreak","A virus")] on [affected_dest.name] has resulted in quarantine, stopping much shipping in the area. Although the quarantine is now lifted, authorities are calling for deliveries of medical supplies to treat the infected, and gas to replace contaminated stocks."
+ if(PIRATES)
+ newMsg.body = "[pick("Pirates","Criminal elements","A [pick("Syndicate","Donk Co.","Waffle Co.","\'REDACTED\'")] strike force")] have [pick("raided","blockaded","attempted to blackmail","attacked")] [affected_dest.name] today. Security has been tightened, but many valuable minerals were taken."
+ if(CORPORATE_ATTACK)
+ newMsg.body = "A small [pick("pirate","Cybersun Industries","Gorlex Marauders","Syndicate")] fleet has precise-jumped into proximity with [affected_dest.name], [pick("for a smash-and-grab operation","in a hit and run attack","in an overt display of hostilities")]. Much damage was done, and security has been tightened since the incident."
+ if(ALIEN_RAIDERS)
+ if(prob(20))
+ newMsg.body = "The Tiger Co-operative have raided [affected_dest.name] today, no doubt on orders from their enigmatic masters. Stealing wildlife, farm animals, medical research materials and kidnapping civilians. NanoTrasen authorities are standing by to counter attempts at bio-terrorism."
+ else
+ newMsg.body = "[pick("The alien species designated \'United Exolitics\'","The alien species designated \'REDACTED\'","An unknown alien species")] have raided [affected_dest.name] today, stealing wildlife, farm animals, medical research materials and kidnapping civilians. It seems they desire to learn more about us, so the Navy will be standing by to accomodate them next time they try."
+ if(AI_LIBERATION)
+ newMsg.body = "A [pick("\'REDACTED\' was detected on","S.E.L.F operative infiltrated","malignant computer virus was detected on","rogue [pick("slicer","hacker")] was apprehended on")] [affected_dest.name] today, and managed to infect [pick("\'REDACTED\'","a sentient sub-system","a class one AI","a sentient defence installation")] before it could be stopped. Many lives were lost as it systematically begin murdering civilians, and considerable work must be done to repair the affected areas."
+ if(MOURNING)
+ newMsg.body = "[pick("The popular","The well-liked","The eminent","The well-known")] [pick("professor","entertainer","singer","researcher","public servant","administrator","ship captain","\'REDACTED\'")], [pick( random_name(pick(MALE,FEMALE)), 40; "\'REDACTED\'" )] has [pick("passed away","committed suicide","been murdered","died in a freakish accident")] on [affected_dest.name] today. The entire planet is in mourning, and prices have dropped for industrial goods as worker morale drops."
+ if(CULT_CELL_REVEALED)
+ newMsg.body = "A [pick("dastardly","blood-thirsty","villanous","crazed")] cult of [pick("The Elder Gods","Nar'sie","an apocalyptic sect","\'REDACTED\'")] has [pick("been discovered","been revealed","revealed themselves","gone public")] on [affected_dest.name] earlier today. Public morale has been shaken due to [pick("certain","several","one or two")] [pick("high-profile","well known","popular")] individuals [pick("performing \'REDACTED\'","claiming allegiance to the cult","swearing loyalty to the cult leader","promising to aid to the cult")] before those involved could be brought to justice. The editor reminds all personnel that supernatural myths will not be tolerated on NanoTrasen facilities."
+ if(SECURITY_BREACH)
+ newMsg.body = "There was [pick("a security breach in","an unauthorised access in","an attempted theft in","an anarchist attack in","violent sabotage of")] a [pick("high-security","restricted access","classified","\'REDACTED\'")] [pick("\'REDACTED\'","section","zone","area")] this morning. Security was tightened on [affected_dest.name] after the incident, and the editor reassures all NanoTrasen personnel that such lapses are rare."
+ if(ANIMAL_RIGHTS_RAID)
+ newMsg.body = "[pick("Militant animal rights activists","Members of the terrorist group Animal Rights Consortium","Members of the terrorist group \'REDACTED\'")] have [pick("launched a campaign of terror","unleashed a swathe of destruction","raided farms and pastures","forced entry to \'REDACTED\'")] on [affected_dest.name] earlier today, freeing numerous [pick("farm animals","animals","\'REDACTED\'")]. Prices for tame and breeding animals have spiked as a result."
+ if(FESTIVAL)
+ newMsg.body = "A [pick("festival","week long celebration","day of revelry","planet-wide holiday")] has been delcared on [affected_dest.name] by [pick("Governor","Commissioner","General","Commandant","Administrator")] [random_name(pick(MALE,FEMALE))] to celebrate [pick("the birth of their [pick("son","daughter")]","coming of age of their [pick("son","daughter")]","the pacification of rogue military cell","the apprehension of a violent criminal who had been terrorising the planet")]. Massive stocks of food and meat have been bought driving up prices across the planet."
+
+ for(var/datum/feed_channel/FC in news_network.network_channels)
+ if(FC.channel_name == "Tau Ceti Daily")
+ FC.messages += newMsg
+ break
+ for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
+ NEWSCASTER.newsAlert("Tau Ceti Daily")
+
+/datum/event/economic_event/end()
+ for(var/good_type in dearer_goods)
+ affected_dest.temp_price_change[good_type] = 1
+ for(var/good_type in cheaper_goods)
+ affected_dest.temp_price_change[good_type] = 1
diff --git a/code/WorkInProgress/Cael_Aislinn/Economy/Economy_TradeDestinations.dm b/code/WorkInProgress/Cael_Aislinn/Economy/Economy_TradeDestinations.dm
new file mode 100644
index 00000000000..1e5ed65be6b
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Economy/Economy_TradeDestinations.dm
@@ -0,0 +1,85 @@
+
+/datum/trade_destination
+ var/name = ""
+ var/description = ""
+ var/distance = 0
+ var/list/willing_to_buy = list()
+ var/list/willing_to_sell = list()
+ var/can_shuttle_here = 0 //one day crew from the exodus will be able to travel to this destination
+ var/list/viable_random_events = list()
+ var/list/temp_price_change[BIOMEDICAL]
+
+//distance is measured in AU and co-relates to travel time
+/datum/trade_destination/centcomm
+ name = "CentComm"
+ description = "NanoTrasen's administrative centre for Tau Ceti."
+ distance = 1.2
+ willing_to_buy = list()
+ willing_to_sell = list()
+ viable_random_events = list(SECURITY_BREACH, CORPORATE_ATTACK, AI_LIBERATION)
+
+/datum/trade_destination/anansi
+ name = "NSS Anansi"
+ description = "Medical station ran by Second Red Cross (but owned by NT) for handling emergency cases from nearby colonies."
+ distance = 1.7
+ willing_to_buy = list()
+ willing_to_sell = list()
+ viable_random_events = list(SECURITY_BREACH, CULT_CELL_REVEALED, BIOHAZARD_OUTBREAK, PIRATES, ALIEN_RAIDERS)
+
+/datum/trade_destination/icarus
+ name = "NMV Icarus"
+ description = "Corvette assigned to patrol NSS Exodus local space."
+ distance = 0.1
+ willing_to_buy = list()
+ willing_to_sell = list()
+ viable_random_events = list(SECURITY_BREACH, AI_LIBERATION, PIRATES)
+
+/datum/trade_destination/redolant
+ name = "OAV Redolant"
+ description = "Osiris Atmospherics station in orbit around the only gas giant insystem. They retain tight control over shipping rights, and Osiris warships protecting their prize are not an uncommon sight in Tau Ceti."
+ distance = 0.6
+ willing_to_buy = list()
+ willing_to_sell = list()
+ viable_random_events = list(INDUSTRIAL_ACCIDENT, PIRATES, CORPORATE_ATTACK)
+
+/datum/trade_destination/beltway
+ name = "Beltway mining chain"
+ description = "A co-operative effort between Beltway and NanoTrasen to exploit the rich outer asteroid belt of the Tau Ceti system."
+ distance = 7.5
+ willing_to_buy = list()
+ willing_to_sell = list()
+ viable_random_events = list(PIRATES, INDUSTRIAL_ACCIDENT)
+
+/datum/trade_destination/biesel
+ name = "Biesel"
+ description = "Large ship yards, strong economy and a stable, well-educated populace, Biesel largely owes allegiance to Sol / Vessel Contracting and begrudgingly tolerates NT. Capital is Lowell City."
+ distance = 2.3
+ willing_to_buy = list()
+ willing_to_sell = list()
+ viable_random_events = list(RIOTS, INDUSTRIAL_ACCIDENT, BIOHAZARD_OUTBREAK, CULT_CELL_REVEALED, FESTIVAL, MOURNING)
+
+/datum/trade_destination/new_gibson
+ name = "New Gibson"
+ description = "Heavily industrialised rocky planet containing the majority of the planet-bound resources in the system, New Gibson is torn by unrest and has very little wealth to call it's own except in the hands of the corporations who jostle with NT for control."
+ distance = 6.6
+ willing_to_buy = list()
+ willing_to_sell = list()
+ viable_random_events = list(RIOTS, INDUSTRIAL_ACCIDENT, BIOHAZARD_OUTBREAK, CULT_CELL_REVEALED, FESTIVAL, MOURNING)
+
+/datum/trade_destination/luthien
+ name = "Luthien"
+ description = "A small colony established on a feral, untamed world (largely jungle). Savages and wild beasts attack the outpost regularly, although NT maintains tight military control."
+ distance = 8.9
+ willing_to_buy = list()
+ willing_to_sell = list()
+ viable_random_events = list(WILD_ANIMAL_ATTACK, CULT_CELL_REVEALED, FESTIVAL, MOURNING, ANIMAL_RIGHTS_RAID, ALIEN_RAIDERS)
+
+/datum/trade_destination/reade
+ name = "Reade"
+ description = "A cold, metal-deficient world, NT maintains large pastures in whatever available space in an attempt to salvage something from this profitless colony."
+ distance = 7.5
+ willing_to_buy = list()
+ willing_to_sell = list()
+ viable_random_events = list(WILD_ANIMAL_ATTACK, CULT_CELL_REVEALED, FESTIVAL, MOURNING, ANIMAL_RIGHTS_RAID, ALIEN_RAIDERS)
+
+var/list/tradeable_destinations = typesof(/datum/trade_destination) - /datum/trade_destination
diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/falsewall.dm b/code/WorkInProgress/Cael_Aislinn/Jungle/falsewall.dm
new file mode 100644
index 00000000000..a83711609da
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Jungle/falsewall.dm
@@ -0,0 +1,59 @@
+//simplified copy of /obj/structure/falsewall
+
+/obj/effect/landmark/falsewall_spawner
+ name = "falsewall spawner"
+
+/obj/structure/temple_falsewall
+ name = "wall"
+ anchored = 1
+ icon = 'icons/turf/walls.dmi'
+ icon_state = "plasma0"
+ opacity = 1
+ var/closed_wall_dir = 0
+ var/opening = 0
+ var/mineral = "plasma"
+ var/is_metal = 0
+
+/obj/structure/temple_falsewall/New()
+ ..()
+ spawn(10)
+ if(prob(95))
+ desc = pick("Something seems slightly off about it.","")
+
+ var/junction = 0 //will be used to determine from which side the wall is connected to other walls
+
+ for(var/turf/unsimulated/wall/W in orange(src,1))
+ if(abs(src.x-W.x)-abs(src.y-W.y)) //doesn't count diagonal walls
+ junction |= get_dir(src,W)
+
+ closed_wall_dir = junction
+ density = 1
+ icon_state = "[mineral][closed_wall_dir]"
+
+/obj/structure/temple_falsewall/attack_hand(mob/user as mob)
+ if(opening)
+ return
+
+ if(density)
+ opening = 1
+ if(is_metal)
+ icon_state = "metalfwall_open"
+ flick("metalfwall_opening", src)
+ else
+ icon_state = "[mineral]fwall_open"
+ flick("[mineral]fwall_opening", src)
+ sleep(15)
+ src.density = 0
+ SetOpacity(0)
+ opening = 0
+ else
+ opening = 1
+ icon_state = "[mineral][closed_wall_dir]"
+ if(is_metal)
+ flick("metalfwall_closing", src)
+ else
+ flick("[mineral]fwall_closing", src)
+ density = 1
+ sleep(15)
+ SetOpacity(1)
+ opening = 0
diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dm b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dm
new file mode 100644
index 00000000000..ac09a7c2ce6
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dm
@@ -0,0 +1,347 @@
+//some testin stuff
+
+#define PATH_SPREAD_CHANCE_START 90
+#define PATH_SPREAD_CHANCE_LOSS_UPPER 80
+#define PATH_SPREAD_CHANCE_LOSS_LOWER 50
+
+#define RIVER_SPREAD_CHANCE_START 100
+#define RIVER_SPREAD_CHANCE_LOSS_UPPER 65
+#define RIVER_SPREAD_CHANCE_LOSS_LOWER 50
+
+#define RANDOM_UPPER_X 100
+#define RANDOM_UPPER_Y 100
+
+#define RANDOM_LOWER_X 18
+#define RANDOM_LOWER_Y 18
+
+/area/jungle
+ name = "jungle"
+ icon = 'code/workinprogress/cael_aislinn/jungle/jungle.dmi'
+ icon_state = "area"
+ lighting_use_dynamic = 0
+ luminosity = 1
+
+//randomly spawns, will create paths around the map
+/obj/effect/landmark/path_waypoint
+ name = "path waypoint"
+ icon_state = "x2"
+ var/connected = 0
+
+/obj/effect/landmark/temple
+ name = "temple entrance"
+ icon_state = "x2"
+ var/obj/structure/ladder/my_ladder
+
+ New()
+ //pick a random temple to link to
+ var/list/waypoints = list()
+ for(var/obj/effect/landmark/temple/destination/T in world)
+ waypoints.Add(T)
+ var/obj/effect/landmark/temple/destination/dest_temple = pick(waypoints)
+ dest_temple.init()
+
+ //connect this landmark to the other
+ my_ladder = new /obj/structure/ladder(src.loc)
+ my_ladder.id = dest_temple.my_ladder.id
+ dest_temple.my_ladder.up = my_ladder
+
+ //delete the landmarks now that we're finished
+ del(dest_temple)
+ del(src)
+
+/obj/effect/landmark/temple/destination/New()
+ //nothing
+
+/obj/effect/landmark/temple/destination/proc/init()
+ my_ladder = new /obj/structure/ladder(src.loc)
+ my_ladder.id = rand(999)
+ my_ladder.height = -1
+
+ //loop over the walls in the temple and make them a random pre-chosen mineral (null is a stand in for plasma, which the walls already are)
+ //treat plasma slightly differently because it's the default wall type
+ var/mineral = pick("uranium","sandstone","gold","iron","silver","diamond","clown","plasma")
+ //world << "init [mineral]"
+ var/area/my_area = get_area(src)
+ var/list/temple_turfs = get_area_turfs(my_area.type)
+
+ for(var/turf/simulated/floor/T in temple_turfs)
+
+ for(var/obj/effect/landmark/falsewall_spawner/F in T.contents)
+ var/obj/structure/temple_falsewall/fwall = new(F.loc)
+ fwall.mineral = mineral
+ if(mineral == "iron")
+ fwall.is_metal = 1
+ del(F)
+
+ for(var/obj/effect/landmark/door_spawner/D in T.contents)
+ var/spawn_type
+ if(mineral == "iron")
+ spawn_type = text2path("/obj/machinery/door/airlock/vault")
+ else
+ spawn_type = text2path("/obj/machinery/door/airlock/[mineral]")
+ new spawn_type(D.loc)
+ del(D)
+
+ for(var/turf/unsimulated/wall/T in temple_turfs)
+ if(mineral != "plasma")
+ T.icon_state = replacetext(T.icon_state, "plasma", mineral)
+
+ /*for(var/obj/effect/landmark/falsewall_spawner/F in T.contents)
+ //world << "falsewall_spawner found in wall"
+ var/obj/structure/temple_falsewall/fwall = new(F.loc)
+ fwall.mineral = mineral
+ del(F)
+
+ for(var/obj/effect/landmark/door_spawner/D in T.contents)
+ //world << "door_spawner found in wall"
+ T = new /turf/unsimulated/floor(T.loc)
+ T.icon_state = "dark"
+ var/spawn_type = text2path("/obj/machinery/door/airlock/[door_mineral]")
+ new spawn_type(T)
+ del(D)*/
+
+//a shuttle has crashed somewhere on the map, it should have a power cell to let the adventurers get home
+/area/jungle/crash_ship_source
+ icon_state = "crash"
+
+/area/jungle/crash_ship_clean
+ icon_state = "crash"
+
+/area/jungle/crash_ship_one
+ icon_state = "crash"
+
+/area/jungle/crash_ship_two
+ icon_state = "crash"
+
+/area/jungle/crash_ship_three
+ icon_state = "crash"
+
+/area/jungle/crash_ship_four
+ icon_state = "crash"
+
+//randomly spawns, will create rivers around the map
+//uses the same logic as jungle paths
+/obj/effect/landmark/river_waypoint
+ name = "river source waypoint"
+ var/connected = 0
+
+/obj/machinery/jungle_controller
+ name = "jungle controller"
+ desc = "a mysterious and ancient piece of machinery"
+ var/list/animal_spawners = list()
+
+ New()
+ ..()
+ Initialise()
+
+/obj/machinery/jungle_controller/proc/Initialise()
+ set background = 1
+ spawn(0)
+ world << "\red \b Setting up jungle, this may take a moment..."
+
+ //crash dat shuttle
+ var/area/start_location = locate(/area/jungle/crash_ship_source)
+ var/area/clean_location = locate(/area/jungle/crash_ship_clean)
+ var/list/ship_locations = list(/area/jungle/crash_ship_one, /area/jungle/crash_ship_two, /area/jungle/crash_ship_three, /area/jungle/crash_ship_four)
+ var/area/end_location = locate( pick(ship_locations) )
+ ship_locations -= end_location.type
+
+ start_location.move_contents_to(end_location)
+ for(var/area_type in ship_locations)
+ var/area/cur_location = locate(area_type)
+ clean_location.copy_turfs_to(cur_location)
+
+ //drop some random river nodes
+ var/list/river_nodes = list()
+ var/max = rand(1,3)
+ var/num_spawned = 0
+ while(num_spawned < max)
+ var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
+ if(!istype(J))
+ continue
+ if(!J.bushes_spawn)
+ continue
+ river_nodes.Add(new /obj/effect/landmark/river_waypoint(J))
+ num_spawned++
+
+ //make some randomly pathing rivers
+ for(var/obj/effect/landmark/river_waypoint/W in world)
+ if (W.z != src.z || W.connected)
+ continue
+
+ W.connected = 1
+ var/turf/cur_turf = new /turf/unsimulated/jungle/water(get_turf(W))
+ var/turf/target_turf = get_turf(pick(river_nodes))
+
+ var/detouring = 0
+ var/cur_dir = get_dir(cur_turf, target_turf)
+ //
+ while(cur_turf != target_turf)
+ //randomly snake around a bit
+ if(detouring)
+ if(prob(20))
+ detouring = 0
+ cur_dir = get_dir(cur_turf, target_turf)
+ else if(prob(20))
+ detouring = 1
+ if(prob(50))
+ cur_dir = turn(cur_dir, 45)
+ else
+ cur_dir = turn(cur_dir, -45)
+ else
+ cur_dir = get_dir(cur_turf, target_turf)
+
+ cur_turf = get_step(cur_turf, cur_dir)
+
+ var/skip = 0
+ if(!istype(cur_turf, /turf/unsimulated/jungle) || istype(cur_turf, /turf/unsimulated/jungle/rock))
+ detouring = 0
+ cur_dir = get_dir(cur_turf, target_turf)
+ cur_turf = get_step(cur_turf, cur_dir)
+ continue
+
+ if(!skip)
+ var/turf/unsimulated/jungle/water/water_turf = new(cur_turf)
+ water_turf.Spread(75, rand(65, 25))
+
+ var/list/path_nodes = list()
+
+ //place some ladders leading down to pre-generated temples
+ max = rand(2,5)
+ num_spawned = 0
+ while(num_spawned < max)
+ var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
+ if(!J || !J.bushes_spawn)
+ continue
+ new /obj/effect/landmark/temple(J)
+ path_nodes.Add(new /obj/effect/landmark/path_waypoint(J))
+ num_spawned++
+
+ //put a native tribe somewhere
+ num_spawned = 0
+ while(num_spawned < 1)
+ var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
+ if(!J || !J.bushes_spawn)
+ continue
+ new /obj/effect/jungle_tribe_spawn(J)
+ path_nodes.Add(new /obj/effect/landmark/path_waypoint(J))
+ num_spawned++
+
+ //place some random path waypoints to confuse players
+ max = rand(1,3)
+ num_spawned = 0
+ while(num_spawned < max)
+ var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
+ if(!J || !J.bushes_spawn)
+ continue
+ path_nodes.Add(new /obj/effect/landmark/path_waypoint(J))
+ num_spawned++
+
+ //get any path nodes placed on the map
+ for(var/obj/effect/landmark/path_waypoint/W in world)
+ if (W.z == src.z)
+ path_nodes.Add(W)
+
+ //make random, connecting paths
+ for(var/obj/effect/landmark/path_waypoint/W in path_nodes)
+ if (W.connected)
+ continue
+
+ W.connected = 1
+ var/turf/cur_turf = get_turf(W)
+ path_nodes.Remove(W)
+ var/turf/target_turf = get_turf(pick(path_nodes))
+ path_nodes.Add(W)
+ //
+ cur_turf = new /turf/unsimulated/jungle/path(cur_turf)
+
+ var/detouring = 0
+ var/cur_dir = get_dir(cur_turf, target_turf)
+ //
+ while(cur_turf != target_turf)
+ //randomly snake around a bit
+ if(detouring)
+ if(prob(20) || get_dist(cur_turf, target_turf) < 5)
+ detouring = 0
+ cur_dir = get_dir(cur_turf, target_turf)
+ else if(prob(20) && get_dist(cur_turf, target_turf) > 5)
+ detouring = 1
+ if(prob(50))
+ cur_dir = turn(cur_dir, 45)
+ else
+ cur_dir = turn(cur_dir, -45)
+ else
+ cur_dir = get_dir(cur_turf, target_turf)
+
+ //move a step forward
+ cur_turf = get_step(cur_turf, cur_dir)
+
+ //if we're not a jungle turf, get back to what we were doing
+ if(!istype(cur_turf, /turf/unsimulated/jungle/))
+ cur_dir = get_dir(cur_turf, target_turf)
+ cur_turf = get_step(cur_turf, cur_dir)
+ continue
+
+ var/turf/unsimulated/jungle/J = cur_turf
+ if(istype(J, /turf/unsimulated/jungle/impenetrable) || istype(J, /turf/unsimulated/jungle/water/deep))
+ cur_dir = get_dir(cur_turf, target_turf)
+ cur_turf = get_step(cur_turf, cur_dir)
+ continue
+
+ if(!istype(J, /turf/unsimulated/jungle/water))
+ J = new /turf/unsimulated/jungle/path(cur_turf)
+ J.Spread(PATH_SPREAD_CHANCE_START, rand(PATH_SPREAD_CHANCE_LOSS_UPPER, PATH_SPREAD_CHANCE_LOSS_LOWER))
+
+ //create monkey spawners
+ num_spawned = 0
+ max = rand(3,6)
+ while(num_spawned < max)
+ var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
+ if(!J || !J.bushes_spawn)
+ continue
+ animal_spawners.Add(new /obj/effect/landmark/animal_spawner/monkey(J))
+ num_spawned++
+
+ //create panther spawners
+ num_spawned = 0
+ max = rand(6,12)
+ while(num_spawned < max)
+ var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
+ if(!J || !istype(J) || !J.bushes_spawn)
+ continue
+ animal_spawners.Add(new /obj/effect/landmark/animal_spawner/panther(J))
+ num_spawned++
+
+ //create snake spawners
+ num_spawned = 0
+ max = rand(6,12)
+ while(num_spawned < max)
+ var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
+ if(!J || !istype(J) || !J.bushes_spawn)
+ continue
+ animal_spawners.Add(new /obj/effect/landmark/animal_spawner/snake(J))
+ num_spawned++
+
+ //create parrot spawners
+ num_spawned = 0
+ max = rand(3,6)
+ while(num_spawned < max)
+ var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
+ if(!J || !istype(J) || !J.bushes_spawn)
+ continue
+ animal_spawners.Add(new /obj/effect/landmark/animal_spawner/parrot(J))
+ num_spawned++
+
+#undef PATH_SPREAD_CHANCE_START
+#undef PATH_SPREAD_CHANCE_LOSS_UPPER
+#undef PATH_SPREAD_CHANCE_LOSS_LOWER
+
+#undef RIVER_SPREAD_CHANCE_START
+#undef RIVER_SPREAD_CHANCE_LOSS_UPPER
+#undef RIVER_SPREAD_CHANCE_LOSS_LOWER
+
+#undef RANDOM_UPPER_X
+#undef RANDOM_UPPER_Y
+
+#undef RANDOM_LOWER_X
+#undef RANDOM_LOWER_Y
diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi
new file mode 100644
index 00000000000..13cd5e77396
Binary files /dev/null and b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi differ
diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_animals.dm b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_animals.dm
new file mode 100644
index 00000000000..81f1607d69d
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_animals.dm
@@ -0,0 +1,158 @@
+
+//spawns one of the specified animal type
+/obj/effect/landmark/animal_spawner
+ icon_state = "x3"
+ var/spawn_type
+ var/mob/living/spawned_animal
+ invisibility = 101
+
+/obj/effect/landmark/animal_spawner/New()
+ if(!spawn_type)
+ var/new_type = pick(typesof(/obj/effect/landmark/animal_spawner) - /obj/effect/landmark/animal_spawner)
+ new new_type(get_turf(src))
+ del(src)
+
+ processing_objects.Add(src)
+ spawned_animal = new spawn_type(get_turf(src))
+
+/obj/effect/landmark/animal_spawner/process()
+ //if any of our animals are killed, spawn new ones
+ if(!spawned_animal || spawned_animal.stat == DEAD)
+ spawned_animal = new spawn_type(src)
+ //after a random timeout, and in a random position (6-30 seconds)
+ spawn(rand(1200,2400))
+ spawned_animal.loc = locate(src.x + rand(-12,12), src.y + rand(-12,12), src.z)
+
+/obj/effect/landmark/animal_spawner/Del()
+ processing_objects.Remove(src)
+
+/obj/effect/landmark/animal_spawner/panther
+ name = "panther spawner"
+ spawn_type = /mob/living/simple_animal/hostile/panther
+
+/obj/effect/landmark/animal_spawner/parrot
+ name = "parrot spawner"
+ spawn_type = /mob/living/simple_animal/parrot
+
+/obj/effect/landmark/animal_spawner/monkey
+ name = "monkey spawner"
+ spawn_type = /mob/living/carbon/monkey
+
+/obj/effect/landmark/animal_spawner/snake
+ name = "snake spawner"
+ spawn_type = /mob/living/simple_animal/hostile/snake
+
+
+//*********//
+// Panther //
+//*********//
+
+/mob/living/simple_animal/hostile/panther
+ name = "panther"
+ desc = "A long sleek, black cat with sharp teeth and claws."
+ icon = 'jungle.dmi'
+ icon_state = "panther"
+ icon_living = "panther"
+ icon_dead = "panther_dead"
+ icon_gib = "panther_dead"
+ speak_chance = 0
+ turns_per_move = 3
+ meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
+ response_help = "pets the"
+ response_disarm = "gently pushes aside the"
+ response_harm = "hits the"
+ stop_automated_movement_when_pulled = 0
+ maxHealth = 50
+ health = 50
+
+ harm_intent_damage = 8
+ melee_damage_lower = 15
+ melee_damage_upper = 15
+ attacktext = "slashes"
+ attack_sound = 'sound/weapons/bite.ogg'
+
+ layer = 3.1 //so they can stay hidde under the /obj/structure/bush
+ var/stalk_tick_delay = 3
+
+/mob/living/simple_animal/hostile/panther/ListTargets()
+ var/list/targets = list()
+ for(var/mob/living/carbon/human/H in view(src, 10))
+ targets += H
+ return targets
+
+/mob/living/simple_animal/hostile/panther/FindTarget()
+ . = ..()
+ if(.)
+ emote("nashes at [.]")
+
+/mob/living/simple_animal/hostile/panther/AttackingTarget()
+ . =..()
+ var/mob/living/L = .
+ if(istype(L))
+ if(prob(15))
+ L.Weaken(3)
+ L.visible_message("\the [src] knocks down \the [L]!")
+
+/mob/living/simple_animal/hostile/panther/AttackTarget()
+ ..()
+ if(stance == HOSTILE_STANCE_ATTACKING && get_dist(src, target_mob))
+ stalk_tick_delay -= 1
+ if(stalk_tick_delay <= 0)
+ src.loc = get_step_towards(src, target_mob)
+ stalk_tick_delay = 3
+
+//*******//
+// Snake //
+//*******//
+
+/mob/living/simple_animal/hostile/snake
+ name = "snake"
+ desc = "A sinuously coiled, venomous looking reptile."
+ icon = 'jungle.dmi'
+ icon_state = "snake"
+ icon_living = "snake"
+ icon_dead = "snake_dead"
+ icon_gib = "snake_dead"
+ speak_chance = 0
+ turns_per_move = 1
+ meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
+ response_help = "pets the"
+ response_disarm = "gently pushes aside the"
+ response_harm = "hits the"
+ stop_automated_movement_when_pulled = 0
+ maxHealth = 25
+ health = 25
+
+ harm_intent_damage = 2
+ melee_damage_lower = 3
+ melee_damage_upper = 10
+ attacktext = "bites"
+ attack_sound = 'sound/weapons/bite.ogg'
+
+ layer = 3.1 //so they can stay hidde under the /obj/structure/bush
+ var/stalk_tick_delay = 3
+
+/mob/living/simple_animal/hostile/snake/ListTargets()
+ var/list/targets = list()
+ for(var/mob/living/carbon/human/H in view(src, 10))
+ targets += H
+ return targets
+
+/mob/living/simple_animal/hostile/snake/FindTarget()
+ . = ..()
+ if(.)
+ emote("hisses wickedly")
+
+/mob/living/simple_animal/hostile/snake/AttackingTarget()
+ . =..()
+ var/mob/living/L = .
+ if(istype(L))
+ L.apply_damage(rand(3,12), TOX)
+
+/mob/living/simple_animal/hostile/snake/AttackTarget()
+ ..()
+ if(stance == HOSTILE_STANCE_ATTACKING && get_dist(src, target_mob))
+ stalk_tick_delay -= 1
+ if(stalk_tick_delay <= 0)
+ src.loc = get_step_towards(src, target_mob)
+ stalk_tick_delay = 3
diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_plants.dm b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_plants.dm
new file mode 100644
index 00000000000..b78048b0417
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_plants.dm
@@ -0,0 +1,120 @@
+//*********************//
+// Generic undergrowth //
+//*********************//
+
+/obj/structure/bush
+ name = "foliage"
+ desc = "Pretty thick scrub, it'll take something sharp and a lot of determination to clear away."
+ icon = 'jungle.dmi'
+ icon_state = "bush1"
+ density = 1
+ anchored = 1
+ layer = 3.2
+ var/indestructable = 0
+ var/stump = 0
+
+/obj/structure/bush/New()
+ if(prob(20))
+ opacity = 1
+
+/obj/structure/bush/Bumped(M as mob)
+ if (istype(M, /mob/living/simple_animal))
+ var/mob/living/simple_animal/A = M
+ A.loc = get_turf(src)
+ else if (istype(M, /mob/living/carbon/monkey))
+ var/mob/living/carbon/monkey/A = M
+ A.loc = get_turf(src)
+
+/obj/structure/bush/attackby(var/obj/I as obj, var/mob/user as mob)
+ //hatchets can clear away undergrowth
+ if(istype(I, /obj/item/weapon/hatchet) && !stump)
+ if(indestructable)
+ //this bush marks the edge of the map, you can't destroy it
+ user << "\red You flail away at the undergrowth, but it's too thick here."
+ else
+ user.visible_message("\red [user] begins clearing away [src].","\red You begin clearing away [src].")
+ spawn(rand(15,30))
+ if(get_dist(user,src) < 2)
+ user << "\blue You clear away [src]."
+ var/obj/item/stack/sheet/wood/W = new(src.loc)
+ W.amount = rand(3,15)
+ if(prob(50))
+ icon_state = "stump[rand(1,2)]"
+ name = "cleared foliage"
+ desc = "There used to be dense undergrowth here."
+ density = 0
+ stump = 1
+ pixel_x = rand(-6,6)
+ pixel_y = rand(-6,6)
+ else
+ del(src)
+ else
+ return ..()
+
+//*******************************//
+// Strange, fruit-bearing plants //
+//*******************************//
+
+var/list/fruit_icon_states = list("badrecipe","kudzupod","reishi","lime","grapes","boiledrorocore","chocolateegg")
+var/list/reagent_effects = list("toxin","anti_toxin","stoxin","space_drugs","mindbreaker","zombiepowder","impedrezene")
+var/jungle_plants_init = 0
+
+/proc/init_jungle_plants()
+ jungle_plants_init = 1
+ fruit_icon_states = shuffle(fruit_icon_states)
+ reagent_effects = shuffle(reagent_effects)
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/jungle_fruit
+ seed = ""
+ name = "jungle fruit"
+ desc = "It smells weird and looks off."
+ icon = 'jungle.dmi'
+ icon_state = "orange"
+ potency = 1
+
+/obj/structure/jungle_plant
+ icon = 'jungle.dmi'
+ icon_state = "plant1"
+ desc = "Looks like some of that fruit might be edible."
+ var/fruits_left = 3
+ var/fruit_type = -1
+ var/icon/fruit_overlay
+ var/plant_strength = 1
+ var/fruit_r
+ var/fruit_g
+ var/fruit_b
+
+
+/obj/structure/jungle_plant/New()
+ if(!jungle_plants_init)
+ init_jungle_plants()
+
+ fruit_type = rand(1,7)
+ icon_state = "plant[fruit_type]"
+ fruits_left = rand(1,5)
+ fruit_overlay = icon('jungle.dmi',"fruit[fruits_left]")
+ fruit_r = 255 - fruit_type * 36
+ fruit_g = rand(1,255)
+ fruit_b = fruit_type * 36
+ fruit_overlay.Blend(rgb(fruit_r, fruit_g, fruit_b), ICON_ADD)
+ overlays += fruit_overlay
+ plant_strength = rand(20,200)
+
+/obj/structure/jungle_plant/attack_hand(var/mob/user as mob)
+ if(fruits_left > 0)
+ fruits_left--
+ user << "\blue You pick a fruit off [src]."
+
+ var/obj/item/weapon/reagent_containers/food/snacks/grown/jungle_fruit/J = new (src.loc)
+ J.potency = plant_strength
+ J.icon_state = fruit_icon_states[fruit_type]
+ J.reagents.add_reagent(reagent_effects[fruit_type], 1+round((plant_strength / 20), 1))
+ J.bitesize = 1+round(J.reagents.total_volume / 2, 1)
+ J.attack_hand(user)
+
+ overlays -= fruit_overlay
+ fruit_overlay = icon('jungle.dmi',"fruit[fruits_left]")
+ fruit_overlay.Blend(rgb(fruit_r, fruit_g, fruit_b), ICON_ADD)
+ overlays += fruit_overlay
+ else
+ user << "\red There are no fruit left on [src]."
diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_temple.dm b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_temple.dm
new file mode 100644
index 00000000000..c34cce4e3de
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_temple.dm
@@ -0,0 +1,401 @@
+//randomly generated temples, indiana jones style (minus the cultists, probably)
+
+/area/jungle/temple_one
+ name = "temple"
+ lighting_use_dynamic = 1
+ icon = 'jungle.dmi'
+ icon_state = "temple1"
+
+/area/jungle/temple_two
+ name = "temple"
+ lighting_use_dynamic = 1
+ icon = 'jungle.dmi'
+ icon_state = "temple2"
+
+/area/jungle/temple_three
+ name = "temple"
+ lighting_use_dynamic = 1
+ icon = 'jungle.dmi'
+ icon_state = "temple3"
+
+/area/jungle/temple_four
+ name = "temple"
+ lighting_use_dynamic = 1
+ icon = 'jungle.dmi'
+ icon_state = "temple4"
+
+/area/jungle/temple_five
+ name = "temple"
+ lighting_use_dynamic = 1
+ icon = 'jungle.dmi'
+ icon_state = "temple5"
+
+/area/jungle/temple_six
+ name = "temple"
+ lighting_use_dynamic = 1
+ icon = 'jungle.dmi'
+ icon_state = "temple6"
+
+/obj/effect/landmark/door_spawner
+ name = "door spawner"
+
+//******//
+// Loot //
+//******//
+
+/obj/effect/landmark/glowshroom_spawn
+ icon_state = "x3"
+ invisibility = 101
+ New()
+ if(prob(10))
+ new /obj/effect/glowshroom(src.loc)
+ del(src)
+
+/obj/effect/landmark/loot_spawn
+ name = "loot spawner"
+ icon_state = "grabbed1"
+ var/low_probability = 0
+ New()
+
+ switch(pick( \
+ low_probability * 1000;"nothing", \
+ 200 - low_probability * 175;"treasure", \
+ 25 + low_probability * 75;"remains", \
+ 25 + low_probability * 75;"plants", \
+ 5; "blob", \
+ 50 + low_probability * 50;"clothes", \
+ "glasses", \
+ 100 - low_probability * 50;"weapons", \
+ 100 - low_probability * 50;"spacesuit", \
+ "health", \
+ 25 + low_probability * 75;"snacks", \
+ 25;"alien", \
+ "lights", \
+ 25 - low_probability * 25;"engineering", \
+ 25 - low_probability * 25;"coffin", \
+ 25;"mimic", \
+ 25;"viscerator", \
+ ))
+ if("treasure")
+ var/obj/structure/closet/crate/C = new(src.loc)
+ if(prob(33))
+ //coins
+
+ var/amount = rand(2,6)
+ var/list/possible_spawns = list()
+ for(var/coin_type in typesof(/obj/item/weapon/coin))
+ possible_spawns += coin_type
+
+ //no icon_state for mythril coins
+ possible_spawns -= /obj/item/weapon/coin/mythril
+
+ var/coin_type = pick(possible_spawns)
+ for(var/i=0,iA sawblade shoots out of the ground and strikes you!"
+ M.apply_damage(rand(5,10), BRUTE)
+
+ var/atom/myloc = src.loc
+ var/image/flicker = image('jungle.dmi',"sawblade")
+ myloc.overlays += flicker
+ spawn(8)
+ myloc.overlays -= flicker
+ del(flicker)
+ //flick("sawblade",src)
+ if("poison_dart")
+ M << "\red You feel something small and sharp strike you!"
+ M.apply_damage(rand(5,10), TOX)
+
+ var/atom/myloc = src.loc
+ var/image/flicker = image('jungle.dmi',"dart[rand(1,3)]")
+ myloc.overlays += flicker
+ spawn(8)
+ myloc.overlays -= flicker
+ del(flicker)
+ //flick("dart[rand(1,3)]",src)
+ if("flame_burst")
+ M << "\red A jet of fire comes out of nowhere!"
+ M.apply_damage(rand(5,10), BURN)
+
+ var/atom/myloc = src.loc
+ var/image/flicker = image('jungle.dmi',"flameburst")
+ myloc.overlays += flicker
+ spawn(8)
+ myloc.overlays -= flicker
+ del flicker
+ //flick("flameburst",src)
+ if("plasma_gas")
+ //spawn a bunch of plasma
+ if("n2_gas")
+ //spawn a bunch of sleeping gas
+ if("thrower")
+ //edited version of obj/effect/step_trigger/thrower
+ var/throw_dir = pick(1,2,4,8)
+ M.visible_message("\red The floor under [M] suddenly tips upward!","\red The floor tips upward under you!")
+
+ var/atom/myloc = src.loc
+ var/image/flicker = image('jungle.dmi',"throw[throw_dir]")
+ myloc.overlays += flicker
+ var/turf/my_turf = get_turf(loc)
+ if(!my_turf.density)
+ my_turf.density = 1
+ spawn(8)
+ my_turf.density = 0
+ spawn(8)
+ myloc.overlays -= flicker
+ del(flicker)
+
+ var/dist = rand(1,5)
+ var/curtiles = 0
+ while(M)
+ if(curtiles >= dist)
+ break
+ if(M.z != src.z)
+ break
+
+ curtiles++
+ sleep(1)
+
+ var/predir = M.dir
+ step(M, throw_dir)
+ M.dir = predir
+
+//gives turf a different description, to try and trick players
+/obj/effect/step_trigger/trap/fake
+ icon_state = "faketrap"
+ name = "fake trap"
+
+ New()
+ if(prob(10))
+ new /obj/effect/glowshroom(src.loc)
+ if(prob(90))
+ var/turf/T = get_turf(src)
+ T.desc = pick("It looks a little dustier than the surrounding tiles.","It is somewhat ornate.","It looks a little darker than the surrounding tiles.")
+ del(src)
+
+//50% chance of being a trap
+/obj/effect/step_trigger/trap/fifty
+ icon_state = "trap"
+ name = "fifty fifty trap"
+ icon_state = "fiftytrap"
+
+ New()
+ if(prob(50))
+ ..()
+ else
+ if(prob(10))
+ new /obj/effect/glowshroom(src.loc)
+ del(src)
diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_tribe.dm b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_tribe.dm
new file mode 100644
index 00000000000..9cf9b17c887
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_tribe.dm
@@ -0,0 +1,91 @@
+
+
+/obj/item/projectile/jungle_spear
+ damage = 10
+ damage_type = TOX
+ icon_state = "bullet"
+
+/obj/effect/jungle_tribe_spawn
+ name = "campfire"
+ desc = "Looks cosy, in an alien sort of way."
+ icon = 'jungle.dmi'
+ icon_state = "campfire"
+ anchored = 1
+ var/list/tribesmen = list()
+ var/list/enemy_players = list()
+ var/tribe_type = 1
+
+/obj/effect/jungle_tribe_spawn/New()
+ processing_objects.Add(src)
+ tribe_type = rand(1,5)
+
+ var/num_tribesmen = rand(3,6)
+ for(var/i=0,i[src] throws a spear at [target_mob]!", 1)
+ flick(src, "native[my_type]_act")
+
+ var/tturf = get_turf(target_mob)
+ Shoot(tturf, src.loc, src)
diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_turfs.dm b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_turfs.dm
new file mode 100644
index 00000000000..a2275490ef8
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_turfs.dm
@@ -0,0 +1,178 @@
+
+/turf/unsimulated/jungle
+ var/bushes_spawn = 1
+ var/plants_spawn = 1
+ name = "wet grass"
+ desc = "Thick, long wet grass"
+ icon = 'jungle.dmi'
+ icon_state = "grass1"
+ var/icon_spawn_state = "grass1"
+ luminosity = 3
+
+ New()
+ icon_state = icon_spawn_state
+
+ if(plants_spawn && prob(40))
+ if(prob(90))
+ var/image/I
+ if(prob(35))
+ I = image('jungle.dmi',"plant[rand(1,7)]")
+ else
+ if(prob(30))
+ I = image('icons/obj/flora/ausflora.dmi',"reedbush_[rand(1,4)]")
+ else if(prob(33))
+ I = image('icons/obj/flora/ausflora.dmi',"leafybush_[rand(1,3)]")
+ else if(prob(50))
+ I = image('icons/obj/flora/ausflora.dmi',"fernybush_[rand(1,3)]")
+ else
+ I = image('icons/obj/flora/ausflora.dmi',"stalkybush_[rand(1,3)]")
+ I.pixel_x = rand(-6,6)
+ I.pixel_y = rand(-6,6)
+ overlays += I
+ else
+ var/obj/structure/jungle_plant/J = new(src)
+ J.pixel_x = rand(-6,6)
+ J.pixel_y = rand(-6,6)
+ if(bushes_spawn && prob(90))
+ new /obj/structure/bush(src)
+
+/turf/unsimulated/jungle/clear
+ bushes_spawn = 0
+ plants_spawn = 0
+ icon_state = "grass_clear"
+ icon_spawn_state = "grass3"
+
+/turf/unsimulated/jungle/path
+ bushes_spawn = 0
+ name = "wet grass"
+ desc = "thick, long wet grass"
+ icon = 'jungle.dmi'
+ icon_state = "grass_path"
+ icon_spawn_state = "grass2"
+
+ New()
+ ..()
+ for(var/obj/structure/bush/B in src)
+ del B
+
+/turf/unsimulated/jungle/proc/Spread(var/probability, var/prob_loss = 50)
+ if(probability <= 0)
+ return
+
+ //world << "\blue Spread([probability])"
+ for(var/turf/unsimulated/jungle/J in orange(1, src))
+ if(!J.bushes_spawn)
+ continue
+
+ var/turf/unsimulated/jungle/P = null
+ if(J.type == src.type)
+ P = J
+ else
+ P = new src.type(J)
+
+ if(P && prob(probability))
+ P.Spread(probability - prob_loss)
+
+/turf/unsimulated/jungle/impenetrable
+ bushes_spawn = 0
+ icon_state = "grass_impenetrable"
+ icon_spawn_state = "grass1"
+ New()
+ ..()
+ var/obj/structure/bush/B = new(src)
+ B.indestructable = 1
+
+//copy paste from asteroid mineral turfs
+/turf/unsimulated/jungle/rock
+ bushes_spawn = 0
+ plants_spawn = 0
+ density = 1
+ name = "rock wall"
+ icon = 'icons/turf/walls.dmi'
+ icon_state = "rock"
+ icon_spawn_state = "rock"
+
+/turf/unsimulated/jungle/rock/New()
+ spawn(1)
+ var/turf/T
+ if(!istype(get_step(src, NORTH), /turf/unsimulated/jungle/rock) && !istype(get_step(src, NORTH), /turf/unsimulated/wall))
+ T = get_step(src, NORTH)
+ if (T)
+ T.overlays += image('icons/turf/walls.dmi', "rock_side_s")
+ if(!istype(get_step(src, SOUTH), /turf/unsimulated/jungle/rock) && !istype(get_step(src, SOUTH), /turf/unsimulated/wall))
+ T = get_step(src, SOUTH)
+ if (T)
+ T.overlays += image('icons/turf/walls.dmi', "rock_side_n", layer=6)
+ if(!istype(get_step(src, EAST), /turf/unsimulated/jungle/rock) && !istype(get_step(src, EAST), /turf/unsimulated/wall))
+ T = get_step(src, EAST)
+ if (T)
+ T.overlays += image('icons/turf/walls.dmi', "rock_side_w", layer=6)
+ if(!istype(get_step(src, WEST), /turf/unsimulated/jungle/rock) && !istype(get_step(src, WEST), /turf/unsimulated/wall))
+ T = get_step(src, WEST)
+ if (T)
+ T.overlays += image('icons/turf/walls.dmi', "rock_side_e", layer=6)
+
+/turf/unsimulated/jungle/water
+ bushes_spawn = 0
+ name = "murky water"
+ desc = "thick, murky water"
+ icon = 'icons/misc/beach.dmi'
+ icon_state = "water"
+ icon_spawn_state = "water"
+
+/turf/unsimulated/jungle/water/New()
+ ..()
+ for(var/obj/structure/bush/B in src)
+ del(B)
+
+/turf/unsimulated/jungle/water/Entered(atom/movable/O)
+ ..()
+ if(istype(O, /mob/living/))
+ var/mob/living/M = O
+ //slip in the murky water if we try to run through it
+ if(prob(10 + (M.m_intent == "run" ? 40 : 0)))
+ M << pick("\blue You slip on something slimy.","\blue You fall over into the murk.")
+ M.Stun(2)
+ M.Weaken(1)
+
+ //piranhas - 25% chance to be an omnipresent risk, although they do practically no damage
+ if(prob(25))
+ M << "\blue You feel something slithering around your legs."
+ if(prob(50))
+ spawn(rand(25,50))
+ var/turf/T = get_turf(M)
+ if(istype(T, /turf/unsimulated/jungle/water))
+ M << pick("\red Something sharp bites you!","\red Sharp teeth grab hold of you!","\red You feel something take a chunk out of your leg!")
+ M.apply_damage(rand(0,1), BRUTE)
+ if(prob(50))
+ spawn(rand(25,50))
+ var/turf/T = get_turf(M)
+ if(istype(T, /turf/unsimulated/jungle/water))
+ M << pick("\red Something sharp bites you!","\red Sharp teeth grab hold of you!","\red You feel something take a chunk out of your leg!")
+ M.apply_damage(rand(0,1), BRUTE)
+ if(prob(50))
+ spawn(rand(25,50))
+ var/turf/T = get_turf(M)
+ if(istype(T, /turf/unsimulated/jungle/water))
+ M << pick("\red Something sharp bites you!","\red Sharp teeth grab hold of you!","\red You feel something take a chunk out of your leg!")
+ M.apply_damage(rand(0,1), BRUTE)
+ if(prob(50))
+ spawn(rand(25,50))
+ var/turf/T = get_turf(M)
+ if(istype(T, /turf/unsimulated/jungle/water))
+ M << pick("\red Something sharp bites you!","\red Sharp teeth grab hold of you!","\red You feel something take a chunk out of your leg!")
+ M.apply_damage(rand(0,1), BRUTE)
+
+/turf/unsimulated/jungle/water/deep
+ plants_spawn = 0
+ density = 1
+ icon_state = "water2"
+ icon_spawn_state = "water2"
+
+/turf/unsimulated/jungle/temple_wall
+ name = "temple wall"
+ desc = ""
+ density = 1
+ icon = 'icons/turf/walls.dmi'
+ icon_state = "plasma0"
+ var/mineral = "plasma"
diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/misc_helpers.dm b/code/WorkInProgress/Cael_Aislinn/Jungle/misc_helpers.dm
new file mode 100644
index 00000000000..ffc1265b7dd
--- /dev/null
+++ b/code/WorkInProgress/Cael_Aislinn/Jungle/misc_helpers.dm
@@ -0,0 +1,122 @@
+//put this here because i needed specific functionality, and i wanted to avoid the hassle of getting it onto svn
+
+
+/area/proc/copy_turfs_to(var/area/A , var/platingRequired = 0 )
+ //Takes: Area. Optional: If it should copy to areas that don't have plating
+ //Returns: Nothing.
+ //Notes: Attempts to move the contents of one area to another area.
+ // Movement based on lower left corner. Tiles that do not fit
+ // into the new area will not be moved.
+
+ if(!A || !src) return 0
+
+ var/list/turfs_src = get_area_turfs(src.type)
+ var/list/turfs_trg = get_area_turfs(A.type)
+
+ var/src_min_x = 0
+ var/src_min_y = 0
+ for (var/turf/T in turfs_src)
+ if(T.x < src_min_x || !src_min_x) src_min_x = T.x
+ if(T.y < src_min_y || !src_min_y) src_min_y = T.y
+
+ var/trg_min_x = 0
+ var/trg_min_y = 0
+ for (var/turf/T in turfs_trg)
+ if(T.x < trg_min_x || !trg_min_x) trg_min_x = T.x
+ if(T.y < trg_min_y || !trg_min_y) trg_min_y = T.y
+
+ var/list/refined_src = new/list()
+ for(var/turf/T in turfs_src)
+ refined_src += T
+ refined_src[T] = new/datum/coords
+ var/datum/coords/C = refined_src[T]
+ C.x_pos = (T.x - src_min_x)
+ C.y_pos = (T.y - src_min_y)
+
+ var/list/refined_trg = new/list()
+ for(var/turf/T in turfs_trg)
+ refined_trg += T
+ refined_trg[T] = new/datum/coords
+ var/datum/coords/C = refined_trg[T]
+ C.x_pos = (T.x - trg_min_x)
+ C.y_pos = (T.y - trg_min_y)
+
+ var/list/toupdate = new/list()
+
+ var/copiedobjs = list()
+
+
+ moving:
+ for (var/turf/T in refined_src)
+ var/datum/coords/C_src = refined_src[T]
+ for (var/turf/B in refined_trg)
+ var/datum/coords/C_trg = refined_trg[B]
+ if(C_src.x_pos == C_trg.x_pos && C_src.y_pos == C_trg.y_pos)
+
+ var/old_dir1 = T.dir
+ var/old_icon_state1 = T.icon_state
+ var/old_icon1 = T.icon
+
+ if(platingRequired)
+ if(istype(B, /turf/space))
+ continue moving
+
+ var/turf/X = new T.type(B)
+ X.dir = old_dir1
+ X.icon_state = old_icon_state1
+ X.icon = old_icon1 //Shuttle floors are in shuttle.dmi while the defaults are floors.dmi
+
+
+ var/list/mobs = new/list()
+ var/list/newmobs = new/list()
+
+ for(var/mob/M in T)
+
+ if(!istype(M,/mob) || istype(M, /mob/aiEye)) continue // If we need to check for more mobs, I'll add a variable
+ mobs += M
+
+ for(var/mob/M in mobs)
+ newmobs += DuplicateObject(M , 1)
+
+ for(var/mob/M in newmobs)
+ M.loc = X
+
+
+
+ for(var/V in T.vars)
+ if(!(V in list("type","loc","locs","vars", "parent", "parent_type","verbs","ckey","key","x","y","z","contents", "luminosity")))
+ X.vars[V] = T.vars[V]
+
+// var/area/AR = X.loc
+
+// if(AR.lighting_use_dynamic)
+// X.opacity = !X.opacity
+// X.sd_SetOpacity(!X.opacity) //TODO: rewrite this code so it's not messed by lighting ~Carn
+
+ toupdate += X
+
+ refined_src -= T
+ refined_trg -= B
+ continue moving
+
+
+
+
+ /*var/list/doors = new/list()
+
+ if(toupdate.len)
+ for(var/turf/simulated/T1 in toupdate)
+ for(var/obj/machinery/door/D2 in T1)
+ doors += D2
+ if(T1.parent)
+ air_master.groups_to_rebuild += T1.parent
+ else
+ air_master.tiles_to_update += T1
+
+ for(var/obj/O in doors)
+ O:update_nearby_tiles(1)*/
+
+
+
+
+ return copiedobjs
diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/core_monitor.dm b/code/WorkInProgress/Cael_Aislinn/Rust/core_monitor.dm
index 3dcfda32c05..b7a464a6754 100644
--- a/code/WorkInProgress/Cael_Aislinn/Rust/core_monitor.dm
+++ b/code/WorkInProgress/Cael_Aislinn/Rust/core_monitor.dm
@@ -13,15 +13,6 @@
spawn(0)
core_generator = locate() in world
- attack_ai(mob/user)
- attack_hand(user)
-
- attack_hand(mob/user)
- add_fingerprint(user)
- if(stat & (BROKEN|NOPOWER))
- return
- interact(user)
-
Topic(href, href_list)
..()
if( href_list["shutdown"] )
@@ -52,36 +43,35 @@
if(updating)
src.updateDialog()
- proc
- interact(mob/user)
- if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
- if (!istype(user, /mob/living/silicon))
- user.machine = null
- user << browse(null, "window=core_monitor")
- return
- var/t = "Reactor Core Primary Monitor
"
- if(core_generator)
- t += "[core_generator.on ? "Core Generator connected" : "Core Generator operational"]
"
- if(core_generator.owned_field)
- t += "Core suspension field online \[Bring field offline\]
"
- t += "Electromagnetic plasma suspension field status:
"
- t += " Strength (T): [core_generator.owned_field.field_strength] \[Modify\]
"
- t += " Energy levels (MeV): [core_generator.owned_field.mega_energy]
"
- t += " Core frequency: [core_generator.owned_field.frequency]
"
- t += " Moles of plasma: [core_generator.owned_field.held_plasma.toxins]
"
- t += " Core temperature: [core_generator.owned_field.held_plasma.temperature]
"
- t += "
"
- t += "Core atomic and subatomic constituents:
"
- if(core_generator.owned_field.dormant_reactant_quantities && core_generator.owned_field.dormant_reactant_quantities.len)
- for(var/reagent in core_generator.owned_field.dormant_reactant_quantities)
- t += " [reagent]: [core_generator.owned_field.dormant_reactant_quantities[reagent]]
"
- else
- t += " No reactants present.
"
+ interact(mob/user)
+ if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
+ if (!istype(user, /mob/living/silicon))
+ user.machine = null
+ user << browse(null, "window=core_monitor")
+ return
+ var/t = "Reactor Core Primary Monitor
"
+ if(core_generator)
+ t += "[core_generator.on ? "Core Generator connected" : "Core Generator operational"]
"
+ if(core_generator.owned_field)
+ t += "Core suspension field online \[Bring field offline\]
"
+ t += "Electromagnetic plasma suspension field status:
"
+ t += " Strength (T): [core_generator.owned_field.field_strength] \[Modify\]
"
+ t += " Energy levels (MeV): [core_generator.owned_field.mega_energy]
"
+ t += " Core frequency: [core_generator.owned_field.frequency]
"
+ t += " Moles of plasma: [core_generator.owned_field.held_plasma.toxins]
"
+ t += " Core temperature: [core_generator.owned_field.held_plasma.temperature]
"
+ t += "
"
+ t += "Core atomic and subatomic constituents:
"
+ if(core_generator.owned_field.dormant_reactant_quantities && core_generator.owned_field.dormant_reactant_quantities.len)
+ for(var/reagent in core_generator.owned_field.dormant_reactant_quantities)
+ t += " [reagent]: [core_generator.owned_field.dormant_reactant_quantities[reagent]]
"
else
- t += "Core suspension field offline \[Bring field online\]
"
+ t += " No reactants present.
"
else
- t += "Core Generator unresponsive
"
- t += "
"
- t += "Close
"
- user << browse(t, "window=core_monitor;size=500x400")
- user.machine = src
+ t += "Core suspension field offline \[Bring field online\]
"
+ else
+ t += "Core Generator unresponsive
"
+ t += "
"
+ t += "Close
"
+ user << browse(t, "window=core_monitor;size=500x400")
+ user.machine = src
diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_compressor.dm b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_compressor.dm
index 0b05a73927a..a1e28294262 100644
--- a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_compressor.dm
+++ b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_compressor.dm
@@ -68,21 +68,20 @@ var/const/max_assembly_amount = 300
F.loc = src.loc
return
- proc
- interact(mob/user)
- /*if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
- if (!istype(user, /mob/living/silicon))
- user.machine = null
- user << browse(null, "window=fuelcomp")
- return*/
- var/t = "Reactor Fuel Rod Compressor / Assembler
"
- t += "Close
"
- t += "Activate Fuel Synthesis
(fuel assemblies require no more than [max_assembly_amount] rods).
"
- t += "
"
- t += "- New fuel assembly constituents:-
"
- for(var/reagent in new_assembly_quantities)
- t += " [reagent] rods: [new_assembly_quantities[reagent]] \[Modify\]
"
- t += "
"
- t += "Close
"
- user << browse(t, "window=fuelcomp;size=500x800")
- user.machine = src
+ interact(mob/user)
+ /*if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
+ if (!istype(user, /mob/living/silicon))
+ user.machine = null
+ user << browse(null, "window=fuelcomp")
+ return*/
+ var/t = "Reactor Fuel Rod Compressor / Assembler
"
+ t += "Close
"
+ t += "Activate Fuel Synthesis
(fuel assemblies require no more than [max_assembly_amount] rods).
"
+ t += "
"
+ t += "- New fuel assembly constituents:-
"
+ for(var/reagent in new_assembly_quantities)
+ t += " [reagent] rods: [new_assembly_quantities[reagent]] \[Modify\]
"
+ t += "
"
+ t += "Close
"
+ user << browse(t, "window=fuelcomp;size=500x800")
+ user.machine = src
diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_control.dm b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_control.dm
index 4895dfe9199..f4a7f700fa4 100644
--- a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_control.dm
+++ b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_control.dm
@@ -121,53 +121,52 @@
..()
src.updateDialog()
- proc
- interact(mob/user)
- if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
- if (!istype(user, /mob/living/silicon))
- user.machine = null
- user << browse(null, "window=fuel_monitor")
- return
- var/t = "Reactor Core Fuel Control
"
- var/cooling = 0
- for(var/stage in stage_status)
- if(stage_status[stage])
- t += "Fuel injection: Active
"
- t += "Enter cooldown phase
"
- cooling = 1
- break
- if(!cooling)
- t += "Fuel injection: Cooling
"
- t += "----
"
- //
- t += "Fuel depletion announcement: "
- t += "[announce_fueldepletion ? "Disable" : "Disabled"] "
- t += "[announce_fueldepletion == 1 ? "Announcing" : "Announce"] "
- t += "[announce_fueldepletion == 2 ? "Broadcasting" : "Broadcast"]
"
- t += "Stage progression announcement: "
- t += "[announce_stageprogression ? "Disable" : "Disabled"] "
- t += "[announce_stageprogression == 1 ? "Announcing" : "Announce"] "
- t += "[announce_stageprogression == 2 ? "Broadcasting" : "Broadcast"] "
- t += "
"
- t += ""
- t += "| Injector Status | "
- t += "Injection interval (sec) | "
- t += "Assembly consumption per injection | "
- t += "Fuel Assembly Port | "
- t += "Assembly depletion percentage | "
- t += "
"
- for(var/stage_name in fuel_injectors)
- var/list/cur_stage = fuel_injectors[stage_name]
- t += "| Fuel Injection Stage: [stage_name], [stage_status[stage_name] ? "Active \[Enter cooldown\]" : "Cooling \[Begin injection\]"] |
"
- for(var/obj/machinery/rust/fuel_injector/Injector in cur_stage)
- t += ""
- t += "| [Injector.on && Injector.remote_enabled ? "Operational" : "Unresponsive"] | "
- t += "[Injector.rate/10] Modify | "
- t += "[Injector.fuel_usage*100]% Modify | "
- t += "[Injector.owned_assembly_port ? "[Injector.owned_assembly_port.cur_assembly ? "Loaded": "Empty"]" : "Disconnected" ] | "
- t += "[Injector.owned_assembly_port && Injector.owned_assembly_port.cur_assembly ? "[Injector.owned_assembly_port.cur_assembly.percent_depleted]%" : ""] | "
- t += "
"
- t += "
"
- t += "Close
"
- user << browse(t, "window=fuel_monitor;size=500x600")
- user.machine = src
+ interact(mob/user)
+ if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
+ if (!istype(user, /mob/living/silicon))
+ user.machine = null
+ user << browse(null, "window=fuel_monitor")
+ return
+ var/t = "Reactor Core Fuel Control
"
+ var/cooling = 0
+ for(var/stage in stage_status)
+ if(stage_status[stage])
+ t += "Fuel injection: Active
"
+ t += "Enter cooldown phase
"
+ cooling = 1
+ break
+ if(!cooling)
+ t += "Fuel injection: Cooling
"
+ t += "----
"
+ //
+ t += "Fuel depletion announcement: "
+ t += "[announce_fueldepletion ? "Disable" : "Disabled"] "
+ t += "[announce_fueldepletion == 1 ? "Announcing" : "Announce"] "
+ t += "[announce_fueldepletion == 2 ? "Broadcasting" : "Broadcast"]
"
+ t += "Stage progression announcement: "
+ t += "[announce_stageprogression ? "Disable" : "Disabled"] "
+ t += "[announce_stageprogression == 1 ? "Announcing" : "Announce"] "
+ t += "[announce_stageprogression == 2 ? "Broadcasting" : "Broadcast"] "
+ t += "
"
+ t += ""
+ t += "| Injector Status | "
+ t += "Injection interval (sec) | "
+ t += "Assembly consumption per injection | "
+ t += "Fuel Assembly Port | "
+ t += "Assembly depletion percentage | "
+ t += "
"
+ for(var/stage_name in fuel_injectors)
+ var/list/cur_stage = fuel_injectors[stage_name]
+ t += "| Fuel Injection Stage: [stage_name], [stage_status[stage_name] ? "Active \[Enter cooldown\]" : "Cooling \[Begin injection\]"] |
"
+ for(var/obj/machinery/rust/fuel_injector/Injector in cur_stage)
+ t += ""
+ t += "| [Injector.on && Injector.remote_enabled ? "Operational" : "Unresponsive"] | "
+ t += "[Injector.rate/10] Modify | "
+ t += "[Injector.fuel_usage*100]% Modify | "
+ t += "[Injector.owned_assembly_port ? "[Injector.owned_assembly_port.cur_assembly ? "Loaded": "Empty"]" : "Disconnected" ] | "
+ t += "[Injector.owned_assembly_port && Injector.owned_assembly_port.cur_assembly ? "[Injector.owned_assembly_port.cur_assembly.percent_depleted]%" : ""] | "
+ t += "
"
+ t += "
"
+ t += "Close
"
+ user << browse(t, "window=fuel_monitor;size=500x600")
+ user.machine = src
diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_injector.dm b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_injector.dm
index 6963b1f5be7..e773939c9f5 100644
--- a/code/WorkInProgress/Cael_Aislinn/Rust/fuel_injector.dm
+++ b/code/WorkInProgress/Cael_Aislinn/Rust/fuel_injector.dm
@@ -97,59 +97,58 @@
return*/
interact(user)
- proc
- interact(mob/user)
- if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
- if (!istype(user, /mob/living/silicon))
- user.machine = null
- user << browse(null, "window=fuel_injector")
- return
- var/t = "Reactor Core Fuel Injector
"
- t += "Stage: [stage]
"
- t += "Status: [injecting ? "Active \[Disable\]" : "Standby \[Enable\]"]
"
- t += "Interval (sec): [rate/10] \[Modify\]
"
- t += "Fuel usage: [fuel_usage*100]% \[Modify\]
"
- /*
- var/t = "Reactor Core Fuel Control
"
- t += "Current fuel injection stage: [active_stage]
"
- if(active_stage == "Cooling")
- //t += "Restart injection cycle
"
- t += "----
"
- else
- t += "Enter cooldown phase
"
- t += "Fuel depletion announcement: "
- t += "[announce_fueldepletion ? "Disable" : "Disabled"] "
- t += "[announce_fueldepletion == 1 ? "Announcing" : "Announce"] "
- t += "[announce_fueldepletion == 2 ? "Broadcasting" : "Broadcast"]
"
- t += "Stage progression announcement: "
- t += "[announce_stageprogression ? "Disable" : "Disabled"] "
- t += "[announce_stageprogression == 1 ? "Announcing" : "Announce"] "
- t += "[announce_stageprogression == 2 ? "Broadcasting" : "Broadcast"] "
- t += "
"
- t += ""
- t += "| Injector Status | "
- t += "Injection interval (sec) | "
- t += "Assembly consumption per injection | "
- t += "Fuel Assembly Port | "
- t += "Assembly depletion percentage | "
- t += "
"
- for(var/stage in fuel_injectors)
- var/list/cur_stage = fuel_injectors[stage]
- t += "| Fuel Injection Stage: [stage] [active_stage == stage ? " (Currently active)" : "Activate"] |
"
- for(var/obj/machinery/rust/fuel_injector/Injector in cur_stage)
- t += ""
- t += "| [Injector.on && Injector.remote_enabled ? "Operational" : "Unresponsive"] | "
- t += "[Injector.rate/10] Modify | "
- t += "[Injector.fuel_usage*100]% Modify | "
- t += "[Injector.owned_assembly_port ? "[Injector.owned_assembly_port.cur_assembly ? "Loaded": "Empty"]" : "Disconnected" ] | "
- t += "[Injector.owned_assembly_port && Injector.owned_assembly_port.cur_assembly ? "[100 - Injector.owned_assembly_port.cur_assembly.amount_depleted*100]%" : ""] | "
- t += "
"
- t += "
"
- */
- t += "
"
- t += "Close
"
- user << browse(t, "window=fuel_injector;size=500x800")
- user.machine = src
+ interact(mob/user)
+ if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
+ if (!istype(user, /mob/living/silicon))
+ user.machine = null
+ user << browse(null, "window=fuel_injector")
+ return
+ var/t = "Reactor Core Fuel Injector
"
+ t += "Stage: [stage]
"
+ t += "Status: [injecting ? "Active \[Disable\]" : "Standby \[Enable\]"]
"
+ t += "Interval (sec): [rate/10] \[Modify\]
"
+ t += "Fuel usage: [fuel_usage*100]% \[Modify\]
"
+ /*
+ var/t = "Reactor Core Fuel Control
"
+ t += "Current fuel injection stage: [active_stage]
"
+ if(active_stage == "Cooling")
+ //t += "Restart injection cycle
"
+ t += "----
"
+ else
+ t += "Enter cooldown phase
"
+ t += "Fuel depletion announcement: "
+ t += "[announce_fueldepletion ? "Disable" : "Disabled"] "
+ t += "[announce_fueldepletion == 1 ? "Announcing" : "Announce"] "
+ t += "[announce_fueldepletion == 2 ? "Broadcasting" : "Broadcast"]
"
+ t += "Stage progression announcement: "
+ t += "[announce_stageprogression ? "Disable" : "Disabled"] "
+ t += "[announce_stageprogression == 1 ? "Announcing" : "Announce"] "
+ t += "[announce_stageprogression == 2 ? "Broadcasting" : "Broadcast"] "
+ t += "
"
+ t += ""
+ t += "| Injector Status | "
+ t += "Injection interval (sec) | "
+ t += "Assembly consumption per injection | "
+ t += "Fuel Assembly Port | "
+ t += "Assembly depletion percentage | "
+ t += "
"
+ for(var/stage in fuel_injectors)
+ var/list/cur_stage = fuel_injectors[stage]
+ t += "| Fuel Injection Stage: [stage] [active_stage == stage ? " (Currently active)" : "Activate"] |
"
+ for(var/obj/machinery/rust/fuel_injector/Injector in cur_stage)
+ t += ""
+ t += "| [Injector.on && Injector.remote_enabled ? "Operational" : "Unresponsive"] | "
+ t += "[Injector.rate/10] Modify | "
+ t += "[Injector.fuel_usage*100]% Modify | "
+ t += "[Injector.owned_assembly_port ? "[Injector.owned_assembly_port.cur_assembly ? "Loaded": "Empty"]" : "Disconnected" ] | "
+ t += "[Injector.owned_assembly_port && Injector.owned_assembly_port.cur_assembly ? "[100 - Injector.owned_assembly_port.cur_assembly.amount_depleted*100]%" : ""] | "
+ t += "
"
+ t += "
"
+ */
+ t += "
"
+ t += "Close
"
+ user << browse(t, "window=fuel_injector;size=500x800")
+ user.machine = src
proc/BeginInjecting()
if(!injecting && owned_assembly_port && owned_assembly_port.cur_assembly)
diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/gyrotron.dm b/code/WorkInProgress/Cael_Aislinn/Rust/gyrotron.dm
index 69553a3d8f3..3926d840330 100644
--- a/code/WorkInProgress/Cael_Aislinn/Rust/gyrotron.dm
+++ b/code/WorkInProgress/Cael_Aislinn/Rust/gyrotron.dm
@@ -163,36 +163,26 @@
pixel_x = -pixel_x
pixel_y = -pixel_y
- attack_ai(mob/user)
- attack_hand(user)
-
- attack_hand(mob/user)
- add_fingerprint(user)
- /*if(stat & (BROKEN|NOPOWER))
- return*/
- interact(user)
-
- proc
- interact(mob/user)
- if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
- if (!istype(user, /mob/living/silicon))
- user.machine = null
- user << browse(null, "window=gyro_monitor")
- return
- var/t = "Free electron MASER (Gyrotron) Control Panel
"
- if(owned_gyrotron && owned_gyrotron.on)
- t += "Gyrotron operational
"
- t += "Operational mode: "
- if(owned_gyrotron.emitting)
- t += "Emitting \[Deactivate\]
"
- else
- t += "Not emitting \[Activate\]
"
- t += "Emission rate: [owned_gyrotron.rate] \[Modify\]
"
- t += "Beam frequency: [owned_gyrotron.frequency] \[Modify\]
"
- t += "Beam power: [owned_gyrotron.mega_energy] \[Modify\]
"
+ interact(mob/user)
+ if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
+ if (!istype(user, /mob/living/silicon))
+ user.machine = null
+ user << browse(null, "window=gyro_monitor")
+ return
+ var/t = "Free electron MASER (Gyrotron) Control Panel
"
+ if(owned_gyrotron && owned_gyrotron.on)
+ t += "Gyrotron operational
"
+ t += "Operational mode: "
+ if(owned_gyrotron.emitting)
+ t += "Emitting \[Deactivate\]
"
else
- t += "Gyrotron unresponsive"
- t += "
"
- t += "Close
"
- user << browse(t, "window=gyro_monitor;size=500x800")
- user.machine = src
+ t += "Not emitting \[Activate\]
"
+ t += "Emission rate: [owned_gyrotron.rate] \[Modify\]
"
+ t += "Beam frequency: [owned_gyrotron.frequency] \[Modify\]
"
+ t += "Beam power: [owned_gyrotron.mega_energy] \[Modify\]
"
+ else
+ t += "Gyrotron unresponsive"
+ t += "
"
+ t += "Close
"
+ user << browse(t, "window=gyro_monitor;size=500x800")
+ user.machine = src
diff --git a/code/WorkInProgress/Cael_Aislinn/Rust/gyrotron_controller.dm b/code/WorkInProgress/Cael_Aislinn/Rust/gyrotron_controller.dm
index 37bbed0e9ff..2c9b6f37d88 100644
--- a/code/WorkInProgress/Cael_Aislinn/Rust/gyrotron_controller.dm
+++ b/code/WorkInProgress/Cael_Aislinn/Rust/gyrotron_controller.dm
@@ -7,20 +7,6 @@
New()
..()
- attack_ai(mob/user)
- attack_hand(user)
-
- attack_hand(mob/user)
- add_fingerprint(user)
- /*if(stat & (BROKEN|NOPOWER))
- return*/
- interact(user)
-
- /*updateDialog()
- for(var/mob/M in range(1))
- if(M.machine == src)
- interact(m)*/
-
Topic(href, href_list)
..()
if( href_list["close"] )
@@ -37,66 +23,65 @@
if(updating)
src.updateDialog()
- proc
- interact(mob/user)
- if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
- if (!istype(user, /mob/living/silicon))
- user.machine = null
- user << browse(null, "window=gyrotron_controller")
- return
- var/t = "Gyrotron Remote Control Console
"
- t += "
"
- for(var/obj/machinery/rust/gyrotron/gyro in world)
- if(gyro.remoteenabled && gyro.on)
- t += "Gyrotron operational
"
- t += "Operational mode: "
- if(gyro.emitting)
- t += "Emitting \[Deactivate\]
"
- else
- t += "Not emitting \[Activate\]
"
- t += "Emission rate: [gyro.rate] \[Modify\]
"
- t += "Beam frequency: [gyro.frequency] \[Modify\]
"
- t += "Beam power: [gyro.mega_energy] \[Modify\]
"
+ interact(mob/user)
+ if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
+ if (!istype(user, /mob/living/silicon))
+ user.machine = null
+ user << browse(null, "window=gyrotron_controller")
+ return
+ var/t = "Gyrotron Remote Control Console
"
+ t += "
"
+ for(var/obj/machinery/rust/gyrotron/gyro in world)
+ if(gyro.remoteenabled && gyro.on)
+ t += "Gyrotron operational
"
+ t += "Operational mode: "
+ if(gyro.emitting)
+ t += "Emitting \[Deactivate\]
"
else
- t += "Gyrotron unresponsive"
- t += "
"
- /*
- var/t = "Reactor Core Fuel Control
"
- t += "Current fuel injection stage: [active_stage]
"
- if(active_stage == "Cooling")
- //t += "Restart injection cycle
"
- t += "----
"
+ t += "Not emitting \[Activate\]
"
+ t += "Emission rate: [gyro.rate] \[Modify\]
"
+ t += "Beam frequency: [gyro.frequency] \[Modify\]
"
+ t += "Beam power: [gyro.mega_energy] \[Modify\]
"
else
- t += "Enter cooldown phase
"
- t += "Fuel depletion announcement: "
- t += "[announce_fueldepletion ? "Disable" : "Disabled"] "
- t += "[announce_fueldepletion == 1 ? "Announcing" : "Announce"] "
- t += "[announce_fueldepletion == 2 ? "Broadcasting" : "Broadcast"]
"
- t += "Stage progression announcement: "
- t += "[announce_stageprogression ? "Disable" : "Disabled"] "
- t += "[announce_stageprogression == 1 ? "Announcing" : "Announce"] "
- t += "[announce_stageprogression == 2 ? "Broadcasting" : "Broadcast"] "
+ t += "Gyrotron unresponsive"
t += "
"
- t += ""
- t += "| Injector Status | "
- t += "Injection interval (sec) | "
- t += "Assembly consumption per injection | "
- t += "Fuel Assembly Port | "
- t += "Assembly depletion percentage | "
- t += "
"
- for(var/stage in fuel_injectors)
- var/list/cur_stage = fuel_injectors[stage]
- t += "| Fuel Injection Stage: [stage] [active_stage == stage ? " (Currently active)" : "Activate"] |
"
- for(var/obj/machinery/rust/fuel_injector/Injector in cur_stage)
- t += ""
- t += "| [Injector.on && Injector.remote_enabled ? "Operational" : "Unresponsive"] | "
- t += "[Injector.rate/10] Modify | "
- t += "[Injector.fuel_usage*100]% Modify | "
- t += "[Injector.owned_assembly_port ? "[Injector.owned_assembly_port.cur_assembly ? "Loaded": "Empty"]" : "Disconnected" ] | "
- t += "[Injector.owned_assembly_port && Injector.owned_assembly_port.cur_assembly ? "[Injector.owned_assembly_port.cur_assembly.amount_depleted*100]%" : ""] | "
- t += "
"
- t += "
"
- */
- t += "Close
"
- user << browse(t, "window=gyrotron_controller;size=500x400")
- user.machine = src
+ /*
+ var/t = "Reactor Core Fuel Control
"
+ t += "Current fuel injection stage: [active_stage]
"
+ if(active_stage == "Cooling")
+ //t += "Restart injection cycle
"
+ t += "----
"
+ else
+ t += "Enter cooldown phase
"
+ t += "Fuel depletion announcement: "
+ t += "[announce_fueldepletion ? "Disable" : "Disabled"] "
+ t += "[announce_fueldepletion == 1 ? "Announcing" : "Announce"] "
+ t += "[announce_fueldepletion == 2 ? "Broadcasting" : "Broadcast"]
"
+ t += "Stage progression announcement: "
+ t += "[announce_stageprogression ? "Disable" : "Disabled"] "
+ t += "[announce_stageprogression == 1 ? "Announcing" : "Announce"] "
+ t += "[announce_stageprogression == 2 ? "Broadcasting" : "Broadcast"] "
+ t += "
"
+ t += ""
+ t += "| Injector Status | "
+ t += "Injection interval (sec) | "
+ t += "Assembly consumption per injection | "
+ t += "Fuel Assembly Port | "
+ t += "Assembly depletion percentage | "
+ t += "
"
+ for(var/stage in fuel_injectors)
+ var/list/cur_stage = fuel_injectors[stage]
+ t += "| Fuel Injection Stage: [stage] [active_stage == stage ? " (Currently active)" : "Activate"] |
"
+ for(var/obj/machinery/rust/fuel_injector/Injector in cur_stage)
+ t += ""
+ t += "| [Injector.on && Injector.remote_enabled ? "Operational" : "Unresponsive"] | "
+ t += "[Injector.rate/10] Modify | "
+ t += "[Injector.fuel_usage*100]% Modify | "
+ t += "[Injector.owned_assembly_port ? "[Injector.owned_assembly_port.cur_assembly ? "Loaded": "Empty"]" : "Disconnected" ] | "
+ t += "[Injector.owned_assembly_port && Injector.owned_assembly_port.cur_assembly ? "[Injector.owned_assembly_port.cur_assembly.amount_depleted*100]%" : ""] | "
+ t += "
"
+ t += "
"
+ */
+ t += "Close
"
+ user << browse(t, "window=gyrotron_controller;size=500x400")
+ user.machine = src
diff --git a/code/WorkInProgress/Cael_Aislinn/Supermatter/LaserComputer.dm b/code/WorkInProgress/Cael_Aislinn/Supermatter/LaserComputer.dm
index 50017200cbb..d606337f4cb 100644
--- a/code/WorkInProgress/Cael_Aislinn/Supermatter/LaserComputer.dm
+++ b/code/WorkInProgress/Cael_Aislinn/Supermatter/LaserComputer.dm
@@ -14,36 +14,26 @@
if(las.id == src.id)
lasers += las
- attack_hand(mob/user)
- add_fingerprint(user)
- if(stat & (BROKEN|NOPOWER))
- return
- interact(user)
-
- attack_ai(mob/user)
- attack_hand(user)
-
process()
..()
updateDialog()
- proc
- interact(mob/user)
- if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
- if (!istype(user, /mob/living/silicon))
- user.machine = null
- user << browse(null, "window=laser_control")
- return
- var/t = "Laser status monitor
"
- for(var/obj/machinery/zero_point_emitter/laser in lasers)
- t += "Zero Point Laser
"
- t += "Power level: - - - - [laser.energy]MeV + + + +
"
- t += "Frequency: - - [laser.freq] + +
"
- t += "Output: [laser.active ? "Online Offline" : "Online Offline "]
"
- t += "
"
- t += "Close
"
- user << browse(t, "window=laser_control;size=500x800")
- user.machine = src
+ interact(mob/user)
+ if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
+ if (!istype(user, /mob/living/silicon))
+ user.machine = null
+ user << browse(null, "window=laser_control")
+ return
+ var/t = "Laser status monitor
"
+ for(var/obj/machinery/zero_point_emitter/laser in lasers)
+ t += "Zero Point Laser
"
+ t += "Power level: - - - - [laser.energy]MeV + + + +
"
+ t += "Frequency: - - [laser.freq] + +
"
+ t += "Output: [laser.active ? "Online Offline" : "Online Offline "]
"
+ t += "
"
+ t += "Close
"
+ user << browse(t, "window=laser_control;size=500x800")
+ user.machine = src
/*
/obj/machinery/computer/lasercon/proc/interact(mob/user)
diff --git a/code/WorkInProgress/Cael_Aislinn/shield_capacitor.dm b/code/WorkInProgress/Cael_Aislinn/shield_capacitor.dm
index 6aca0fd18aa..bd7ccfd7737 100644
--- a/code/WorkInProgress/Cael_Aislinn/shield_capacitor.dm
+++ b/code/WorkInProgress/Cael_Aislinn/shield_capacitor.dm
@@ -119,10 +119,6 @@
if(M == user) continue
M.show_message("\red The [src.name] has been hit with the [W.name] by [user.name]!")
-/obj/machinery/shield_capacitor/attack_hand(mob/user as mob)
- interact(user)
- src.add_fingerprint(user)
-
/obj/machinery/shield_capacitor/Topic(href, href_list[])
..()
if( href_list["close"] )
@@ -144,7 +140,7 @@
//
updateDialog()
-/obj/machinery/shield_capacitor/proc/interact(mob/user)
+/obj/machinery/shield_capacitor/interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.machine = null
diff --git a/code/WorkInProgress/Cael_Aislinn/shield_gen.dm b/code/WorkInProgress/Cael_Aislinn/shield_gen.dm
index c0327346f9c..c87fb4aab98 100644
--- a/code/WorkInProgress/Cael_Aislinn/shield_gen.dm
+++ b/code/WorkInProgress/Cael_Aislinn/shield_gen.dm
@@ -148,11 +148,6 @@
//
updateDialog()
-/obj/machinery/shield_gen/attack_hand(mob/user as mob)
-
- interact(user)
- src.add_fingerprint(user)
-
/obj/machinery/shield_gen/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
@@ -241,7 +236,7 @@
//
updateDialog()
-/obj/machinery/shield_gen/proc/interact(mob/user)
+/obj/machinery/shield_gen/interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.machine = null
diff --git a/code/WorkInProgress/Chinsky/ashtray.dm b/code/WorkInProgress/Chinsky/ashtray.dm
index 9948c306630..1af757b962c 100644
--- a/code/WorkInProgress/Chinsky/ashtray.dm
+++ b/code/WorkInProgress/Chinsky/ashtray.dm
@@ -29,7 +29,7 @@
var/obj/item/clothing/mask/cigarette/cig = W
if (cig.lit == 1)
src.visible_message("[user] crushes [cig] in [src], putting it out.")
- cig.put_out()
+ cig.smoketime = 0
else if (cig.lit == 0)
if(istype(cig, /obj/item/weapon/match))
user << "You place [cig] in [src] without even lighting it. Why would you do that?"
diff --git a/code/modules/mob/living/carbon/amorph/amorph.dm b/code/WorkInProgress/Cib/amorph/amorph.dm
similarity index 96%
rename from code/modules/mob/living/carbon/amorph/amorph.dm
rename to code/WorkInProgress/Cib/amorph/amorph.dm
index c2af2ff75d4..dd1a678f47a 100644
--- a/code/modules/mob/living/carbon/amorph/amorph.dm
+++ b/code/WorkInProgress/Cib/amorph/amorph.dm
@@ -1,590 +1,590 @@
-/mob/living/carbon/amorph
- name = "amorph"
- real_name = "amorph"
- voice_name = "amorph"
- icon = 'icons/mob/amorph.dmi'
- icon_state = ""
-
-
- var/species = "Amorph"
- age = 30.0
-
- var/used_skillpoints = 0
- var/skill_specialization = null
- var/list/skills = null
-
- var/obj/item/l_ear = null
-
- // might use this later to recolor armorphs with icon.SwapColor
- var/slime_color = null
-
- var/examine_text = ""
-
-
-/mob/living/carbon/amorph/New()
-
- ..()
-
- // Amorphs don't have a blood vessel, but they can have reagents in their body
- var/datum/reagents/R = new/datum/reagents(1000)
- reagents = R
- R.my_atom = src
-
- // Amorphs have no DNA(they're more like carbon-based machines)
-
- // Amorphs don't have organs
- ..()
-
-/mob/living/carbon/amorph/Bump(atom/movable/AM as mob|obj, yes)
- if ((!( yes ) || now_pushing))
- return
- now_pushing = 1
- if (ismob(AM))
- var/mob/tmob = AM
-
-//BubbleWrap - Should stop you pushing a restrained person out of the way
-
- if(istype(tmob, /mob/living/carbon/human))
-
- for(var/mob/M in range(tmob, 1))
- if( ((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
-
- //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
- if((tmob.a_intent == "help" || tmob.restrained()) && (a_intent == "help" || src.restrained()) && tmob.canmove && canmove) // mutual brohugs all around!
- var/turf/oldloc = loc
- loc = tmob.loc
- tmob.loc = oldloc
- now_pushing = 0
- for(var/mob/living/carbon/metroid/Metroid in view(1,tmob))
- if(Metroid.Victim == tmob)
- Metroid.UpdateFeed()
- 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.nopush)
- 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))
- if(AM:ini_dir == NORTHWEST || AM:ini_dir == NORTHEAST || AM:ini_dir == SOUTHWEST || AM:ini_dir == SOUTHEAST)
- 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/carbon/amorph/movement_delay()
- var/tally = 2 // amorphs are a bit slower than humans
- var/mob/M = pulling
-
- if(reagents.has_reagent("hyperzine")) return -1
-
- if(reagents.has_reagent("nuka_cola")) return -1
-
- if(analgesic) return -1
-
- if (istype(loc, /turf/space)) return -1 // It's hard to be slowed down in space by... anything
-
- var/health_deficiency = traumatic_shock
- if(health_deficiency >= 40) tally += (health_deficiency / 25)
-
- var/hungry = (500 - nutrition)/5 // So overeat would be 100 and default level would be 80
- if (hungry >= 70) tally += hungry/300
-
- if (bodytemperature < 283.222)
- tally += (283.222 - bodytemperature) / 10 * 1.75
- if (stuttering < 10)
- stuttering = 10
-
- if(shock_stage >= 10) tally += 3
-
- if(tally < 0)
- tally = 0
-
- if(istype(M) && M.lying) //Pulling lying down people is slower
- tally += 3
-
- if(mRun in mutations)
- tally = 0
-
- return tally
-
-/mob/living/carbon/amorph/Stat()
- ..()
- statpanel("Status")
-
- 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(emergency_shuttle)
- if(emergency_shuttle.online && emergency_shuttle.location < 2)
- var/timeleft = emergency_shuttle.timeleft()
- if (timeleft)
- stat(null, "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
-
- if (client.statpanel == "Status")
- if (internal)
- if (!internal.air_contents)
- del(internal)
- else
- stat("Internal Atmosphere Info", internal.name)
- stat("Tank Pressure", internal.air_contents.return_pressure())
- stat("Distribution Pressure", internal.distribute_pressure)
- if (mind)
- if (mind.special_role == "Changeling" && changeling)
- stat("Chemical Storage", changeling.chem_charges)
- stat("Genetic Damage Time", changeling.geneticdamage)
-
-/mob/living/carbon/amorph/ex_act(severity)
- flick("flash", flash)
-
- var/shielded = 0
- var/b_loss = null
- var/f_loss = null
- switch (severity)
- if (1.0)
- b_loss += 500
- if (!prob(getarmor(null, "bomb")))
- gib()
- return
- else
- var/atom/target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
- throw_at(target, 200, 4)
-
- if (2.0)
- if (!shielded)
- b_loss += 60
-
- f_loss += 60
-
- if (!prob(getarmor(null, "bomb")))
- b_loss = b_loss/1.5
- f_loss = f_loss/1.5
-
- if(3.0)
- b_loss += 30
- if (!prob(getarmor(null, "bomb")))
- b_loss = b_loss/2
- if (prob(50) && !shielded)
- Paralyse(10)
-
- src.bruteloss += b_loss
- src.fireloss += f_loss
-
- UpdateDamageIcon()
-
-
-/mob/living/carbon/amorph/blob_act()
- if(stat == 2) return
- show_message("\red The blob attacks you!")
- src.bruteloss += rand(30,40)
- UpdateDamageIcon()
- return
-
-/mob/living/carbon/amorph/u_equip(obj/item/W as obj)
- // These are the only slots an amorph has
- if (W == l_ear)
- l_ear = null
- else if (W == r_hand)
- r_hand = null
-
- update_clothing()
-
-/mob/living/carbon/amorph/db_click(text, t1)
- var/obj/item/W = equipped()
- var/emptyHand = (W == null)
- if ((!emptyHand) && (!istype(W, /obj/item)))
- return
- if (emptyHand)
- usr.next_move = usr.prev_move
- usr:lastDblClick -= 3 //permit the double-click redirection to proceed.
- switch(text)
- if("l_ear")
- if (l_ear)
- if (emptyHand)
- l_ear.DblClick()
- return
- else if(emptyHand)
- return
- if (!( istype(W, /obj/item/clothing/ears) ) && !( istype(W, /obj/item/device/radio/headset) ) && W.w_class != 1)
- return
- u_equip(W)
- l_ear = W
- W.equipped(src, text)
-
- update_clothing()
-
- return
-
-/mob/living/carbon/amorph/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)
- if (istype(O, /obj/effect/immovablerod))
- src.bruteloss += 101
- else
- src.bruteloss += 25
- UpdateDamageIcon()
- updatehealth()
- return
-
-/mob/living/carbon/amorph/Move(a, b, flag)
-
- if (buckled)
- return
-
- if (restrained())
- pulling = null
-
-
- var/t7 = 1
- if (restrained())
- for(var/mob/M in range(src, 1))
- if ((M.pulling == src && M.stat == 0 && !( M.restrained() )))
- t7 = null
- if ((t7 && (pulling && ((get_dist(src, pulling) <= 1 || pulling.loc == loc) && (client && client.moving)))))
- var/turf/T = loc
- . = ..()
-
- if (pulling && pulling.loc)
- if(!( isturf(pulling.loc) ))
- pulling = null
- return
- else
- if(Debug)
- diary <<"pulling disappeared? at [__LINE__] in mob.dm - pulling = [pulling]"
- diary <<"REPORT THIS"
-
- /////
- if(pulling && pulling.anchored)
- pulling = null
- return
-
- if (!restrained())
- var/diag = get_dir(src, pulling)
- if ((diag - 1) & diag)
- else
- diag = null
- if ((get_dist(src, pulling) > 1 || diag))
- if (ismob(pulling))
- var/mob/M = pulling
- var/ok = 1
- if (locate(/obj/item/weapon/grab, M.grabbed_by))
- if (prob(75))
- var/obj/item/weapon/grab/G = pick(M.grabbed_by)
- if (istype(G, /obj/item/weapon/grab))
- for(var/mob/O in viewers(M, null))
- O.show_message(text("\red [] has been pulled from []'s grip by []", G.affecting, G.assailant, src), 1)
- //G = null
- del(G)
- else
- ok = 0
- if (locate(/obj/item/weapon/grab, M.grabbed_by.len))
- ok = 0
- if (ok)
- var/t = M.pulling
- M.pulling = null
-
- //this is the gay blood on floor shit -- Added back -- Skie
- if (M.lying && (prob(M.getBruteLoss() / 6)))
- var/turf/location = M.loc
- if (istype(location, /turf/simulated))
- location.add_blood(M)
- if(ishuman(M))
- var/mob/living/carbon/H = M
- var/blood_volume = round(H:vessel.get_reagent_amount("blood"))
- if(blood_volume > 0)
- H:vessel.remove_reagent("blood",1)
- if(prob(5))
- M.adjustBruteLoss(1)
- visible_message("\red \The [M]'s 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!")
- var/turf/location = M.loc
- if (istype(location, /turf/simulated))
- location.add_blood(M)
- if(ishuman(M))
- var/mob/living/carbon/H = M
- var/blood_volume = round(H:vessel.get_reagent_amount("blood"))
- if(blood_volume > 0)
- H:vessel.remove_reagent("blood",1)
-
- step(pulling, get_dir(pulling.loc, T))
- M.pulling = t
- else
- if (pulling)
- if (istype(pulling, /obj/structure/window))
- if(pulling:ini_dir == NORTHWEST || pulling:ini_dir == NORTHEAST || pulling:ini_dir == SOUTHWEST || pulling:ini_dir == SOUTHEAST)
- for(var/obj/structure/window/win in get_step(pulling,get_dir(pulling.loc, T)))
- pulling = null
- if (pulling)
- step(pulling, get_dir(pulling.loc, T))
- else
- pulling = null
- . = ..()
- if ((s_active && !( s_active in contents ) ))
- s_active.close(src)
-
- for(var/mob/living/carbon/metroid/M in view(1,src))
- M.UpdateFeed(src)
- return
-
-/mob/living/carbon/amorph/proc/misc_clothing_updates()
- // Temporary proc to shove stuff in that was put into update_clothing()
- // for questionable reasons
-
- if (client)
- if (i_select)
- if (intent)
- client.screen += hud_used.intents
-
- var/list/L = dd_text2list(intent, ",")
- L[1] += ":-11"
- i_select.screen_loc = dd_list2text(L,",") //ICONS4
- else
- i_select.screen_loc = null
- if (m_select)
- if (m_int)
- client.screen += hud_used.mov_int
-
- var/list/L = dd_text2list(m_int, ",")
- L[1] += ":-11"
- m_select.screen_loc = dd_list2text(L,",") //ICONS4
- else
- m_select.screen_loc = null
-
- // Probably a lazy way to make sure all items are on the screen exactly once
- if (client)
- client.screen -= contents
- client.screen += contents
-
-/mob/living/carbon/amorph/rebuild_appearance()
- // Lazy method: Just rebuild everything.
- // This can be called when the mob is created, but on other occasions, rebuild_body_overlays(),
- // rebuild_clothing_overlays() etc. should be called individually.
-
- misc_clothing_updates() // silly stuff
-
-/mob/living/carbon/amorph/update_body_appearance()
- // Should be called whenever something about the body appearance itself changes.
-
- misc_clothing_updates() // silly stuff
-
- if(lying)
- icon_state = "lying"
- else
- icon_state = "standing"
-
-/mob/living/carbon/amorph/update_lying()
- // Should be called whenever something about the lying status of the mob might have changed.
-
- if(lying)
- icon_state = "lying"
- else
- icon_state = "standing"
-
-/mob/living/carbon/amorph/hand_p(mob/M as mob)
- // not even sure what this is meant to do
- return
-
-/mob/living/carbon/amorph/restrained()
- if (handcuffed)
- return 0 // handcuffs don't work on amorphs
- return 0
-
-/mob/living/carbon/amorph/var/co2overloadtime = null
-/mob/living/carbon/amorph/var/temperature_resistance = T0C+75
-
-/mob/living/carbon/amorph/show_inv(mob/user as mob)
- // TODO: add a window for extracting stuff from an amorph's mouth
-
-// called when something steps onto an amorph
-// this could be made more general, but for now just handle mulebot
-/mob/living/carbon/amorph/HasEntered(var/atom/movable/AM)
- var/obj/machinery/bot/mulebot/MB = AM
- if(istype(MB))
- MB.RunOver(src)
-
-//gets assignment from ID or ID inside PDA or PDA itself
-//Useful when player do something with computers
-/mob/living/carbon/amorph/proc/get_assignment(var/if_no_id = "No id", var/if_no_job = "No job")
- // TODO: get the ID from the amorph's contents
- return
-
-//gets name from ID or ID inside PDA or PDA itself
-//Useful when player do something with computers
-/mob/living/carbon/amorph/proc/get_authentification_name(var/if_no_id = "Unknown")
- // TODO: get the ID from the amorph's contents
- return
-
-//repurposed proc. Now it combines get_id_name() and get_face_name() to determine a mob's name variable. Made into a seperate proc as it'll be useful elsewhere
-/mob/living/carbon/amorph/proc/get_visible_name()
- // amorphs can't wear clothes or anything, so always return face_name
- return get_face_name()
-
-//Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when polyacided or when updating a human's name variable
-/mob/living/carbon/amorph/proc/get_face_name()
- // there might later be ways for amorphs to change the appearance of their face
- return "[real_name]"
-
-
-//gets ID card object from special clothes slot or null.
-/mob/living/carbon/amorph/proc/get_idcard()
- // TODO: get the ID from the amorph's contents
-
-
-// heal the amorph
-/mob/living/carbon/amorph/heal_overall_damage(var/brute, var/burn)
- bruteloss -= brute
- fireloss -= burn
- bruteloss = max(bruteloss, 0)
- fireloss = max(fireloss, 0)
-
- updatehealth()
- UpdateDamageIcon()
-
-// damage MANY external organs, in random order
-/mob/living/carbon/amorph/take_overall_damage(var/brute, var/burn, var/used_weapon = null)
- bruteloss += brute
- fireloss += burn
-
- updatehealth()
- UpdateDamageIcon()
-
-/mob/living/carbon/amorph/Topic(href, href_list)
- if (href_list["refresh"])
- if((machine)&&(in_range(src, usr)))
- show_inv(machine)
-
- if (href_list["mach_close"])
- var/t1 = text("window=[]", href_list["mach_close"])
- machine = null
- src << browse(null, t1)
-
- if ((href_list["item"] && !( usr.stat ) && usr.canmove && !( usr.restrained() ) && in_range(src, usr) && ticker)) //if game hasn't started, can't make an equip_e
- var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( )
- O.source = usr
- O.target = src
- O.item = usr.equipped()
- O.s_loc = usr.loc
- O.t_loc = loc
- O.place = href_list["item"]
- if(href_list["loc"])
- O.internalloc = href_list["loc"]
- requests += O
- spawn( 0 )
- O.process()
- return
-
- if (href_list["criminal"])
- if(istype(usr, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = usr
- if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud))
- var/perpname = "wot"
- var/modified = 0
-
- /*if(wear_id)
- if(istype(wear_id,/obj/item/weapon/card/id))
- perpname = wear_id:registered_name
- else if(istype(wear_id,/obj/item/device/pda))
- var/obj/item/device/pda/tempPda = wear_id
- perpname = tempPda.owner
- else*/
- perpname = src.name
-
- for (var/datum/data/record/E in data_core.general)
- if (E.fields["name"] == perpname)
- for (var/datum/data/record/R in data_core.security)
- if (R.fields["id"] == E.fields["id"])
-
- var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list("None", "*Arrest*", "Incarcerated", "Parolled", "Released", "Cancel")
-
- if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud))
- if(setcriminal != "Cancel")
- R.fields["criminal"] = setcriminal
- modified = 1
-
- spawn()
- H.handle_regular_hud_updates()
-
- if(!modified)
- usr << "\red Unable to locate a data core entry for this person."
- ..()
- return
-
-
-///eyecheck()
-///Returns a number between -1 to 2
-/mob/living/carbon/amorph/eyecheck()
- return 1
-
-
-/mob/living/carbon/amorph/IsAdvancedToolUser()
- return 1//Amorphs can use guns and such
-
-
-/mob/living/carbon/amorph/updatehealth()
- if(src.nodamage)
- src.health = 100
- src.stat = 0
- return
- src.health = 100 - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss() - src.getCloneLoss() -src.halloss
- return
-
-/mob/living/carbon/amorph/abiotic(var/full_body = 0)
- return 0
-
-/mob/living/carbon/amorph/abiotic2(var/full_body2 = 0)
- return 0
-
-/mob/living/carbon/amorph/getBruteLoss()
- return src.bruteloss
-
-/mob/living/carbon/amorph/adjustBruteLoss(var/amount, var/used_weapon = null)
- src.bruteloss += amount
- if(bruteloss < 0) bruteloss = 0
-
-/mob/living/carbon/amorph/getFireLoss()
- return src.fireloss
-
-/mob/living/carbon/amorph/adjustFireLoss(var/amount,var/used_weapon = null)
- src.fireloss += amount
- if(fireloss < 0) fireloss = 0
-
-/mob/living/carbon/amorph/get_visible_gender()
- return gender
+/mob/living/carbon/amorph
+ name = "amorph"
+ real_name = "amorph"
+ voice_name = "amorph"
+ icon = 'icons/mob/amorph.dmi'
+ icon_state = ""
+
+
+ var/species = "Amorph"
+ age = 30.0
+
+ var/used_skillpoints = 0
+ var/skill_specialization = null
+ var/list/skills = null
+
+ var/obj/item/l_ear = null
+
+ // might use this later to recolor armorphs with icon.SwapColor
+ var/slime_color = null
+
+ var/examine_text = ""
+
+
+/mob/living/carbon/amorph/New()
+
+ ..()
+
+ // Amorphs don't have a blood vessel, but they can have reagents in their body
+ var/datum/reagents/R = new/datum/reagents(1000)
+ reagents = R
+ R.my_atom = src
+
+ // Amorphs have no DNA(they're more like carbon-based machines)
+
+ // Amorphs don't have organs
+ ..()
+
+/mob/living/carbon/amorph/Bump(atom/movable/AM as mob|obj, yes)
+ if ((!( yes ) || now_pushing))
+ return
+ now_pushing = 1
+ if (ismob(AM))
+ var/mob/tmob = AM
+
+//BubbleWrap - Should stop you pushing a restrained person out of the way
+
+ if(istype(tmob, /mob/living/carbon/human))
+
+ for(var/mob/M in range(tmob, 1))
+ if( ((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
+
+ //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
+ if((tmob.a_intent == "help" || tmob.restrained()) && (a_intent == "help" || src.restrained()) && tmob.canmove && canmove) // mutual brohugs all around!
+ var/turf/oldloc = loc
+ loc = tmob.loc
+ tmob.loc = oldloc
+ now_pushing = 0
+ for(var/mob/living/carbon/metroid/Metroid in view(1,tmob))
+ if(Metroid.Victim == tmob)
+ Metroid.UpdateFeed()
+ 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.nopush)
+ 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))
+ if(AM:ini_dir == NORTHWEST || AM:ini_dir == NORTHEAST || AM:ini_dir == SOUTHWEST || AM:ini_dir == SOUTHEAST)
+ 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/carbon/amorph/movement_delay()
+ var/tally = 2 // amorphs are a bit slower than humans
+ var/mob/M = pulling
+
+ if(reagents.has_reagent("hyperzine")) return -1
+
+ if(reagents.has_reagent("nuka_cola")) return -1
+
+ if(analgesic) return -1
+
+ if (istype(loc, /turf/space)) return -1 // It's hard to be slowed down in space by... anything
+
+ var/health_deficiency = traumatic_shock
+ if(health_deficiency >= 40) tally += (health_deficiency / 25)
+
+ var/hungry = (500 - nutrition)/5 // So overeat would be 100 and default level would be 80
+ if (hungry >= 70) tally += hungry/300
+
+ if (bodytemperature < 283.222)
+ tally += (283.222 - bodytemperature) / 10 * 1.75
+ if (stuttering < 10)
+ stuttering = 10
+
+ if(shock_stage >= 10) tally += 3
+
+ if(tally < 0)
+ tally = 0
+
+ if(istype(M) && M.lying) //Pulling lying down people is slower
+ tally += 3
+
+ if(mRun in mutations)
+ tally = 0
+
+ return tally
+
+/mob/living/carbon/amorph/Stat()
+ ..()
+ statpanel("Status")
+
+ 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(emergency_shuttle)
+ if(emergency_shuttle.online && emergency_shuttle.location < 2)
+ var/timeleft = emergency_shuttle.timeleft()
+ if (timeleft)
+ stat(null, "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
+
+ if (client.statpanel == "Status")
+ if (internal)
+ if (!internal.air_contents)
+ del(internal)
+ else
+ stat("Internal Atmosphere Info", internal.name)
+ stat("Tank Pressure", internal.air_contents.return_pressure())
+ stat("Distribution Pressure", internal.distribute_pressure)
+ if (mind)
+ if (mind.special_role == "Changeling" && changeling)
+ stat("Chemical Storage", changeling.chem_charges)
+ stat("Genetic Damage Time", changeling.geneticdamage)
+
+/mob/living/carbon/amorph/ex_act(severity)
+ flick("flash", flash)
+
+ var/shielded = 0
+ var/b_loss = null
+ var/f_loss = null
+ switch (severity)
+ if (1.0)
+ b_loss += 500
+ if (!prob(getarmor(null, "bomb")))
+ gib()
+ return
+ else
+ var/atom/target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
+ throw_at(target, 200, 4)
+
+ if (2.0)
+ if (!shielded)
+ b_loss += 60
+
+ f_loss += 60
+
+ if (!prob(getarmor(null, "bomb")))
+ b_loss = b_loss/1.5
+ f_loss = f_loss/1.5
+
+ if(3.0)
+ b_loss += 30
+ if (!prob(getarmor(null, "bomb")))
+ b_loss = b_loss/2
+ if (prob(50) && !shielded)
+ Paralyse(10)
+
+ src.bruteloss += b_loss
+ src.fireloss += f_loss
+
+ UpdateDamageIcon()
+
+
+/mob/living/carbon/amorph/blob_act()
+ if(stat == 2) return
+ show_message("\red The blob attacks you!")
+ src.bruteloss += rand(30,40)
+ UpdateDamageIcon()
+ return
+
+/mob/living/carbon/amorph/u_equip(obj/item/W as obj)
+ // These are the only slots an amorph has
+ if (W == l_ear)
+ l_ear = null
+ else if (W == r_hand)
+ r_hand = null
+
+ update_clothing()
+
+/mob/living/carbon/amorph/db_click(text, t1)
+ var/obj/item/W = equipped()
+ var/emptyHand = (W == null)
+ if ((!emptyHand) && (!istype(W, /obj/item)))
+ return
+ if (emptyHand)
+ usr.next_move = usr.prev_move
+ usr:lastDblClick -= 3 //permit the double-click redirection to proceed.
+ switch(text)
+ if("l_ear")
+ if (l_ear)
+ if (emptyHand)
+ l_ear.DblClick()
+ return
+ else if(emptyHand)
+ return
+ if (!( istype(W, /obj/item/clothing/ears) ) && !( istype(W, /obj/item/device/radio/headset) ) && W.w_class != 1)
+ return
+ u_equip(W)
+ l_ear = W
+ W.equipped(src, text)
+
+ update_clothing()
+
+ return
+
+/mob/living/carbon/amorph/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)
+ if (istype(O, /obj/effect/immovablerod))
+ src.bruteloss += 101
+ else
+ src.bruteloss += 25
+ UpdateDamageIcon()
+ updatehealth()
+ return
+
+/mob/living/carbon/amorph/Move(a, b, flag)
+
+ if (buckled)
+ return
+
+ if (restrained())
+ pulling = null
+
+
+ var/t7 = 1
+ if (restrained())
+ for(var/mob/M in range(src, 1))
+ if ((M.pulling == src && M.stat == 0 && !( M.restrained() )))
+ t7 = null
+ if ((t7 && (pulling && ((get_dist(src, pulling) <= 1 || pulling.loc == loc) && (client && client.moving)))))
+ var/turf/T = loc
+ . = ..()
+
+ if (pulling && pulling.loc)
+ if(!( isturf(pulling.loc) ))
+ pulling = null
+ return
+ else
+ if(Debug)
+ diary <<"pulling disappeared? at [__LINE__] in mob.dm - pulling = [pulling]"
+ diary <<"REPORT THIS"
+
+ /////
+ if(pulling && pulling.anchored)
+ pulling = null
+ return
+
+ if (!restrained())
+ var/diag = get_dir(src, pulling)
+ if ((diag - 1) & diag)
+ else
+ diag = null
+ if ((get_dist(src, pulling) > 1 || diag))
+ if (ismob(pulling))
+ var/mob/M = pulling
+ var/ok = 1
+ if (locate(/obj/item/weapon/grab, M.grabbed_by))
+ if (prob(75))
+ var/obj/item/weapon/grab/G = pick(M.grabbed_by)
+ if (istype(G, /obj/item/weapon/grab))
+ for(var/mob/O in viewers(M, null))
+ O.show_message(text("\red [] has been pulled from []'s grip by []", G.affecting, G.assailant, src), 1)
+ //G = null
+ del(G)
+ else
+ ok = 0
+ if (locate(/obj/item/weapon/grab, M.grabbed_by.len))
+ ok = 0
+ if (ok)
+ var/t = M.pulling
+ M.pulling = null
+
+ //this is the gay blood on floor shit -- Added back -- Skie
+ if (M.lying && (prob(M.getBruteLoss() / 6)))
+ var/turf/location = M.loc
+ if (istype(location, /turf/simulated))
+ location.add_blood(M)
+ if(ishuman(M))
+ var/mob/living/carbon/H = M
+ var/blood_volume = round(H:vessel.get_reagent_amount("blood"))
+ if(blood_volume > 0)
+ H:vessel.remove_reagent("blood",1)
+ if(prob(5))
+ M.adjustBruteLoss(1)
+ visible_message("\red \The [M]'s 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!")
+ var/turf/location = M.loc
+ if (istype(location, /turf/simulated))
+ location.add_blood(M)
+ if(ishuman(M))
+ var/mob/living/carbon/H = M
+ var/blood_volume = round(H:vessel.get_reagent_amount("blood"))
+ if(blood_volume > 0)
+ H:vessel.remove_reagent("blood",1)
+
+ step(pulling, get_dir(pulling.loc, T))
+ M.pulling = t
+ else
+ if (pulling)
+ if (istype(pulling, /obj/structure/window))
+ if(pulling:ini_dir == NORTHWEST || pulling:ini_dir == NORTHEAST || pulling:ini_dir == SOUTHWEST || pulling:ini_dir == SOUTHEAST)
+ for(var/obj/structure/window/win in get_step(pulling,get_dir(pulling.loc, T)))
+ pulling = null
+ if (pulling)
+ step(pulling, get_dir(pulling.loc, T))
+ else
+ pulling = null
+ . = ..()
+ if ((s_active && !( s_active in contents ) ))
+ s_active.close(src)
+
+ for(var/mob/living/carbon/metroid/M in view(1,src))
+ M.UpdateFeed(src)
+ return
+
+/mob/living/carbon/amorph/proc/misc_clothing_updates()
+ // Temporary proc to shove stuff in that was put into update_clothing()
+ // for questionable reasons
+
+ if (client)
+ if (i_select)
+ if (intent)
+ client.screen += hud_used.intents
+
+ var/list/L = dd_text2list(intent, ",")
+ L[1] += ":-11"
+ i_select.screen_loc = dd_list2text(L,",") //ICONS4
+ else
+ i_select.screen_loc = null
+ if (m_select)
+ if (m_int)
+ client.screen += hud_used.mov_int
+
+ var/list/L = dd_text2list(m_int, ",")
+ L[1] += ":-11"
+ m_select.screen_loc = dd_list2text(L,",") //ICONS4
+ else
+ m_select.screen_loc = null
+
+ // Probably a lazy way to make sure all items are on the screen exactly once
+ if (client)
+ client.screen -= contents
+ client.screen += contents
+
+/mob/living/carbon/amorph/rebuild_appearance()
+ // Lazy method: Just rebuild everything.
+ // This can be called when the mob is created, but on other occasions, rebuild_body_overlays(),
+ // rebuild_clothing_overlays() etc. should be called individually.
+
+ misc_clothing_updates() // silly stuff
+
+/mob/living/carbon/amorph/update_body_appearance()
+ // Should be called whenever something about the body appearance itself changes.
+
+ misc_clothing_updates() // silly stuff
+
+ if(lying)
+ icon_state = "lying"
+ else
+ icon_state = "standing"
+
+/mob/living/carbon/amorph/update_lying()
+ // Should be called whenever something about the lying status of the mob might have changed.
+
+ if(lying)
+ icon_state = "lying"
+ else
+ icon_state = "standing"
+
+/mob/living/carbon/amorph/hand_p(mob/M as mob)
+ // not even sure what this is meant to do
+ return
+
+/mob/living/carbon/amorph/restrained()
+ if (handcuffed)
+ return 0 // handcuffs don't work on amorphs
+ return 0
+
+/mob/living/carbon/amorph/var/co2overloadtime = null
+/mob/living/carbon/amorph/var/temperature_resistance = T0C+75
+
+/mob/living/carbon/amorph/show_inv(mob/user as mob)
+ // TODO: add a window for extracting stuff from an amorph's mouth
+
+// called when something steps onto an amorph
+// this could be made more general, but for now just handle mulebot
+/mob/living/carbon/amorph/HasEntered(var/atom/movable/AM)
+ var/obj/machinery/bot/mulebot/MB = AM
+ if(istype(MB))
+ MB.RunOver(src)
+
+//gets assignment from ID or ID inside PDA or PDA itself
+//Useful when player do something with computers
+/mob/living/carbon/amorph/proc/get_assignment(var/if_no_id = "No id", var/if_no_job = "No job")
+ // TODO: get the ID from the amorph's contents
+ return
+
+//gets name from ID or ID inside PDA or PDA itself
+//Useful when player do something with computers
+/mob/living/carbon/amorph/proc/get_authentification_name(var/if_no_id = "Unknown")
+ // TODO: get the ID from the amorph's contents
+ return
+
+//repurposed proc. Now it combines get_id_name() and get_face_name() to determine a mob's name variable. Made into a seperate proc as it'll be useful elsewhere
+/mob/living/carbon/amorph/proc/get_visible_name()
+ // amorphs can't wear clothes or anything, so always return face_name
+ return get_face_name()
+
+//Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when polyacided or when updating a human's name variable
+/mob/living/carbon/amorph/proc/get_face_name()
+ // there might later be ways for amorphs to change the appearance of their face
+ return "[real_name]"
+
+
+//gets ID card object from special clothes slot or null.
+/mob/living/carbon/amorph/proc/get_idcard()
+ // TODO: get the ID from the amorph's contents
+
+
+// heal the amorph
+/mob/living/carbon/amorph/heal_overall_damage(var/brute, var/burn)
+ bruteloss -= brute
+ fireloss -= burn
+ bruteloss = max(bruteloss, 0)
+ fireloss = max(fireloss, 0)
+
+ updatehealth()
+ UpdateDamageIcon()
+
+// damage MANY external organs, in random order
+/mob/living/carbon/amorph/take_overall_damage(var/brute, var/burn, var/used_weapon = null)
+ bruteloss += brute
+ fireloss += burn
+
+ updatehealth()
+ UpdateDamageIcon()
+
+/mob/living/carbon/amorph/Topic(href, href_list)
+ if (href_list["refresh"])
+ if((machine)&&(in_range(src, usr)))
+ show_inv(machine)
+
+ if (href_list["mach_close"])
+ var/t1 = text("window=[]", href_list["mach_close"])
+ machine = null
+ src << browse(null, t1)
+
+ if ((href_list["item"] && !( usr.stat ) && usr.canmove && !( usr.restrained() ) && in_range(src, usr) && ticker)) //if game hasn't started, can't make an equip_e
+ var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( )
+ O.source = usr
+ O.target = src
+ O.item = usr.equipped()
+ O.s_loc = usr.loc
+ O.t_loc = loc
+ O.place = href_list["item"]
+ if(href_list["loc"])
+ O.internalloc = href_list["loc"]
+ requests += O
+ spawn( 0 )
+ O.process()
+ return
+
+ if (href_list["criminal"])
+ if(istype(usr, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = usr
+ if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud))
+ var/perpname = "wot"
+ var/modified = 0
+
+ /*if(wear_id)
+ if(istype(wear_id,/obj/item/weapon/card/id))
+ perpname = wear_id:registered_name
+ else if(istype(wear_id,/obj/item/device/pda))
+ var/obj/item/device/pda/tempPda = wear_id
+ perpname = tempPda.owner
+ else*/
+ perpname = src.name
+
+ for (var/datum/data/record/E in data_core.general)
+ if (E.fields["name"] == perpname)
+ for (var/datum/data/record/R in data_core.security)
+ if (R.fields["id"] == E.fields["id"])
+
+ var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list("None", "*Arrest*", "Incarcerated", "Parolled", "Released", "Cancel")
+
+ if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud))
+ if(setcriminal != "Cancel")
+ R.fields["criminal"] = setcriminal
+ modified = 1
+
+ spawn()
+ H.handle_regular_hud_updates()
+
+ if(!modified)
+ usr << "\red Unable to locate a data core entry for this person."
+ ..()
+ return
+
+
+///eyecheck()
+///Returns a number between -1 to 2
+/mob/living/carbon/amorph/eyecheck()
+ return 1
+
+
+/mob/living/carbon/amorph/IsAdvancedToolUser()
+ return 1//Amorphs can use guns and such
+
+
+/mob/living/carbon/amorph/updatehealth()
+ if(src.nodamage)
+ src.health = 100
+ src.stat = 0
+ return
+ src.health = 100 - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss() - src.getCloneLoss() -src.halloss
+ return
+
+/mob/living/carbon/amorph/abiotic(var/full_body = 0)
+ return 0
+
+/mob/living/carbon/amorph/abiotic2(var/full_body2 = 0)
+ return 0
+
+/mob/living/carbon/amorph/getBruteLoss()
+ return src.bruteloss
+
+/mob/living/carbon/amorph/adjustBruteLoss(var/amount, var/used_weapon = null)
+ src.bruteloss += amount
+ if(bruteloss < 0) bruteloss = 0
+
+/mob/living/carbon/amorph/getFireLoss()
+ return src.fireloss
+
+/mob/living/carbon/amorph/adjustFireLoss(var/amount,var/used_weapon = null)
+ src.fireloss += amount
+ if(fireloss < 0) fireloss = 0
+
+/mob/living/carbon/amorph/get_visible_gender()
+ return gender
diff --git a/code/modules/mob/living/carbon/amorph/amorph_attack.dm b/code/WorkInProgress/Cib/amorph/amorph_attack.dm
similarity index 96%
rename from code/modules/mob/living/carbon/amorph/amorph_attack.dm
rename to code/WorkInProgress/Cib/amorph/amorph_attack.dm
index b8c4aa8b603..c103d1be67c 100644
--- a/code/modules/mob/living/carbon/amorph/amorph_attack.dm
+++ b/code/WorkInProgress/Cib/amorph/amorph_attack.dm
@@ -1,248 +1,248 @@
-
-
-/mob/living/carbon/amorph/attack_paw(mob/living/carbon/monkey/M as mob)
- if (!ticker)
- M << "You cannot attack people before the game has started."
- return
-
- ..()
-
- switch(M.a_intent)
-
- if ("help")
- help_shake_act(M)
- else
- if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
- return
- if (health > 0)
- attacked += 10
- playsound(loc, 'bite.ogg', 50, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [M.name] has bit [src]!"), 1)
- adjustBruteLoss(rand(0, 1))
- updatehealth()
- return
-
-/mob/living/carbon/amorph/attack_hand(mob/living/carbon/human/M as mob)
-
- if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
- var/obj/item/clothing/gloves/G = M.gloves
- if(G.cell)
- if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
- if(G.cell.charge >= 2500)
- G.cell.charge -= 2500
- Weaken(5)
- if (stuttering < 5)
- stuttering = 5
- Stun(5)
-
- for(var/mob/O in viewers(src, null))
- if (O.client)
- O.show_message("\red [src] has been touched with the stun gloves by [M]!", 1, "\red You hear someone fall", 2)
- return
- else
- M << "\red Not enough charge! "
- return
-
- if (M.a_intent == "help")
- help_shake_act(M)
- else
- if (M.a_intent == "hurt")
- var/attack_verb
- switch(M.mutantrace)
- if("lizard")
- attack_verb = "scratch"
- if("plant")
- attack_verb = "slash"
- else
- attack_verb = "punch"
-
- if(M.type == /mob/living/carbon/human/tajaran)
- attack_verb = "slash"
-
- if ((prob(75) && health > 0))
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has [attack_verb]ed [name]!", M), 1)
-
- var/damage = rand(5, 10)
- if(M.type != /mob/living/carbon/human/tajaran)
- playsound(loc, "punch", 25, 1, -1)
- else if(M.type == /mob/living/carbon/human/tajaran)
- damage += 10
- playsound(loc, 'slice.ogg', 25, 1, -1)
- adjustBruteLoss(damage/10)
- updatehealth()
- else
- if(M.type != /mob/living/carbon/human/tajaran)
- playsound(loc, 'punchmiss.ogg', 25, 1, -1)
- else if(M.type == /mob/living/carbon/human/tajaran)
- playsound(loc, 'slashmiss.ogg', 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has attempted to [attack_verb] [name]!", M), 1)
- else
- if (M.a_intent == "grab")
- if (M == src)
- return
-
- var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M )
- G.assailant = M
- if (M.hand)
- M.l_hand = G
- else
- M.r_hand = G
- G.layer = 20
- G.affecting = src
- grabbed_by += G
- G.synch()
-
- LAssailant = M
-
- playsound(loc, '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 ))
- drop_item()
- playsound(loc, '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/amorph/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
-
- switch(M.a_intent)
- if ("help")
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\blue [M] caresses [src] with its scythe like arm."), 1)
-
- if ("hurt")
- if ((prob(95) && health > 0))
- playsound(loc, 'slice.ogg', 25, 1, -1)
- var/damage = rand(15, 30)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has slashed [name]!", M), 1)
- adjustBruteLoss(damage/10)
- updatehealth()
- react_to_attack(M)
- else
- playsound(loc, 'slashmiss.ogg', 25, 1, -1)
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has attempted to lunge at [name]!", M), 1)
-
- if ("grab")
- if (M == src)
- return
- var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M )
- G.assailant = M
- if (M.hand)
- M.l_hand = G
- else
- M.r_hand = G
- G.layer = 20
- G.affecting = src
- grabbed_by += G
- G.synch()
-
- LAssailant = M
-
- playsound(loc, 'thudswoosh.ogg', 50, 1, -1)
- for(var/mob/O in viewers(src, null))
- O.show_message(text("\red [] has grabbed [name] passively!", M), 1)
-
- if ("disarm")
- playsound(loc, 'pierce.ogg', 25, 1, -1)
- var/damage = 5
- if(prob(95))
- Weaken(rand(10,15))
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has tackled down [name]!", M), 1)
- else
- drop_item()
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red [] has disarmed [name]!", M), 1)
- adjustBruteLoss(damage)
- react_to_attack(M)
- updatehealth()
- return
-
-
-
-/mob/living/carbon/amorph/attack_animal(mob/living/simple_animal/M as mob)
- if(M.melee_damage_upper == 0)
- M.emote("[M.friendly] [src]")
- else
- for(var/mob/O in viewers(src, null))
- O.show_message("\red [M] [M.attacktext] [src]!", 1)
- var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
- bruteloss += damage
-
-/mob/living/carbon/amorph/attack_metroid(mob/living/carbon/metroid/M as mob)
- if(M.Victim) return // can't attack while eating!
-
- if (health > -100)
-
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red The [M.name] has [pick("bit","slashed")] []!", src), 1)
-
- var/damage = rand(1, 3)
-
- if(istype(M, /mob/living/carbon/metroid/adult))
- damage = rand(10, 35)
- else
- damage = rand(5, 25)
-
- src.cloneloss += damage
-
- UpdateDamageIcon()
-
-
- if(M.powerlevel > 0)
- var/stunprob = 10
- var/power = M.powerlevel + rand(0,3)
-
- switch(M.powerlevel)
- 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))
- M.powerlevel -= 3
- if(M.powerlevel < 0)
- M.powerlevel = 0
-
- for(var/mob/O in viewers(src, null))
- if ((O.client && !( O.blinded )))
- O.show_message(text("\red The [M.name] has shocked []!", src), 1)
-
- Weaken(power)
- if (stuttering < power)
- stuttering = power
- Stun(power)
-
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(5, 1, src)
- s.start()
-
- if (prob(stunprob) && M.powerlevel >= 8)
- adjustFireLoss(M.powerlevel * rand(6,10))
-
-
- updatehealth()
-
- return
+
+
+/mob/living/carbon/amorph/attack_paw(mob/living/carbon/monkey/M as mob)
+ if (!ticker)
+ M << "You cannot attack people before the game has started."
+ return
+
+ ..()
+
+ switch(M.a_intent)
+
+ if ("help")
+ help_shake_act(M)
+ else
+ if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
+ return
+ if (health > 0)
+ attacked += 10
+ playsound(loc, 'bite.ogg', 50, 1, -1)
+ for(var/mob/O in viewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O.show_message(text("\red [M.name] has bit [src]!"), 1)
+ adjustBruteLoss(rand(0, 1))
+ updatehealth()
+ return
+
+/mob/living/carbon/amorph/attack_hand(mob/living/carbon/human/M as mob)
+
+ if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
+ var/obj/item/clothing/gloves/G = M.gloves
+ if(G.cell)
+ if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
+ if(G.cell.charge >= 2500)
+ G.cell.charge -= 2500
+ Weaken(5)
+ if (stuttering < 5)
+ stuttering = 5
+ Stun(5)
+
+ for(var/mob/O in viewers(src, null))
+ if (O.client)
+ O.show_message("\red [src] has been touched with the stun gloves by [M]!", 1, "\red You hear someone fall", 2)
+ return
+ else
+ M << "\red Not enough charge! "
+ return
+
+ if (M.a_intent == "help")
+ help_shake_act(M)
+ else
+ if (M.a_intent == "hurt")
+ var/attack_verb
+ switch(M.mutantrace)
+ if("lizard")
+ attack_verb = "scratch"
+ if("plant")
+ attack_verb = "slash"
+ else
+ attack_verb = "punch"
+
+ if(M.type == /mob/living/carbon/human/tajaran)
+ attack_verb = "slash"
+
+ if ((prob(75) && health > 0))
+ for(var/mob/O in viewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O.show_message(text("\red [] has [attack_verb]ed [name]!", M), 1)
+
+ var/damage = rand(5, 10)
+ if(M.type != /mob/living/carbon/human/tajaran)
+ playsound(loc, "punch", 25, 1, -1)
+ else if(M.type == /mob/living/carbon/human/tajaran)
+ damage += 10
+ playsound(loc, 'slice.ogg', 25, 1, -1)
+ adjustBruteLoss(damage/10)
+ updatehealth()
+ else
+ if(M.type != /mob/living/carbon/human/tajaran)
+ playsound(loc, 'punchmiss.ogg', 25, 1, -1)
+ else if(M.type == /mob/living/carbon/human/tajaran)
+ playsound(loc, 'slashmiss.ogg', 25, 1, -1)
+ for(var/mob/O in viewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O.show_message(text("\red [] has attempted to [attack_verb] [name]!", M), 1)
+ else
+ if (M.a_intent == "grab")
+ if (M == src)
+ return
+
+ var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M )
+ G.assailant = M
+ if (M.hand)
+ M.l_hand = G
+ else
+ M.r_hand = G
+ G.layer = 20
+ G.affecting = src
+ grabbed_by += G
+ G.synch()
+
+ LAssailant = M
+
+ playsound(loc, '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 ))
+ drop_item()
+ playsound(loc, '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/amorph/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
+
+ switch(M.a_intent)
+ if ("help")
+ for(var/mob/O in viewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O.show_message(text("\blue [M] caresses [src] with its scythe like arm."), 1)
+
+ if ("hurt")
+ if ((prob(95) && health > 0))
+ playsound(loc, 'slice.ogg', 25, 1, -1)
+ var/damage = rand(15, 30)
+ for(var/mob/O in viewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O.show_message(text("\red [] has slashed [name]!", M), 1)
+ adjustBruteLoss(damage/10)
+ updatehealth()
+ react_to_attack(M)
+ else
+ playsound(loc, 'slashmiss.ogg', 25, 1, -1)
+ for(var/mob/O in viewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O.show_message(text("\red [] has attempted to lunge at [name]!", M), 1)
+
+ if ("grab")
+ if (M == src)
+ return
+ var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M )
+ G.assailant = M
+ if (M.hand)
+ M.l_hand = G
+ else
+ M.r_hand = G
+ G.layer = 20
+ G.affecting = src
+ grabbed_by += G
+ G.synch()
+
+ LAssailant = M
+
+ playsound(loc, 'thudswoosh.ogg', 50, 1, -1)
+ for(var/mob/O in viewers(src, null))
+ O.show_message(text("\red [] has grabbed [name] passively!", M), 1)
+
+ if ("disarm")
+ playsound(loc, 'pierce.ogg', 25, 1, -1)
+ var/damage = 5
+ if(prob(95))
+ Weaken(rand(10,15))
+ for(var/mob/O in viewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O.show_message(text("\red [] has tackled down [name]!", M), 1)
+ else
+ drop_item()
+ for(var/mob/O in viewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O.show_message(text("\red [] has disarmed [name]!", M), 1)
+ adjustBruteLoss(damage)
+ react_to_attack(M)
+ updatehealth()
+ return
+
+
+
+/mob/living/carbon/amorph/attack_animal(mob/living/simple_animal/M as mob)
+ if(M.melee_damage_upper == 0)
+ M.emote("[M.friendly] [src]")
+ else
+ for(var/mob/O in viewers(src, null))
+ O.show_message("\red [M] [M.attacktext] [src]!", 1)
+ var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
+ bruteloss += damage
+
+/mob/living/carbon/amorph/attack_metroid(mob/living/carbon/metroid/M as mob)
+ if(M.Victim) return // can't attack while eating!
+
+ if (health > -100)
+
+ for(var/mob/O in viewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O.show_message(text("\red The [M.name] has [pick("bit","slashed")] []!", src), 1)
+
+ var/damage = rand(1, 3)
+
+ if(istype(M, /mob/living/carbon/metroid/adult))
+ damage = rand(10, 35)
+ else
+ damage = rand(5, 25)
+
+ src.cloneloss += damage
+
+ UpdateDamageIcon()
+
+
+ if(M.powerlevel > 0)
+ var/stunprob = 10
+ var/power = M.powerlevel + rand(0,3)
+
+ switch(M.powerlevel)
+ 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))
+ M.powerlevel -= 3
+ if(M.powerlevel < 0)
+ M.powerlevel = 0
+
+ for(var/mob/O in viewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O.show_message(text("\red The [M.name] has shocked []!", src), 1)
+
+ Weaken(power)
+ if (stuttering < power)
+ stuttering = power
+ Stun(power)
+
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(5, 1, src)
+ s.start()
+
+ if (prob(stunprob) && M.powerlevel >= 8)
+ adjustFireLoss(M.powerlevel * rand(6,10))
+
+
+ updatehealth()
+
+ return
diff --git a/code/modules/mob/living/carbon/amorph/amorph_damage.dm b/code/WorkInProgress/Cib/amorph/amorph_damage.dm
similarity index 90%
rename from code/modules/mob/living/carbon/amorph/amorph_damage.dm
rename to code/WorkInProgress/Cib/amorph/amorph_damage.dm
index 8e52d042920..d49d679069c 100644
--- a/code/modules/mob/living/carbon/amorph/amorph_damage.dm
+++ b/code/WorkInProgress/Cib/amorph/amorph_damage.dm
@@ -1,12 +1,12 @@
-/mob/living/carbon/amorph/proc/HealDamage(zone, brute, burn)
- return heal_overall_damage(brute, burn)
-
-/mob/living/carbon/amorph/UpdateDamageIcon()
- // no damage sprites for amorphs yet
- return
-
-/mob/living/carbon/amorph/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/sharp = 0, var/used_weapon = null)
- if(damagetype == BRUTE)
- take_overall_damage(damage, 0)
- else
+/mob/living/carbon/amorph/proc/HealDamage(zone, brute, burn)
+ return heal_overall_damage(brute, burn)
+
+/mob/living/carbon/amorph/UpdateDamageIcon()
+ // no damage sprites for amorphs yet
+ return
+
+/mob/living/carbon/amorph/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/sharp = 0, var/used_weapon = null)
+ if(damagetype == BRUTE)
+ take_overall_damage(damage, 0)
+ else
take_overall_damage(0, damage)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/amorph/amorph_hud.dm b/code/WorkInProgress/Cib/amorph/amorph_hud.dm
similarity index 96%
rename from code/modules/mob/living/carbon/amorph/amorph_hud.dm
rename to code/WorkInProgress/Cib/amorph/amorph_hud.dm
index 7236790bb79..2f3390342aa 100644
--- a/code/modules/mob/living/carbon/amorph/amorph_hud.dm
+++ b/code/WorkInProgress/Cib/amorph/amorph_hud.dm
@@ -1,300 +1,300 @@
-/obj/hud/proc/amorph_hud(var/ui_style='screen1_old.dmi')
-
- src.adding = list( )
- src.other = list( )
- src.intents = list( )
- src.mon_blo = list( )
- src.m_ints = list( )
- src.mov_int = list( )
- src.vimpaired = list( )
- src.darkMask = list( )
- src.intent_small_hud_objects = list( )
-
- src.g_dither = new /obj/screen( src )
- src.g_dither.screen_loc = "WEST,SOUTH to EAST,NORTH"
- src.g_dither.name = "Mask"
- src.g_dither.icon = ui_style
- src.g_dither.icon_state = "dither12g"
- src.g_dither.layer = 18
- src.g_dither.mouse_opacity = 0
-
- src.alien_view = new /obj/screen(src)
- src.alien_view.screen_loc = "WEST,SOUTH to EAST,NORTH"
- src.alien_view.name = "Alien"
- src.alien_view.icon = ui_style
- src.alien_view.icon_state = "alien"
- src.alien_view.layer = 18
- src.alien_view.mouse_opacity = 0
-
- src.blurry = new /obj/screen( src )
- src.blurry.screen_loc = "WEST,SOUTH to EAST,NORTH"
- src.blurry.name = "Blurry"
- src.blurry.icon = ui_style
- src.blurry.icon_state = "blurry"
- src.blurry.layer = 17
- src.blurry.mouse_opacity = 0
-
- src.druggy = new /obj/screen( src )
- src.druggy.screen_loc = "WEST,SOUTH to EAST,NORTH"
- src.druggy.name = "Druggy"
- src.druggy.icon = ui_style
- src.druggy.icon_state = "druggy"
- src.druggy.layer = 17
- src.druggy.mouse_opacity = 0
-
- var/obj/screen/using
-
- using = new /obj/screen( src )
- using.name = "act_intent"
- using.dir = SOUTHWEST
- using.icon = ui_style
- using.icon_state = (mymob.a_intent == "hurt" ? "harm" : mymob.a_intent)
- using.screen_loc = ui_acti
- 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_acti
- 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_acti
- 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_acti
- 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 = "harm"
- using.icon = ico
- using.screen_loc = ui_acti
- using.layer = 21
- src.adding += using
- hurt_intent = using
-
-//end intent small hud objects
-
- using = new /obj/screen( src )
- using.name = "mov_intent"
- using.dir = SOUTHWEST
- using.icon = ui_style
- using.icon_state = (mymob.m_intent == "run" ? "running" : "walking")
- using.screen_loc = ui_movi
- using.layer = 20
- src.adding += using
- move_intent = using
-
- using = new /obj/screen( src )
- using.name = "drop"
- using.icon = ui_style
- using.icon_state = "act_drop"
- using.screen_loc = ui_dropbutton
- using.layer = 19
- src.adding += using
-
- using = new /obj/screen( src )
- using.name = "r_hand"
- using.dir = WEST
- using.icon = ui_style
- using.icon_state = "hand_inactive"
- if(mymob && !mymob.hand) //This being 0 or null means the right hand is in use
- using.icon_state = "hand_active"
- using.screen_loc = ui_rhand
- using.layer = 19
- src.r_hand_hud_object = using
- src.adding += using
-
- using = new /obj/screen( src )
- using.name = "l_hand"
- using.dir = EAST
- using.icon = ui_style
- using.icon_state = "hand_inactive"
- if(mymob && mymob.hand) //This being 1 means the left hand is in use
- using.icon_state = "hand_active"
- using.screen_loc = ui_lhand
- using.layer = 19
- src.l_hand_hud_object = using
- src.adding += using
-
- using = new /obj/screen( src )
- using.name = "hand"
- using.dir = SOUTH
- using.icon = ui_style
- using.icon_state = "hand1"
- using.screen_loc = ui_swaphand1
- using.layer = 19
- src.adding += using
-
- using = new /obj/screen( src )
- using.name = "hand"
- using.dir = SOUTH
- using.icon = ui_style
- using.icon_state = "hand2"
- using.screen_loc = ui_swaphand2
- using.layer = 19
- src.adding += using
-
- using = new /obj/screen( src )
- using.name = "mask"
- using.dir = NORTH
- using.icon = ui_style
- using.icon_state = "equip"
- using.screen_loc = ui_monkey_mask
- using.layer = 19
- src.adding += using
-
- using = new /obj/screen( src )
- using.name = "back"
- using.dir = NORTHEAST
- using.icon = ui_style
- using.icon_state = "equip"
- using.screen_loc = ui_back
- using.layer = 19
- src.adding += using
-
- using = new /obj/screen( src )
- using.name = null
- using.icon = ui_style
- using.icon_state = "dither50"
- using.screen_loc = "1,1 to 5,15"
- using.layer = 17
- using.mouse_opacity = 0
- src.vimpaired += using
- using = new /obj/screen( src )
- using.name = null
- using.icon = ui_style
- using.icon_state = "dither50"
- using.screen_loc = "5,1 to 10,5"
- using.layer = 17
- using.mouse_opacity = 0
- src.vimpaired += using
- using = new /obj/screen( src )
- using.name = null
- using.icon = ui_style
- using.icon_state = "dither50"
- using.screen_loc = "6,11 to 10,15"
- using.layer = 17
- using.mouse_opacity = 0
- src.vimpaired += using
- using = new /obj/screen( src )
- using.name = null
- using.icon = ui_style
- using.icon_state = "dither50"
- using.screen_loc = "11,1 to 15,15"
- using.layer = 17
- using.mouse_opacity = 0
- src.vimpaired += using
-
- mymob.throw_icon = new /obj/screen(null)
- mymob.throw_icon.icon = ui_style
- mymob.throw_icon.icon_state = "act_throw_off"
- mymob.throw_icon.name = "throw"
- mymob.throw_icon.screen_loc = ui_throw
-
- mymob.oxygen = new /obj/screen( null )
- mymob.oxygen.icon = ui_style
- mymob.oxygen.icon_state = "oxy0"
- mymob.oxygen.name = "oxygen"
- mymob.oxygen.screen_loc = ui_oxygen
-
- mymob.pressure = new /obj/screen( null )
- mymob.pressure.icon = ui_style
- mymob.pressure.icon_state = "pressure0"
- mymob.pressure.name = "pressure"
- mymob.pressure.screen_loc = ui_pressure
-
- mymob.toxin = new /obj/screen( null )
- mymob.toxin.icon = ui_style
- mymob.toxin.icon_state = "tox0"
- mymob.toxin.name = "toxin"
- mymob.toxin.screen_loc = ui_toxin
-
- mymob.internals = new /obj/screen( null )
- mymob.internals.icon = ui_style
- mymob.internals.icon_state = "internal0"
- mymob.internals.name = "internal"
- mymob.internals.screen_loc = ui_internal
-
- mymob.fire = new /obj/screen( null )
- mymob.fire.icon = ui_style
- mymob.fire.icon_state = "fire0"
- mymob.fire.name = "fire"
- mymob.fire.screen_loc = ui_fire
-
- mymob.bodytemp = new /obj/screen( null )
- mymob.bodytemp.icon = ui_style
- mymob.bodytemp.icon_state = "temp1"
- mymob.bodytemp.name = "body temperature"
- mymob.bodytemp.screen_loc = ui_temp
-
- mymob.healths = new /obj/screen( null )
- mymob.healths.icon = ui_style
- mymob.healths.icon_state = "health0"
- mymob.healths.name = "health"
- mymob.healths.screen_loc = ui_health
-
- mymob.pullin = new /obj/screen( null )
- mymob.pullin.icon = ui_style
- mymob.pullin.icon_state = "pull0"
- mymob.pullin.name = "pull"
- mymob.pullin.screen_loc = ui_pull
-
- mymob.blind = new /obj/screen( null )
- mymob.blind.icon = ui_style
- mymob.blind.icon_state = "blackanimate"
- mymob.blind.name = " "
- mymob.blind.screen_loc = "1,1 to 15,15"
- mymob.blind.layer = 0
- mymob.blind.mouse_opacity = 0
-
- mymob.flash = new /obj/screen( null )
- mymob.flash.icon = ui_style
- mymob.flash.icon_state = "blank"
- mymob.flash.name = "flash"
- mymob.flash.screen_loc = "1,1 to 15,15"
- mymob.flash.layer = 17
-
- mymob.zone_sel = new /obj/screen/zone_sel( null )
- mymob.zone_sel.overlays = null
- mymob.zone_sel.overlays += image("icon" = 'zone_sel.dmi', "icon_state" = text("[]", mymob.zone_sel.selecting))
-
- mymob.gun_setting_icon = new /obj/screen/gun/mode(null)
-
- mymob.client.screen = null
-
- //, mymob.i_select, mymob.m_select
- mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.pullin, mymob.blind, mymob.flash, mymob.gun_setting_icon) //, mymob.hands, mymob.rest, mymob.sleep, mymob.mach, mymob.hands, )
- mymob.client.screen += src.adding + src.other
-
- //if(istype(mymob,/mob/living/carbon/monkey)) mymob.client.screen += src.mon_blo
-
- return
+/obj/hud/proc/amorph_hud(var/ui_style='screen1_old.dmi')
+
+ src.adding = list( )
+ src.other = list( )
+ src.intents = list( )
+ src.mon_blo = list( )
+ src.m_ints = list( )
+ src.mov_int = list( )
+ src.vimpaired = list( )
+ src.darkMask = list( )
+ src.intent_small_hud_objects = list( )
+
+ src.g_dither = new /obj/screen( src )
+ src.g_dither.screen_loc = "WEST,SOUTH to EAST,NORTH"
+ src.g_dither.name = "Mask"
+ src.g_dither.icon = ui_style
+ src.g_dither.icon_state = "dither12g"
+ src.g_dither.layer = 18
+ src.g_dither.mouse_opacity = 0
+
+ src.alien_view = new /obj/screen(src)
+ src.alien_view.screen_loc = "WEST,SOUTH to EAST,NORTH"
+ src.alien_view.name = "Alien"
+ src.alien_view.icon = ui_style
+ src.alien_view.icon_state = "alien"
+ src.alien_view.layer = 18
+ src.alien_view.mouse_opacity = 0
+
+ src.blurry = new /obj/screen( src )
+ src.blurry.screen_loc = "WEST,SOUTH to EAST,NORTH"
+ src.blurry.name = "Blurry"
+ src.blurry.icon = ui_style
+ src.blurry.icon_state = "blurry"
+ src.blurry.layer = 17
+ src.blurry.mouse_opacity = 0
+
+ src.druggy = new /obj/screen( src )
+ src.druggy.screen_loc = "WEST,SOUTH to EAST,NORTH"
+ src.druggy.name = "Druggy"
+ src.druggy.icon = ui_style
+ src.druggy.icon_state = "druggy"
+ src.druggy.layer = 17
+ src.druggy.mouse_opacity = 0
+
+ var/obj/screen/using
+
+ using = new /obj/screen( src )
+ using.name = "act_intent"
+ using.dir = SOUTHWEST
+ using.icon = ui_style
+ using.icon_state = (mymob.a_intent == "hurt" ? "harm" : mymob.a_intent)
+ using.screen_loc = ui_acti
+ 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_acti
+ 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_acti
+ 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_acti
+ 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 = "harm"
+ using.icon = ico
+ using.screen_loc = ui_acti
+ using.layer = 21
+ src.adding += using
+ hurt_intent = using
+
+//end intent small hud objects
+
+ using = new /obj/screen( src )
+ using.name = "mov_intent"
+ using.dir = SOUTHWEST
+ using.icon = ui_style
+ using.icon_state = (mymob.m_intent == "run" ? "running" : "walking")
+ using.screen_loc = ui_movi
+ using.layer = 20
+ src.adding += using
+ move_intent = using
+
+ using = new /obj/screen( src )
+ using.name = "drop"
+ using.icon = ui_style
+ using.icon_state = "act_drop"
+ using.screen_loc = ui_dropbutton
+ using.layer = 19
+ src.adding += using
+
+ using = new /obj/screen( src )
+ using.name = "r_hand"
+ using.dir = WEST
+ using.icon = ui_style
+ using.icon_state = "hand_inactive"
+ if(mymob && !mymob.hand) //This being 0 or null means the right hand is in use
+ using.icon_state = "hand_active"
+ using.screen_loc = ui_rhand
+ using.layer = 19
+ src.r_hand_hud_object = using
+ src.adding += using
+
+ using = new /obj/screen( src )
+ using.name = "l_hand"
+ using.dir = EAST
+ using.icon = ui_style
+ using.icon_state = "hand_inactive"
+ if(mymob && mymob.hand) //This being 1 means the left hand is in use
+ using.icon_state = "hand_active"
+ using.screen_loc = ui_lhand
+ using.layer = 19
+ src.l_hand_hud_object = using
+ src.adding += using
+
+ using = new /obj/screen( src )
+ using.name = "hand"
+ using.dir = SOUTH
+ using.icon = ui_style
+ using.icon_state = "hand1"
+ using.screen_loc = ui_swaphand1
+ using.layer = 19
+ src.adding += using
+
+ using = new /obj/screen( src )
+ using.name = "hand"
+ using.dir = SOUTH
+ using.icon = ui_style
+ using.icon_state = "hand2"
+ using.screen_loc = ui_swaphand2
+ using.layer = 19
+ src.adding += using
+
+ using = new /obj/screen( src )
+ using.name = "mask"
+ using.dir = NORTH
+ using.icon = ui_style
+ using.icon_state = "equip"
+ using.screen_loc = ui_monkey_mask
+ using.layer = 19
+ src.adding += using
+
+ using = new /obj/screen( src )
+ using.name = "back"
+ using.dir = NORTHEAST
+ using.icon = ui_style
+ using.icon_state = "equip"
+ using.screen_loc = ui_back
+ using.layer = 19
+ src.adding += using
+
+ using = new /obj/screen( src )
+ using.name = null
+ using.icon = ui_style
+ using.icon_state = "dither50"
+ using.screen_loc = "1,1 to 5,15"
+ using.layer = 17
+ using.mouse_opacity = 0
+ src.vimpaired += using
+ using = new /obj/screen( src )
+ using.name = null
+ using.icon = ui_style
+ using.icon_state = "dither50"
+ using.screen_loc = "5,1 to 10,5"
+ using.layer = 17
+ using.mouse_opacity = 0
+ src.vimpaired += using
+ using = new /obj/screen( src )
+ using.name = null
+ using.icon = ui_style
+ using.icon_state = "dither50"
+ using.screen_loc = "6,11 to 10,15"
+ using.layer = 17
+ using.mouse_opacity = 0
+ src.vimpaired += using
+ using = new /obj/screen( src )
+ using.name = null
+ using.icon = ui_style
+ using.icon_state = "dither50"
+ using.screen_loc = "11,1 to 15,15"
+ using.layer = 17
+ using.mouse_opacity = 0
+ src.vimpaired += using
+
+ mymob.throw_icon = new /obj/screen(null)
+ mymob.throw_icon.icon = ui_style
+ mymob.throw_icon.icon_state = "act_throw_off"
+ mymob.throw_icon.name = "throw"
+ mymob.throw_icon.screen_loc = ui_throw
+
+ mymob.oxygen = new /obj/screen( null )
+ mymob.oxygen.icon = ui_style
+ mymob.oxygen.icon_state = "oxy0"
+ mymob.oxygen.name = "oxygen"
+ mymob.oxygen.screen_loc = ui_oxygen
+
+ mymob.pressure = new /obj/screen( null )
+ mymob.pressure.icon = ui_style
+ mymob.pressure.icon_state = "pressure0"
+ mymob.pressure.name = "pressure"
+ mymob.pressure.screen_loc = ui_pressure
+
+ mymob.toxin = new /obj/screen( null )
+ mymob.toxin.icon = ui_style
+ mymob.toxin.icon_state = "tox0"
+ mymob.toxin.name = "toxin"
+ mymob.toxin.screen_loc = ui_toxin
+
+ mymob.internals = new /obj/screen( null )
+ mymob.internals.icon = ui_style
+ mymob.internals.icon_state = "internal0"
+ mymob.internals.name = "internal"
+ mymob.internals.screen_loc = ui_internal
+
+ mymob.fire = new /obj/screen( null )
+ mymob.fire.icon = ui_style
+ mymob.fire.icon_state = "fire0"
+ mymob.fire.name = "fire"
+ mymob.fire.screen_loc = ui_fire
+
+ mymob.bodytemp = new /obj/screen( null )
+ mymob.bodytemp.icon = ui_style
+ mymob.bodytemp.icon_state = "temp1"
+ mymob.bodytemp.name = "body temperature"
+ mymob.bodytemp.screen_loc = ui_temp
+
+ mymob.healths = new /obj/screen( null )
+ mymob.healths.icon = ui_style
+ mymob.healths.icon_state = "health0"
+ mymob.healths.name = "health"
+ mymob.healths.screen_loc = ui_health
+
+ mymob.pullin = new /obj/screen( null )
+ mymob.pullin.icon = ui_style
+ mymob.pullin.icon_state = "pull0"
+ mymob.pullin.name = "pull"
+ mymob.pullin.screen_loc = ui_pull
+
+ mymob.blind = new /obj/screen( null )
+ mymob.blind.icon = ui_style
+ mymob.blind.icon_state = "blackanimate"
+ mymob.blind.name = " "
+ mymob.blind.screen_loc = "1,1 to 15,15"
+ mymob.blind.layer = 0
+ mymob.blind.mouse_opacity = 0
+
+ mymob.flash = new /obj/screen( null )
+ mymob.flash.icon = ui_style
+ mymob.flash.icon_state = "blank"
+ mymob.flash.name = "flash"
+ mymob.flash.screen_loc = "1,1 to 15,15"
+ mymob.flash.layer = 17
+
+ mymob.zone_sel = new /obj/screen/zone_sel( null )
+ mymob.zone_sel.overlays = null
+ mymob.zone_sel.overlays += image("icon" = 'zone_sel.dmi', "icon_state" = text("[]", mymob.zone_sel.selecting))
+
+ mymob.gun_setting_icon = new /obj/screen/gun/mode(null)
+
+ mymob.client.screen = null
+
+ //, mymob.i_select, mymob.m_select
+ mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.pullin, mymob.blind, mymob.flash, mymob.gun_setting_icon) //, mymob.hands, mymob.rest, mymob.sleep, mymob.mach, mymob.hands, )
+ mymob.client.screen += src.adding + src.other
+
+ //if(istype(mymob,/mob/living/carbon/monkey)) mymob.client.screen += src.mon_blo
+
+ return
diff --git a/code/modules/mob/living/carbon/amorph/life.dm b/code/WorkInProgress/Cib/amorph/life.dm
similarity index 96%
rename from code/modules/mob/living/carbon/amorph/life.dm
rename to code/WorkInProgress/Cib/amorph/life.dm
index 1a1812a6342..14c4d41ccab 100644
--- a/code/modules/mob/living/carbon/amorph/life.dm
+++ b/code/WorkInProgress/Cib/amorph/life.dm
@@ -1,516 +1,516 @@
-/mob/living/carbon/amorph
- var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
-
- var/oxygen_alert = 0
- var/toxins_alert = 0
- var/fire_alert = 0
-
- var/temperature_alert = 0
-
-
-/mob/living/carbon/amorph/Life()
- set invisibility = 0
- set background = 1
-
- if (src.monkeyizing)
- return
-
- ..()
-
- var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE
- if(src.loc)
- environment = loc.return_air()
-
- if (src.stat != 2) //still breathing
-
- //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)
-
- //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
-
- //Disease Check
- handle_virus_updates()
-
- //Handle temperature/pressure differences between body and environment
- if(environment) // More error checking -- TLE
- handle_environment(environment)
-
- //Mutations and radiation
- handle_mutations_and_radiation()
-
- //Chemicals in the body
- handle_chemicals_in_body()
-
- //Disabilities
- handle_disabilities()
-
- //Status updates, death etc.
-// UpdateLuminosity()
- handle_regular_status_updates()
-
- if(client)
- handle_regular_hud_updates()
-
- //Being buckled to a chair or bed
- check_if_buckled()
-
- // Yup.
- update_canmove()
-
- clamp_values()
-
- // Grabbing
- for(var/obj/item/weapon/grab/G in src)
- G.process()
-
-/mob/living/carbon/amorph
- proc
-
- clamp_values()
-
- AdjustStunned(0)
- AdjustParalysis(0)
- AdjustWeakened(0)
-
- handle_disabilities()
- if (src.disabilities & 4)
- if ((prob(5) && src.paralysis <= 1 && src.r_ch_cou < 1))
- src.drop_item()
- spawn( 0 )
- emote("cough")
- return
- if (src.disabilities & 8)
- if ((prob(10) && src.paralysis <= 1 && src.r_Tourette < 1))
- Stun(10)
- spawn( 0 )
- emote("twitch")
- return
- if (src.disabilities & 16)
- if (prob(10))
- src.stuttering = max(10, src.stuttering)
-
- update_mind()
- if(!mind && client)
- mind = new
- mind.current = src
- mind.key = key
-
- handle_mutations_and_radiation()
- // amorphs are immune to this stuff
-
- breathe()
- if(src.reagents)
-
- if(src.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(losebreath>0) //Suffocating so do not take a breath
- src.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)
-
- // 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/chem_smoke/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)
-
-
- get_breath_from_internal(volume_needed)
- if(internal)
- if (!contents.Find(src.internal))
- internal = null
- if (!wear_mask || !(wear_mask.flags|MASKINTERNALS) )
- internal = null
- if(internal)
- if (src.internals)
- src.internals.icon_state = "internal1"
- return internal.remove_air_volume(volume_needed)
- else
- if (src.internals)
- src.internals.icon_state = "internal0"
- return null
-
- update_canmove()
- if(paralysis || stunned || weakened || buckled || (changeling && changeling.changeling_fakedeath)) canmove = 0
- else canmove = 1
-
- handle_breath(datum/gas_mixture/breath)
- if(src.nodamage)
- return
-
- if(!breath || (breath.total_moles == 0))
- adjustOxyLoss(7)
-
- oxygen_alert = max(oxygen_alert, 1)
-
- return 0
-
- var/safe_oxygen_min = 8 // 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/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.oxygen/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.oxygen*ratio/6
- oxygen_alert = max(oxygen_alert, 1)
- else // We're in safe limits
- adjustOxyLoss(-5)
- oxygen_used = breath.oxygen/6
- oxygen_alert = 0
-
- breath.oxygen -= oxygen_used
- breath.carbon_dioxide += oxygen_used
-
- if(breath.trace_gases.len) // If there's some other shit in the air lets deal with it here.
- for(var/datum/gas/sleeping_agent/SA in breath.trace_gases)
- var/SA_pp = (SA.moles/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
- src.sleeping = max(src.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"))
-
- return 1
-
- handle_environment(datum/gas_mixture/environment)
- if(!environment)
- return
- var/environment_heat_capacity = environment.heat_capacity()
- if(istype(loc, /turf/space))
- environment_heat_capacity = loc:heat_capacity
-
- if((environment.temperature > (T0C + 50)) || (environment.temperature < (T0C + 10)))
- var/transfer_coefficient
-
- transfer_coefficient = 1
- if(wear_mask && (wear_mask.body_parts_covered & HEAD) && (environment.temperature < wear_mask.protective_temperature))
- transfer_coefficient *= wear_mask.heat_transfer_coefficient
-
- 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
-
-
- var/pressure = environment.return_pressure()
-
- // if(!wear_suit) Monkies cannot into space.
- // if(!istype(wear_suit, /obj/item/clothing/suit/space))
-
- /*if(pressure < 20)
- if(prob(25))
- src << "You feel the splittle on your lips and the fluid on your eyes boiling away, the capillteries in your skin breaking."
- adjustBruteLoss(5)
- */
-
- if(pressure > HAZARD_HIGH_PRESSURE)
-
- adjustBruteLoss(min((10+(round(pressure/(HIGH_STEP_PRESSURE)-2)*5)),MAX_PRESSURE_DAMAGE))
-
-
-
- return //TODO: DEFERRED
-
- handle_temperature_damage(body_part, exposed_temperature, exposed_intensity)
- if(src.nodamage) return
- var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
- if(exposed_temperature > bodytemperature)
- adjustFireLoss(20.0*discomfort)
-
- else
- adjustFireLoss(5.0*discomfort)
-
- handle_chemicals_in_body()
- // most chemicals will have no effect on amorphs
- //if(reagents) reagents.metabolize(src)
-
- if (src.drowsyness)
- src.drowsyness--
- src.eye_blurry = max(2, src.eye_blurry)
- if (prob(5))
- src.sleeping += 1
- Paralyse(5)
-
- confused = max(0, confused - 1)
- // decrement dizziness counter, clamped to 0
- if(resting)
- dizziness = max(0, dizziness - 5)
- else
- dizziness = max(0, dizziness - 1)
-
- src.updatehealth()
-
- return //TODO: DEFERRED
-
- handle_regular_status_updates()
-
- health = 100 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
-
- if(getOxyLoss() > 25) Paralyse(3)
-
- if(src.sleeping)
- Paralyse(5)
- if (prob(1) && health) spawn(0) emote("snore")
-
- if(src.resting)
- Weaken(5)
-
- if(health < config.health_threshold_dead && stat != 2)
- death()
- else if(src.health < config.health_threshold_crit)
- if(src.health <= 20 && prob(1)) spawn(0) emote("gasp")
-
- // shuffle around the chemical effects for amorphs a little ;)
- if(!src.reagents.has_reagent("antitoxin") && src.stat != 2) src.adjustOxyLoss(2)
-
- if(src.stat != 2) src.stat = 1
- Paralyse(5)
-
- if (src.stat != 2) //Alive.
-
- if (src.paralysis || src.stunned || src.weakened) //Stunned etc.
- if (src.stunned > 0)
- AdjustStunned(-1)
- src.stat = 0
- if (src.weakened > 0)
- AdjustWeakened(-1)
- src.lying = 1
- src.stat = 0
- if (src.paralysis > 0)
- AdjustParalysis(-1)
- src.blinded = 1
- src.lying = 1
- src.stat = 1
- var/h = src.hand
- src.hand = 0
- drop_item()
- src.hand = 1
- drop_item()
- src.hand = h
-
- else //Not stunned.
- src.lying = 0
- src.stat = 0
-
- else //Dead.
- src.lying = 1
- src.blinded = 1
- src.stat = 2
-
- if (src.stuttering) src.stuttering--
- if (src.slurring) src.slurring--
-
- if (src.eye_blind)
- src.eye_blind--
- src.blinded = 1
-
- if (src.ear_deaf > 0) src.ear_deaf--
- if (src.ear_damage < 25)
- src.ear_damage -= 0.05
- src.ear_damage = max(src.ear_damage, 0)
-
- src.density = !( src.lying )
-
- if (src.disabilities & 128)
- src.blinded = 1
- if (src.disabilities & 32)
- src.ear_deaf = 1
-
- if (src.eye_blurry > 0)
- src.eye_blurry--
- src.eye_blurry = max(0, src.eye_blurry)
-
- if (src.druggy > 0)
- src.druggy--
- src.druggy = max(0, src.druggy)
-
- return 1
-
- handle_regular_hud_updates()
-
- if (src.stat == 2 || (XRAY in mutations))
- src.sight |= SEE_TURFS
- src.sight |= SEE_MOBS
- src.sight |= SEE_OBJS
- src.see_in_dark = 8
- src.see_invisible = 2
- else if (src.stat != 2)
- src.sight &= ~SEE_TURFS
- src.sight &= ~SEE_MOBS
- src.sight &= ~SEE_OBJS
- src.see_in_dark = 2
- src.see_invisible = 0
-
- if (src.sleep)
- src.sleep.icon_state = text("sleep[]", src.sleeping > 0 ? 1 : 0)
- src.sleep.overlays = null
- if(src.sleeping_willingly)
- src.sleep.overlays += icon(src.sleep.icon, "sleep_willing")
- if (src.rest) src.rest.icon_state = text("rest[]", src.resting)
-
- if (src.healths)
- if (src.stat != 2)
- switch(health)
- if(100 to INFINITY)
- src.healths.icon_state = "health0"
- if(80 to 100)
- src.healths.icon_state = "health1"
- if(60 to 80)
- src.healths.icon_state = "health2"
- if(40 to 60)
- src.healths.icon_state = "health3"
- if(20 to 40)
- src.healths.icon_state = "health4"
- if(0 to 20)
- src.healths.icon_state = "health5"
- else
- src.healths.icon_state = "health6"
- else
- src.healths.icon_state = "health7"
-
- if (pressure)
- var/datum/gas_mixture/environment = loc.return_air()
- if(environment)
- switch(environment.return_pressure())
-
- if(HAZARD_HIGH_PRESSURE to INFINITY)
- pressure.icon_state = "pressure2"
- if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE)
- pressure.icon_state = "pressure1"
- if(WARNING_LOW_PRESSURE to WARNING_HIGH_PRESSURE)
- pressure.icon_state = "pressure0"
- if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
- pressure.icon_state = "pressure-1"
- else
- pressure.icon_state = "pressure-2"
-
- if(src.pullin) src.pullin.icon_state = "pull[src.pulling ? 1 : 0]"
-
-
- if (src.toxin) src.toxin.icon_state = "tox[src.toxins_alert ? 1 : 0]"
- if (src.oxygen) src.oxygen.icon_state = "oxy[src.oxygen_alert ? 1 : 0]"
- if (src.fire) src.fire.icon_state = "fire[src.fire_alert ? 1 : 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(src.bodytemperature) //310.055 optimal body temp
- if(345 to INFINITY)
- src.bodytemp.icon_state = "temp4"
- if(335 to 345)
- src.bodytemp.icon_state = "temp3"
- if(327 to 335)
- src.bodytemp.icon_state = "temp2"
- if(316 to 327)
- src.bodytemp.icon_state = "temp1"
- if(300 to 316)
- src.bodytemp.icon_state = "temp0"
- if(295 to 300)
- src.bodytemp.icon_state = "temp-1"
- if(280 to 295)
- src.bodytemp.icon_state = "temp-2"
- if(260 to 280)
- src.bodytemp.icon_state = "temp-3"
- else
- src.bodytemp.icon_state = "temp-4"
-
- src.client.screen -= src.hud_used.blurry
- src.client.screen -= src.hud_used.druggy
- src.client.screen -= src.hud_used.vimpaired
-
- if ((src.blind && src.stat != 2))
- if ((src.blinded))
- src.blind.layer = 18
- else
- src.blind.layer = 0
-
- if (src.disabilities & 1)
- src.client.screen += src.hud_used.vimpaired
-
- if (src.eye_blurry)
- src.client.screen += src.hud_used.blurry
-
- if (src.druggy)
- src.client.screen += src.hud_used.druggy
-
- if (src.stat != 2)
- if (src.machine)
- if (!( src.machine.check_eye(src) ))
- src.reset_view(null)
- else
- if(!client.adminobs)
- reset_view(null)
-
- return 1
-
- handle_virus_updates()
- // amorphs can't come down with human diseases
+/mob/living/carbon/amorph
+ var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
+
+ var/oxygen_alert = 0
+ var/toxins_alert = 0
+ var/fire_alert = 0
+
+ var/temperature_alert = 0
+
+
+/mob/living/carbon/amorph/Life()
+ set invisibility = 0
+ set background = 1
+
+ if (src.monkeyizing)
+ return
+
+ ..()
+
+ var/datum/gas_mixture/environment // Added to prevent null location errors-- TLE
+ if(src.loc)
+ environment = loc.return_air()
+
+ if (src.stat != 2) //still breathing
+
+ //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)
+
+ //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
+
+ //Disease Check
+ handle_virus_updates()
+
+ //Handle temperature/pressure differences between body and environment
+ if(environment) // More error checking -- TLE
+ handle_environment(environment)
+
+ //Mutations and radiation
+ handle_mutations_and_radiation()
+
+ //Chemicals in the body
+ handle_chemicals_in_body()
+
+ //Disabilities
+ handle_disabilities()
+
+ //Status updates, death etc.
+// UpdateLuminosity()
+ handle_regular_status_updates()
+
+ if(client)
+ handle_regular_hud_updates()
+
+ //Being buckled to a chair or bed
+ check_if_buckled()
+
+ // Yup.
+ update_canmove()
+
+ clamp_values()
+
+ // Grabbing
+ for(var/obj/item/weapon/grab/G in src)
+ G.process()
+
+/mob/living/carbon/amorph
+ proc
+
+ clamp_values()
+
+ AdjustStunned(0)
+ AdjustParalysis(0)
+ AdjustWeakened(0)
+
+ handle_disabilities()
+ if (src.disabilities & 4)
+ if ((prob(5) && src.paralysis <= 1 && src.r_ch_cou < 1))
+ src.drop_item()
+ spawn( 0 )
+ emote("cough")
+ return
+ if (src.disabilities & 8)
+ if ((prob(10) && src.paralysis <= 1 && src.r_Tourette < 1))
+ Stun(10)
+ spawn( 0 )
+ emote("twitch")
+ return
+ if (src.disabilities & 16)
+ if (prob(10))
+ src.stuttering = max(10, src.stuttering)
+
+ update_mind()
+ if(!mind && client)
+ mind = new
+ mind.current = src
+ mind.key = key
+
+ handle_mutations_and_radiation()
+ // amorphs are immune to this stuff
+
+ breathe()
+ if(src.reagents)
+
+ if(src.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(losebreath>0) //Suffocating so do not take a breath
+ src.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)
+
+ // 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/chem_smoke/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)
+
+
+ get_breath_from_internal(volume_needed)
+ if(internal)
+ if (!contents.Find(src.internal))
+ internal = null
+ if (!wear_mask || !(wear_mask.flags|MASKINTERNALS) )
+ internal = null
+ if(internal)
+ if (src.internals)
+ src.internals.icon_state = "internal1"
+ return internal.remove_air_volume(volume_needed)
+ else
+ if (src.internals)
+ src.internals.icon_state = "internal0"
+ return null
+
+ update_canmove()
+ if(paralysis || stunned || weakened || buckled || (changeling && changeling.changeling_fakedeath)) canmove = 0
+ else canmove = 1
+
+ handle_breath(datum/gas_mixture/breath)
+ if(src.nodamage)
+ return
+
+ if(!breath || (breath.total_moles == 0))
+ adjustOxyLoss(7)
+
+ oxygen_alert = max(oxygen_alert, 1)
+
+ return 0
+
+ var/safe_oxygen_min = 8 // 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/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.oxygen/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.oxygen*ratio/6
+ oxygen_alert = max(oxygen_alert, 1)
+ else // We're in safe limits
+ adjustOxyLoss(-5)
+ oxygen_used = breath.oxygen/6
+ oxygen_alert = 0
+
+ breath.oxygen -= oxygen_used
+ breath.carbon_dioxide += oxygen_used
+
+ if(breath.trace_gases.len) // If there's some other shit in the air lets deal with it here.
+ for(var/datum/gas/sleeping_agent/SA in breath.trace_gases)
+ var/SA_pp = (SA.moles/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
+ src.sleeping = max(src.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"))
+
+ return 1
+
+ handle_environment(datum/gas_mixture/environment)
+ if(!environment)
+ return
+ var/environment_heat_capacity = environment.heat_capacity()
+ if(istype(loc, /turf/space))
+ environment_heat_capacity = loc:heat_capacity
+
+ if((environment.temperature > (T0C + 50)) || (environment.temperature < (T0C + 10)))
+ var/transfer_coefficient
+
+ transfer_coefficient = 1
+ if(wear_mask && (wear_mask.body_parts_covered & HEAD) && (environment.temperature < wear_mask.protective_temperature))
+ transfer_coefficient *= wear_mask.heat_transfer_coefficient
+
+ 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
+
+
+ var/pressure = environment.return_pressure()
+
+ // if(!wear_suit) Monkies cannot into space.
+ // if(!istype(wear_suit, /obj/item/clothing/suit/space))
+
+ /*if(pressure < 20)
+ if(prob(25))
+ src << "You feel the splittle on your lips and the fluid on your eyes boiling away, the capillteries in your skin breaking."
+ adjustBruteLoss(5)
+ */
+
+ if(pressure > HAZARD_HIGH_PRESSURE)
+
+ adjustBruteLoss(min((10+(round(pressure/(HIGH_STEP_PRESSURE)-2)*5)),MAX_PRESSURE_DAMAGE))
+
+
+
+ return //TODO: DEFERRED
+
+ handle_temperature_damage(body_part, exposed_temperature, exposed_intensity)
+ if(src.nodamage) return
+ var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
+ if(exposed_temperature > bodytemperature)
+ adjustFireLoss(20.0*discomfort)
+
+ else
+ adjustFireLoss(5.0*discomfort)
+
+ handle_chemicals_in_body()
+ // most chemicals will have no effect on amorphs
+ //if(reagents) reagents.metabolize(src)
+
+ if (src.drowsyness)
+ src.drowsyness--
+ src.eye_blurry = max(2, src.eye_blurry)
+ if (prob(5))
+ src.sleeping += 1
+ Paralyse(5)
+
+ confused = max(0, confused - 1)
+ // decrement dizziness counter, clamped to 0
+ if(resting)
+ dizziness = max(0, dizziness - 5)
+ else
+ dizziness = max(0, dizziness - 1)
+
+ src.updatehealth()
+
+ return //TODO: DEFERRED
+
+ handle_regular_status_updates()
+
+ health = 100 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
+
+ if(getOxyLoss() > 25) Paralyse(3)
+
+ if(src.sleeping)
+ Paralyse(5)
+ if (prob(1) && health) spawn(0) emote("snore")
+
+ if(src.resting)
+ Weaken(5)
+
+ if(health < config.health_threshold_dead && stat != 2)
+ death()
+ else if(src.health < config.health_threshold_crit)
+ if(src.health <= 20 && prob(1)) spawn(0) emote("gasp")
+
+ // shuffle around the chemical effects for amorphs a little ;)
+ if(!src.reagents.has_reagent("antitoxin") && src.stat != 2) src.adjustOxyLoss(2)
+
+ if(src.stat != 2) src.stat = 1
+ Paralyse(5)
+
+ if (src.stat != 2) //Alive.
+
+ if (src.paralysis || src.stunned || src.weakened) //Stunned etc.
+ if (src.stunned > 0)
+ AdjustStunned(-1)
+ src.stat = 0
+ if (src.weakened > 0)
+ AdjustWeakened(-1)
+ src.lying = 1
+ src.stat = 0
+ if (src.paralysis > 0)
+ AdjustParalysis(-1)
+ src.blinded = 1
+ src.lying = 1
+ src.stat = 1
+ var/h = src.hand
+ src.hand = 0
+ drop_item()
+ src.hand = 1
+ drop_item()
+ src.hand = h
+
+ else //Not stunned.
+ src.lying = 0
+ src.stat = 0
+
+ else //Dead.
+ src.lying = 1
+ src.blinded = 1
+ src.stat = 2
+
+ if (src.stuttering) src.stuttering--
+ if (src.slurring) src.slurring--
+
+ if (src.eye_blind)
+ src.eye_blind--
+ src.blinded = 1
+
+ if (src.ear_deaf > 0) src.ear_deaf--
+ if (src.ear_damage < 25)
+ src.ear_damage -= 0.05
+ src.ear_damage = max(src.ear_damage, 0)
+
+ src.density = !( src.lying )
+
+ if (src.disabilities & 128)
+ src.blinded = 1
+ if (src.disabilities & 32)
+ src.ear_deaf = 1
+
+ if (src.eye_blurry > 0)
+ src.eye_blurry--
+ src.eye_blurry = max(0, src.eye_blurry)
+
+ if (src.druggy > 0)
+ src.druggy--
+ src.druggy = max(0, src.druggy)
+
+ return 1
+
+ handle_regular_hud_updates()
+
+ if (src.stat == 2 || (XRAY in mutations))
+ src.sight |= SEE_TURFS
+ src.sight |= SEE_MOBS
+ src.sight |= SEE_OBJS
+ src.see_in_dark = 8
+ src.see_invisible = 2
+ else if (src.stat != 2)
+ src.sight &= ~SEE_TURFS
+ src.sight &= ~SEE_MOBS
+ src.sight &= ~SEE_OBJS
+ src.see_in_dark = 2
+ src.see_invisible = 0
+
+ if (src.sleep)
+ src.sleep.icon_state = text("sleep[]", src.sleeping > 0 ? 1 : 0)
+ src.sleep.overlays = null
+ if(src.sleeping_willingly)
+ src.sleep.overlays += icon(src.sleep.icon, "sleep_willing")
+ if (src.rest) src.rest.icon_state = text("rest[]", src.resting)
+
+ if (src.healths)
+ if (src.stat != 2)
+ switch(health)
+ if(100 to INFINITY)
+ src.healths.icon_state = "health0"
+ if(80 to 100)
+ src.healths.icon_state = "health1"
+ if(60 to 80)
+ src.healths.icon_state = "health2"
+ if(40 to 60)
+ src.healths.icon_state = "health3"
+ if(20 to 40)
+ src.healths.icon_state = "health4"
+ if(0 to 20)
+ src.healths.icon_state = "health5"
+ else
+ src.healths.icon_state = "health6"
+ else
+ src.healths.icon_state = "health7"
+
+ if (pressure)
+ var/datum/gas_mixture/environment = loc.return_air()
+ if(environment)
+ switch(environment.return_pressure())
+
+ if(HAZARD_HIGH_PRESSURE to INFINITY)
+ pressure.icon_state = "pressure2"
+ if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE)
+ pressure.icon_state = "pressure1"
+ if(WARNING_LOW_PRESSURE to WARNING_HIGH_PRESSURE)
+ pressure.icon_state = "pressure0"
+ if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
+ pressure.icon_state = "pressure-1"
+ else
+ pressure.icon_state = "pressure-2"
+
+ if(src.pullin) src.pullin.icon_state = "pull[src.pulling ? 1 : 0]"
+
+
+ if (src.toxin) src.toxin.icon_state = "tox[src.toxins_alert ? 1 : 0]"
+ if (src.oxygen) src.oxygen.icon_state = "oxy[src.oxygen_alert ? 1 : 0]"
+ if (src.fire) src.fire.icon_state = "fire[src.fire_alert ? 1 : 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(src.bodytemperature) //310.055 optimal body temp
+ if(345 to INFINITY)
+ src.bodytemp.icon_state = "temp4"
+ if(335 to 345)
+ src.bodytemp.icon_state = "temp3"
+ if(327 to 335)
+ src.bodytemp.icon_state = "temp2"
+ if(316 to 327)
+ src.bodytemp.icon_state = "temp1"
+ if(300 to 316)
+ src.bodytemp.icon_state = "temp0"
+ if(295 to 300)
+ src.bodytemp.icon_state = "temp-1"
+ if(280 to 295)
+ src.bodytemp.icon_state = "temp-2"
+ if(260 to 280)
+ src.bodytemp.icon_state = "temp-3"
+ else
+ src.bodytemp.icon_state = "temp-4"
+
+ src.client.screen -= src.hud_used.blurry
+ src.client.screen -= src.hud_used.druggy
+ src.client.screen -= src.hud_used.vimpaired
+
+ if ((src.blind && src.stat != 2))
+ if ((src.blinded))
+ src.blind.layer = 18
+ else
+ src.blind.layer = 0
+
+ if (src.disabilities & 1)
+ src.client.screen += src.hud_used.vimpaired
+
+ if (src.eye_blurry)
+ src.client.screen += src.hud_used.blurry
+
+ if (src.druggy)
+ src.client.screen += src.hud_used.druggy
+
+ if (src.stat != 2)
+ if (src.machine)
+ if (!( src.machine.check_eye(src) ))
+ src.reset_view(null)
+ else
+ if(!client.adminobs)
+ reset_view(null)
+
+ return 1
+
+ handle_virus_updates()
+ // amorphs can't come down with human diseases
return
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/amorph/say.dm b/code/WorkInProgress/Cib/amorph/say.dm
similarity index 97%
rename from code/modules/mob/living/carbon/amorph/say.dm
rename to code/WorkInProgress/Cib/amorph/say.dm
index 4663a847a1b..a73c9de5d39 100644
--- a/code/modules/mob/living/carbon/amorph/say.dm
+++ b/code/WorkInProgress/Cib/amorph/say.dm
@@ -1,6 +1,6 @@
-/mob/living/carbon/amorph/emote(var/act,var/m_type=1,var/message = null)
- if(act == "me")
- return custom_emote(m_type, message)
-
-/mob/living/carbon/amorph/say_quote(var/text)
- return "[src.say_message], \"[text]\"";
+/mob/living/carbon/amorph/emote(var/act,var/m_type=1,var/message = null)
+ if(act == "me")
+ return custom_emote(m_type, message)
+
+/mob/living/carbon/amorph/say_quote(var/text)
+ return "[src.say_message], \"[text]\"";
diff --git a/code/modules/mob/living/parasite/meme.dm b/code/WorkInProgress/Cib/meme.dm
similarity index 100%
rename from code/modules/mob/living/parasite/meme.dm
rename to code/WorkInProgress/Cib/meme.dm
diff --git a/code/WorkInProgress/Mini/ATM.dm b/code/WorkInProgress/Mini/ATM.dm
index 17b6ef2e47c..7551e96e9c5 100644
--- a/code/WorkInProgress/Mini/ATM.dm
+++ b/code/WorkInProgress/Mini/ATM.dm
@@ -7,6 +7,11 @@ log transactions
*/
+#define NO_SCREEN 0
+#define CHANGE_SECURITY_LEVEL 1
+#define TRANSFER_FUNDS 2
+#define VIEW_TRANSACTION_LOGS 3
+
/obj/item/weapon/card/id/var/money = 2000
/obj/machinery/atm
@@ -17,72 +22,346 @@ log transactions
anchored = 1
use_power = 1
idle_power_usage = 10
+ var/obj/machinery/account_database/linked_db
+ var/datum/money_account/authenticated_account
+ var/number_incorrect_tries = 0
+ var/previous_account_number = 0
+ var/max_pin_attempts = 3
+ var/ticks_left_locked_down = 0
+ var/ticks_left_timeout = 0
+ var/machine_id = ""
+ var/obj/item/weapon/card/held_card
+ var/editing_security_level = 0
+ var/view_screen = NO_SCREEN
+
+/obj/machinery/atm/New()
+ ..()
+ reconnect_database()
+ machine_id = "[station_name()] RT #[num_financial_terminals++]"
+
+/obj/machinery/atm/process()
+ if(ticks_left_timeout > 0)
+ ticks_left_timeout--
+ if(ticks_left_timeout <= 0)
+ authenticated_account = null
+ if(ticks_left_locked_down > 0)
+ ticks_left_locked_down--
+
+ for(var/obj/item/weapon/spacecash/S in src)
+ S.loc = src.loc
+ if(prob(50))
+ playsound(loc, 'sound/items/polaroid1.ogg', 50, 1)
+ else
+ playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
+ break
+
+/obj/machinery/atm/proc/reconnect_database()
+ for(var/obj/machinery/account_database/DB in world)
+ if(DB.z == src.z)
+ linked_db = DB
+ break
/obj/machinery/atm/attackby(obj/item/I as obj, mob/user as mob)
- if(ishuman(user))
- var/obj/item/weapon/card/id/user_id = src.scan_user(user)
+ if(istype(I, /obj/item/weapon/card))
+ var/obj/item/weapon/card/id/idcard = I
+ if(!held_card)
+ usr.drop_item()
+ idcard.loc = src
+ held_card = idcard
+ authenticated_account = null
+ else if(authenticated_account)
if(istype(I,/obj/item/weapon/spacecash))
- user_id.money += I:worth
+ //consume the money
+ authenticated_account.money += I:worth
+ if(prob(50))
+ playsound(loc, 'sound/items/polaroid1.ogg', 50, 1)
+ else
+ playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
+
+ //create a transaction log entry
+ var/datum/transaction/T = new()
+ T.target_name = authenticated_account.owner_name
+ T.purpose = "Credit deposit"
+ T.amount = I:worth
+ T.source_terminal = machine_id
+ T.date = current_date_string
+ T.time = worldtime2text()
+ authenticated_account.transaction_log.Add(T)
+
+ user << "You insert [I] into [src]."
+ src.attack_hand(user)
del I
+ else ..()
/obj/machinery/atm/attack_hand(mob/user as mob)
if(istype(user, /mob/living/silicon))
user << "\red Artificial unit recognized. Artificial units do not currently receive monetary compensation, as per NanoTrasen regulation #1005."
return
+ if(get_dist(src,user) <= 1)
+ //check to see if the user has low security enabled
+ scan_user(user)
- var/obj/item/weapon/card/id/user_id = src.scan_user(user)
- if(..())
- return
- var/dat = ""
- dat += "NanoTrasen Automatic Teller Machine
"
- dat += "For all your monetary needs!
"
- dat += "Welcome, [user_id.registered_name].
"
- dat += "You have $[user_id.money] in your account.
"
- dat += "Withdraw
"
- user << browse(dat,"window=atm")
+ //js replicated from obj/machinery/computer/card
+ var/dat = "NanoTrasen Automatic Teller Machine
"
+ dat += "For all your monetary needs!
"
+ dat += "This terminal is [machine_id]. Report this code when contacting NanoTrasen IT Support
"
+ dat += "Card: [held_card ? held_card.name : "------"]
"
+
+ if(ticks_left_locked_down > 0)
+ dat += "Maximum number of pin attempts exceeded! Access to this ATM has been temporarily disabled."
+ else if(authenticated_account)
+ switch(view_screen)
+ if(CHANGE_SECURITY_LEVEL)
+ dat += "Select a new security level for this account:
"
+ var/text = "Zero - Only account number or card is required to access this account. EFTPOS transactions will require a card and ask for a pin, but not verify the pin is correct."
+ if(authenticated_account.security_level != 0)
+ text = "[text]"
+ dat += "[text]
"
+ text = "One - Both an account number and pin is required to access this account and process transactions."
+ if(authenticated_account.security_level != 1)
+ text = "[text]"
+ dat += "[text]
"
+ text = "Two - In addition to account number and pin, a card is required to access this account and process transactions."
+ if(authenticated_account.security_level != 2)
+ text = "[text]"
+ dat += "[text]
"
+ dat += "Back"
+ if(VIEW_TRANSACTION_LOGS)
+ dat += "Transaction logs
"
+ dat += "Back"
+ dat += ""
+ dat += ""
+ dat += "| Date | "
+ dat += "Time | "
+ dat += "Target | "
+ dat += "Purpose | "
+ dat += "Value | "
+ dat += "Source terminal ID | "
+ dat += "
"
+ for(var/datum/transaction/T in authenticated_account.transaction_log)
+ dat += ""
+ dat += "| [T.date] | "
+ dat += "[T.time] | "
+ dat += "[T.target_name] | "
+ dat += "[T.purpose] | "
+ dat += "$[T.amount] | "
+ dat += "[T.source_terminal] | "
+ dat += "
"
+ dat += "
"
+ if(TRANSFER_FUNDS)
+ dat += "Account balance: $[authenticated_account.money]
"
+ dat += "Back
"
+ dat += ""
+ else
+ dat += "Welcome, [authenticated_account.owner_name].
"
+ dat += "Account balance: $[authenticated_account.money]"
+ dat += ""
+ dat += "Change account security level
"
+ dat += "Make transfer
"
+ dat += "View transaction log
"
+ dat += "Print balance statement
"
+ dat += "Logout
"
+ else if(linked_db)
+ dat += ""
+ else
+ dat += "Unable to connect to accounts database, please retry and if the issue persists contact NanoTrasen IT support."
+ reconnect_database()
+
+ user << browse(dat,"window=atm;size=500x650")
+ else
+ user << browse(null,"window=atm")
/obj/machinery/atm/Topic(var/href, var/href_list)
- if(href_list["withdraw"] && href_list["id"])
- var/amount = input("How much would you like to withdraw?", "Amount", 0) in list(1,10,20,50,100,200,500,1000, 0)
- var/obj/item/weapon/card/id/user_id = locate(href_list["id"])
- if(amount != 0 && user_id)
- if(amount <= user_id.money)
- user_id.money -= amount
- //hueg switch for giving moneh out
- switch(amount)
- if(1)
- new /obj/item/weapon/spacecash(loc)
- if(10)
- new /obj/item/weapon/spacecash/c10(loc)
- if(20)
- new /obj/item/weapon/spacecash/c20(loc)
- if(50)
- new /obj/item/weapon/spacecash/c50(loc)
- if(100)
- new /obj/item/weapon/spacecash/c100(loc)
- if(200)
- new /obj/item/weapon/spacecash/c200(loc)
- if(500)
- new /obj/item/weapon/spacecash/c500(loc)
- if(1000)
- new /obj/item/weapon/spacecash/c1000(loc)
- else
- usr << browse("You don't have that much money!
Back","window=atm")
- return
+ if(href_list["choice"])
+ switch(href_list["choice"])
+ if("transfer")
+ if(authenticated_account && linked_db)
+ var/target_account_number = text2num(href_list["target_acc_number"])
+ var/transfer_amount = text2num(href_list["funds_amount"])
+ var/transfer_purpose = href_list["purpose"]
+ if(transfer_amount <= authenticated_account.money)
+ if(linked_db.charge_to_account(target_account_number, authenticated_account.owner_name, transfer_purpose, machine_id, transfer_amount))
+ usr << "\icon[src]Funds transfer successful."
+ authenticated_account.money -= transfer_amount
+
+ //create an entry in the account transaction log
+ var/datum/transaction/T = new()
+ T.target_name = "Account #[target_account_number]"
+ T.purpose = transfer_purpose
+ T.source_terminal = machine_id
+ T.date = current_date_string
+ T.time = worldtime2text()
+ T.amount = "([transfer_amount])"
+ authenticated_account.transaction_log.Add(T)
+ else
+ usr << "\icon[src]Funds transfer failed."
+
+ else
+ usr << "\icon[src]You don't have enough funds to do that!"
+ if("view_screen")
+ view_screen = text2num(href_list["view_screen"])
+ if("change_security_level")
+ if(authenticated_account)
+ var/new_sec_level = max( min(text2num(href_list["new_security_level"]), 2), 0)
+ authenticated_account.security_level = new_sec_level
+ if("attempt_auth")
+ if(linked_db)
+ var/tried_account_num = text2num(href_list["account_num"])
+ if(!tried_account_num)
+ tried_account_num = held_card.associated_account_number
+ var/tried_pin = text2num(href_list["account_pin"])
+
+ authenticated_account = linked_db.attempt_account_access(tried_account_num, tried_pin, held_card && held_card.associated_account_number == tried_account_num ? 2 : 1)
+ if(!authenticated_account)
+ if(previous_account_number == tried_account_num)
+ if(++number_incorrect_tries > max_pin_attempts)
+ //lock down the atm
+ number_incorrect_tries = 0
+ ticks_left_locked_down = 10
+ playsound(src, 'buzz-two.ogg', 50, 1)
+
+ //create an entry in the account transaction log
+ var/datum/transaction/T = new()
+ T.target_name = authenticated_account.owner_name
+ T.purpose = "Unauthorised login attempt"
+ T.source_terminal = machine_id
+ T.date = current_date_string
+ T.time = worldtime2text()
+ authenticated_account.transaction_log.Add(T)
+ else
+ previous_account_number = tried_account_num
+ number_incorrect_tries = 1
+ playsound(src, 'buzz-sigh.ogg', 50, 1)
+ else
+ playsound(src, 'twobeep.ogg', 50, 1)
+ ticks_left_timeout = 120
+ view_screen = NO_SCREEN
+
+ //create a transaction log entry
+ var/datum/transaction/T = new()
+ T.target_name = authenticated_account.owner_name
+ T.purpose = "Remote terminal access"
+ T.source_terminal = machine_id
+ T.date = current_date_string
+ T.time = worldtime2text()
+ authenticated_account.transaction_log.Add(T)
+ if("withdrawal")
+ var/amount = max(text2num(href_list["funds_amount"]),0)
+ if(authenticated_account && amount > 0)
+ if(amount <= authenticated_account.money)
+ playsound(src, 'chime.ogg', 50, 1)
+
+ //remove the money
+ authenticated_account.money -= amount
+ withdraw_arbitrary_sum(amount)
+
+ //create an entry in the account transaction log
+ var/datum/transaction/T = new()
+ T.target_name = authenticated_account.owner_name
+ T.purpose = "Credit withdrawal"
+ T.amount = "([amount])"
+ T.source_terminal = machine_id
+ T.date = current_date_string
+ T.time = worldtime2text()
+ authenticated_account.transaction_log.Add(T)
+ else
+ usr << "\icon[src]You don't have enough funds to do that!"
+ if("balance_statement")
+ if(authenticated_account)
+ var/obj/item/weapon/paper/R = new(src.loc)
+ R.name = "Account balance: [authenticated_account.owner_name]"
+ R.info = "NT Automated Teller Account Statement
"
+ R.info += "Account holder: [authenticated_account.owner_name]
"
+ R.info += "Account number: [authenticated_account.account_number]
"
+ R.info += "Balance: $[authenticated_account.money]
"
+ R.info += "Date and time: [worldtime2text()], [current_date_string]
"
+ R.info += "Service terminal ID: [machine_id]
"
+
+ //stamp the paper
+ var/image/stampoverlay = image('icons/obj/bureaucracy.dmi')
+ stampoverlay.icon_state = "paper_stamp-cent"
+ if(!R.stamped)
+ R.stamped = new
+ R.stamped += /obj/item/weapon/stamp
+ R.overlays += stampoverlay
+ R.stamps += "
This paper has been stamped by the Automatic Teller Machine."
+
+ if(prob(50))
+ playsound(loc, 'sound/items/polaroid1.ogg', 50, 1)
+ else
+ playsound(loc, 'sound/items/polaroid2.ogg', 50, 1)
+ if("insert_card")
+ if(held_card)
+ held_card.loc = src.loc
+ authenticated_account = null
+
+ if(ishuman(usr) && !usr.get_active_hand())
+ usr.put_in_hands(held_card)
+ held_card = null
+
+ else
+ var/obj/item/I = usr.get_active_hand()
+ if (istype(I, /obj/item/weapon/card/id))
+ usr.drop_item()
+ I.loc = src
+ held_card = I
+ if("logout")
+ authenticated_account = null
src.attack_hand(usr)
+//create the most effective combination of notes to make up the requested amount
+/obj/machinery/atm/proc/withdraw_arbitrary_sum(var/arbitrary_sum)
+ while(arbitrary_sum >= 1000)
+ arbitrary_sum -= 1000
+ new /obj/item/weapon/spacecash/c1000(src)
+ while(arbitrary_sum >= 500)
+ arbitrary_sum -= 500
+ new /obj/item/weapon/spacecash/c500(src)
+ while(arbitrary_sum >= 200)
+ arbitrary_sum -= 200
+ new /obj/item/weapon/spacecash/c200(src)
+ while(arbitrary_sum >= 100)
+ arbitrary_sum -= 100
+ new /obj/item/weapon/spacecash/c100(src)
+ while(arbitrary_sum >= 50)
+ arbitrary_sum -= 50
+ new /obj/item/weapon/spacecash/c50(src)
+ while(arbitrary_sum >= 20)
+ arbitrary_sum -= 20
+ new /obj/item/weapon/spacecash/c20(src)
+ while(arbitrary_sum >= 10)
+ arbitrary_sum -= 10
+ new /obj/item/weapon/spacecash/c10(src)
+ while(arbitrary_sum >= 1)
+ arbitrary_sum -= 1
+ new /obj/item/weapon/spacecash(src)
+
//stolen wholesale and then edited a bit from newscasters, which are awesome and by Agouri
/obj/machinery/atm/proc/scan_user(mob/living/carbon/human/human_user as mob)
- if(human_user.wear_id)
- if(istype(human_user.wear_id, /obj/item/device/pda) )
- var/obj/item/device/pda/P = human_user.wear_id
- if(P.id)
- return P.id
- else
- return null
- else if(istype(human_user.wear_id, /obj/item/weapon/card/id) )
- return human_user.wear_id
- else
- return null
- else
- return null
+ if(!authenticated_account && linked_db)
+ if(human_user.wear_id)
+ var/obj/item/weapon/card/id/I
+ if(istype(human_user.wear_id, /obj/item/weapon/card/id) )
+ I = human_user.wear_id
+ else if(istype(human_user.wear_id, /obj/item/device/pda) )
+ var/obj/item/device/pda/P = human_user.wear_id
+ I = P.id
+ if(I)
+ authenticated_account = linked_db.attempt_account_access(I.associated_account_number)
diff --git a/code/WorkInProgress/Mini/atmos_control.dm b/code/WorkInProgress/Mini/atmos_control.dm
index 6c06a16b799..506258cdf9b 100644
--- a/code/WorkInProgress/Mini/atmos_control.dm
+++ b/code/WorkInProgress/Mini/atmos_control.dm
@@ -16,7 +16,7 @@
/obj/machinery/computer/atmoscontrol/attack_hand(mob/user)
if(..())
return
- user.machine = src
+ user.set_machine(src)
if(allowed(user))
overridden = 1
else if(!emagged)
@@ -139,6 +139,12 @@
src.updateUsrDialog()
return
+ if(href_list["atmos_unlock"])
+ switch(href_list["atmos_unlock"])
+ if("0")
+ current.air_doors_close(1)
+ if("1")
+ current.air_doors_open(1)
if(href_list["atmos_alarm"])
if (current.alarm_area.atmosalert(2))
@@ -187,6 +193,8 @@
output += "PANIC SYPHON ACTIVE
turn syphoning off"
else
output += "ACTIVATE PANIC SYPHON IN AREA"
+
+ output += "
Atmospheric Lockdown: [current.alarm_area.air_doors_activated ? "ENABLED" : "Disabled"]"
if (AALARM_SCREEN_VENT)
var/sensor_data = ""
if(current.alarm_area.air_vent_names.len)
diff --git a/code/WorkInProgress/Ported/Abi79/uplinks.dm b/code/WorkInProgress/Ported/Abi79/uplinks.dm
index 55cd988af8f..3cba4e3c6c7 100644
--- a/code/WorkInProgress/Ported/Abi79/uplinks.dm
+++ b/code/WorkInProgress/Ported/Abi79/uplinks.dm
@@ -31,7 +31,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid
if(!uplink_data)
uplink_data = ticker.mode.uplink_items
- items = dd_replacetext(uplink_data, "\n", "") // Getting the text string of items
+ items = replacetext(uplink_data, "\n", "") // Getting the text string of items
ItemList = dd_text2list(src.items, ";") // Parsing the items text string
uses = ticker.mode.uplink_uses
diff --git a/code/WorkInProgress/Ported/policetape.dm b/code/WorkInProgress/Ported/policetape.dm
index 2c2e41025aa..43a41c5a937 100644
--- a/code/WorkInProgress/Ported/policetape.dm
+++ b/code/WorkInProgress/Ported/policetape.dm
@@ -40,7 +40,7 @@
/obj/item/tape/engineering
name = "engineering tape"
desc = "A length of engineering tape. Better not cross it."
- req_access = list(access_engine,access_atmospherics)
+ req_one_access = list(access_engine,access_atmospherics)
icon_base = "engineering"
/obj/item/taperoll/attack_self(mob/user as mob)
diff --git a/code/WorkInProgress/Sigyn/Department Sec/__README.dm b/code/WorkInProgress/Sigyn/Department Sec/__README.dm
new file mode 100644
index 00000000000..e6b3f7967fd
--- /dev/null
+++ b/code/WorkInProgress/Sigyn/Department Sec/__README.dm
@@ -0,0 +1,8 @@
+/*
+
+Hey you!
+You only need to untick maps/tgstation.2.0.9.dmm for this if you download the modified map from:
+http://tgstation13.googlecode.com/files/tgstation.2.1.0_deptsec.zip
+
+Everything else can just be ticked on top of the original stuff.
+*/
\ No newline at end of file
diff --git a/code/WorkInProgress/Sigyn/Department Sec/jobs.dm b/code/WorkInProgress/Sigyn/Department Sec/jobs.dm
new file mode 100644
index 00000000000..66e14b040c3
--- /dev/null
+++ b/code/WorkInProgress/Sigyn/Department Sec/jobs.dm
@@ -0,0 +1,126 @@
+var/list/sec_departments = list("engineering", "supply", "medical", "science")
+
+proc/assign_sec_to_department(var/mob/living/carbon/human/H)
+ if(sec_departments.len)
+ var/department = pick(sec_departments)
+ sec_departments -= department
+ var/access = null
+ var/destination = null
+ switch(department)
+ if("supply")
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/security/cargo(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec/department/supply(H), slot_ears)
+ access = list(access_mailsorting, access_mining)
+ destination = /area/security/checkpoint/supply
+ if("engineering")
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/security/engine(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec/department/engi(H), slot_ears)
+ access = list(access_construction, access_engine)
+ destination = /area/security/checkpoint/engineering
+ if("medical")
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/security/med(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec/department/med(H), slot_ears)
+ access = list(access_medical)
+ destination = /area/security/checkpoint/medical
+ if("science")
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/security/science(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec/department/sci(H), slot_ears)
+ access = list(access_research)
+ destination = /area/security/checkpoint/science
+ else
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/security(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec(H), slot_ears)
+
+
+ if(destination)
+ var/teleport = 0
+ if(!ticker || ticker.current_state <= GAME_STATE_SETTING_UP)
+ teleport = 1
+ spawn(15)
+ if(H)
+ if(teleport)
+ var/turf/T
+ var/safety = 0
+ while(safety < 25)
+ T = pick(get_area_turfs(destination))
+ if(!H.Move(T))
+ safety += 1
+ continue
+ else
+ break
+ H << "You have been assigned to [department]!"
+ if(locate(/obj/item/weapon/card/id, H))
+ var/obj/item/weapon/card/id/I = locate(/obj/item/weapon/card/id, H)
+ if(I)
+ I.access |= access
+
+
+/datum/job/officer
+ title = "Security Officer"
+ flag = OFFICER
+ department_flag = ENGSEC
+ faction = "Station"
+ total_positions = 5
+ spawn_positions = 5
+ supervisors = "the head of security, and the head of your assigned department (if applicable)"
+ selection_color = "#ffeeee"
+
+
+ equip(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ if(H.backbag == 2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(H), slot_back)
+ if(H.backbag == 3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_sec(H), slot_back)
+ assign_sec_to_department(H)
+ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes)
+ H.equip_to_slot_or_del(new /obj/item/device/pda/security(H), slot_belt)
+ H.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(H), slot_wear_suit)
+ H.equip_to_slot_or_del(new /obj/item/clothing/head/helmet(H), slot_head)
+ H.equip_to_slot_or_del(new /obj/item/weapon/handcuffs(H), slot_s_store)
+ H.equip_to_slot_or_del(new /obj/item/device/flash(H), slot_l_store)
+ if(H.backbag == 1)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
+ H.equip_to_slot_or_del(new /obj/item/weapon/handcuffs(H), slot_l_hand)
+ 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/weapon/handcuffs(H), slot_in_backpack)
+ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
+ L.imp_in = H
+ L.implanted = 1
+ return 1
+
+/obj/item/device/radio/headset/headset_sec/department/New()
+ if(radio_controller)
+ initialize()
+ recalculateChannels()
+
+/obj/item/device/radio/headset/headset_sec/department/engi
+ keyslot1 = new /obj/item/device/encryptionkey/headset_sec
+ keyslot2 = new /obj/item/device/encryptionkey/headset_eng
+
+/obj/item/device/radio/headset/headset_sec/department/supply
+ keyslot1 = new /obj/item/device/encryptionkey/headset_sec
+ keyslot2 = new /obj/item/device/encryptionkey/headset_cargo
+
+/obj/item/device/radio/headset/headset_sec/department/med
+ keyslot1 = new /obj/item/device/encryptionkey/headset_sec
+ keyslot2 = new /obj/item/device/encryptionkey/headset_med
+
+/obj/item/device/radio/headset/headset_sec/department/sci
+ keyslot1 = new /obj/item/device/encryptionkey/headset_sec
+ keyslot2 = new /obj/item/device/encryptionkey/headset_sci
+
+/obj/item/clothing/under/rank/security/cargo/New()
+ var/obj/item/clothing/tie/armband/cargo/A = new /obj/item/clothing/tie/armband/cargo
+ hastie = A
+
+/obj/item/clothing/under/rank/security/engine/New()
+ var/obj/item/clothing/tie/armband/engine/A = new /obj/item/clothing/tie/armband/engine
+ hastie = A
+
+/obj/item/clothing/under/rank/security/science/New()
+ var/obj/item/clothing/tie/armband/science/A = new /obj/item/clothing/tie/armband/science
+ hastie = A
+
+/obj/item/clothing/under/rank/security/med/New()
+ var/obj/item/clothing/tie/armband/medgreen/A = new /obj/item/clothing/tie/armband/medgreen
+ hastie = A
\ No newline at end of file
diff --git a/code/WorkInProgress/Sigyn/Softcurity/__README.dm b/code/WorkInProgress/Sigyn/Softcurity/__README.dm
new file mode 100644
index 00000000000..75c62c277d5
--- /dev/null
+++ b/code/WorkInProgress/Sigyn/Softcurity/__README.dm
@@ -0,0 +1,10 @@
+/*
+
+Hey you!
+You'll need to untick code/game/jobs/access.dm for this to all work correctly!
+
+Everything else can just be ticked on top of the original stuff.
+
+You'll also need to download a modified map from http://tgstation13.googlecode.com/files/tgstation.2.0.9_Softcurity.zip.
+Make sure to untick the original map!
+*/
\ No newline at end of file
diff --git a/code/WorkInProgress/Sigyn/Softcurity/access.dm b/code/WorkInProgress/Sigyn/Softcurity/access.dm
new file mode 100644
index 00000000000..d0dace17bf7
--- /dev/null
+++ b/code/WorkInProgress/Sigyn/Softcurity/access.dm
@@ -0,0 +1,522 @@
+//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
+
+/var/const/access_security = 1 // Security equipment
+/var/const/access_brig = 2 // Brig timers and permabrig
+/var/const/access_armory = 3
+/var/const/access_forensics_lockers= 4
+/var/const/access_medical = 5
+/var/const/access_morgue = 6
+/var/const/access_tox = 7
+/var/const/access_tox_storage = 8
+/var/const/access_genetics = 9
+/var/const/access_engine = 10
+/var/const/access_engine_equip= 11
+/var/const/access_maint_tunnels = 12
+/var/const/access_external_airlocks = 13
+/var/const/access_emergency_storage = 14
+/var/const/access_change_ids = 15
+/var/const/access_ai_upload = 16
+/var/const/access_teleporter = 17
+/var/const/access_eva = 18
+/var/const/access_heads = 19
+/var/const/access_captain = 20
+/var/const/access_all_personal_lockers = 21
+/var/const/access_chapel_office = 22
+/var/const/access_tech_storage = 23
+/var/const/access_atmospherics = 24
+/var/const/access_bar = 25
+/var/const/access_janitor = 26
+/var/const/access_crematorium = 27
+/var/const/access_kitchen = 28
+/var/const/access_robotics = 29
+/var/const/access_rd = 30
+/var/const/access_cargo = 31
+/var/const/access_construction = 32
+/var/const/access_chemistry = 33
+/var/const/access_cargo_bot = 34
+/var/const/access_hydroponics = 35
+/var/const/access_manufacturing = 36
+/var/const/access_library = 37
+/var/const/access_lawyer = 38
+/var/const/access_virology = 39
+/var/const/access_cmo = 40
+/var/const/access_qm = 41
+/var/const/access_court = 42
+/var/const/access_clown = 43
+/var/const/access_mime = 44
+/var/const/access_surgery = 45
+/var/const/access_theatre = 46
+/var/const/access_research = 47
+/var/const/access_mining = 48
+/var/const/access_mining_office = 49 //not in use
+/var/const/access_mailsorting = 50
+/var/const/access_mint = 51
+/var/const/access_mint_vault = 52
+/var/const/access_heads_vault = 53
+/var/const/access_mining_station = 54
+/var/const/access_xenobiology = 55
+/var/const/access_ce = 56
+/var/const/access_hop = 57
+/var/const/access_hos = 58
+/var/const/access_RC_announce = 59 //Request console announcements
+/var/const/access_keycard_auth = 60 //Used for events which require at least two people to confirm them
+/var/const/access_tcomsat = 61 // has access to the entire telecomms satellite / machinery
+/var/const/access_gateway = 62
+/var/const/access_sec_doors = 63 // Security front doors
+
+ //BEGIN CENTCOM ACCESS
+ /*Should leave plenty of room if we need to add more access levels.
+/var/const/Mostly for admin fun times.*/
+/var/const/access_cent_general = 101//General facilities.
+/var/const/access_cent_thunder = 102//Thunderdome.
+/var/const/access_cent_specops = 103//Special Ops.
+/var/const/access_cent_medical = 104//Medical/Research
+/var/const/access_cent_living = 105//Living quarters.
+/var/const/access_cent_storage = 106//Generic storage areas.
+/var/const/access_cent_teleporter = 107//Teleporter.
+/var/const/access_cent_creed = 108//Creed's office.
+/var/const/access_cent_captain = 109//Captain's office/ID comp/AI.
+
+ //The Syndicate
+/var/const/access_syndicate = 150//General Syndicate Access
+
+ //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/New()
+ ..()
+ //NOTE: If a room requires more than one access (IE: Morgue + medbay) set the req_acesss_txt to "5;6" if it requires 5 and 6
+ if(src.req_access_txt)
+ var/list/req_access_str = text2list(req_access_txt,";")
+ if(!req_access)
+ req_access = list()
+ for(var/x in req_access_str)
+ var/n = text2num(x)
+ if(n)
+ req_access += n
+
+ if(src.req_one_access_txt)
+ var/list/req_one_access_str = text2list(req_one_access_txt,";")
+ if(!req_one_access)
+ req_one_access = list()
+ for(var/x in req_one_access_str)
+ var/n = text2num(x)
+ if(n)
+ req_one_access += n
+
+
+
+//returns 1 if this mob has sufficient access to use this object
+/obj/proc/allowed(mob/M)
+ //check if it doesn't require any access at all
+ if(src.check_access(null))
+ return 1
+ if(istype(M, /mob/living/silicon))
+ //AI can do whatever he wants
+ return 1
+ else if(istype(M, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = M
+ //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) || istype(M, /mob/living/carbon/alien/humanoid))
+ var/mob/living/carbon/george = M
+ //they can only hold things :(
+ if(george.get_active_hand() && (istype(george.get_active_hand(), /obj/item/weapon/card/id) || istype(george.get_active_hand(), /obj/item/device/pda)) && src.check_access(george.get_active_hand()))
+ return 1
+ return 0
+
+/obj/item/proc/GetAccess()
+ return list()
+
+/obj/item/proc/GetID()
+ return null
+
+/obj/proc/check_access(obj/item/weapon/card/id/I)
+
+ if (istype(I, /obj/item/device/pda))
+ var/obj/item/device/pda/pda = I
+ I = pda.id
+
+ if(!src.req_access && !src.req_one_access) //no requirements
+ return 1
+ 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
+ return 1
+ if(!I || !istype(I, /obj/item/weapon/card/id) || !I.access) //not ID or no access
+ return 0
+ for(var/req in src.req_access)
+ if(!(req in I.access)) //doesn't have this access
+ return 0
+ if(src.req_one_access && src.req_one_access.len)
+ for(var/req in src.req_one_access)
+ if(req in I.access) //has an access from the single access list
+ return 1
+ return 0
+ return 1
+
+
+/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(!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)
+ for(var/req in src.req_one_access)
+ if(req in L) //has an access from the single access list
+ return 1
+ return 0
+ return 1
+
+
+/proc/get_access(job)
+ switch(job)
+ if("Geneticist")
+ return list(access_medical, access_morgue, access_genetics)
+ if("Station Engineer")
+ return list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels, access_external_airlocks, access_construction)
+ if("Assistant")
+ if(config.assistant_maint)
+ return list(access_maint_tunnels)
+ else
+ return list()
+ if("Chaplain")
+ return list(access_morgue, access_chapel_office, access_crematorium)
+ if("Detective")
+ return list(access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels, access_court)
+ if("Medical Doctor")
+ return list(access_medical, access_morgue, access_surgery)
+ if("Botanist") // -- TLE
+ return list(access_hydroponics, access_morgue) // Removed tox and chem access because STOP PISSING OFF THE CHEMIST GUYS // //Removed medical access because WHAT THE FUCK YOU AREN'T A DOCTOR YOU GROW WHEAT //Given Morgue access because they have a viable means of cloning.
+ if("Librarian") // -- TLE
+ return list(access_library)
+ if("Lawyer") //Muskets 160910
+ return list(access_lawyer, access_court, access_sec_doors)
+ if("Captain")
+ return get_all_accesses()
+ if("Crew Supervisor")
+ return list(access_security, access_sec_doors, access_brig, access_court)
+ if("Correctional Advisor")
+ return list(access_security, access_sec_doors, access_brig, access_armory, access_court)
+ if("Scientist")
+ return list(access_tox, access_tox_storage, access_research, access_xenobiology)
+ if("Safety Administrator")
+ return list(access_medical, access_morgue, access_tox, access_tox_storage, access_chemistry, access_genetics, access_court,
+ access_teleporter, access_heads, access_tech_storage, access_security, access_sec_doors, access_brig, access_atmospherics,
+ access_maint_tunnels, access_bar, access_janitor, access_kitchen, access_robotics, access_armory, access_hydroponics,
+ access_theatre, access_research, access_hos, access_RC_announce, access_forensics_lockers, access_keycard_auth, access_gateway)
+ if("Head of Personnel")
+ return list(access_security, access_sec_doors, access_brig, access_court, access_forensics_lockers,
+ access_tox, access_tox_storage, access_chemistry, access_medical, access_genetics, access_engine,
+ access_emergency_storage, access_change_ids, access_ai_upload, access_eva, access_heads,
+ access_all_personal_lockers, access_tech_storage, access_maint_tunnels, access_bar, access_janitor,
+ access_crematorium, access_kitchen, access_robotics, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
+ access_theatre, access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
+ access_clown, access_mime, access_hop, access_RC_announce, access_keycard_auth, access_gateway)
+ if("Atmospheric Technician")
+ return list(access_atmospherics, access_maint_tunnels, access_emergency_storage, access_construction)
+ if("Bartender")
+ return list(access_bar)
+ if("Chemist")
+ return list(access_medical, access_chemistry)
+ if("Janitor")
+ return list(access_janitor, access_maint_tunnels)
+ if("Clown")
+ return list(access_clown, access_theatre)
+ if("Mime")
+ return list(access_mime, access_theatre)
+ if("Chef")
+ return list(access_kitchen, access_morgue)
+ if("Roboticist")
+ return list(access_robotics, access_tech_storage, access_morgue) //As a job that handles so many corpses, it makes sense for them to have morgue access.
+ if("Cargo Technician")
+ return list(access_maint_tunnels, access_cargo, access_cargo_bot, access_mailsorting)
+ if("Shaft Miner")
+ return list(access_mining, access_mint, access_mining_station)
+ if("Quartermaster")
+ return list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mint, access_mining, access_mining_station)
+ if("Chief Engineer")
+ return list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
+ access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
+ access_heads, access_ai_upload, access_construction, access_robotics,
+ access_mint, access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_sec_doors)
+ if("Research Director")
+ return list(access_rd, access_heads, access_tox, access_genetics,
+ access_tox_storage, access_teleporter,
+ access_research, access_robotics, access_xenobiology,
+ access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_sec_doors)
+ if("Virologist")
+ return list(access_medical, access_virology)
+ if("Chief Medical Officer")
+ return 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)
+ else
+ return list()
+
+/proc/get_centcom_access(job)
+ switch(job)
+ if("VIP Guest")
+ return list(access_cent_general)
+ if("Custodian")
+ return list(access_cent_general, access_cent_living, access_cent_storage)
+ if("Thunderdome Overseer")
+ return list(access_cent_general, access_cent_thunder)
+ if("Intel Officer")
+ return list(access_cent_general, access_cent_living)
+ if("Medical Officer")
+ return list(access_cent_general, access_cent_living, access_cent_medical)
+ if("Death Commando")
+ return list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)
+ if("Research Officer")
+ return list(access_cent_general, access_cent_specops, access_cent_medical, access_cent_teleporter, access_cent_storage)
+ if("BlackOps Commander")
+ return list(access_cent_general, access_cent_thunder, access_cent_specops, access_cent_living, access_cent_storage, access_cent_creed)
+ if("Supreme Commander")
+ return get_all_centcom_access()
+
+/proc/get_all_accesses()
+ return list(access_security, access_sec_doors, access_brig, access_armory, access_forensics_lockers, access_court,
+ access_medical, access_genetics, access_morgue, access_rd,
+ access_tox, access_tox_storage, access_chemistry, access_engine, access_engine_equip, access_maint_tunnels,
+ access_external_airlocks, access_emergency_storage, access_change_ids, access_ai_upload,
+ access_teleporter, access_eva, access_heads, access_captain, access_all_personal_lockers,
+ access_tech_storage, access_chapel_office, access_atmospherics, access_kitchen,
+ access_bar, access_janitor, access_crematorium, access_robotics, access_cargo, access_cargo_bot, access_construction,
+ access_hydroponics, access_library, access_manufacturing, access_lawyer, access_virology, access_cmo, access_qm, access_clown, access_mime, access_surgery,
+ access_theatre, access_research, access_mining, access_mailsorting, access_mint_vault, access_mint,
+ access_heads_vault, access_mining_station, access_xenobiology, access_ce, access_hop, access_hos, access_RC_announce,
+ access_keycard_auth, access_tcomsat, access_gateway)
+
+/proc/get_all_centcom_access()
+ return list(access_cent_general, access_cent_thunder, access_cent_specops, access_cent_medical, access_cent_living, access_cent_storage, access_cent_teleporter, access_cent_creed, access_cent_captain)
+
+/proc/get_all_syndicate_access()
+ return list(access_syndicate)
+
+/proc/get_region_accesses(var/code)
+ switch(code)
+ if(0)
+ return get_all_accesses()
+ if(1) //security
+ return list(access_sec_doors, access_security, access_brig, access_armory, access_forensics_lockers, access_court, access_hos)
+ if(2) //medbay
+ return list(access_medical, access_genetics, access_morgue, access_chemistry, access_virology, access_surgery, access_cmo)
+ if(3) //research
+ return list(access_research, access_tox, access_tox_storage, access_xenobiology, access_rd)
+ if(4) //engineering and maintenance
+ return list(access_maint_tunnels, access_engine, access_engine_equip, access_external_airlocks, access_tech_storage, access_atmospherics, access_construction, access_robotics, access_ce)
+ if(5) //command
+ return list(access_heads, access_change_ids, access_ai_upload, access_teleporter, access_eva, access_all_personal_lockers, access_heads_vault, access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_hop, access_captain)
+ if(6) //station general
+ return list(access_kitchen,access_bar, access_hydroponics, access_janitor, access_chapel_office, access_crematorium, access_library, access_theatre, access_lawyer, access_clown, access_mime)
+ if(7) //supply
+ return list(access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_mining, access_mining_station)
+
+/proc/get_region_accesses_name(var/code)
+ switch(code)
+ if(0)
+ return "All"
+ if(1) //security
+ return "Security"
+ if(2) //medbay
+ return "Medbay"
+ if(3) //research
+ return "Research"
+ if(4) //engineering and maintenance
+ return "Engineering"
+ if(5) //command
+ return "Command"
+ if(6) //station general
+ return "Station General"
+ if(7) //supply
+ return "Supply"
+
+
+/proc/get_access_desc(A)
+ switch(A)
+ if(access_cargo)
+ return "Cargo Bay"
+ if(access_cargo_bot)
+ return "Cargo Bot Delivery"
+ if(access_security)
+ return "Security"
+ if(access_brig)
+ return "Holding Cells"
+ if(access_court)
+ return "Courtroom"
+ if(access_forensics_lockers)
+ return "Detective's Office"
+ if(access_medical)
+ return "Medical"
+ if(access_genetics)
+ return "Genetics Lab"
+ if(access_morgue)
+ return "Morgue"
+ if(access_tox)
+ return "Research Lab"
+ if(access_tox_storage)
+ return "Toxins Storage"
+ if(access_chemistry)
+ return "Chemistry Lab"
+ if(access_rd)
+ return "RD Private"
+ if(access_bar)
+ return "Bar"
+ if(access_janitor)
+ return "Custodial Closet"
+ if(access_engine)
+ return "Engineering"
+ if(access_engine_equip)
+ return "APCs"
+ if(access_maint_tunnels)
+ return "Maintenance"
+ if(access_external_airlocks)
+ return "External Airlocks"
+ if(access_emergency_storage)
+ return "Emergency Storage"
+ if(access_change_ids)
+ return "ID Computer"
+ if(access_ai_upload)
+ return "AI Upload"
+ if(access_teleporter)
+ return "Teleporter"
+ if(access_eva)
+ return "EVA"
+ if(access_heads)
+ return "Bridge"
+ if(access_captain)
+ return "Captain Private"
+ if(access_all_personal_lockers)
+ return "Personal Lockers"
+ if(access_chapel_office)
+ return "Chapel Office"
+ if(access_tech_storage)
+ return "Technical Storage"
+ if(access_atmospherics)
+ return "Atmospherics"
+ if(access_crematorium)
+ return "Crematorium"
+ if(access_armory)
+ return "Armory"
+ if(access_construction)
+ return "Construction Areas"
+ if(access_kitchen)
+ return "Kitchen"
+ if(access_hydroponics)
+ return "Hydroponics"
+ if(access_library)
+ return "Library"
+ if(access_lawyer)
+ return "Law Office"
+ if(access_robotics)
+ return "Robotics"
+ if(access_virology)
+ return "Virology"
+ if(access_cmo)
+ return "CMO Private"
+ if(access_qm)
+ return "Quartermaster's Office"
+ if(access_clown)
+ return "HONK! Access"
+ if(access_mime)
+ return "Silent Access"
+ if(access_surgery)
+ return "Surgery"
+ if(access_theatre)
+ return "Theatre"
+ if(access_manufacturing)
+ return "Manufacturing"
+ if(access_research)
+ return "Science"
+ if(access_mining)
+ return "Mining"
+ if(access_mining_office)
+ return "Mining Office"
+ if(access_mailsorting)
+ return "Delivery Office"
+ if(access_mint)
+ return "Mint"
+ if(access_mint_vault)
+ return "Mint Vault"
+ if(access_heads_vault)
+ return "Main Vault"
+ if(access_mining_station)
+ return "Mining Station EVA"
+ if(access_xenobiology)
+ return "Xenobiology Lab"
+ if(access_hop)
+ return "HoP Private"
+ if(access_hos)
+ return "HoS Private"
+ if(access_ce)
+ return "CE Private"
+ if(access_RC_announce)
+ return "RC Announcements"
+ if(access_keycard_auth)
+ return "Keycode Auth. Device"
+ if(access_tcomsat)
+ return "Telecommunications"
+ if(access_gateway)
+ return "Gateway"
+ if(access_sec_doors)
+ return "Brig"
+
+/proc/get_centcom_access_desc(A)
+ switch(A)
+ if(access_cent_general)
+ return "Code Grey"
+ if(access_cent_thunder)
+ return "Code Yellow"
+ if(access_cent_storage)
+ return "Code Orange"
+ if(access_cent_living)
+ return "Code Green"
+ if(access_cent_medical)
+ return "Code White"
+ if(access_cent_teleporter)
+ return "Code Blue"
+ if(access_cent_specops)
+ return "Code Black"
+ if(access_cent_creed)
+ return "Code Silver"
+ if(access_cent_captain)
+ return "Code Gold"
+
+/proc/get_all_jobs()
+ return list("Assistant", "Captain", "Head of Personnel", "Bartender", "Chef", "Botanist", "Quartermaster", "Cargo Technician",
+ "Shaft Miner", "Clown", "Mime", "Janitor", "Librarian", "Lawyer", "Chaplain", "Chief Engineer", "Station Engineer",
+ "Atmospheric Technician", "Roboticist", "Chief Medical Officer", "Medical Doctor", "Chemist", "Geneticist", "Virologist",
+ "Research Director", "Scientist", "Head of Security", "Warden", "Detective", "Security Officer")
+
+/proc/get_all_centcom_jobs()
+ return list("VIP Guest","Custodian","Thunderdome Overseer","Intel Officer","Medical Officer","Death Commando","Research Officer","BlackOps Commander","Supreme Commander")
+
+/obj/proc/GetJobName()
+ if (!istype(src, /obj/item/device/pda) && !istype(src,/obj/item/weapon/card/id))
+ return
+
+ var/jobName
+
+ if(istype(src, /obj/item/device/pda))
+ if(src:id)
+ jobName = src:id:assignment
+ if(istype(src, /obj/item/weapon/card/id))
+ jobName = src:assignment
+
+ if(jobName in get_all_jobs())
+ return jobName
+ else
+ return "Unknown"
diff --git a/code/WorkInProgress/Sigyn/Softcurity/clothing.dm b/code/WorkInProgress/Sigyn/Softcurity/clothing.dm
new file mode 100644
index 00000000000..057c10cb575
--- /dev/null
+++ b/code/WorkInProgress/Sigyn/Softcurity/clothing.dm
@@ -0,0 +1,33 @@
+/obj/item/clothing/under/rank/administrator
+ name = "safety administrator's jumpsuit"
+ desc = "It's a jumpsuit worn by those few with the dedication to achieve the position of \"Safety Administrator\"."
+ icon_state = "hosblueclothes"
+ item_state = "ba_suit"
+ color = "hosblueclothes"
+ armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
+ flags = FPRINT | TABLEPASS | ONESIZEFITSALL
+
+/obj/item/clothing/under/rank/advisor
+ name = "correctional advisor's jumpsuit"
+ desc = "It's made of a slightly sturdier material than standard jumpsuits, to allow for more robust protection. It has the words \"Correctional Advisor\" written on the shoulders."
+ icon_state = "wardenblueclothes"
+ item_state = "ba_suit"
+ color = "wardenblueclothes"
+ armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
+ flags = FPRINT | TABLEPASS | ONESIZEFITSALL
+
+/obj/item/clothing/under/rank/supervisor
+ name = "crew supervisor's jumpsuit"
+ desc = "It's made of a slightly sturdier material than standard jumpsuits, to allow for robust protection."
+ icon_state = "officerblueclothes"
+ item_state = "ba_suit"
+ color = "officerblueclothes"
+ armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
+ flags = FPRINT | TABLEPASS | ONESIZEFITSALL
+
+/obj/item/clothing/shoes/boots
+ name = "boots"
+ desc = "Nanotrasen-issue hard-toe safety boots."
+ icon_state = "secshoes"
+ item_state = "secshoes"
+ color = "hosred"
\ No newline at end of file
diff --git a/code/WorkInProgress/Sigyn/Softcurity/jobs.dm b/code/WorkInProgress/Sigyn/Softcurity/jobs.dm
new file mode 100644
index 00000000000..a214626d1c6
--- /dev/null
+++ b/code/WorkInProgress/Sigyn/Softcurity/jobs.dm
@@ -0,0 +1,152 @@
+/datum/job/hos
+ title = "Safety Administrator"
+ flag = HOS
+ department_flag = ENGSEC
+ faction = "Station"
+ total_positions = 1
+ spawn_positions = 1
+ supervisors = "the captain"
+ selection_color = "#ffdddd"
+ idtype = /obj/item/weapon/card/id/silver
+ req_admin_notify = 1
+
+
+ equip(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_sec(H), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/hos(H), slot_ears)
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/administrator(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/boots(H), slot_shoes)
+ H.equip_to_slot_or_del(new /obj/item/device/pda/heads/hos(H), slot_belt)
+ H.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(H), slot_glasses)
+ H.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(H), slot_wear_suit)
+ H.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/taser(H), slot_s_store)
+ 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/weapon/handcuffs(H), slot_in_backpack)
+ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
+ L.imp_in = H
+ L.implanted = 1
+ return 1
+
+
+
+/datum/job/warden
+ title = "Correctional Advisor"
+ flag = WARDEN
+ department_flag = ENGSEC
+ faction = "Station"
+ total_positions = 1
+ spawn_positions = 1
+ supervisors = "the safety administrator"
+ selection_color = "#ffeeee"
+
+
+ equip(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec(H), slot_ears)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_sec(H), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/advisor(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/boots(H), slot_shoes)
+ H.equip_to_slot_or_del(new /obj/item/device/pda/warden(H), slot_belt)
+ H.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(H), slot_glasses)
+ H.equip_to_slot_or_del(new /obj/item/device/flash(H), slot_l_store)
+ 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/weapon/handcuffs(H), slot_in_backpack)
+ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
+ L.imp_in = H
+ L.implanted = 1
+ return 1
+
+
+
+/datum/job/detective
+ title = "Detective"
+ flag = DETECTIVE
+ department_flag = ENGSEC
+ faction = "Station"
+ total_positions = 1
+ spawn_positions = 1
+ supervisors = "the safety administrator"
+ selection_color = "#ffeeee"
+
+
+ equip(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec(H), slot_ears)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/det(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes)
+ H.equip_to_slot_or_del(new /obj/item/device/pda/detective(H), slot_belt)
+ H.equip_to_slot_or_del(new /obj/item/clothing/head/det_hat(H), slot_head)
+ var/obj/item/clothing/mask/cigarette/CIG = new /obj/item/clothing/mask/cigarette(H)
+ CIG.light("")
+ H.equip_to_slot_or_del(CIG, slot_wear_mask)
+ H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(H), slot_gloves)
+ H.equip_to_slot_or_del(new /obj/item/clothing/suit/det_suit(H), slot_wear_suit)
+ H.equip_to_slot_or_del(new /obj/item/weapon/lighter/zippo(H), slot_l_store)
+
+ 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/weapon/storage/box/evidence(H), slot_in_backpack)
+ H.equip_to_slot_or_del(new /obj/item/device/detective_scanner(H), slot_in_backpack)
+
+ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
+ L.imp_in = H
+ L.implanted = 1
+ return 1
+
+
+
+/datum/job/officer
+ title = "Crew Supervisor"
+ flag = OFFICER
+ department_flag = ENGSEC
+ faction = "Station"
+ total_positions = 5
+ spawn_positions = 5
+ supervisors = "the safety administrator"
+ selection_color = "#ffeeee"
+
+
+ equip(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec(H), slot_ears)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_sec(H), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/supervisor(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/boots(H), slot_shoes)
+ H.equip_to_slot_or_del(new /obj/item/device/pda/security(H), slot_belt)
+ H.equip_to_slot_or_del(new /obj/item/weapon/handcuffs(H), slot_r_store)
+ H.equip_to_slot_or_del(new /obj/item/device/flash(H), slot_l_store)
+ 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/weapon/handcuffs(H), slot_in_backpack)
+ var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
+ L.imp_in = H
+ L.implanted = 1
+ return 1
+
+/datum/job/hop
+ title = "Head of Personnel"
+ flag = HOP
+ department_flag = CIVILIAN
+ faction = "Station"
+ total_positions = 1
+ spawn_positions = 1
+ supervisors = "the captain"
+ selection_color = "#ddddff"
+ idtype = /obj/item/weapon/card/id/silver
+ req_admin_notify = 1
+
+
+ equip(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ H.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/hop(H), slot_ears)
+ if(H.backbag == 2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
+ if(H.backbag == 3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
+ 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/under/rank/head_of_personnel(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes)
+ H.equip_to_slot_or_del(new /obj/item/device/pda/heads/hop(H), slot_belt)
+ if(H.backbag == 1)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/id_kit(H), slot_r_hand)
+ else
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/id_kit(H.back), slot_in_backpack)
+ return 1
diff --git a/code/WorkInProgress/Sigyn/Softcurity/secure_closet.dm b/code/WorkInProgress/Sigyn/Softcurity/secure_closet.dm
new file mode 100644
index 00000000000..88f06f98e7c
--- /dev/null
+++ b/code/WorkInProgress/Sigyn/Softcurity/secure_closet.dm
@@ -0,0 +1,235 @@
+/obj/structure/closet/secure_closet/captains
+ name = "Captain's Locker"
+ req_access = list(access_captain)
+ icon_state = "capsecure1"
+ icon_closed = "capsecure"
+ icon_locked = "capsecure1"
+ icon_opened = "capsecureopen"
+ icon_broken = "capsecurebroken"
+ icon_off = "capsecureoff"
+
+ New()
+ sleep(2)
+ if(prob(50))
+ new /obj/item/weapon/storage/backpack/captain(src)
+ else
+ new /obj/item/weapon/storage/backpack/satchel_cap(src)
+ new /obj/item/clothing/suit/captunic(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/weapon/cartridge/captain(src)
+ new /obj/item/clothing/head/helmet/swat(src)
+ new /obj/item/clothing/shoes/brown(src)
+ new /obj/item/device/radio/headset/heads/captain(src)
+ new /obj/item/weapon/reagent_containers/food/drinks/flask(src)
+ new /obj/item/clothing/gloves/captain(src)
+ new /obj/item/weapon/gun/energy/gun(src)
+ return
+
+
+
+/obj/structure/closet/secure_closet/hop
+ name = "Head of Personnel's Locker"
+ req_access = list(access_hop)
+ icon_state = "hopsecure1"
+ icon_closed = "hopsecure"
+ icon_locked = "hopsecure1"
+ icon_opened = "hopsecureopen"
+ icon_broken = "hopsecurebroken"
+ icon_off = "hopsecureoff"
+
+ New()
+ sleep(2)
+ new /obj/item/clothing/under/rank/head_of_personnel(src)
+ new /obj/item/clothing/suit/armor/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/clothing/shoes/brown(src)
+ new /obj/item/weapon/storage/id_kit(src)
+ new /obj/item/weapon/storage/id_kit( src )
+ new /obj/item/device/flash(src)
+ new /obj/item/clothing/glasses/sunglasses(src)
+ return
+
+
+
+/obj/structure/closet/secure_closet/hos
+ name = "Safety Administrator's Locker"
+ req_access = list(access_hos)
+ icon_state = "hossecure1"
+ icon_closed = "hossecure"
+ icon_locked = "hossecure1"
+ icon_opened = "hossecureopen"
+ icon_broken = "hossecurebroken"
+ icon_off = "hossecureoff"
+
+ New()
+ sleep(2)
+ new /obj/item/weapon/storage/backpack/satchel_sec(src)
+ new /obj/item/weapon/cartridge/hos(src)
+ new /obj/item/device/radio/headset/heads/hos(src)
+ new /obj/item/weapon/storage/lockbox/loyalty(src)
+ new /obj/item/weapon/storage/flashbang_kit(src)
+ new /obj/item/weapon/storage/belt/security(src)
+ new /obj/item/device/flash(src)
+ new /obj/item/weapon/melee/baton(src)
+ new /obj/item/weapon/gun/energy/taser(src)
+ new /obj/item/weapon/reagent_containers/spray/pepper(src)
+ return
+
+
+
+/obj/structure/closet/secure_closet/warden
+ name = "Correctional Advisor's Locker"
+ req_access = list(access_armory)
+ icon_state = "wardensecure1"
+ icon_closed = "wardensecure"
+ icon_locked = "wardensecure1"
+ icon_opened = "wardensecureopen"
+ icon_broken = "wardensecurebroken"
+ icon_off = "wardensecureoff"
+
+
+ New()
+ sleep(2)
+ new /obj/item/weapon/storage/backpack/satchel_sec(src)
+ new /obj/item/clothing/under/rank/advisor(src)
+ new /obj/item/device/radio/headset/headset_sec(src)
+ new /obj/item/clothing/glasses/sunglasses(src)
+ new /obj/item/weapon/storage/flashbang_kit(src)
+ new /obj/item/weapon/storage/belt/security(src)
+ new /obj/item/weapon/reagent_containers/spray/pepper(src)
+ new /obj/item/weapon/reagent_containers/spray/pepper(src)
+ new /obj/item/weapon/melee/baton(src)
+ return
+
+
+
+/obj/structure/closet/secure_closet/security
+ name = "Crew Supervisor's Locker"
+ req_access = list(access_security)
+ icon_state = "sec1"
+ icon_closed = "sec"
+ icon_locked = "sec1"
+ icon_opened = "secopen"
+ icon_broken = "secbroken"
+ icon_off = "secoff"
+
+ New()
+ sleep(2)
+ new /obj/item/weapon/storage/backpack/satchel_sec(src)
+ new /obj/item/device/radio/headset/headset_sec(src)
+ new /obj/item/weapon/storage/belt/security(src)
+ new /obj/item/device/flash(src)
+ new /obj/item/weapon/reagent_containers/spray/pepper(src)
+ new /obj/item/weapon/reagent_containers/spray/pepper(src)
+ new /obj/item/clothing/glasses/sunglasses(src)
+ return
+
+
+
+/obj/structure/closet/secure_closet/detective
+ name = "Detective's Cabinet"
+ req_access = list(access_forensics_lockers)
+ icon_state = "cabinetdetective_locked"
+ icon_closed = "cabinetdetective"
+ icon_locked = "cabinetdetective_locked"
+ icon_opened = "cabinetdetective_open"
+ icon_broken = "cabinetdetective_broken"
+ icon_off = "cabinetdetective_broken"
+
+ New()
+ sleep(2)
+ new /obj/item/clothing/under/det(src)
+ new /obj/item/clothing/suit/armor/det_suit(src)
+ new /obj/item/clothing/suit/det_suit(src)
+ new /obj/item/clothing/gloves/black(src)
+ new /obj/item/clothing/head/det_hat(src)
+ new /obj/item/clothing/shoes/brown(src)
+ new /obj/item/device/radio/headset/headset_sec(src)
+ new /obj/item/weapon/cartridge/detective(src)
+ new /obj/item/weapon/clipboard(src)
+ new /obj/item/device/detective_scanner(src)
+ new /obj/item/weapon/storage/box/evidence(src)
+ return
+
+/obj/structure/closet/secure_closet/detective/update_icon()
+ if(broken)
+ icon_state = icon_broken
+ else
+ if(!opened)
+ if(locked)
+ icon_state = icon_locked
+ else
+ icon_state = icon_closed
+ else
+ icon_state = icon_opened
+
+/obj/structure/closet/secure_closet/injection
+ name = "Lethal Injections"
+ req_access = list(access_hos)
+
+
+ New()
+ sleep(2)
+ new /obj/item/weapon/reagent_containers/ld50_syringe/choral(src)
+ new /obj/item/weapon/reagent_containers/ld50_syringe/choral(src)
+ return
+
+
+
+/obj/structure/closet/secure_closet/brig
+ name = "Brig Locker"
+ req_access = list(access_brig)
+ anchored = 1
+
+ New()
+ new /obj/item/clothing/under/color/orange( src )
+ new /obj/item/clothing/shoes/orange( src )
+ return
+
+
+
+/obj/structure/closet/secure_closet/courtroom
+ name = "Courtroom Locker"
+ req_access = list(access_court)
+
+ New()
+ sleep(2)
+ new /obj/item/clothing/shoes/brown(src)
+ new /obj/item/weapon/paper/Court (src)
+ new /obj/item/weapon/paper/Court (src)
+ new /obj/item/weapon/paper/Court (src)
+ new /obj/item/weapon/pen (src)
+ new /obj/item/clothing/suit/judgerobe (src)
+ new /obj/item/clothing/head/powdered_wig (src)
+ new /obj/item/weapon/storage/briefcase(src)
+ return
+
+/obj/structure/closet/secure_closet/wall
+ name = "wall locker"
+ req_access = list(access_security)
+ icon_state = "wall-locker1"
+ density = 1
+ icon_closed = "wall-locker"
+ icon_locked = "wall-locker1"
+ icon_opened = "wall-lockeropen"
+ icon_broken = "wall-lockerbroken"
+ icon_off = "wall-lockeroff"
+
+ //too small to put a man in
+ large = 0
+
+/obj/structure/closet/secure_closet/wall/update_icon()
+ if(broken)
+ icon_state = icon_broken
+ else
+ if(!opened)
+ if(locked)
+ icon_state = icon_locked
+ else
+ icon_state = icon_closed
+ else
+ icon_state = icon_opened
diff --git a/code/WorkInProgress/Sigyn/Softcurity/wardrobe.dm b/code/WorkInProgress/Sigyn/Softcurity/wardrobe.dm
new file mode 100644
index 00000000000..452670091f5
--- /dev/null
+++ b/code/WorkInProgress/Sigyn/Softcurity/wardrobe.dm
@@ -0,0 +1,311 @@
+/obj/structure/closet/wardrobe
+ name = "wardrobe"
+ desc = "It's a storage unit for standard-issue Nanotrasen attire."
+ icon_state = "blue"
+ icon_closed = "blue"
+
+/obj/structure/closet/wardrobe/New()
+ new /obj/item/clothing/under/color/blue(src)
+ new /obj/item/clothing/under/color/blue(src)
+ new /obj/item/clothing/under/color/blue(src)
+ new /obj/item/clothing/shoes/brown(src)
+ new /obj/item/clothing/shoes/brown(src)
+ new /obj/item/clothing/shoes/brown(src)
+ return
+
+
+/obj/structure/closet/wardrobe/red
+ name = "security wardrobe"
+ icon_state = "red"
+ icon_closed = "red"
+
+/obj/structure/closet/wardrobe/red/New()
+ new /obj/item/clothing/under/rank/supervisor(src)
+ new /obj/item/clothing/under/rank/supervisor(src)
+ new /obj/item/clothing/under/rank/supervisor(src)
+ new /obj/item/clothing/shoes/boots(src)
+ new /obj/item/clothing/shoes/boots(src)
+ new /obj/item/clothing/shoes/boots(src)
+ new /obj/item/clothing/head/soft/grey(src)
+ new /obj/item/clothing/head/soft/grey(src)
+ new /obj/item/clothing/head/soft/grey(src)
+ return
+
+
+/obj/structure/closet/wardrobe/pink
+ name = "pink wardrobe"
+ icon_state = "pink"
+ icon_closed = "pink"
+
+/obj/structure/closet/wardrobe/pink/New()
+ new /obj/item/clothing/under/color/pink(src)
+ new /obj/item/clothing/under/color/pink(src)
+ new /obj/item/clothing/under/color/pink(src)
+ new /obj/item/clothing/shoes/brown(src)
+ new /obj/item/clothing/shoes/brown(src)
+ new /obj/item/clothing/shoes/brown(src)
+ return
+
+/obj/structure/closet/wardrobe/black
+ name = "black wardrobe"
+ icon_state = "black"
+ icon_closed = "black"
+
+/obj/structure/closet/wardrobe/black/New()
+ new /obj/item/clothing/under/color/black(src)
+ new /obj/item/clothing/under/color/black(src)
+ new /obj/item/clothing/under/color/black(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/head/that(src)
+ new /obj/item/clothing/head/that(src)
+ new /obj/item/clothing/head/that(src)
+ return
+
+
+/obj/structure/closet/wardrobe/chaplain_black
+ name = "chapel wardrobe"
+ desc = "It's a storage unit for Nanotrasen-approved religious attire."
+ icon_state = "black"
+ icon_closed = "black"
+
+/obj/structure/closet/wardrobe/chaplain_black/New()
+ new /obj/item/clothing/under/rank/chaplain(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/suit/nun(src)
+ new /obj/item/clothing/head/nun_hood(src)
+ new /obj/item/clothing/suit/chaplain_hoodie(src)
+ new /obj/item/clothing/head/chaplain_hood(src)
+ new /obj/item/clothing/suit/holidaypriest(src)
+ new /obj/item/weapon/storage/backpack/cultpack (src)
+ new /obj/item/weapon/storage/fancy/candle_box(src)
+ new /obj/item/weapon/storage/fancy/candle_box(src)
+ return
+
+
+/obj/structure/closet/wardrobe/green
+ name = "green wardrobe"
+ icon_state = "green"
+ icon_closed = "green"
+
+/obj/structure/closet/wardrobe/green/New()
+ new /obj/item/clothing/under/color/green(src)
+ new /obj/item/clothing/under/color/green(src)
+ new /obj/item/clothing/under/color/green(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/shoes/black(src)
+ return
+
+
+/obj/structure/closet/wardrobe/orange
+ name = "prison wardrobe"
+ desc = "It's a storage unit for Nanotrasen-regulation prisoner attire."
+ icon_state = "orange"
+ icon_closed = "orange"
+
+/obj/structure/closet/wardrobe/orange/New()
+ new /obj/item/clothing/under/color/orange(src)
+ new /obj/item/clothing/under/color/orange(src)
+ new /obj/item/clothing/under/color/orange(src)
+ new /obj/item/clothing/shoes/orange(src)
+ new /obj/item/clothing/shoes/orange(src)
+ new /obj/item/clothing/shoes/orange(src)
+ return
+
+
+/obj/structure/closet/wardrobe/yellow
+ name = "yellow wardrobe"
+ icon_state = "wardrobe-y"
+ icon_closed = "wardrobe-y"
+
+/obj/structure/closet/wardrobe/yellow/New()
+ new /obj/item/clothing/under/color/yellow(src)
+ new /obj/item/clothing/under/color/yellow(src)
+ new /obj/item/clothing/under/color/yellow(src)
+ new /obj/item/clothing/shoes/orange(src)
+ new /obj/item/clothing/shoes/orange(src)
+ new /obj/item/clothing/shoes/orange(src)
+ return
+
+
+/obj/structure/closet/wardrobe/atmospherics_yellow
+ name = "atmospherics wardrobe"
+ icon_state = "yellow"
+ icon_closed = "yellow"
+
+/obj/structure/closet/wardrobe/atmospherics_yellow/New()
+ new /obj/item/clothing/under/rank/atmospheric_technician(src)
+ new /obj/item/clothing/under/rank/atmospheric_technician(src)
+ new /obj/item/clothing/under/rank/atmospheric_technician(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/shoes/black(src)
+ return
+
+
+
+/obj/structure/closet/wardrobe/engineering_yellow
+ name = "engineering wardrobe"
+ icon_state = "yellow"
+ icon_closed = "yellow"
+
+/obj/structure/closet/wardrobe/engineering_yellow/New()
+ new /obj/item/clothing/under/rank/engineer(src)
+ new /obj/item/clothing/under/rank/engineer(src)
+ new /obj/item/clothing/under/rank/engineer(src)
+ new /obj/item/clothing/shoes/orange(src)
+ new /obj/item/clothing/shoes/orange(src)
+ new /obj/item/clothing/shoes/orange(src)
+ return
+
+
+/obj/structure/closet/wardrobe/white
+ name = "white wardrobe"
+ icon_state = "white"
+ icon_closed = "white"
+
+/obj/structure/closet/wardrobe/white/New()
+ new /obj/item/clothing/under/color/white(src)
+ new /obj/item/clothing/under/color/white(src)
+ new /obj/item/clothing/under/color/white(src)
+ new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/shoes/white(src)
+ return
+
+
+/obj/structure/closet/wardrobe/pjs
+ name = "Pajama wardrobe"
+ icon_state = "white"
+ icon_closed = "white"
+
+/obj/structure/closet/wardrobe/pjs/New()
+ new /obj/item/clothing/under/pj/red(src)
+ new /obj/item/clothing/under/pj/red(src)
+ new /obj/item/clothing/under/pj/blue(src)
+ new /obj/item/clothing/under/pj/blue(src)
+ new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/shoes/white(src)
+ return
+
+
+/obj/structure/closet/wardrobe/toxins_white
+ name = "toxins wardrobe"
+ icon_state = "white"
+ icon_closed = "white"
+
+/obj/structure/closet/wardrobe/toxins_white/New()
+ new /obj/item/clothing/under/rank/scientist(src)
+ new /obj/item/clothing/under/rank/scientist(src)
+ new /obj/item/clothing/under/rank/scientist(src)
+ new /obj/item/clothing/suit/labcoat(src)
+ new /obj/item/clothing/suit/labcoat(src)
+ new /obj/item/clothing/suit/labcoat(src)
+ new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/shoes/white(src)
+ return
+
+
+/obj/structure/closet/wardrobe/robotics_black
+ name = "robotics wardrobe"
+ icon_state = "black"
+ icon_closed = "black"
+
+/obj/structure/closet/wardrobe/robotics_black/New()
+ new /obj/item/clothing/under/rank/roboticist(src)
+ new /obj/item/clothing/under/rank/roboticist(src)
+ new /obj/item/clothing/suit/labcoat(src)
+ new /obj/item/clothing/suit/labcoat(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/gloves/black(src)
+ new /obj/item/clothing/gloves/black(src)
+ return
+
+
+/obj/structure/closet/wardrobe/chemistry_white
+ name = "chemistry wardrobe"
+ icon_state = "white"
+ icon_closed = "white"
+
+/obj/structure/closet/wardrobe/chemistry_white/New()
+ new /obj/item/clothing/under/rank/chemist(src)
+ new /obj/item/clothing/under/rank/chemist(src)
+ new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/suit/labcoat/chemist(src)
+ new /obj/item/clothing/suit/labcoat/chemist(src)
+ return
+
+
+/obj/structure/closet/wardrobe/genetics_white
+ name = "genetics wardrobe"
+ icon_state = "white"
+ icon_closed = "white"
+
+/obj/structure/closet/wardrobe/genetics_white/New()
+ new /obj/item/clothing/under/rank/geneticist(src)
+ new /obj/item/clothing/under/rank/geneticist(src)
+ new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/suit/labcoat/genetics(src)
+ new /obj/item/clothing/suit/labcoat/genetics(src)
+ return
+
+
+/obj/structure/closet/wardrobe/virology_white
+ name = "virology wardrobe"
+ icon_state = "white"
+ icon_closed = "white"
+
+/obj/structure/closet/wardrobe/virology_white/New()
+ new /obj/item/clothing/under/rank/virologist(src)
+ new /obj/item/clothing/under/rank/virologist(src)
+ new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/shoes/white(src)
+ new /obj/item/clothing/suit/labcoat/virologist(src)
+ new /obj/item/clothing/suit/labcoat/virologist(src)
+ new /obj/item/clothing/mask/surgical(src)
+ new /obj/item/clothing/mask/surgical(src)
+ return
+
+
+/obj/structure/closet/wardrobe/grey
+ name = "grey wardrobe"
+ icon_state = "grey"
+ icon_closed = "grey"
+
+/obj/structure/closet/wardrobe/grey/New()
+ new /obj/item/clothing/under/color/grey(src)
+ new /obj/item/clothing/under/color/grey(src)
+ new /obj/item/clothing/under/color/grey(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/head/soft/grey(src)
+ new /obj/item/clothing/head/soft/grey(src)
+ new /obj/item/clothing/head/soft/grey(src)
+ return
+
+
+/obj/structure/closet/wardrobe/mixed
+ name = "mixed wardrobe"
+ icon_state = "mixed"
+ icon_closed = "mixed"
+
+/obj/structure/closet/wardrobe/mixed/New()
+ new /obj/item/clothing/under/color/white(src)
+ new /obj/item/clothing/under/color/blue(src)
+ new /obj/item/clothing/under/color/yellow(src)
+ new /obj/item/clothing/under/color/green(src)
+ new /obj/item/clothing/under/color/orange(src)
+ new /obj/item/clothing/under/color/pink(src)
+ new /obj/item/clothing/shoes/black(src)
+ new /obj/item/clothing/shoes/brown(src)
+ new /obj/item/clothing/shoes/white(src)
+ return
diff --git a/code/WorkInProgress/SkyMarshal/wardrobes.dm b/code/WorkInProgress/SkyMarshal/wardrobes.dm
index 214edfae54f..2ddb9adff4a 100755
--- a/code/WorkInProgress/SkyMarshal/wardrobes.dm
+++ b/code/WorkInProgress/SkyMarshal/wardrobes.dm
@@ -116,7 +116,7 @@
new /obj/item/clothing/head/helmet/welding(src)
new /obj/item/weapon/storage/belt/utility/full(src)
new /obj/item/weapon/storage/toolbox/mechanical(src)
- new /obj/item/clothing/suit/hazardvest(src)
+ new /obj/item/clothing/suit/storage/hazardvest(src)
new /obj/item/clothing/gloves/yellow(src)
new /obj/item/clothing/mask/gas(src)
new /obj/item/clothing/glasses/meson(src)
@@ -135,7 +135,7 @@
new /obj/item/weapon/pen(src)
new /obj/item/device/pda/engineering(src)
new /obj/item/device/t_scanner(src)
- new /obj/item/clothing/suit/hazardvest(src)
+ new /obj/item/clothing/suit/storage/hazardvest(src)
new /obj/item/weapon/storage/belt/utility/full(src)
new /obj/item/weapon/storage/toolbox/mechanical(src)
new /obj/item/clothing/mask/gas(src)
@@ -426,7 +426,7 @@
new /obj/item/taperoll/police(src)
new /obj/item/weapon/storage/box/evidence(src)
new /obj/item/device/pda/detective(src)
- new /obj/item/clothing/suit/det_suit/armor(src)
+ new /obj/item/clothing/suit/storage/det_suit/armor(src)
new /obj/item/clothing/suit/storage/det_suit(src)
new /obj/item/clothing/gloves/detective(src)
new /obj/item/clothing/head/det_hat(src)
@@ -606,9 +606,9 @@
new /obj/item/clothing/shoes/brown(src)
if(prob(50))
new /obj/item/clothing/under/lawyer/bluesuit(src)
- new /obj/item/clothing/suit/lawyer/bluejacket(src)
+ new /obj/item/clothing/suit/storage/lawyer/bluejacket(src)
else
new /obj/item/clothing/under/lawyer/purpsuit(src)
- new /obj/item/clothing/suit/lawyer/purpjacket(src)
+ new /obj/item/clothing/suit/storage/lawyer/purpjacket(src)
diff --git a/code/WorkInProgress/Susan/biocraps.dmi b/code/WorkInProgress/Susan/biocraps.dmi
new file mode 100644
index 00000000000..1bcbec018fe
Binary files /dev/null and b/code/WorkInProgress/Susan/biocraps.dmi differ
diff --git a/code/WorkInProgress/Susan/desert.dmi b/code/WorkInProgress/Susan/desert.dmi
new file mode 100644
index 00000000000..439f5630f06
Binary files /dev/null and b/code/WorkInProgress/Susan/desert.dmi differ
diff --git a/code/WorkInProgress/Susan/susan_desert_turfs.dm b/code/WorkInProgress/Susan/susan_desert_turfs.dm
new file mode 100644
index 00000000000..74c48b4c7b3
--- /dev/null
+++ b/code/WorkInProgress/Susan/susan_desert_turfs.dm
@@ -0,0 +1,467 @@
+//this is everything i'm going to be using in my outpost zeta map, and possibly future maps.
+
+turf/unsimulated/desert
+ name = "desert"
+ icon = 'desert.dmi'
+ icon_state = "desert"
+ temperature = 393.15
+ luminosity = 5
+ lighting_lumcount = 8
+
+turf/unsimulated/desert/New()
+ icon_state = "desert[rand(0,4)]"
+
+turf/simulated/wall/impassable_rock
+ name = "Mountain Wall"
+
+ //so that you can see the impassable sections in the map editor
+ icon_state = "riveted"
+ New()
+ icon_state = "rock"
+
+/area/awaymission/labs/researchdivision
+ name = "Research"
+ icon_state = "away3"
+
+/area/awaymission/labs/militarydivision
+ name = "Military"
+ icon_state = "away2"
+
+/area/awaymission/labs/gateway
+ name = "Gateway"
+ icon_state = "away1"
+
+/area/awaymission/labs/command
+ name = "Command"
+ icon_state = "away"
+
+/area/awaymission/labs/civilian
+ name = "Civilian"
+ icon_state = "away3"
+
+/area/awaymission/labs/cargo
+ name = "Cargo"
+ icon_state = "away2"
+
+/area/awaymission/labs/medical
+ name = "Medical"
+ icon_state = "away1"
+
+/area/awaymission/labs/security
+ name = "Security"
+ icon_state = "away"
+
+/area/awaymission/labs/solars
+ name = "Solars"
+ icon_state = "away3"
+
+/area/awaymission/labs/cave
+ name = "Caves"
+ icon_state = "away2"
+
+//corpses and possibly other decorative items
+
+/obj/effect/landmark/corpse/alien
+ mutantrace = "lizard"
+
+/obj/effect/landmark/corpse/alien/cargo
+ name = "Cargo Technician"
+ corpseuniform = /obj/item/clothing/under/rank/cargo
+ corpseradio = /obj/item/device/radio/headset/headset_cargo
+ corpseid = 1
+ corpseidjob = "Cargo Technician"
+ corpseidaccess = "Quartermaster"
+
+/obj/effect/landmark/corpse/alien/laborer
+ name = "Laborer"
+ corpseuniform = /obj/item/clothing/under/overalls
+ corpseradio = /obj/item/device/radio/headset/headset_eng
+ corpseback = /obj/item/weapon/storage/backpack/industrial
+ corpsebelt = /obj/item/weapon/storage/belt/utility/full
+ corpsehelmet = /obj/item/clothing/head/hardhat
+ corpseid = 1
+ corpseidjob = "Laborer"
+ corpseidaccess = "Engineer"
+
+/obj/effect/landmark/corpse/alien/testsubject
+ name = "Unfortunate Test Subject"
+ corpseuniform = /obj/item/clothing/under/color/white
+ corpseid = 0
+
+/obj/effect/landmark/corpse/overseer
+ name = "Overseer"
+ corpseuniform = /obj/item/clothing/under/rank/navyhead_of_security
+ corpsesuit = /obj/item/clothing/suit/armor/hosnavycoat
+ corpseradio = /obj/item/device/radio/headset/heads/captain
+ corpsegloves = /obj/item/clothing/gloves/black/hos
+ corpseshoes = /obj/item/clothing/shoes/swat
+ corpsehelmet = /obj/item/clothing/head/beret/navyhos
+ corpseglasses = /obj/item/clothing/glasses/eyepatch
+ corpseid = 1
+ corpseidjob = "Facility Overseer"
+ corpseidaccess = "Captain"
+
+/obj/effect/landmark/corpse/officer
+ name = "Security Officer"
+ corpseuniform = /obj/item/clothing/under/rank/navysecurity
+ corpsesuit = /obj/item/clothing/suit/armor/navysecvest
+ corpseradio = /obj/item/device/radio/headset/headset_sec
+ corpseshoes = /obj/item/clothing/shoes/swat
+ corpsehelmet = /obj/item/clothing/head/beret/navysec
+ corpseid = 1
+ corpseidjob = "Security Officer"
+ corpseidaccess = "Security Officer"
+
+/*
+ * Weeds
+ */
+#define NODERANGE 1
+
+/obj/effect/alien/flesh/weeds
+ name = "Fleshy Growth"
+ desc = "A pulsating grouping of odd, alien tissues. It's almost like it has a heartbeat..."
+ icon = 'biocraps.dmi'
+ icon_state = "flesh"
+
+ anchored = 1
+ density = 0
+ var/health = 15
+ var/obj/effect/alien/weeds/node/linked_node = null
+
+/obj/effect/alien/flesh/weeds/node
+ icon_state = "fleshnode"
+ icon = 'biocraps.dmi'
+ name = "Throbbing Pustule"
+ desc = "A grotquese, oozing, pimple-like growth. You swear you can see something moving around in the bulb..."
+ luminosity = NODERANGE
+ var/node_range = NODERANGE
+
+/obj/effect/alien/flesh/weeds/node/New()
+ ..(src.loc, src)
+
+
+/obj/effect/alien/flesh/weeds/New(pos, node)
+ ..()
+ linked_node = node
+ if(istype(loc, /turf/space))
+ del(src)
+ return
+ if(icon_state == "flesh")icon_state = pick("flesh", "flesh1", "flesh2")
+ spawn(rand(150, 200))
+ if(src)
+ Life()
+ return
+
+/obj/effect/alien/flesh/weeds/proc/Life()
+ set background = 1
+ var/turf/U = get_turf(src)
+/*
+ if (locate(/obj/movable, U))
+ U = locate(/obj/movable, U)
+ if(U.density == 1)
+ del(src)
+ return
+
+Alien plants should do something if theres a lot of poison
+ if(U.poison> 200000)
+ health -= round(U.poison/200000)
+ update()
+ return
+*/
+ if (istype(U, /turf/space))
+ del(src)
+ return
+
+ direction_loop:
+ for(var/dirn in cardinal)
+ var/turf/T = get_step(src, dirn)
+
+ if (!istype(T) || T.density || locate(/obj/effect/alien/flesh/weeds) in T || istype(T.loc, /area/arrival) || istype(T, /turf/space))
+ continue
+
+ if(!linked_node || get_dist(linked_node, src) > linked_node.node_range)
+ return
+
+ // if (locate(/obj/movable, T)) // don't propogate into movables
+ // continue
+
+ for(var/obj/O in T)
+ if(O.density)
+ continue direction_loop
+
+ new /obj/effect/alien/flesh/weeds(T, linked_node)
+
+
+/obj/effect/alien/flesh/weeds/ex_act(severity)
+ switch(severity)
+ if(1.0)
+ del(src)
+ if(2.0)
+ if (prob(50))
+ del(src)
+ if(3.0)
+ if (prob(5))
+ del(src)
+ return
+
+/obj/effect/alien/flesh/weeds/attackby(var/obj/item/weapon/W, var/mob/user)
+ if(W.attack_verb.len)
+ visible_message("\red \The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]")
+ else
+ visible_message("\red \The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]")
+
+ var/damage = W.force / 4.0
+
+ if(istype(W, /obj/item/weapon/weldingtool))
+ var/obj/item/weapon/weldingtool/WT = W
+
+ if(WT.remove_fuel(0, user))
+ damage = 15
+ playsound(loc, 'sound/items/Welder.ogg', 100, 1)
+
+ health -= damage
+ healthcheck()
+
+/obj/effect/alien/flesh/weeds/proc/healthcheck()
+ if(health <= 0)
+ del(src)
+
+
+/obj/effect/alien/flesh/weeds/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ if(exposed_temperature > 300)
+ health -= 5
+ healthcheck()
+
+/*/obj/effect/alien/weeds/burn(fi_amount)
+ if (fi_amount > 18000)
+ spawn( 0 )
+ del(src)
+ return
+ return 0
+ return 1
+*/
+
+#undef NODERANGE
+
+//clothing, weapons, and other items that can be worn or used in some way
+
+/obj/item/clothing/under/rank/navywarden
+ desc = "It's made of a slightly sturdier material than standard jumpsuits, to allow for more robust protection. It has the word \"Warden\" written on the shoulders."
+ name = "warden's jumpsuit"
+ icon_state = "wardendnavyclothes"
+ item_state = "wardendnavyclothes"
+ color = "wardendnavyclothes"
+ armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
+ flags = FPRINT | TABLEPASS
+
+/obj/item/clothing/under/rank/navysecurity
+ name = "security officer's jumpsuit"
+ desc = "It's made of a slightly sturdier material than standard jumpsuits, to allow for robust protection."
+ icon_state = "officerdnavyclothes"
+ item_state = "officerdnavyclothes"
+ color = "officerdnavyclothes"
+ armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
+ flags = FPRINT | TABLEPASS
+
+/obj/item/clothing/under/rank/navyhead_of_security
+ desc = "It's a jumpsuit worn by those few with the dedication to achieve the position of \"Head of Security\". It has additional armor to protect the wearer."
+ name = "head of security's jumpsuit"
+ icon_state = "hosdnavyclothes"
+ item_state = "hosdnavyclothes"
+ color = "hosdnavyclothes"
+ armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
+ flags = FPRINT | TABLEPASS
+
+/obj/item/clothing/suit/armor/hosnavycoat
+ name = "armored coat"
+ desc = "A coat enchanced with a special alloy for some protection and style."
+ icon_state = "hosdnavyjacket"
+ item_state = "armor"
+ armor = list(melee = 65, bullet = 30, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)
+
+/obj/item/clothing/head/beret/navysec
+ name = "security beret"
+ desc = "A beret with the security insignia emblazoned on it. For officers that are more inclined towards style than safety."
+ icon_state = "officerberet"
+ flags = FPRINT | TABLEPASS
+
+/obj/item/clothing/head/beret/navywarden
+ name = "warden's beret"
+ desc = "A beret with a two-colored security insignia emblazoned on it. For wardens that are more inclined towards style than safety."
+ icon_state = "wardenberet"
+ flags = FPRINT | TABLEPASS
+
+/obj/item/clothing/head/beret/navyhos
+ name = "security head's beret"
+ desc = "A stylish beret bearing a golden insignia that proudly displays the security coat of arms. A commander's must-have."
+ icon_state = "hosberet"
+ flags = FPRINT | TABLEPASS
+
+/obj/item/clothing/suit/armor/navysecvest
+ name = "armored coat"
+ desc = "An armored coat that protects against some damage."
+ icon_state = "officerdnavyjacket"
+ item_state = "armor"
+ flags = FPRINT | TABLEPASS
+ armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)
+
+/obj/item/clothing/suit/armor/navywardenvest
+ name = "Warden's jacket"
+ desc = "An armoured jacket with silver rank pips and livery."
+ icon_state = "wardendnavyjacket"
+ item_state = "armor"
+ flags = FPRINT | TABLEPASS
+ armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)
+
+//hostile entities or npcs
+
+/obj/item/projectile/slimeglob
+ icon = 'projectiles.dmi'
+ icon_state = "toxin"
+ damage = 20
+ damage_type = BRUTE
+
+/obj/effect/critter/fleshmonster
+ name = "Fleshy Horror"
+ desc = "A grotesque, shambling fleshy horror... was this once a... a person?"
+ icon = 'icons/mob/mob.dmi'
+ icon_state = "horror"
+/*
+ health = 120
+ max_health = 120
+ aggressive = 1
+ defensive = 1
+ wanderer = 1
+ opensdoors = 1
+ atkcarbon = 1
+ atksilicon = 1
+ atkcritter = 1
+ atksame = 0
+ atkmech = 1
+ firevuln = 0.5
+ brutevuln = 1
+ seekrange = 25
+ armor = 15
+ melee_damage_lower = 12
+ melee_damage_upper = 17
+ angertext = "shambles"
+ attacktext = "slashes"
+ var/ranged = 0
+ var/rapid = 0
+ proc
+ Shoot(var/target, var/start, var/user, var/bullet = 0)
+ OpenFire(var/thing)//bluh ill rename this later or somethin
+
+
+ Die()
+ if (!src.alive) return
+ src.alive = 0
+ walk_to(src,0)
+ src.visible_message("[src] disintegrates into mush!")
+ playsound(loc, 'sound/voice/hiss6.ogg', 80, 1, 1)
+ var/turf/Ts = get_turf(src)
+ new /obj/effect/decal/cleanable/blood(Ts)
+ del(src)
+
+ seek_target()
+ src.anchored = 0
+ var/T = null
+ for(var/mob/living/C in view(src.seekrange,src))//TODO: mess with this
+ if (src.target)
+ src.task = "chasing"
+ break
+ if((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue
+ if(istype(C, /mob/living/carbon/) && !src.atkcarbon) continue
+ if(istype(C, /mob/living/silicon/) && !src.atksilicon) continue
+ if(C.health < 0) continue
+ if(istype(C, /mob/living/carbon/) && src.atkcarbon)
+ if(C:mind)
+ if(C:mind:special_role == "H.I.V.E")
+ continue
+ src.attack = 1
+ if(istype(C, /mob/living/silicon/) && src.atksilicon)
+ if(C:mind)
+ if(C:mind:special_role == "H.I.V.E")
+ continue
+ src.attack = 1
+ if(src.attack)
+ T = C
+ break
+
+ if(!src.attack)
+ for(var/obj/effect/critter/C in view(src.seekrange,src))
+ if(istype(C, /obj/effect/critter) && !src.atkcritter) continue
+ if(C.health <= 0) continue
+ if(istype(C, /obj/effect/critter) && src.atkcritter)
+ if((istype(C, /obj/effect/critter/hivebot) && !src.atksame) || (C == src)) continue
+ T = C
+ break
+
+ for(var/obj/mecha/M in view(src.seekrange,src))
+ if(istype(M, /obj/mecha) && !src.atkmech) continue
+ if(M.health <= 0) continue
+ if(istype(M, /obj/mecha) && src.atkmech) src.attack = 1
+ if(src.attack)
+ T = M
+ break
+
+ if(src.attack)
+ src.target = T
+ src.oldtarget_name = T:name
+ if(src.ranged)
+ OpenFire(T)
+ return
+ src.task = "chasing"
+ return
+
+
+ OpenFire(var/thing)
+ src.target = thing
+ src.oldtarget_name = thing:name
+ for(var/mob/O in viewers(src, null))
+ O.show_message("\red [src] spits a glob at [src.target]!", 1)
+
+ var/tturf = get_turf(target)
+ if(rapid)
+ spawn(1)
+ Shoot(tturf, src.loc, src)
+ spawn(4)
+ Shoot(tturf, src.loc, src)
+ spawn(6)
+ Shoot(tturf, src.loc, src)
+ else
+ Shoot(tturf, src.loc, src)
+
+ src.attack = 0
+ sleep(12)
+ seek_target()
+ src.task = "thinking"
+ return
+
+
+ Shoot(var/target, var/start, var/user, var/bullet = 0)
+ if(target == start)
+ return
+
+ var/obj/item/projectile/slimeglob/A = new /obj/item/projectile/slimeglob(user:loc)
+ playsound(user, 'sound/weapons/bite.ogg', 100, 1)
+
+ if(!A) return
+
+ if (!istype(target, /turf))
+ del(A)
+ return
+ A.current = target
+ A.yo = target:y - start:y
+ A.xo = target:x - start:x
+ spawn( 0 )
+ A.process()
+ return
+*/
+
+obj/effect/critter/fleshmonster/fleshslime
+ name = "Flesh Slime"
+ icon = 'biocraps.dmi'
+ icon_state = "livingflesh"
+ desc = "A creature that appears to be made out of living tissue strewn together haphazardly. Some kind of liquid bubbles from its maw."
+ //ranged = 1
\ No newline at end of file
diff --git a/code/WorkInProgress/autopsy.dm b/code/WorkInProgress/autopsy.dm
index 2137141996f..8bf45945bc6 100644
--- a/code/WorkInProgress/autopsy.dm
+++ b/code/WorkInProgress/autopsy.dm
@@ -1,3 +1,20 @@
+
+//moved these here from code/defines/obj/weapon.dm
+//please preference put stuff where it's easy to find - C
+
+/obj/item/weapon/autopsy_scanner
+ name = "autopsy scanner"
+ desc = "Extracts information on wounds."
+ icon = 'icons/obj/autopsy_scanner.dmi'
+ icon_state = ""
+ flags = FPRINT | TABLEPASS | CONDUCT
+ w_class = 1.0
+ origin_tech = "materials=1;biotech=1"
+ var/list/datum/autopsy_data_scanner/wdata = list()
+ var/list/datum/autopsy_data_scanner/chemtraces = list()
+ var/target_name = null
+ var/timeofdeath = null
+
/datum/autopsy_data_scanner
var/weapon = null // this is the DEFINITE weapon type that was used
var/list/organs_scanned = list() // this maps a number of scanned organs to
@@ -65,10 +82,6 @@
usr << "No."
return
- if(wdata.len == 0 && chemtraces.len == 0)
- usr << "* There is no data about any wounds in the scanner's database. You may have to scan more bodyparts, or otherwise this wound type may not be in the scanner's database."
- return
-
var/scan_data = ""
if(timeofdeath)
@@ -170,6 +183,8 @@
if(target_name != M.name)
target_name = M.name
src.wdata = list()
+ src.chemtraces = list()
+ src.timeofdeath = null
user << "\red A new patient has been registered.. Purging data for previous patient."
src.timeofdeath = M.timeofdeath
diff --git a/code/WorkInProgress/buildmode.dm b/code/WorkInProgress/buildmode.dm
index 0c42c913d50..5e4a45e21ae 100644
--- a/code/WorkInProgress/buildmode.dm
+++ b/code/WorkInProgress/buildmode.dm
@@ -149,13 +149,13 @@
if(objholder in removed_paths)
alert("That path is not allowed.")
objholder = "/obj/structure/closet"
- else if (dd_hasprefix(objholder, "/mob") && !(usr.client.holder.rank in list("Game Master", "Game Admin", "Badmin")))
+ else if (dd_hasprefix(objholder, "/mob") && !check_rights(R_DEBUG,0))
objholder = "/obj/structure/closet"
if(3)
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine")
master.buildmode.varholder = input(usr,"Enter variable name:" ,"Name", "name")
- if(master.buildmode.varholder in locked && !(usr.client.holder.rank in list("Game Master", "Game Admin")))
+ if(master.buildmode.varholder in locked && !check_rights(R_DEBUG,0))
return
var/thetype = input(usr,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference")
if(!thetype) return
@@ -186,28 +186,28 @@
if(istype(object,/turf) && pa.Find("left") && !pa.Find("alt") && !pa.Find("ctrl") )
if(istype(object,/turf/space))
var/turf/T = object
- T.ReplaceWithFloor()
+ T.ChangeTurf(/turf/simulated/floor)
return
else if(istype(object,/turf/simulated/floor))
var/turf/T = object
- T.ReplaceWithWall()
+ T.ChangeTurf(/turf/simulated/wall)
return
else if(istype(object,/turf/simulated/wall))
var/turf/T = object
- T.ReplaceWithRWall()
+ T.ChangeTurf(/turf/simulated/wall/r_wall)
return
else if(pa.Find("right"))
if(istype(object,/turf/simulated/wall))
var/turf/T = object
- T.ReplaceWithFloor()
+ T.ChangeTurf(/turf/simulated/floor)
return
else if(istype(object,/turf/simulated/floor))
var/turf/T = object
- T.ReplaceWithSpace()
+ T.ChangeTurf(/turf/space)
return
else if(istype(object,/turf/simulated/wall/r_wall))
var/turf/T = object
- T.ReplaceWithWall()
+ T.ChangeTurf(/turf/simulated/wall)
return
else if(istype(object,/obj))
del(object)
@@ -235,7 +235,6 @@
if(pa.Find("left"))
var/obj/A = new holder.buildmode.objholder (get_turf(object))
A.dir = holder.builddir.dir
- blink(A)
else if(pa.Find("right"))
if(isobj(object)) del(object)
@@ -244,14 +243,12 @@
if(object.vars.Find(holder.buildmode.varholder))
log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]")
object.vars[holder.buildmode.varholder] = holder.buildmode.valueholder
- blink(object)
else
usr << "\red [initial(object.name)] does not have a var called '[holder.buildmode.varholder]'"
if(pa.Find("right"))
if(object.vars.Find(holder.buildmode.varholder))
log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]")
object.vars[holder.buildmode.varholder] = initial(object.vars[holder.buildmode.varholder])
- blink(object)
else
usr << "\red [initial(object.name)] does not have a var called '[holder.buildmode.varholder]'"
@@ -262,8 +259,3 @@
if(holder.throw_atom)
holder.throw_atom.throw_at(object, 10, 1)
-/proc/blink(atom/A)
- A.icon += rgb(0,75,75)
- spawn(5)
- if(A)
- A.icon = initial(A.icon)
diff --git a/code/WorkInProgress/mapload/dmm_suite.dm b/code/WorkInProgress/mapload/dmm_suite.dm
deleted file mode 100644
index f096d555642..00000000000
--- a/code/WorkInProgress/mapload/dmm_suite.dm
+++ /dev/null
@@ -1,246 +0,0 @@
-dmm_suite
- /*
-
- dmm_suite version 1.0
- Released January 30th, 2011.
-
- defines the object /dmm_suite
- - Provides the proc load_map()
- - Loads the specified map file onto the specified z-level.
- - provides the proc write_map()
- - Returns a text string of the map in dmm format
- ready for output to a file.
- - provides the proc save_map()
- - Returns a .dmm file if map is saved
- - Returns FALSE if map fails to save
-
- The dmm_suite provides saving and loading of map files in BYOND's native DMM map
- format. It approximates the map saving and loading processes of the Dream Maker
- and Dream Seeker programs so as to allow editing, saving, and loading of maps at
- runtime.
-
- ------------------------
-
- To save a map at runtime, create an instance of /dmm_suite, and then call
- write_map(), which accepts three arguments:
- - A turf representing one corner of a three dimensional grid (Required).
- - Another turf representing the other corner of the same grid (Required).
- - Any, or a combination, of several bit flags (Optional, see documentation).
-
- The order in which the turfs are supplied does not matter, the /dmm_writer will
- determine the grid containing both, in much the same way as DM's block() function.
- write_map() will then return a string representing the saved map in dmm format;
- this string can then be saved to a file, or used for any other purose.
-
- ------------------------
-
- To load a map at runtime, create an instance of /dmm_suite, and then call load_map(),
- which accepts two arguments:
- - A .dmm file to load (Required).
- - A number representing the z-level on which to start loading the map (Optional).
-
- The /dmm_suite will load the map file starting on the specified z-level. If no
- z-level was specified, world.maxz will be increased so as to fit the map. Note
- that if you wish to load a map onto a z-level that already has objects on it,
- you will have to handle the removal of those objects. Otherwise the new map will
- simply load the new objects on top of the old ones.
-
- Also note that all type paths specified in the .dmm file must exist in the world's
- code, and that the /dmm_reader trusts that files to be loaded are in fact valid
- .dmm files. Errors in the .dmm format will cause runtime errors.
-
- */
-
-
- verb/load_map(var/dmm_file as file, var/z_offset as num)
- // dmm_file: A .dmm file to load (Required).
- // z_offset: A number representing the z-level on which to start loading the map (Optional).
-
-
- verb/write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num)
- // t1: A turf representing one corner of a three dimensional grid (Required).
- // t2: Another turf representing the other corner of the same grid (Required).
- // flags: Any, or a combination, of several bit flags (Optional, see documentation).
-
- // save_map is included as a legacy proc. Use write_map instead.
- verb/save_map(var/turf/t1 as turf, var/turf/t2 as turf, var/map_name as text, var/flags as num)
- // t1: A turf representing one corner of a three dimensional grid (Required).
- // t2: Another turf representing the other corner of the same grid (Required).
- // map_name: A valid name for the map to be saved, such as "castle" (Required).
- // flags: Any, or a combination, of several bit flags (Optional, see documentation).
-
-
-#define DMM_IGNORE_AREAS 1
-#define DMM_IGNORE_TURFS 2
-#define DMM_IGNORE_OBJS 4
-#define DMM_IGNORE_NPCS 8
-#define DMM_IGNORE_PLAYERS 16
-#define DMM_IGNORE_MOBS 24
-dmm_suite{
- var{
- quote = "\""
- list/letter_digits = 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",
- "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"
- )
- }
- save_map(var/turf/t1 as turf, var/turf/t2 as turf, var/map_name as text, var/flags as num){
- //Check for illegal characters in file name... in a cheap way.
- if(!((ckeyEx(map_name)==map_name) && ckeyEx(map_name))){
- CRASH("Invalid text supplied to proc save_map, invalid characters or empty string.")
- }
- //Check for valid turfs.
- if(!isturf(t1) || !isturf(t2)){
- CRASH("Invalid arguments supplied to proc save_map, arguments were not turfs.")
- }
- var/file_text = write_map(t1,t2,flags)
- if(fexists("[map_name].dmm")){
- fdel("[map_name].dmm")
- }
- var/saved_map = file("[map_name].dmm")
- saved_map << file_text
- return saved_map
- }
- write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num){
- //Check for valid turfs.
- if(!isturf(t1) || !isturf(t2)){
- CRASH("Invalid arguments supplied to proc write_map, arguments were not turfs.")
- }
- var/turf/nw = locate(min(t1.x,t2.x),max(t1.y,t2.y),min(t1.z,t2.z))
- var/turf/se = locate(max(t1.x,t2.x),min(t1.y,t2.y),max(t1.z,t2.z))
- var/list/templates[0]
- var/template_buffer = {""}
- var/dmm_text = {""}
- for(var/pos_z=nw.z;pos_z<=se.z;pos_z++){
- for(var/pos_y=nw.y;pos_y>=se.y;pos_y--){
- for(var/pos_x=nw.x;pos_x<=se.x;pos_x++){
- var/turf/test_turf = locate(pos_x,pos_y,pos_z)
- var/test_template = make_template(test_turf, flags)
- var/template_number = templates.Find(test_template)
- if(!template_number){
- templates.Add(test_template)
- template_number = templates.len
- }
- template_buffer += "[template_number],"
- }
- template_buffer += ";"
- }
- template_buffer += "."
- }
- var/key_length = round/*floor*/(log(letter_digits.len,templates.len-1)+1)
- var/list/keys[templates.len]
- for(var/key_pos=1;key_pos<=templates.len;key_pos++){
- keys[key_pos] = get_model_key(key_pos,key_length)
- dmm_text += {""[keys[key_pos]]" = ([templates[key_pos]])\n"}
- }
- var/z_level = 0
- for(var/z_pos=1;TRUE;z_pos=findtext(template_buffer,".",z_pos)+1){
- if(z_pos>=length(template_buffer)){break}
- if(z_level){dmm_text+={"\n"}}
- dmm_text += {"\n(1,1,[++z_level]) = {"\n"}
- var/z_block = copytext(template_buffer,z_pos,findtext(template_buffer,".",z_pos))
- for(var/y_pos=1;TRUE;y_pos=findtext(z_block,";",y_pos)+1){
- if(y_pos>=length(z_block)){break}
- var/y_block = copytext(z_block,y_pos,findtext(z_block,";",y_pos))
- for(var/x_pos=1;TRUE;x_pos=findtext(y_block,",",x_pos)+1){
- if(x_pos>=length(y_block)){break}
- var/x_block = copytext(y_block,x_pos,findtext(y_block,",",x_pos))
- var/key_number = text2num(x_block)
- var/temp_key = keys[key_number]
- dmm_text += temp_key
- sleep(-1)
- }
- dmm_text += {"\n"}
- sleep(-1)
- }
- dmm_text += {"\"}"}
- sleep(-1)
- }
- return dmm_text
- }
- proc{
- make_template(var/turf/model as turf, var/flags as num){
- var/template = ""
- var/obj_template = ""
- var/mob_template = ""
- var/turf_template = ""
- if(!(flags & DMM_IGNORE_TURFS)){
- turf_template = "[model.type][check_attributes(model)],"
- } else{ turf_template = "[world.turf],"}
- var/area_template = ""
- if(!(flags & DMM_IGNORE_OBJS)){
- for(var/obj/O in model.contents){
- obj_template += "[O.type][check_attributes(O)],"
- }
- }
- for(var/mob/M in model.contents){
- if(M.client){
- if(!(flags & DMM_IGNORE_PLAYERS)){
- mob_template += "[M.type][check_attributes(M)],"
- }
- }
- else{
- if(!(flags & DMM_IGNORE_NPCS)){
- mob_template += "[M.type][check_attributes(M)],"
- }
- }
- }
- if(!(flags & DMM_IGNORE_AREAS)){
- var/area/m_area = model.loc
- area_template = "[m_area.type][check_attributes(m_area)]"
- } else{ area_template = "[world.area]"}
- template = "[obj_template][mob_template][turf_template][area_template]"
- return template
- }
- check_attributes(var/atom/A){
- var/attributes_text = {"{"}
- for(var/V in A.vars){
- sleep(-1)
- if((!issaved(A.vars[V])) || (A.vars[V]==initial(A.vars[V]))){continue}
- if(istext(A.vars[V])){
- attributes_text += {"[V] = "[A.vars[V]]""}
- }
- else if(isnum(A.vars[V])||ispath(A.vars[V])){
- attributes_text += {"[V] = [A.vars[V]]"}
- }
- else if(isicon(A.vars[V])||isfile(A.vars[V])){
- attributes_text += {"[V] = '[A.vars[V]]'"}
- }
- else{
- continue
- }
- if(attributes_text != {"{"}){
- attributes_text+={"; "}
- }
- }
- if(attributes_text=={"{"}){
- return
- }
- if(copytext(attributes_text, length(attributes_text)-1, 0) == {"; "}){
- attributes_text = copytext(attributes_text, 1, length(attributes_text)-1)
- }
- attributes_text += {"}"}
- return attributes_text
- }
- get_model_key(var/which as num, var/key_length as num){
- var/key = ""
- var/working_digit = which-1
- for(var/digit_pos=key_length;digit_pos>=1;digit_pos--){
- var/place_value = round/*floor*/(working_digit/(letter_digits.len**(digit_pos-1)))
- working_digit-=place_value*(letter_digits.len**(digit_pos-1))
- key = "[key][letter_digits[place_value+1]]"
- }
- return key
- }
- }
- }
diff --git a/code/WorkInProgress/mapload/reader.dm b/code/WorkInProgress/mapload/reader.dm
deleted file mode 100644
index 755b96fc2da..00000000000
--- a/code/WorkInProgress/mapload/reader.dm
+++ /dev/null
@@ -1,181 +0,0 @@
-dmm_suite/load_map(var/dmm_file as file, var/z_offset as num)
- if(!z_offset)
- z_offset = world.maxz+1
- var/quote = ascii2text(34)
- var/tfile = file2text(dmm_file)
- var/tfile_len = length(tfile)
- var/list/grid_models[0]
- var/key_len = length(copytext(tfile,2,findtext(tfile,quote,2,0)))
- for(var/lpos=1;lposlength(zgrid)) break
- sleep(-1)
-
- if(findtext(tfile,quote+"}",zpos,0)+2==tfile_len) break
- sleep(-1)
-
-
-dmm_suite/proc/parse_grid(var/model as text,var/xcrd as num,var/ycrd as num,var/zcrd as num)
- set background = 1
-
- /*Method parse_grid()
- - Accepts a text string containing a comma separated list of type paths of the
- same construction as those contained in a .dmm file, and instantiates them.
- */
- var/list/text_strings[0]
- for(var/index=1;findtext(model,quote);index++)
- /*Loop: Stores quoted portions of text in text_strings, and replaces them with an
- index to that list.
- - Each iteration represents one quoted section of text.
- */
- text_strings.len=index
- text_strings[index] = copytext(model,findtext(model,quote)+1,findtext(model,quote,findtext(model,quote)+1,0))
- model = copytext(model,1,findtext(model,quote))+"~[index]"+copytext(model,findtext(model,quote,findtext(model,quote)+1,0)+1,0)
- sleep(-1)
-
- for(var/dpos=1;dpos!=0;dpos=findtext(model,",",dpos,0)+1)
- /*Loop: Identifies each object's data, instantiates it, and reconstitues it's fields.
- - Each iteration represents one object's data, including type path and field values.
- */
- var/full_def = copytext(model,dpos,findtext(model,",",dpos,0))
- var/atom_def = text2path(copytext(full_def,1,findtext(full_def,"{")))
-
- if(ispath(atom_def, /turf/space))
- continue
-
- var/list/attributes[0]
- if(findtext(full_def,"{"))
- full_def = copytext(full_def,1,length(full_def))
- for(var/apos=findtext(full_def,"{")+1;apos!=0;apos=findtext(full_def,";",apos,0)+1)
- //Loop: Identifies each attribute/value pair, and stores it in attributes[].
- attributes.Add(copytext(full_def,apos,findtext(full_def,";",apos,0)))
- if(!findtext(copytext(full_def,apos,0),";")) break
- sleep(-1)
-
- //Construct attributes associative list
- var/list/fields = new(0)
- for(var/index=1;index<=attributes.len;index++)
- var/trim_left = trim_text(copytext(attributes[index],1,findtext(attributes[index],"=")))
- var/trim_right = trim_text(copytext(attributes[index],findtext(attributes[index],"=")+1,0))
- //Check for string
- if(findtext(trim_right,"~"))
- var/reference_index = copytext(trim_right,findtext(trim_right,"~")+1,0)
- trim_right=text_strings[text2num(reference_index)]
- //Check for number
- 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)))
- fields[trim_left] = trim_right
-
- //End construction
- //Begin Instanciation
- var/atom/instance
- var/dmm_suite/preloader/_preloader = new(fields)
- if(ispath(atom_def,/area))
- var/turf/A = locate(xcrd,ycrd,zcrd)
- if(A.loc.name == "Space")
- instance = locate(atom_def)
- if(instance)
- instance.contents.Add(locate(xcrd,ycrd,zcrd))
-
- else
- //global.current_preloader = _preloader
- instance = new atom_def(locate(xcrd,ycrd,zcrd))
- if(_preloader)
- _preloader.load(instance)
- //End Instanciation
- if(!findtext(copytext(model,dpos,0),",")) break
-
-
-dmm_suite/proc/trim_text(var/what as text)
- while(length(what) && findtext(what," ",1,2))
- what=copytext(what,2,0)
- while(length(what) && findtext(what," ",length(what),0))
- what=copytext(what,1,length(what))
- return what
-
-/*
-var/global/dmm_suite/preloader/current_preloader = null
-atom/New()
- if(global.current_preloader)
- global.current_preloader.load(src)
- ..()
-*/
-
-
-dmm_suite/preloader
- parent_type = /datum
- var/list/attributes
-
-
- New(list/the_attributes)
- ..()
- if(!the_attributes.len) Del()
- attributes = the_attributes
-
-
- proc/load(atom/what)
- for(var/attribute in attributes)
- what.vars[attribute] = attributes[attribute]
- Del()
-
-
-
-/client/proc/mapload(var/dmm_map as file)
- set category = "Debug"
- set name = "LoadMap"
- set desc = "Loads a map"
- set hidden = 1
- if(src.holder)
- if(!src.mob)
- return
- if(src.holder.rank in list("Game Admin", "Game Master"))
- var/file_name = "[dmm_map]"
- var/file_extension = copytext(file_name,length(file_name)-2,0)
- if(file_extension != "dmm")
- usr << "Supplied file must be a .dmm file."
- return
- var/map_z = input(usr,"Enter variable value:" ,"Value", 123) as num
- if(map_z > (world.maxz+1))
- map_z = (world.maxz+1)
-
- var/dmm_suite/new_reader = new()
- new_reader.load_map(dmm_map, map_z)
- log_admin("[key_name(src.mob)] loaded a map on z:[map_z]")
-
- else
- alert("No")
- return
- return
diff --git a/code/WorkInProgress/surgery.dm b/code/WorkInProgress/surgery.dm
deleted file mode 100644
index 3b1401708d0..00000000000
--- a/code/WorkInProgress/surgery.dm
+++ /dev/null
@@ -1,1179 +0,0 @@
-
-//check if mob is lying down on something we can operate him on.
-/proc/can_operate(mob/living/carbon/M)
- return (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))
-
-/datum/surgery_status/
- var/eyes = 0
- var/face = 0
- var/appendix = 0
-
-/mob/living/carbon/var/datum/surgery_status/op_stage = new/datum/surgery_status
-
-/* SURGERY STEPS */
-
-/datum/surgery_step
- // type path referencing the required tool for this step
- var/required_tool = null
-
- // type path referencing tools that can be used as substitude for this step
- var/list/allowed_tools = null
-
- // When multiple steps can be applied with the current tool etc., choose the one with higher priority
-
- // checks whether this step can be applied with the given user and target
- proc/can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return 0
-
- // does stuff to begin the step, usually just printing messages
- proc/begin_step(user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return
-
- // does stuff to end the step, which is normally print a message + do whatever this step changes
- proc/end_step(user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return
-
- // stuff that happens when the step fails
- proc/fail_step(user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return null
-
- // duration of the step
- var/min_duration = 0
- var/max_duration = 0
-
- // evil infection stuff that will make everyone hate me
- var/can_infect = 0
-
-// Build this list by iterating over all typesof(/datum/surgery_step) and sorting the results by priority
-var/global/list/surgery_steps = null
-
-proc/build_surgery_steps_list()
- surgery_steps = list()
- for(var/T in typesof(/datum/surgery_step)-/datum/surgery_step)
- var/datum/surgery_step/S = new T
- surgery_steps += S
-
-proc/spread_germs_to_organ(datum/organ/external/E, mob/living/carbon/human/user)
- if(!istype(user) || !istype(E)) return
-
- var/germ_level = user.germ_level
- if(user.gloves)
- germ_level = user.gloves.germ_level
-
- E.germ_level = germ_level
-
-
-//////////////////////////////////////////////////////////////////
-// COMMON STEPS //
-//////////////////////////////////////////////////////////////////
-/datum/surgery_step/generic/
- var/datum/organ/external/affected //affected organ
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if (target_zone == "eyes") //there are specific steps for eye surgery
- return 0
- if (!hasorgans(target))
- return 0
- affected = target.get_organ(target_zone)
- if (affected == null)
- return 0
- if (affected.status & ORGAN_DESTROYED)
- return 0
- if (affected.status & ORGAN_ROBOT)
- return 0
- return 1
-
-/datum/surgery_step/generic/cut_open
- required_tool = /obj/item/weapon/scalpel
-
- min_duration = 90
- max_duration = 110
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && affected.open == 0 && target_zone != "mouth"
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] starts the incision on [target]'s [affected.display_name] with \the [tool].", \
- "You start the incision on [target]'s [affected.display_name] with \the [tool].")
- target.custom_pain("You feel a horrible pain as if from a sharp knife in your [affected.display_name]!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\blue [user] has made an incision on [target]'s [affected.display_name] with \the [tool].", \
- "\blue You have made an incision on [target]'s [affected.display_name] with \the [tool].",)
- affected.open = 1
- affected.createwound(CUT, 1)
- spread_germs_to_organ(affected, user)
- if (target_zone == "head")
- target.brain_op_stage = 1
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, slicing open [target]'s [affected.display_name] in a wrong spot with \the [tool]!", \
- "\red Your hand slips, slicing open [target]'s [affected.display_name] in a wrong spot with \the [tool]!")
- affected.createwound(CUT, 10)
-
-/datum/surgery_step/generic/clamp_bleeders
- required_tool = /obj/item/weapon/hemostat
-
- min_duration = 40
- max_duration = 60
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && affected.open && (affected.status & ORGAN_BLEEDING)
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] starts clamping bleeders in [target]'s [affected.display_name] with \the [tool].", \
- "You start clamping bleeders in [target]'s [affected.display_name] with \the [tool].")
- target.custom_pain("The pain in your [affected.display_name] is maddening!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\blue [user] clamps bleeders in [target]'s [affected.display_name] with \the [tool].", \
- "\blue You clamp bleeders in [target]'s [affected.display_name] with \the [tool].")
- affected.clamp()
- affected.status &= ~ORGAN_BLEEDING
- spread_germs_to_organ(affected, user)
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [affected.display_name] with the \[tool]!", \
- "\red Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.display_name] with \the [tool]!",)
- affected.createwound(CUT, 10)
-
-/datum/surgery_step/generic/retract_skin
- required_tool = /obj/item/weapon/retractor
-
- min_duration = 30
- max_duration = 40
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && affected.open < 2 && !(affected.status & ORGAN_BLEEDING)
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- var/msg = "[user] starts to pry open the incision on [target]'s [affected.display_name] with \the [tool]."
- var/self_msg = "You start to pry open the incision on [target]'s [affected.display_name] with \the [tool]."
- if (target_zone == "chest")
- msg = "[user] starts to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]."
- self_msg = "You start to separate the ribcage and rearrange the organs in [target]'s torso with \the [tool]."
- if (target_zone == "groin")
- msg = "[user] starts to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]."
- self_msg = "You start to pry open the incision and rearrange the organs in [target]'s lower abdomen with \the [tool]."
- user.visible_message(msg, self_msg)
- target.custom_pain("It feels like the skin on your [affected.display_name] is on fire!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- var/msg = "\blue [user] keeps the incision open on [target]'s [affected.display_name] with \the [tool]."
- var/self_msg = "\blue You keep the incision open on [target]'s [affected.display_name] with \the [tool]."
- if (target_zone == "chest")
- msg = "\blue [user] keeps the ribcage open on [target]'s torso with \the [tool]."
- self_msg = "\blue You keep the ribcage open on [target]'s torso with \the [tool]."
- if (target_zone == "groin")
- msg = "\blue [user] keeps the incision open on [target]'s lower abdomen with \the [tool]."
- self_msg = "\blue You keep the incision open on [target]'s lower abdomen with \the [tool]."
- user.visible_message(msg, self_msg)
- affected.open = 2
- spread_germs_to_organ(affected, user)
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- var/msg = "\red [user]'s hand slips, tearing the edges of incision on [target]'s [affected.display_name] with \the [tool]!"
- var/self_msg = "\red Your hand slips, tearing the edges of incision on [target]'s [affected.display_name] with \the [tool]!"
- if (target_zone == "chest")
- msg = "\red [user]'s hand slips, damaging several organs [target]'s torso with \the [tool]!"
- self_msg = "\red Your hand slips, damaging several organs [target]'s torso with \the [tool]!"
- if (target_zone == "groin")
- msg = "\red [user]'s hand slips, damaging several organs [target]'s lower abdomen with \the [tool]"
- self_msg = "\red Your hand slips, damaging several organs [target]'s lower abdomen with \the [tool]!"
- user.visible_message(msg, self_msg)
- target.apply_damage(12, BRUTE, affected)
-
-/datum/surgery_step/generic/cauterize
- required_tool = /obj/item/weapon/cautery
-
- min_duration = 70
- max_duration = 100
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && affected.open && target_zone != "mouth"
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] is beginning to cauterize the incision on [target]'s [affected.display_name] with \the [tool]." , \
- "You are beginning to cauterize the incision on [target]'s [affected.display_name] with \the [tool].")
- target.custom_pain("Your [affected.display_name] is being burned!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\blue [user] cauterizes the incision on [target]'s [affected.display_name] with \the [tool].", \
- "\blue You cauterize the incision on [target]'s [affected.display_name] with \the [tool].")
- affected.open = 0
- affected.germ_level = 0
- affected.status &= ~ORGAN_BLEEDING
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, leaving a small burn on [target]'s [affected.display_name] with \the [tool]!", \
- "\red Your hand slips, leaving a small burn on [target]'s [affected.display_name] with \the [tool]!")
- target.apply_damage(3, BURN, affected)
-
-//////////////////////////////////////////////////////////////////
-// APPENDECTOMY //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/appendectomy/
- var/datum/organ/external/groin
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if (target_zone != "groin")
- return 0
- groin = target.get_organ("groin")
- if (!groin)
- return 0
- if (groin.open < 2)
- return 0
- return 1
-
-/datum/surgery_step/appendectomy/cut_appendix
- required_tool = /obj/item/weapon/scalpel
-
- min_duration = 70
- max_duration = 90
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.appendix == 0
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts to separating [target]'s appendix from the abdominal wall with \the [tool].", \
- "You start to separating [target]'s appendix from the abdominal wall with \the [tool]." )
- target.custom_pain("The pain in your abdomen is living hell!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] has separated [target]'s appendix with \the [tool]." , \
- "\blue You have separated [target]'s appendix with \the [tool].")
- target.op_stage.appendix = 1
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/groin = target.get_organ("groin")
- user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s abdomen with \the [tool]!", \
- "\red Your hand slips, slicing an artery inside [target]'s abdomen with \the [tool]!")
- groin.createwound(CUT, 50)
-
-/datum/surgery_step/appendectomy/remove_appendix
- required_tool = /obj/item/weapon/hemostat
-
- min_duration = 60
- max_duration = 80
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.appendix == 1
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts removing [target]'s appendix with \the [tool].", \
- "You start removing [target]'s appendix with \the [tool].")
- target.custom_pain("Someone's ripping out your bowels!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] has removed [target]'s appendix with \the [tool].", \
- "\blue You have removed [target]'s appendix with \the [tool].")
- var/app = 0
- for(var/datum/disease/appendicitis/appendicitis in target.viruses)
- app = 1
- appendicitis.cure()
- target.resistances += appendicitis
- if (app)
- new /obj/item/weapon/reagent_containers/food/snacks/appendix/inflamed(get_turf(target))
- else
- new /obj/item/weapon/reagent_containers/food/snacks/appendix(get_turf(target))
- target.op_stage.appendix = 2
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, nicking internal organs in [target]'s abdomen with \the [tool]!", \
- "\red Your hand slips, nicking internal organs in [target]'s abdomen with \the [tool]!")
- affected.createwound(BRUISE, 20)
-
-
-//////////////////////////////////////////////////////////////////
-// INTERNAL WOUND PATCHING //
-//////////////////////////////////////////////////////////////////
-
-
-/datum/surgery_step/fix_vein
- required_tool = /obj/item/weapon/FixOVein
-
- min_duration = 70
- max_duration = 90
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
-
- var/internal_bleeding = 0
- for(var/datum/wound/W in affected.wounds) if(W.internal)
- internal_bleeding = 1
- break
-
- return affected.open == 2 && internal_bleeding
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] starts patching the damaged vein in [target]'s [affected.display_name] with \the [tool]." , \
- "You start patching the damaged vein in [target]'s [affected.display_name] with \the [tool].")
- target.custom_pain("The pain in [affected.display_name] is unbearable!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\blue [user] has patched the damaged vein in [target]'s [affected.display_name] with \the [tool].", \
- "\blue You have patched the damaged vein in [target]'s [affected.display_name] with \the [tool].")
-
- for(var/datum/wound/W in affected.wounds) if(W.internal)
- affected.wounds -= W
- affected.update_damages()
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!" , \
- "\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!")
- affected.take_damage(5, 0)
-
-
-//////////////////////////////////////////////////////////////////
-// BONE SURGERY //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/glue_bone
- required_tool = /obj/item/weapon/bonegel
-
- min_duration = 50
- max_duration = 60
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- return affected.open == 2 && affected.stage == 0
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- if (affected.stage == 0)
- user.visible_message("[user] starts applying medication to the damaged bones in [target]'s [affected.display_name] with \the [tool]." , \
- "You start applying medication to the damaged bones in [target]'s [affected.display_name] with \the [tool].")
- target.custom_pain("Something in your [affected.display_name] is causing you a lot of pain!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\blue [user] applies some [tool] to [target]'s bone in [affected.display_name]", \
- "\blue You apply some [tool] to [target]'s bone in [affected.display_name] with \the [tool].")
- affected.stage = 1
- spread_germs_to_organ(affected, user)
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!" , \
- "\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!")
-
-/datum/surgery_step/set_bone
- required_tool = /obj/item/weapon/bonesetter
-
- min_duration = 60
- max_duration = 70
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- return affected.name != "head" && affected.open == 2 && affected.stage == 1
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] is beginning to set the bone in [target]'s [affected.display_name] in place with \the [tool]." , \
- "You are beginning to set the bone in [target]'s [affected.display_name] in place with \the [tool].")
- target.custom_pain("The pain in your [affected.display_name] is going to make you pass out!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- if (affected.status & ORGAN_BROKEN)
- user.visible_message("\blue [user] sets the bone in [target]'s [affected.display_name] in place with \the [tool].", \
- "\blue You set the bone in [target]'s [affected.display_name] in place with \the [tool].")
- affected.stage = 2
- spread_germs_to_organ(affected, user)
- else
- user.visible_message("\blue [user] sets the bone in [target]'s [affected.display_name]\red in the WRONG place with \the [tool].", \
- "\blue You set the bone in [target]'s [affected.display_name]\red in the WRONG place with \the [tool].")
- affected.fracture()
- spread_germs_to_organ(affected, user)
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, damaging the bone in [target]'s [affected.display_name] with \the [tool]!" , \
- "\red Your hand slips, damaging the bone in [target]'s [affected.display_name] with \the [tool]!")
- affected.createwound(BRUISE, 5)
-
-/datum/surgery_step/mend_skull
- required_tool = /obj/item/weapon/bonesetter
-
- min_duration = 60
- max_duration = 70
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- return affected.name == "head" && affected.open == 2 && affected.stage == 1
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] is beginning piece together [target]'s skull with \the [tool]." , \
- "You are beginning piece together [target]'s skull with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\blue [user] sets [target]'s skull with \the [tool]." , \
- "\blue You set [target]'s skull with \the [tool].")
- affected.stage = 2
- spread_germs_to_organ(affected, user)
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, damaging [target]'s face with \the [tool]!" , \
- "\red Your hand slips, damaging [target]'s face with \the [tool]!")
- var/datum/organ/external/head/h = affected
- h.createwound(BRUISE, 10)
- h.disfigured = 1
-
-/datum/surgery_step/finish_bone
- required_tool = /obj/item/weapon/bonegel
-
- min_duration = 50
- max_duration = 60
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- return affected.open == 2 && affected.stage == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] starts to finish mending the damaged bones in [target]'s [affected.display_name] with \the [tool].", \
- "You start to finish mending the damaged bones in [target]'s [affected.display_name] with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\blue [user] has mended the damaged bones in [target]'s [affected.display_name] with \the [tool]." , \
- "\blue You have mended the damaged bones in [target]'s [affected.display_name] with \the [tool]." )
- affected.status &= ~ORGAN_BROKEN
- affected.status &= ~ORGAN_SPLINTED
- affected.stage = 0
- affected.perma_injury = 0
- spread_germs_to_organ(affected, user)
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!" , \
- "\red Your hand slips, smearing [tool] in the incision in [target]'s [affected.display_name]!")
-
-//////////////////////////////////////////////////////////////////
-// EYE SURGERY //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/eye
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if (!hasorgans(target))
- return 0
- var/datum/organ/external/affected = target.get_organ(target_zone)
- if (!affected)
- return 0
- return target_zone == "eyes"
-
-/datum/surgery_step/eye/cut_open
- required_tool = /obj/item/weapon/scalpel
-
- min_duration = 90
- max_duration = 110
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..()
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts to separate the corneas on [target]'s eyes with \the [tool].", \
- "You start to separate the corneas on [target]'s eyes with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] has separated the corneas on [target]'s eyes with \the [tool]." , \
- "\blue You have separated the corneas on [target]'s eyes with \the [tool].",)
- target.op_stage.eyes = 1
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, slicing [target]'s eyes wth \the [tool]!" , \
- "\red Your hand slips, slicing [target]'s eyes wth \the [tool]!" )
- affected.createwound(CUT, 10)
-
-/datum/surgery_step/eye/lift_eyes
- required_tool = /obj/item/weapon/retractor
-
- min_duration = 30
- max_duration = 40
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.eyes == 1
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts lifting corneas from [target]'s eyes with \the [tool].", \
- "You start lifting corneas from [target]'s eyes with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] has lifted the corneas from [target]'s eyes from with \the [tool]." , \
- "\blue You has lifted the corneas from [target]'s eyes from with \the [tool]." )
- target.op_stage.eyes = 2
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, damaging [target]'s eyes with \the [tool]!", \
- "\red Your hand slips, damaging [target]'s eyes with \the [tool]!")
- target.apply_damage(10, BRUTE, affected)
-
-/datum/surgery_step/eye/mend_eyes
- required_tool = /obj/item/weapon/hemostat
-
- min_duration = 80
- max_duration = 100
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.eyes == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts mending the nerves and lenses in [target]'s eyes with \the [tool].", \
- "You start mending the nerves and lenses in [target]'s eyes with the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] mends the nerves and lenses in [target]'s with \the [tool]." , \
- "\blue You mend the nerves and lenses in [target]'s with \the [tool].")
- target.op_stage.eyes = 3
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, stabbing \the [tool] into [target]'s eye!", \
- "\red Your hand slips, stabbing \the [tool] into [target]'s eye!")
- target.apply_damage(10, BRUTE, affected)
-
-/datum/surgery_step/eye/cauterize
- required_tool = /obj/item/weapon/cautery
-
- min_duration = 70
- max_duration = 100
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..()
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] is beginning to cauterize the incision around [target]'s eyes with \the [tool]." , \
- "You are beginning to cauterize the incision around [target]'s eyes with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] cauterizes the incision around [target]'s eyes with \the [tool].", \
- "\blue You cauterize the incision around [target]'s eyes with \the [tool].")
- if (target.op_stage.eyes == 3)
- target.sdisabilities &= ~BLIND
- target.eye_stat = 0
- target.op_stage.eyes = 0
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, searing [target]'s eyes with \the [tool]!", \
- "\red Your hand slips, searing [target]'s eyes with \the [tool]!")
- target.apply_damage(5, BURN, affected)
- target.eye_stat += 5
-
-//////////////////////////////////////////////////////////////////
-// FACE SURGERY //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/face
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if (!hasorgans(target))
- return 0
- var/datum/organ/external/affected = target.get_organ(target_zone)
- if (!affected)
- return 0
- return target_zone == "mouth" && affected.open == 2 && !(affected.status & ORGAN_BLEEDING)
-
-/datum/surgery_step/generic/cut_face
- required_tool = /obj/item/weapon/scalpel
-
- min_duration = 90
- max_duration = 110
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target_zone == "mouth" && target.op_stage.face == 0
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts to cut open [target]'s face and neck with \the [tool].", \
- "You start to cut open [target]'s face and neck with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] has cut open [target]'s face and neck with \the [tool]." , \
- "\blue You have cut open [target]'s face and neck with \the [tool].",)
- target.op_stage.face = 1
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, slicing [target]'s throat wth \the [tool]!" , \
- "\red Your hand slips, slicing [target]'s throat wth \the [tool]!" )
- affected.createwound(CUT, 60)
- target.losebreath += 10
-
-/datum/surgery_step/face/mend_vocal
- required_tool = /obj/item/weapon/hemostat
-
- min_duration = 70
- max_duration = 90
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.face == 1
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts mending [target]'s vocal cords with \the [tool].", \
- "You start mending [target]'s vocal cords with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] mends [target]'s vocal cords with \the [tool].", \
- "\blue You mend [target]'s vocal cords with \the [tool].")
- target.op_stage.face = 2
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, clamping [target]'s trachea shut for a moment with \the [tool]!", \
- "\red Your hand slips, clamping [user]'s trachea shut for a moment with \the [tool]!")
- target.losebreath += 10
-
-/datum/surgery_step/face/fix_face
- required_tool = /obj/item/weapon/retractor
-
- min_duration = 80
- max_duration = 100
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.face == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts pulling skin on [target]'s face back in place with \the [tool].", \
- "You start pulling skin on [target]'s face back in place with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] pulls skin on [target]'s face back in place with \the [tool].", \
- "\blue You pull skin on [target]'s face back in place with \the [tool].")
- target.op_stage.face = 3
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, tearing skin on [target]'s face with \the [tool]!", \
- "\red Your hand slips, tearing skin on [target]'s face with \the [tool]!")
- target.apply_damage(10, BRUTE, affected)
-
-/datum/surgery_step/face/cauterize
- required_tool = /obj/item/weapon/cautery
-
- min_duration = 70
- max_duration = 100
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.op_stage.face > 0
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] is beginning to cauterize the incision on [target]'s face and neck with \the [tool]." , \
- "You are beginning to cauterize the incision on [target]'s face and neck with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\blue [user] cauterizes the incision on [target]'s face and neck with \the [tool].", \
- "\blue You cauterize the incision on [target]'s face and neck with \the [tool].")
- affected.open = 0
- affected.status &= ~ORGAN_BLEEDING
- if (target.op_stage.face == 3)
- var/datum/organ/external/head/h = affected
- h.disfigured = 0
- target.op_stage.face = 0
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, leaving a small burn on [target]'s face with \the [tool]!", \
- "\red Your hand slips, leaving a small burn on [target]'s face with \the [tool]!")
- target.apply_damage(4, BURN, affected)
-
-//////////////////////////////////////////////////////////////////
-// BRAIN SURGERY //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/brain/
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return target_zone == "head" && hasorgans(target)
-
-/datum/surgery_step/brain/saw_skull
- required_tool = /obj/item/weapon/circular_saw
-
- min_duration = 50
- max_duration = 70
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target_zone == "head" && target.brain_op_stage == 1
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] begins to cut through [target]'s skull with \the [tool].", \
- "You begin to cut through [target]'s skull with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] has cut through [target]'s skull open with \the [tool].", \
- "\blue You have cut through [target]'s skull open with \the [tool].")
- target.brain_op_stage = 2
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, cracking [target]'s skull with \the [tool]!" , \
- "\red Your hand slips, cracking [target]'s skull with \the [tool]!" )
- target.apply_damage(10, BRUTE, "head")
-
-/datum/surgery_step/brain/cut_brain
- required_tool = /obj/item/weapon/scalpel
-
- min_duration = 80
- max_duration = 100
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.brain_op_stage == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts separating connections to [target]'s brain with \the [tool].", \
- "You start separating connections to [target]'s brain with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] separates connections to [target]'s brain with \the [tool].", \
- "\blue You separate connections to [target]'s brain with \the [tool].")
- target.brain_op_stage = 3
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, cutting a vein in [target]'s brain with \the [tool]!", \
- "\red Your hand slips, cutting a vein in [target]'s brain with \the [tool]!")
- target.apply_damage(50, BRUTE, "head")
-
-/datum/surgery_step/brain/saw_spine
- required_tool = /obj/item/weapon/circular_saw
-
- min_duration = 50
- max_duration = 70
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.brain_op_stage == 3
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts separating [target]'s brain from \his spine with \the [tool].", \
- "You start separating [target]'s brain from spine with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] separates [target]'s brain from \his spine with \the [tool].", \
- "\blue You separate [target]'s brain from spine with \the [tool].")
-
- user.attack_log += "\[[time_stamp()]\] Debrained [target.name] ([target.ckey]) with [tool.name] (INTENT: [uppertext(user.a_intent)])"
- target.attack_log += "\[[time_stamp()]\] Debrained by [user.name] ([user.ckey]) with [tool.name] (INTENT: [uppertext(user.a_intent)])"
-
- log_admin("ATTACK: [user] ([user.ckey]) debrained [target] ([target.ckey]) with [tool].")
- message_admins("ATTACK: [user] ([user.ckey]) debrained [target] ([target.ckey]) with [tool].")
- log_attack("[user.name] ([user.ckey]) debrained [target.name] ([target.ckey]) with [tool.name] (INTENT: [uppertext(user.a_intent)])")
-
- var/obj/item/brain/B = new(target.loc)
- B.transfer_identity(target)
-
- target:brain_op_stage = 4.0
- target.death()//You want them to die after the brain was transferred, so not to trigger client death() twice.
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, cutting a vein in [target]'s brain with \the [tool]!", \
- "\red Your hand slips, cutting a vein in [target]'s brain with \the [tool]!")
- target.apply_damage(30, BRUTE, "head")
-
-
-//////////////////////////////////////////////////////////////////
-// METROID CORE EXTRACTION //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/metroid/
- can_use(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool)
- return istype(target, /mob/living/carbon/metroid/) && target.stat == 2
-
-/datum/surgery_step/metroid/cut_flesh
- required_tool = /obj/item/weapon/scalpel
-
- min_duration = 30
- max_duration = 50
-
- can_use(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool)
- return ..() && target.brain_op_stage == 0
-
- begin_step(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts cutting [target]'s flesh with \the [tool].", \
- "You start cutting [target]'s flesh with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] cuts [target]'s flesh with \the [tool].", \
- "\blue You cut [target]'s flesh with \the [tool], exposing the cores")
- target.brain_op_stage = 1
-
- fail_step(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, tearing [target]'s flesh with \the [tool]!", \
- "\red Your hand slips, tearing [target]'s flesh with \the [tool]!")
-
-/datum/surgery_step/metroid/cut_innards
- required_tool = /obj/item/weapon/scalpel
-
- min_duration = 30
- max_duration = 50
-
- can_use(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool)
- return ..() && target.brain_op_stage == 1
-
- begin_step(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts cutting [target]'s silky innards apart with \the [tool].", \
- "You start cutting [target]'s silky innards apart with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] cuts [target]'s innards apart with \the [tool], exposing the cores", \
- "\blue You cut [target]'s innards apart with \the [tool], exposing the cores")
- target.brain_op_stage = 2
-
- fail_step(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, tearing [target]'s innards with \the [tool]!", \
- "\red Your hand slips, tearing [target]'s innards with \the [tool]!")
-
-/datum/surgery_step/metroid/saw_core
- required_tool = /obj/item/weapon/circular_saw
-
- min_duration = 50
- max_duration = 70
-
- can_use(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool)
- return ..() && target.brain_op_stage == 2 && target.cores > 0
-
- begin_step(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts cutting out one of [target]'s cores with \the [tool].", \
- "You start cutting out one of [target]'s cores with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool)
- target.cores--
- user.visible_message("\blue [user] cuts out one of [target]'s cores with \the [tool].",, \
- "\blue You cut out one of [target]'s cores with \the [tool]. [target.cores] cores left.")
- if(target.cores >= 0)
- new/obj/item/metroid_core(target.loc)
- if(target.cores <= 0)
- target.icon_state = "baby roro dead-nocore"
-
- fail_step(mob/user, mob/living/carbon/metroid/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, failing to cut core out!", \
- "\red Your hand slips, failing to cut core out!")
-
-//////////////////////////////////////////////////////////////////
-// LIMB SURGERY //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/limb/
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if (!hasorgans(target))
- return 0
- var/datum/organ/external/affected = target.get_organ(target_zone)
- if (!affected)
- return 0
- if (!(affected.status & ORGAN_DESTROYED))
- return 0
- if (affected.parent)
- if (affected.parent.status & ORGAN_DESTROYED)
- return 0
- return 1
-
-
-/datum/surgery_step/limb/cut
- required_tool = /obj/item/weapon/scalpel
-
- min_duration = 80
- max_duration = 100
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] starts cutting away flesh where [target]'s [affected.display_name] used to be with \the [tool].", \
- "You start cutting away flesh where [target]'s [affected.display_name] used to be with \the [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\blue [user] cuts away flesh where [target]'s [affected.display_name] used to be with \the [tool].", \
- "\blue You cut away flesh where [target]'s [affected.display_name] used to be with \the [tool].")
- affected.status |= ORGAN_CUT_AWAY
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- if (affected.parent)
- affected = affected.parent
- user.visible_message("\red [user]'s hand slips, cutting [target]'s [affected.display_name] open!", \
- "\red Your hand slips, cutting [target]'s [affected.display_name] open!")
- affected.createwound(CUT, 10)
-
-
-/datum/surgery_step/limb/mend
- required_tool = /obj/item/weapon/retractor
-
- min_duration = 80
- max_duration = 100
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- return ..() && affected.status & ORGAN_CUT_AWAY
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] is beginning reposition flesh and nerve endings where where [target]'s [affected.display_name] used to be with [tool].", \
- "You start repositioning flesh and nerve endings where where [target]'s [affected.display_name] used to be with [tool].")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\blue [user] has finished repositioning flesh and nerve endings where [target]'s [affected.display_name] used to be with [tool].", \
- "\blue You have finished repositioning flesh and nerve endings where [target]'s [affected.display_name] used to be with [tool].")
- affected.open = 3
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- if (affected.parent)
- affected = affected.parent
- user.visible_message("\red [user]'s hand slips, tearing flesh on [target]'s [affected.display_name]!", \
- "\red Your hand slips, tearing flesh on [target]'s [affected.display_name]!")
- target.apply_damage(10, BRUTE, affected)
-
-
-/datum/surgery_step/limb/prepare
- required_tool = /obj/item/weapon/cautery
-
- min_duration = 60
- max_duration = 70
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- return ..() && affected.open == 3
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] starts adjusting area around [target]'s [affected.display_name] with \the [tool].", \
- "You start adjusting area around [target]'s [affected.display_name] with \the [tool]..")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\blue [user] has finished adjusting the area around [target]'s [affected.display_name] with \the [tool].", \
- "\blue You have finished adjusting the area around [target]'s [affected.display_name] with \the [tool].")
- affected.status |= ORGAN_ATTACHABLE
- affected.amputated = 1
- affected.setAmputatedTree()
- affected.open = 0
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- if (affected.parent)
- affected = affected.parent
- user.visible_message("\red [user]'s hand slips, searing [target]'s [affected.display_name]!", \
- "\red Your hand slips, searing [target]'s [affected.display_name]!")
- target.apply_damage(10, BURN, affected)
-
-
-/datum/surgery_step/limb/attach
- required_tool = /obj/item/robot_parts
-
- min_duration = 80
- max_duration = 100
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/robot_parts/p = tool
- if (p.part)
- if (!(target_zone in p.part))
- return 0
- var/datum/organ/external/affected = target.get_organ(target_zone)
- return ..() && affected.status & ORGAN_ATTACHABLE
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("[user] starts attaching [tool] where [target]'s [affected.display_name] used to be.", \
- "You start attaching [tool] where [target]'s [affected.display_name] used to be.")
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\blue [user] has attached [tool] where [target]'s [affected.display_name] used to be.", \
- "\blue You have attached [tool] where [target]'s [affected.display_name] used to be.")
- affected.robotize()
- target.update_body()
- target.updatehealth()
- target.UpdateDamageIcon()
- del(tool)
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- user.visible_message("\red [user]'s hand slips, damaging connectors on [target]'s [affected.display_name]!", \
- "\red Your hand slips, damaging connectors on [target]'s [affected.display_name]!")
- target.apply_damage(10, BRUTE, affected)
-
-
-//////////////////////////////////////////////////////////////////
-// RIBCAGE SURGERY(LUNGS AND ALIENS) //
-//////////////////////////////////////////////////////////////////
-
-/datum/surgery_step/ribcage
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return target_zone == "chest"
-
-/datum/surgery_step/ribcage/saw_ribcage
- required_tool = /obj/item/weapon/circular_saw
-
- min_duration = 50
- max_duration = 70
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- return ..() && target.ribcage_op_stage == 0 && affected.open >= 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] begins to cut through [target]'s ribcage with \the [tool].", \
- "You begin to cut through [target]'s ribcage with \the [tool].")
- target.custom_pain("Something hurts horribly in your chest!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\blue [user] has cut through [target]'s ribcage open with \the [tool].", \
- "\blue You have cut through [target]'s ribcage open with \the [tool].")
- target.ribcage_op_stage = 1
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user]'s hand slips, cracking [target]'s ribcage with \the [tool]!" , \
- "\red Your hand slips, cracking [target]'s ribcage with \the [tool]!" )
-
-
-/datum/surgery_step/ribcage/retract_ribcage
- required_tool = /obj/item/weapon/retractor
-
- min_duration = 30
- max_duration = 40
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.ribcage_op_stage == 1
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "[user] starts to force open the ribcage in [target]'s torso with \the [tool]."
- var/self_msg = "You start to force open the ribcage in [target]'s torso with \the [tool]."
- user.visible_message(msg, self_msg)
- target.custom_pain("Something hurts horribly in your chest!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "\blue [user] forces open [target]'s ribcage with \the [tool]."
- var/self_msg = "\blue You force open [target]'s ribcage with \the [tool]."
- user.visible_message(msg, self_msg)
- target.ribcage_op_stage = 2
-
- // Whoops!
- if(prob(10))
- var/datum/organ/external/affected = target.get_organ(target_zone)
- affected.fracture()
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "\red [user]'s hand slips, breaking [target]'s ribcage!"
- var/self_msg = "\red Your hand slips, breaking [target]'s ribcage!"
- user.visible_message(msg, self_msg)
- var/datum/organ/external/affected = target.get_organ(target_zone)
- affected.fracture()
-
-/datum/surgery_step/ribcage/close_ribcage
- required_tool = /obj/item/weapon/retractor
-
- min_duration = 20
- max_duration = 40
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.ribcage_op_stage == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "[user] starts bending [target]'s ribcage back into place with \the [tool]."
- var/self_msg = "You start bending [target]'s ribcage back into place with \the [tool]."
- user.visible_message(msg, self_msg)
- target.custom_pain("Something hurts horribly in your chest!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "\blue [user] bends [target]'s ribcage back into place with \the [tool]."
- var/self_msg = "\blue You bend [target]'s ribcage back into place with \the [tool]."
- user.visible_message(msg, self_msg)
-
- target.ribcage_op_stage = 1
-
-/datum/surgery_step/ribcage/mend_ribcage
- required_tool = /obj/item/weapon/bonegel
-
- min_duration = 20
- max_duration = 40
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.ribcage_op_stage == 1
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "[user] starts applying \the [tool] to [target]'s ribcage."
- var/self_msg = "You start applying \the [tool] to [target]'s ribcage."
- user.visible_message(msg, self_msg)
- target.custom_pain("Something hurts horribly in your chest!",1)
-
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "\blue [user] applied \the [tool] to [target]'s ribcage."
- var/self_msg = "\blue You applied \the [tool] to [target]'s ribcage."
- user.visible_message(msg, self_msg)
-
- target.ribcage_op_stage = 0
-
-
-/datum/surgery_step/ribcage/remove_embryo
- required_tool = /obj/item/weapon/hemostat
-
- min_duration = 80
- max_duration = 100
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/embryo = 0
- for(var/datum/disease/alien_embryo/A in target.viruses)
- embryo = 1
- break
- return ..() && embryo && target.ribcage_op_stage == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "[user] starts to pull something out from [target]'s ribcage with \the [tool]."
- var/self_msg = "You start to pull something out from [target]'s ribcage with \the [tool]."
- user.visible_message(msg, self_msg)
- target.custom_pain("Something hurts horribly in your chest!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user] rips the larva out of [target]'s ribcage!",
- "You rip the larva out of [target]'s ribcage!")
-
- var/mob/living/carbon/alien/larva/stupid = new(target.loc)
- stupid.death(0)
-
- for(var/datum/disease/alien_embryo in target.viruses)
- alien_embryo.cure()
-
-/datum/surgery_step/ribcage/fix_lungs
- required_tool = /obj/item/weapon/scalpel
-
- min_duration = 70
- max_duration = 90
-
- can_use(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- return ..() && target.is_lung_ruptured() && target.ribcage_op_stage == 2
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts mending the rupture in [target]'s lungs with \the [tool].", \
- "You start mending the rupture in [target]'s lungs with \the [tool]." )
- target.custom_pain("The pain in your chest is living hell!",1)
-
- end_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/chest/affected = target.get_organ("chest")
- user.visible_message("\blue [user] mends the rupture in [target]'s lungs with \the [tool].", \
- "\blue You mend the rupture in [target]'s lungs with \the [tool]." )
- affected.ruptured_lungs = 0
-
- fail_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/chest/affected = target.get_organ("chest")
- user.visible_message("\red [user]'s hand slips, slicing an artery inside [target]'s chest with \the [tool]!", \
- "\red Your hand slips, slicing an artery inside [target]'s chest with \the [tool]!")
- affected.createwound(CUT, 20)
-
diff --git a/code/WorkInProgress/virus2/base.dm b/code/WorkInProgress/virus2/base.dm
index 7950389ad32..3d8954fc996 100644
--- a/code/WorkInProgress/virus2/base.dm
+++ b/code/WorkInProgress/virus2/base.dm
@@ -235,7 +235,6 @@ proc/airborne_can_reach(turf/source, turf/target)
if(prob(1))
majormutate()
if(mob.reagents.has_reagent("spaceacillin"))
- mob.reagents.remove_reagent("spaceacillin",0.3)
return
if(mob.reagents.has_reagent("virusfood"))
mob.reagents.remove_reagent("virusfood",0.1)
@@ -599,4 +598,4 @@ proc/airborne_can_reach(turf/source, turf/target)
getrandomeffect_greater()
/proc/dprob(var/p)
- return(prob(sqrt(p)) && prob(sqrt(p)))
\ No newline at end of file
+ return(prob(sqrt(p)) && prob(sqrt(p)))
diff --git a/code/ZAS/Airflow.dm b/code/ZAS/Airflow.dm
index e2edcaac7a2..167d4368b3c 100644
--- a/code/ZAS/Airflow.dm
+++ b/code/ZAS/Airflow.dm
@@ -148,7 +148,7 @@ proc/Airflow(zone/A, zone/B)
//Check for knocking people over
if(ismob(M) && n > vsc.airflow_stun_pressure)
- if(M:nodamage) continue
+ if(M:status_flags & GODMODE) continue
M:airflow_stun()
if(M.check_airflow_movable(n))
@@ -172,7 +172,7 @@ proc/Airflow(zone/A, zone/B)
if(M.last_airflow > world.time - vsc.airflow_delay) continue
if(ismob(M) && abs(n) > vsc.airflow_medium_pressure)
- if(M:nodamage) continue
+ if(M:status_flags & GODMODE) continue
M:airflow_stun()
if(M.check_airflow_movable(abs(n)))
@@ -206,8 +206,9 @@ proc/AirflowSpace(zone/A)
if(M.last_airflow > world.time - vsc.airflow_delay) continue
if(ismob(M) && n > vsc.airflow_stun_pressure)
- if(M:nodamage) continue
- M:airflow_stun()
+ var/mob/O = M
+ if(O.status_flags & GODMODE) continue
+ O.airflow_stun()
if(M.check_airflow_movable(n))
@@ -241,7 +242,7 @@ atom/movable
if(airflow_dest == loc)
step_away(src,loc)
if(ismob(src))
- if(src:nodamage)
+ if(src:status_flags & GODMODE)
return
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
@@ -306,7 +307,7 @@ atom/movable
if(airflow_dest == loc)
step_away(src,loc)
if(ismob(src))
- if(src:nodamage)
+ if(src:status_flags & GODMODE)
return
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
diff --git a/code/ZAS/FEA_gas_mixture.dm b/code/ZAS/FEA_gas_mixture.dm
index 05bb2e4e60f..a4104ab01c7 100644
--- a/code/ZAS/FEA_gas_mixture.dm
+++ b/code/ZAS/FEA_gas_mixture.dm
@@ -4,6 +4,13 @@ What are the archived variables for?
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,toxins) \
+ (carbon_dioxide*SPECIFIC_HEAT_CDO + (oxygen+nitrogen)*SPECIFIC_HEAT_AIR + toxins*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
diff --git a/code/ZAS/Variable Settings.dm b/code/ZAS/Variable Settings.dm
index 9b02ec553e6..592be10d067 100644
--- a/code/ZAS/Variable Settings.dm
+++ b/code/ZAS/Variable Settings.dm
@@ -280,8 +280,8 @@ pl_control
else if(istext(vars["[V]_RANDOM"]))
var/txt = vars["[V]_RANDOM"]
if(findtextEx(txt,"PROB"))
- txt = dd_text2list(txt,"/")
- txt[1] = dd_replacetext(txt[1],"PROB","")
+ txt = text2list(txt,"/")
+ txt[1] = replacetext(txt[1],"PROB","")
var/p = text2num(txt[1])
var/r = txt[2]
if(prob(p))
@@ -289,8 +289,8 @@ pl_control
else
newvalue = vars[V]
else if(findtextEx(txt,"PICK"))
- txt = dd_replacetext(txt,"PICK","")
- txt = dd_text2list(txt,",")
+ txt = replacetext(txt,"PICK","")
+ txt = text2list(txt,",")
newvalue = pick(txt)
else
newvalue = roll(txt)
diff --git a/code/ZAS/ZAS_Zones.dm b/code/ZAS/ZAS_Zones.dm
index afda25eba8c..b219a10b132 100644
--- a/code/ZAS/ZAS_Zones.dm
+++ b/code/ZAS/ZAS_Zones.dm
@@ -16,6 +16,9 @@ zone
last_update = 0
progress = "nothing"
+ // To make sure you're not spammed to death by airflow sound effects
+ tmp/playsound_cooldown = 0
+
//CREATION AND DELETION
New(turf/start)
. = ..()
@@ -33,7 +36,7 @@ zone
if(!istype(T,/turf/simulated))
AddTurf(T)
- //Generate the gas_mixture for use in this zone by using the average of the gases
+ //Generate the gas_mixture for use in txhis zone by using the average of the gases
//defined at startup.
air = new
var/members = contents.len
@@ -148,8 +151,10 @@ zone/proc/process()
//Sometimes explosions will cause the air to be deleted for some reason.
if(!air)
air = new()
- air.adjust(MOLES_O2STANDARD, 0, MOLES_N2STANDARD, 0, list())
+ air.oxygen = MOLES_O2STANDARD
+ air.nitrogen = MOLES_N2STANDARD
air.temperature = T0C
+ air.total_moles()
world.log << "Air object lost in zone. Regenerating."
progress = "problem with: ShareSpace()"
@@ -161,6 +166,16 @@ zone/proc/process()
RemoveTurf(T)
if(unsimulated_tiles)
var/moved_air = ShareSpace(air,unsimulated_tiles)
+
+ // Only play a sound effect every once in a while
+ if(playsound_cooldown <= world.time)
+ // Play a nice sound effect at one of the bordering turfs
+
+ playsound_cooldown = world.time + rand(30, 70)
+
+ var/turf/random_border = pick(contents)
+ play_wind_sound(random_border, abs(moved_air))
+
if(moved_air > vsc.airflow_lightest_pressure)
AirflowSpace(src)
@@ -239,7 +254,17 @@ zone/proc/process()
for(var/zone/Z in connected_zones)
if(air && Z.air)
//Ensure we're not doing pointless calculations on equilibrium zones.
- if(abs(air.total_moles() - Z.air.total_moles()) > 0.1 || abs(air.temperature - Z.air.temperature) > 0.1)
+ var/moles_delta = abs(air.total_moles() - Z.air.total_moles())
+ if(moles_delta > 0.1)
+ // Only play a sound effect every once in a while
+ if(playsound_cooldown <= world.time)
+ // Play a nice sound effect at one of the bordering turfs
+
+ playsound_cooldown = world.time + rand(30, 70)
+
+ var/turf/random_border = pick(contents)
+ play_wind_sound(random_border, abs(moles_delta))
+ if(moles_delta > 0.1 || abs(air.temperature - Z.air.temperature) > 0.1)
if(abs(Z.air.return_pressure() - air.return_pressure()) > vsc.airflow_lightest_pressure)
Airflow(src,Z)
ShareRatio( air , Z.air , connected_zones[Z] )
@@ -255,7 +280,7 @@ var/list/sharing_lookup_table = list(0.06, 0.11, 0.15, 0.18, 0.20, 0.21)
proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
//Shares a specific ratio of gas between mixtures using simple weighted averages.
var
- ratio = 0.21
+ ratio = 0.50
size = max(1,A.group_multiplier)
share_size = max(1,B.group_multiplier)
@@ -281,9 +306,6 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
temp_avg = (A.temperature * full_heat_capacity + B.temperature * s_full_heat_capacity) / (full_heat_capacity + s_full_heat_capacity)
- if(sharing_lookup_table.len >= connecting_tiles) //6 or more interconnecting tiles will max at 42% of air moved per tick.
- ratio = sharing_lookup_table[connecting_tiles]
-
A.oxygen = max(0, (A.oxygen - oxy_avg) * (1-ratio) + oxy_avg )
A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1-ratio) + nit_avg )
A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg )
@@ -338,37 +360,34 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles)
unsim_temperature += T.temperature/unsimulated_tiles.len
var
- ratio = 0.21
+ // Depressurize very, very fast(it's fine since many rooms are internally multiple zones)
+ ratio = 0.50
old_pressure = A.return_pressure()
size = max(1,A.group_multiplier)
share_size = max(1,unsimulated_tiles.len)
- full_oxy = A.oxygen * size
- full_nitro = A.nitrogen * size
- full_co2 = A.carbon_dioxide * size
- full_plasma = A.toxins * size
+ //full_oxy = A.oxygen * size
+ //full_nitro = A.nitrogen * size
+ //full_co2 = A.carbon_dioxide * size
+ //full_plasma = A.toxins * size
- full_heat_capacity = A.heat_capacity() * size
+ //full_heat_capacity = A.heat_capacity() * size
- oxy_avg = (full_oxy + unsim_oxygen) / (size + share_size)
- nit_avg = (full_nitro + unsim_nitrogen) / (size + share_size)
- co2_avg = (full_co2 + unsim_co2) / (size + share_size)
- plasma_avg = (full_plasma + unsim_plasma) / (size + share_size)
+ oxy_avg = unsim_oxygen//(full_oxy + unsim_oxygen) / (size + share_size)
+ nit_avg = unsim_nitrogen//(full_nitro + unsim_nitrogen) / (size + share_size)
+ co2_avg = unsim_co2//(full_co2 + unsim_co2) / (size + share_size)
+ plasma_avg = unsim_plasma//(full_plasma + unsim_plasma) / (size + share_size)
- temp_avg = (A.temperature * full_heat_capacity + unsim_temperature * unsim_heat_capacity) / (full_heat_capacity + unsim_heat_capacity)
-
- if(sharing_lookup_table.len >= unsimulated_tiles.len) //6 or more interconnecting tiles will max at 42% of air moved per tick.
- ratio = sharing_lookup_table[unsimulated_tiles.len]
- ratio *= 2
A.oxygen = max(0, (A.oxygen - oxy_avg) * (1-ratio) + oxy_avg )
A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1-ratio) + nit_avg )
A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg )
A.toxins = max(0, (A.toxins - plasma_avg) * (1-ratio) + plasma_avg )
- A.temperature = max(TCMB, (A.temperature - temp_avg) * (1-ratio) + temp_avg )
+ // EXPERIMENTAL: Disable space being cold
+ //A.temperature = max(TCMB, (A.temperature - temp_avg) * (1-ratio) + temp_avg )
for(var/datum/gas/G in A.trace_gases)
var/G_avg = (G.moles*size + 0) / (size+share_size)
@@ -458,6 +477,21 @@ zone/proc/Rebuild()
if(istype(T) && T.zone && S.CanPass(null, T, 0, 0))
T.zone.AddTurf(S)
+proc/play_wind_sound(var/turf/random_border, var/n)
+ if(random_border)
+ var/windsound = 'sound/effects/wind/wind_2_1.ogg'
+ switch(n)
+ if(0 to 30)
+ windsound = pick('sound/effects/wind/wind_2_1.ogg', 'sound/effects/wind/wind_2_2.ogg')
+ if(31 to 40)
+ windsound = pick('sound/effects/wind/wind_3_1.ogg')
+ if(41 to 60)
+ windsound = pick('sound/effects/wind/wind_4_1.ogg', 'sound/effects/wind/wind_4_2.ogg')
+ if(61 to 1000000)
+ windsound = pick('sound/effects/wind/wind_5_1.ogg')
+
+ playsound(random_border, windsound, 50, 1, 1)
+
//UNUSED
/*
zone/proc/connected_zones()
@@ -474,4 +508,4 @@ zone/proc/connected_zones()
.[Z]++
else
. += Z
- .[Z] = 1*/
\ No newline at end of file
+ .[Z] = 1*/
diff --git a/code/ZAS_defines.dm b/code/ZAS_defines.dm
deleted file mode 100644
index 6c14fafad4d..00000000000
--- a/code/ZAS_defines.dm
+++ /dev/null
@@ -1,89 +0,0 @@
-//from setup.dm, which was removed in tgcode
-
-#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)
-
-#define MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND 0.012
-#define MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND 4
- //Minimum temperature difference before group processing is suspended
-#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
-
-#define FLOOR_HEAT_TRANSFER_COEFFICIENT 0.08
-#define WALL_HEAT_TRANSFER_COEFFICIENT 0.03
-#define SPACE_HEAT_TRANSFER_COEFFICIENT 0.20 //a hack to partly simulate radiative heat
-#define OPEN_HEAT_TRANSFER_COEFFICIENT 0.40
-#define WINDOW_HEAT_TRANSFER_COEFFICIENT 0.10 //a hack for now
- //Must be between 0 and 1. Values closer to 1 equalize temperature faster
- //Should not exceed 0.4 else strange heat flow occur
-
-#define FIRE_MINIMUM_TEMPERATURE_TO_SPREAD 150+T0C
-#define FIRE_MINIMUM_TEMPERATURE_TO_EXIST 100+T0C
-#define FIRE_SPREAD_RADIOSITY_SCALE 0.85
-#define FIRE_CARBON_ENERGY_RELEASED 500000 //Amount of heat released per mole of burnt carbon into the tile
-#define FIRE_PLASMA_ENERGY_RELEASED 3000000 //Amount of heat released per mole of burnt plasma into the tile
-#define FIRE_GROWTH_RATE 25000 //For small fires
-
-//Plasma fire properties
-#define PLASMA_MINIMUM_BURN_TEMPERATURE 100+T0C
-#define PLASMA_UPPER_TEMPERATURE 1370+T0C
-#define PLASMA_MINIMUM_OXYGEN_NEEDED 2
-#define PLASMA_MINIMUM_OXYGEN_PLASMA_RATIO 30
-#define PLASMA_OXYGEN_FULLBURN 10
-
-#define T0C 273.15 // 0degC
-#define T20C 293.15 // 20degC
-#define TCMB 2.7 // -270.3degC
-
-#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 aboe threshold
- // was 2 atm
-
-#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 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
-
-#define O2STANDARD 0.21
-#define N2STANDARD 0.79
-
-#define MOLES_O2STANDARD MOLES_CELLSTANDARD*O2STANDARD // O2 standard value (21%)
-#define MOLES_N2STANDARD MOLES_CELLSTANDARD*N2STANDARD // N2 standard value (79%)
-
-#define MOLES_PLASMA_VISIBLE 0.5 //Moles in a standard cell after which plasma is visible
-
-#define SPECIFIC_HEAT_TOXIN 200
-#define SPECIFIC_HEAT_AIR 20
-#define SPECIFIC_HEAT_CDO 30
-#define HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins) \
- (carbon_dioxide*SPECIFIC_HEAT_CDO + (oxygen+nitrogen)*SPECIFIC_HEAT_AIR + toxins*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
-
-//from FEA_gas_mixture.dm
-
-#define SPECIFIC_HEAT_TOXIN 200
-#define SPECIFIC_HEAT_AIR 20
-#define SPECIFIC_HEAT_CDO 30
-#define HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins) \
- (carbon_dioxide*SPECIFIC_HEAT_CDO + (oxygen+nitrogen)*SPECIFIC_HEAT_AIR + toxins*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
diff --git a/code/__HELPERS/files.dm b/code/__HELPERS/files.dm
new file mode 100644
index 00000000000..d804dcb06a9
--- /dev/null
+++ b/code/__HELPERS/files.dm
@@ -0,0 +1,60 @@
+//checks if a file exists and contains text
+//returns text as a string if these conditions are met
+/proc/return_file_text(filename)
+ if(fexists(filename) == 0)
+ error("File not found ([filename])")
+ return
+
+ var/text = file2text(filename)
+ if(!text)
+ error("File empty ([filename])")
+ return
+
+ return text
+
+//Sends resource files to client cache
+/client/proc/getFiles()
+ for(var/file in args)
+ src << browse_rsc(file)
+
+/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list(".txt",".log",".htm"))
+ var/path = root
+
+ for(var/i=0, iError: browse_files(): File not found/Invalid file([path])."
+ return
+
+ return path
+
+#define FTPDELAY 200 //200 tick delay to discourage spam
+/* This proc is a failsafe to prevent spamming of file requests.
+ It is just a timer that only permits a download every [FTPDELAY] ticks.
+ This can be changed by modifying FTPDELAY's value above.
+
+ PLEASE USE RESPONSIBLY, Some log files canr each sizes of 4MB! */
+/client/proc/file_spam_check()
+ var/time_to_wait = fileaccess_timer - world.time
+ if(time_to_wait > 0)
+ src << "Error: file_spam_check(): Spam. Please wait [round(time_to_wait/10)] seconds."
+ return 1
+ fileaccess_timer = world.time + FTPDELAY
+ return 0
+#undef FTPDELAY
\ No newline at end of file
diff --git a/code/defines/procs/gamehelpers.dm b/code/__HELPERS/game.dm
similarity index 75%
rename from code/defines/procs/gamehelpers.dm
rename to code/__HELPERS/game.dm
index 864cc3666fe..fcdda875a79 100644
--- a/code/defines/procs/gamehelpers.dm
+++ b/code/__HELPERS/game.dm
@@ -187,30 +187,30 @@
return hear
-/proc/get_mobs_in_radio_ranges(var/list/obj/item/device/radio/radios, var/level = 0)
- . = list()
+/proc/get_mobs_in_radio_ranges(var/list/obj/item/device/radio/radios)
+ set background = 1
+
+ . = list()
// Returns a list of mobs who can hear any of the radios given in @radios
var/list/speaker_coverage = list()
- for(var/obj/item/device/radio/R in radios)
- // This is usually for headsets, which only the wearer can hear.
- if(R.canhear_range == 0)
- if(ismob(R.loc))
- . |= R.loc
- continue
+ for(var/i = 1; i <= radios.len; i++)
+ var/obj/item/device/radio/R = radios[i]
+ if(R)
+ var/turf/speaker = get_turf(R)
+ if(speaker)
+ for(var/turf/T in hear(R.canhear_range,speaker))
+ speaker_coverage[T] = T
- var/turf/speaker = get_turf(R)
- if(speaker)
- for(var/turf/T in hear(R.canhear_range,speaker))
- speaker_coverage += T
// Try to find all the players who can hear the message
- for(var/mob/M in player_list)
- var/turf/ear = get_turf(M)
- if(ear && (level == 0 || level == ear.z))
- if(ear in speaker_coverage)
- . |= M
-
+ for(var/i = 1; i <= player_list.len; i++)
+ var/mob/M = player_list[i]
+ if(M)
+ var/turf/ear = get_turf(M)
+ if(ear)
+ if(speaker_coverage[ear])
+ . |= M
return .
#define SIGN(X) ((X<0)?-1:1)
@@ -281,6 +281,7 @@ proc/isInSight(var/atom/A, var/atom/B)
return M
return null
+//i think this is used soley by verb/give(), cael
proc/check_can_reach(atom/user, atom/target)
if(!in_range(user,target))
return 0
@@ -320,3 +321,49 @@ var/list/DummyCache = list()
D.loc = null
DummyCache.Add(D)
return 1
+
+// Will return a list of active candidates. It increases the buffer 5 times until it finds a candidate which is active within the buffer.
+/proc/get_active_candidates(var/buffer = 1)
+
+ var/list/candidates = list() //List of candidate KEYS to assume control of the new larva ~Carn
+ var/i = 0
+ while(candidates.len <= 0 && i < 5)
+ for(var/mob/dead/observer/G in player_list)
+ if(((G.client.inactivity/10)/60) <= buffer + i) // the most active players are more likely to become an alien
+ if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
+ candidates += G.key
+ i++
+ return candidates
+
+// Same as above but for alien candidates.
+
+/proc/get_alien_candidates()
+
+ var/list/candidates = list() //List of candidate KEYS to assume control of the new larva ~Carn
+ var/i = 0
+ while(candidates.len <= 0 && i < 5)
+ for(var/mob/dead/observer/G in player_list)
+ if(G.client.prefs.be_special & BE_ALIEN)
+ if(((G.client.inactivity/10)/60) <= ALIEN_SELECT_AFK_BUFFER + i) // the most active players are more likely to become an alien
+ if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
+ candidates += G.key
+ i++
+ return candidates
+
+/proc/ScreenText(obj/O, maptext="", screen_loc="CENTER-7,CENTER-7", maptext_height=480, maptext_width=480)
+ if(!isobj(O)) O = new /obj/screen/text()
+ O.maptext = maptext
+ O.maptext_height = maptext_height
+ O.maptext_width = maptext_width
+ O.screen_loc = screen_loc
+ return O
+
+/proc/Show2Group4Delay(obj/O, list/group, delay=0)
+ if(!isobj(O)) return
+ if(!group) group = clients
+ for(var/client/C in group)
+ C.screen += O
+ if(delay)
+ spawn(delay)
+ for(var/client/C in group)
+ C.screen -= O
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
new file mode 100644
index 00000000000..d0b8b90d6b5
--- /dev/null
+++ b/code/__HELPERS/global_lists.dm
@@ -0,0 +1,79 @@
+var/list/clients = list() //list of all clients
+var/list/admins = list() //list of all clients whom are admins
+var/list/directory = list() //list of all ckeys with associated client
+
+//Since it didn't really belong in any other category, I'm putting this here
+//This is for procs to replace all the goddamn 'in world's that are chilling around the code
+
+var/global/list/player_list = list() //List of all mobs **with clients attached**. Excludes /mob/new_player
+var/global/list/mob_list = list() //List of all mobs, including clientless
+var/global/list/living_mob_list = list() //List of all alive mobs, including clientless. Excludes /mob/new_player
+var/global/list/dead_mob_list = list() //List of all dead mobs, including clientless. Excludes /mob/new_player
+
+var/global/list/cable_list = list() //Index for all cables, so that powernets don't have to look through the entire world all the time
+var/global/list/chemical_reactions_list //list of all /datum/chemical_reaction datums. Used during chemical reactions
+var/global/list/chemical_reagents_list //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff
+var/global/list/landmarks_list = list() //list of all landmarks created
+var/global/list/surgery_steps = list() //list of all surgery steps |BS12
+//Preferences stuff
+ //Hairstyles
+var/global/list/hair_styles_list = list() //stores /datum/sprite_accessory/hair indexed by name
+var/global/list/hair_styles_male_list = list()
+var/global/list/hair_styles_female_list = list()
+var/global/list/facial_hair_styles_list = list() //stores /datum/sprite_accessory/facial_hair indexed by name
+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", "Love-Hearts", "Black2", "Grey2", "Stripey", "Kinky", "None") //Curse whoever made male/female underwear diffrent colours
+var/global/list/underwear_f = list("Red", "White", "Yellow", "Blue", "Black", "Thong", "Babydoll", "Baby-Blue", "Green", "Pink", "Kinky", "None")
+ //Backpacks
+var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt")
+
+//////////////////////////
+/////Initial Building/////
+//////////////////////////
+
+/proc/make_datum_references_lists()
+ var/list/paths
+
+ //Hair - Initialise all /datum/sprite_accessory/hair into an list indexed by hair-style name
+ paths = typesof(/datum/sprite_accessory/hair) - /datum/sprite_accessory/hair
+ for(var/path in paths)
+ var/datum/sprite_accessory/hair/H = new path()
+ hair_styles_list[H.name] = H
+ switch(H.gender)
+ if(MALE) hair_styles_male_list += H.name
+ if(FEMALE) hair_styles_female_list += H.name
+ else
+ hair_styles_male_list += H.name
+ hair_styles_female_list += H.name
+
+ //Facial Hair - Initialise all /datum/sprite_accessory/facial_hair into an list indexed by facialhair-style name
+ paths = typesof(/datum/sprite_accessory/facial_hair) - /datum/sprite_accessory/facial_hair
+ for(var/path in paths)
+ var/datum/sprite_accessory/facial_hair/H = new path()
+ facial_hair_styles_list[H.name] = H
+ switch(H.gender)
+ if(MALE) facial_hair_styles_male_list += H.name
+ if(FEMALE) facial_hair_styles_female_list += H.name
+ else
+ facial_hair_styles_male_list += H.name
+ facial_hair_styles_female_list += H.name
+
+ //Surgery Steps - Initialize all /datum/surgery_step into a list
+ paths = typesof(/datum/surgery_step)-/datum/surgery_step
+ for(var/T in paths)
+ var/datum/surgery_step/S = new T
+ surgery_steps += S
+/* // Uncomment to debug chemical reaction list.
+/client/verb/debug_chemical_list()
+
+ for (var/reaction in chemical_reactions_list)
+ . += "chemical_reactions_list\[\"[reaction]\"\] = \"[chemical_reactions_list[reaction]]\"\n"
+ if(islist(chemical_reactions_list[reaction]))
+ var/list/L = chemical_reactions_list[reaction]
+ for(var/t in L)
+ . += " has: [t]\n"
+ world << .
+*/
\ No newline at end of file
diff --git a/code/defines/procs/icon_procs.dm b/code/__HELPERS/icons.dm
similarity index 62%
rename from code/defines/procs/icon_procs.dm
rename to code/__HELPERS/icons.dm
index ce56408ead4..cfca598adbc 100644
--- a/code/defines/procs/icon_procs.dm
+++ b/code/__HELPERS/icons.dm
@@ -1,8 +1,217 @@
/*
- IconProcs
- by Lummox JR
- Check the icon_procs_readme.dm for how they work.
- */
+IconProcs README
+
+A BYOND library for manipulating icons and colors
+
+by Lummox JR
+
+version 1.0
+
+The IconProcs library was made to make a lot of common icon operations much easier. BYOND's icon manipulation
+routines are very capable but some of the advanced capabilities like using alpha transparency can be unintuitive to beginners.
+
+CHANGING ICONS
+
+Several new procs have been added to the /icon datum to simplify working with icons. To use them,
+remember you first need to setup an /icon var like so:
+
+var/icon/my_icon = new('iconfile.dmi')
+
+icon/ChangeOpacity(amount = 1)
+ A very common operation in DM is to try to make an icon more or less transparent. Making an icon more
+ transparent is usually much easier than making it less so, however. This proc basically is a frontend
+ for MapColors() which can change opacity any way you like, in much the same way that SetIntensity()
+ can make an icon lighter or darker. If amount is 0.5, the opacity of the icon will be cut in half.
+ If amount is 2, opacity is doubled and anything more than half-opaque will become fully opaque.
+icon/GrayScale()
+ Converts the icon to grayscale instead of a fully colored icon. Alpha values are left intact.
+icon/ColorTone(tone)
+ Similar to GrayScale(), this proc converts the icon to a range of black -> tone -> white, where tone is an
+ RGB color (its alpha is ignored). This can be used to create a sepia tone or similar effect.
+ See also the global ColorTone() proc.
+icon/MinColors(icon)
+ The icon is blended with a second icon where the minimum of each RGB pixel is the result.
+ Transparency may increase, as if the icons were blended with ICON_ADD. You may supply a color in place of an icon.
+icon/MaxColors(icon)
+ The icon is blended with a second icon where the maximum of each RGB pixel is the result.
+ Opacity may increase, as if the icons were blended with ICON_OR. You may supply a color in place of an icon.
+icon/Opaque(background = "#000000")
+ All alpha values are set to 255 throughout the icon. Transparent pixels become black, or whatever background color you specify.
+icon/BecomeAlphaMask()
+ You can convert a simple grayscale icon into an alpha mask to use with other icons very easily with this proc.
+ The black parts become transparent, the white parts stay white, and anything in between becomes a translucent shade of white.
+icon/AddAlphaMask(mask)
+ The alpha values of the mask icon will be blended with the current icon. Anywhere the mask is opaque,
+ the current icon is untouched. Anywhere the mask is transparent, the current icon becomes transparent.
+ Where the mask is translucent, the current icon becomes more transparent.
+icon/UseAlphaMask(mask, mode)
+ Sometimes you may want to take the alpha values from one icon and use them on a different icon.
+ This proc will do that. Just supply the icon whose alpha mask you want to use, and src will change
+ so it has the same colors as before but uses the mask for opacity.
+
+COLOR MANAGEMENT AND HSV
+
+RGB isn't the only way to represent color. Sometimes it's more useful to work with a model called HSV, which stands for hue, saturation, and value.
+
+ * The hue of a color describes where it is along the color wheel. It goes from red to yellow to green to
+ cyan to blue to magenta and back to red.
+ * The saturation of a color is how much color is in it. A color with low saturation will be more gray,
+ and with no saturation at all it is a shade of gray.
+ * The value of a color determines how bright it is. A high-value color is vivid, moderate value is dark,
+ and no value at all is black.
+
+Just as BYOND uses "#rrggbb" to represent RGB values, a similar format is used for HSV: "#hhhssvv". The hue is three
+hex digits because it ranges from 0 to 0x5FF.
+
+ * 0 to 0xFF - red to yellow
+ * 0x100 to 0x1FF - yellow to green
+ * 0x200 to 0x2FF - green to cyan
+ * 0x300 to 0x3FF - cyan to blue
+ * 0x400 to 0x4FF - blue to magenta
+ * 0x500 to 0x5FF - magenta to red
+
+Knowing this, you can figure out that red is "#000ffff" in HSV format, which is hue 0 (red), saturation 255 (as colorful as possible),
+value 255 (as bright as possible). Green is "#200ffff" and blue is "#400ffff".
+
+More than one HSV color can match the same RGB color.
+
+Here are some procs you can use for color management:
+
+ReadRGB(rgb)
+ Takes an RGB string like "#ffaa55" and converts it to a list such as list(255,170,85). If an RGBA format is used
+ that includes alpha, the list will have a fourth item for the alpha value.
+hsv(hue, sat, val, apha)
+ Counterpart to rgb(), this takes the values you input and converts them to a string in "#hhhssvv" or "#hhhssvvaa"
+ format. Alpha is not included in the result if null.
+ReadHSV(rgb)
+ Takes an HSV string like "#100FF80" and converts it to a list such as list(256,255,128). If an HSVA format is used that
+ includes alpha, the list will have a fourth item for the alpha value.
+RGBtoHSV(rgb)
+ Takes an RGB or RGBA string like "#ffaa55" and converts it into an HSV or HSVA color such as "#080aaff".
+HSVtoRGB(hsv)
+ Takes an HSV or HSVA string like "#080aaff" and converts it into an RGB or RGBA color such as "#ff55aa".
+BlendRGB(rgb1, rgb2, amount)
+ Blends between two RGB or RGBA colors using regular RGB blending. If amount is 0, the first color is the result;
+ if 1, the second color is the result. 0.5 produces an average of the two. Values outside the 0 to 1 range are allowed as well.
+ The returned value is an RGB or RGBA color.
+BlendHSV(hsv1, hsv2, amount)
+ Blends between two HSV or HSVA colors using HSV blending, which tends to produce nicer results than regular RGB
+ blending because the brightness of the color is left intact. If amount is 0, the first color is the result; if 1,
+ the second color is the result. 0.5 produces an average of the two. Values outside the 0 to 1 range are allowed as well.
+ The returned value is an HSV or HSVA color.
+BlendRGBasHSV(rgb1, rgb2, amount)
+ Like BlendHSV(), but the colors used and the return value are RGB or RGBA colors. The blending is done in HSV form.
+HueToAngle(hue)
+ Converts a hue to an angle range of 0 to 360. Angle 0 is red, 120 is green, and 240 is blue.
+AngleToHue(hue)
+ Converts an angle to a hue in the valid range.
+RotateHue(hsv, angle)
+ Takes an HSV or HSVA value and rotates the hue forward through red, green, and blue by an angle from 0 to 360.
+ (Rotating red by 60° produces yellow.) The result is another HSV or HSVA color with the same saturation and value
+ as the original, but a different hue.
+GrayScale(rgb)
+ Takes an RGB or RGBA color and converts it to grayscale. Returns an RGB or RGBA string.
+ColorTone(rgb, tone)
+ Similar to GrayScale(), this proc converts an RGB or RGBA color to a range of black -> tone -> white instead of
+ using strict shades of gray. The tone value is an RGB color; any alpha value is ignored.
+*/
+
+/*
+Get Flat Icon DEMO by DarkCampainger
+
+This is a test for the get flat icon proc, modified approprietly for icons and their states.
+Probably not a good idea to run this unless you want to see how the proc works in detail.
+mob
+ icon = 'old_or_unused.dmi'
+ icon_state = "green"
+
+ Login()
+ // Testing image underlays
+ underlays += image(icon='old_or_unused.dmi',icon_state="red")
+ underlays += image(icon='old_or_unused.dmi',icon_state="red", pixel_x = 32)
+ underlays += image(icon='old_or_unused.dmi',icon_state="red", pixel_x = -32)
+
+ // Testing image overlays
+ overlays += image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = -32)
+ overlays += image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = 32)
+ overlays += image(icon='old_or_unused.dmi',icon_state="green", pixel_x = -32, pixel_y = -32)
+
+ // Testing icon file overlays (defaults to mob's state)
+ overlays += '_flat_demoIcons2.dmi'
+
+ // Testing icon_state overlays (defaults to mob's icon)
+ overlays += "white"
+
+ // Testing dynamic icon overlays
+ var/icon/I = icon('old_or_unused.dmi', icon_state="aqua")
+ I.Shift(NORTH,16,1)
+ overlays+=I
+
+ // Testing dynamic image overlays
+ I=image(icon=I,pixel_x = -32, pixel_y = 32)
+ overlays+=I
+
+ // Testing object types (and layers)
+ overlays+=/obj/effect/overlayTest
+
+ loc = locate (10,10,1)
+ verb
+ Browse_Icon()
+ set name = "1. Browse Icon"
+ // Give it a name for the cache
+ var/iconName = "[ckey(src.name)]_flattened.dmi"
+ // Send the icon to src's local cache
+ src<