diff --git a/baystation12.dme b/baystation12.dme
index 46020da6fbc..1e8bb460966 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -54,6 +54,7 @@
#define FILE_DIR "code/game/machinery"
#define FILE_DIR "code/game/machinery/atmoalter"
#define FILE_DIR "code/game/machinery/bots"
+#define FILE_DIR "code/game/machinery/camera"
#define FILE_DIR "code/game/machinery/computer"
#define FILE_DIR "code/game/machinery/doors"
#define FILE_DIR "code/game/machinery/embedded_controller"
@@ -80,6 +81,8 @@
#define FILE_DIR "code/game/objects/items/devices/radio"
#define FILE_DIR "code/game/objects/items/robot"
#define FILE_DIR "code/game/objects/items/stacks"
+#define FILE_DIR "code/game/objects/items/stacks/sheets"
+#define FILE_DIR "code/game/objects/items/stacks/tiles"
#define FILE_DIR "code/game/objects/items/weapons"
#define FILE_DIR "code/game/objects/items/weapons/grenades"
#define FILE_DIR "code/game/objects/items/weapons/implants"
@@ -91,9 +94,12 @@
#define FILE_DIR "code/game/objects/structures/crates_lockers"
#define FILE_DIR "code/game/objects/structures/crates_lockers/closets"
#define FILE_DIR "code/game/objects/structures/crates_lockers/closets/secure"
+#define FILE_DIR "code/game/objects/structures/stool_bed_chair_nest"
#define FILE_DIR "code/game/player"
#define FILE_DIR "code/game/structure"
#define FILE_DIR "code/game/turfs"
+#define FILE_DIR "code/game/turfs/simulated"
+#define FILE_DIR "code/game/turfs/unsimulated"
#define FILE_DIR "code/game/vehicles"
#define FILE_DIR "code/game/vehicles/airtight"
#define FILE_DIR "code/game/verbs"
@@ -103,6 +109,8 @@
#define FILE_DIR "code/modules/admin/DB ban"
#define FILE_DIR "code/modules/admin/verbs"
#define FILE_DIR "code/modules/assembly"
+#define FILE_DIR "code/modules/awaymissions"
+#define FILE_DIR "code/modules/awaymissions/maploader"
#define FILE_DIR "code/modules/chemical"
#define FILE_DIR "code/modules/client"
#define FILE_DIR "code/modules/clothing"
@@ -119,11 +127,12 @@
#define FILE_DIR "code/modules/critters"
#define FILE_DIR "code/modules/critters/hivebots"
#define FILE_DIR "code/modules/customitems"
-#define FILE_DIR "code/modules/detectivework"
+#define FILE_DIR "code/modules/DetectiveWork"
#define FILE_DIR "code/modules/flufftext"
#define FILE_DIR "code/modules/food"
#define FILE_DIR "code/modules/icon generation"
#define FILE_DIR "code/modules/library"
+#define FILE_DIR "code/modules/liquid"
#define FILE_DIR "code/modules/maps"
#define FILE_DIR "code/modules/mining"
#define FILE_DIR "code/modules/mob"
@@ -268,16 +277,13 @@
#include "code\global.dm"
#include "code\names.dm"
#include "code\setup.dm"
-#include "code\setup_3d.dm"
#include "code\stylesheet.dm"
-#include "code\ZAS_defines.dm"
#include "code\ATMOSPHERICS\atmospherics.dm"
#include "code\ATMOSPHERICS\datum_pipe_network.dm"
#include "code\ATMOSPHERICS\datum_pipeline.dm"
#include "code\ATMOSPHERICS\he_pipes.dm"
#include "code\ATMOSPHERICS\pipes.dm"
#include "code\ATMOSPHERICS\components\portables_connector.dm"
-#include "code\ATMOSPHERICS\components\tvalve.dm"
#include "code\ATMOSPHERICS\components\valve.dm"
#include "code\ATMOSPHERICS\components\binary_devices\binary_atmos_base.dm"
#include "code\ATMOSPHERICS\components\binary_devices\circulator.dm"
@@ -394,6 +400,12 @@
#include "code\defines\procs\syndicate_name.dm"
#include "code\defines\procs\time_stamp.dm"
#include "code\defines\tanning\leather.dm"
+#include "code\FEA\FEA_airgroup.dm"
+#include "code\FEA\FEA_fire.dm"
+#include "code\FEA\FEA_gas_mixture.dm"
+#include "code\FEA\FEA_group_helpers.dm"
+#include "code\FEA\FEA_system.dm"
+#include "code\FEA\FEA_turf_tile.dm"
#include "code\game\algorithm.dm"
#include "code\game\atom_procs.dm"
#include "code\game\cellautomata.dm"
@@ -401,14 +413,11 @@
#include "code\game\communications.dm"
#include "code\game\dna.dm"
#include "code\game\hud.dm"
-#include "code\game\json.dm"
#include "code\game\landmarks.dm"
#include "code\game\prisonshuttle.dm"
-#include "code\game\response_team.dm"
#include "code\game\shuttle_engines.dm"
#include "code\game\skincmd.dm"
#include "code\game\smoothwall.dm"
-#include "code\game\socket_talk.dm"
#include "code\game\sound.dm"
#include "code\game\specops_shuttle.dm"
#include "code\game\status.dm"
@@ -499,7 +508,6 @@
#include "code\game\machinery\autolathe.dm"
#include "code\game\machinery\Beacon.dm"
#include "code\game\machinery\biogenerator.dm"
-#include "code\game\machinery\camera.dm"
#include "code\game\machinery\cell_charger.dm"
#include "code\game\machinery\cloning.dm"
#include "code\game\machinery\constructable_frame.dm"
@@ -517,7 +525,6 @@
#include "code\game\machinery\machinery.dm"
#include "code\game\machinery\magnet.dm"
#include "code\game\machinery\mass_driver.dm"
-#include "code\game\machinery\morgue.dm"
#include "code\game\machinery\navbeacon.dm"
#include "code\game\machinery\newscaster.dm"
#include "code\game\machinery\OpTable.dm"
@@ -544,6 +551,7 @@
#include "code\game\machinery\atmoalter\portable_atmospherics.dm"
#include "code\game\machinery\atmoalter\pump.dm"
#include "code\game\machinery\atmoalter\scrubber.dm"
+#include "code\game\machinery\atmoalter\zvent.dm"
#include "code\game\machinery\bots\bots.dm"
#include "code\game\machinery\bots\cleanbot.dm"
#include "code\game\machinery\bots\ed209bot.dm"
@@ -551,6 +559,12 @@
#include "code\game\machinery\bots\medbot.dm"
#include "code\game\machinery\bots\mulebot.dm"
#include "code\game\machinery\bots\secbot.dm"
+#include "code\game\machinery\camera\camera.dm"
+#include "code\game\machinery\camera\camera_assembly.dm"
+#include "code\game\machinery\camera\motion.dm"
+#include "code\game\machinery\camera\presets.dm"
+#include "code\game\machinery\camera\tracking.dm"
+#include "code\game\machinery\camera\wires.dm"
#include "code\game\machinery\computer\ai_core.dm"
#include "code\game\machinery\computer\aifixer.dm"
#include "code\game\machinery\computer\arcade.dm"
@@ -626,6 +640,7 @@
#include "code\game\objects\empulse.dm"
#include "code\game\objects\explosion.dm"
#include "code\game\objects\explosion_recursive.dm"
+#include "code\game\objects\hud.dm"
#include "code\game\objects\items.dm"
#include "code\game\objects\objs.dm"
#include "code\game\objects\structures.dm"
@@ -635,8 +650,10 @@
#include "code\game\objects\effects\effect_system.dm"
#include "code\game\objects\effects\gibs.dm"
#include "code\game\objects\effects\glowshroom.dm"
+#include "code\game\objects\effects\landmarks.dm"
#include "code\game\objects\effects\manifest.dm"
#include "code\game\objects\effects\mines.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\decals\blood.dm"
@@ -680,12 +697,17 @@
#include "code\game\objects\items\robot\robot_items.dm"
#include "code\game\objects\items\robot\robot_parts.dm"
#include "code\game\objects\items\robot\robot_upgrades.dm"
-#include "code\game\objects\items\stacks\glass.dm"
#include "code\game\objects\items\stacks\medical.dm"
-#include "code\game\objects\items\stacks\metal.dm"
-#include "code\game\objects\items\stacks\minerals.dm"
+#include "code\game\objects\items\stacks\rods.dm"
#include "code\game\objects\items\stacks\stack.dm"
-#include "code\game\objects\items\stacks\wood.dm"
+#include "code\game\objects\items\stacks\sheets\glass.dm"
+#include "code\game\objects\items\stacks\sheets\light.dm"
+#include "code\game\objects\items\stacks\sheets\mineral.dm"
+#include "code\game\objects\items\stacks\sheets\sheet_types.dm"
+#include "code\game\objects\items\stacks\sheets\sheets.dm"
+#include "code\game\objects\items\stacks\tiles\light.dm"
+#include "code\game\objects\items\stacks\tiles\plasteel.dm"
+#include "code\game\objects\items\stacks\tiles\tile_types.dm"
#include "code\game\objects\items\weapons\AI_modules.dm"
#include "code\game\objects\items\weapons\Bedsheets.dm"
#include "code\game\objects\items\weapons\cards_ids.dm"
@@ -750,11 +772,11 @@
#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\structures\aliennests.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\girders.dm"
#include "code\game\objects\structures\grille.dm"
@@ -765,9 +787,9 @@
#include "code\game\objects\structures\mineral_doors.dm"
#include "code\game\objects\structures\mirror.dm"
#include "code\game\objects\structures\mop_bucket.dm"
+#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\stool_chair_bed.dm"
#include "code\game\objects\structures\tables_racks.dm"
#include "code\game\objects\structures\target_stake.dm"
#include "code\game\objects\structures\watercloset.dm"
@@ -778,7 +800,6 @@
#include "code\game\objects\structures\crates_lockers\largecrate.dm"
#include "code\game\objects\structures\crates_lockers\closets\bombsuit.dm"
#include "code\game\objects\structures\crates_lockers\closets\emergency.dm"
-#include "code\game\objects\structures\crates_lockers\closets\extinguisher.dm"
#include "code\game\objects\structures\crates_lockers\closets\fireaxe.dm"
#include "code\game\objects\structures\crates_lockers\closets\firecloset.dm"
#include "code\game\objects\structures\crates_lockers\closets\fitnesscloset.dm"
@@ -801,7 +822,17 @@
#include "code\game\objects\structures\crates_lockers\closets\secure\scientist.dm"
#include "code\game\objects\structures\crates_lockers\closets\secure\secure_closets.dm"
#include "code\game\objects\structures\crates_lockers\closets\secure\security.dm"
+#include "code\game\objects\structures\stool_bed_chair_nest\alien_nests.dm"
+#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\turfs\turf.dm"
+#include "code\game\turfs\simulated\beach.dm"
+#include "code\game\turfs\unsimulated\beach.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\ooc.dm"
#include "code\game\verbs\sound.dm"
#include "code\game\verbs\suicide.dm"
@@ -830,7 +861,6 @@
#include "code\modules\admin\verbs\atmosdebug.dm"
#include "code\modules\admin\verbs\BrokenInhands.dm"
#include "code\modules\admin\verbs\cinematic.dm"
-#include "code\modules\admin\verbs\custom_event.dm"
#include "code\modules\admin\verbs\deadsay.dm"
#include "code\modules\admin\verbs\debug.dm"
#include "code\modules\admin\verbs\diagnostics.dm"
@@ -856,6 +886,14 @@
#include "code\modules\assembly\shock_kit.dm"
#include "code\modules\assembly\signaler.dm"
#include "code\modules\assembly\timer.dm"
+#include "code\modules\awaymissions\gateway.dm"
+#include "code\modules\awaymissions\loot.dm"
+#include "code\modules\awaymissions\trigger.dm"
+#include "code\modules\awaymissions\zlevel.dm"
+#include "code\modules\awaymissions\maploader\dmm_suite.dm"
+#include "code\modules\awaymissions\maploader\reader.dm"
+#include "code\modules\awaymissions\maploader\swapmaps.dm"
+#include "code\modules\awaymissions\maploader\writer.dm"
#include "code\modules\client\client defines.dm"
#include "code\modules\client\client procs.dm"
#include "code\modules\clothing\clothing.dm"
@@ -879,13 +917,10 @@
#include "code\modules\clothing\shoes\colour.dm"
#include "code\modules\clothing\shoes\magboots.dm"
#include "code\modules\clothing\shoes\miscellaneous.dm"
-#include "code\modules\clothing\spacesuits\captain.dm"
-#include "code\modules\clothing\spacesuits\ert.dm"
#include "code\modules\clothing\spacesuits\miscellaneous.dm"
#include "code\modules\clothing\spacesuits\ninja.dm"
#include "code\modules\clothing\spacesuits\rig.dm"
#include "code\modules\clothing\spacesuits\syndi.dm"
-#include "code\modules\clothing\spacesuits\void.dm"
#include "code\modules\clothing\suits\armor.dm"
#include "code\modules\clothing\suits\bio.dm"
#include "code\modules\clothing\suits\jobs.dm"
@@ -898,6 +933,7 @@
#include "code\modules\clothing\under\miscellaneous.dm"
#include "code\modules\clothing\under\shorts.dm"
#include "code\modules\clothing\under\syndicate.dm"
+#include "code\modules\clothing\under\ties.dm"
#include "code\modules\clothing\under\jobs\civilian.dm"
#include "code\modules\clothing\under\jobs\engineering.dm"
#include "code\modules\clothing\under\jobs\medsci.dm"
@@ -907,12 +943,10 @@
#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\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\flufftext\Dreaming.dm"
#include "code\modules\flufftext\Hallucination.dm"
#include "code\modules\flufftext\TextFilters.dm"
@@ -920,11 +954,7 @@
#include "code\modules\library\lib_items.dm"
#include "code\modules\library\lib_machines.dm"
#include "code\modules\library\lib_readme.dm"
-#include "code\modules\maps\dmm_suite.dm"
-#include "code\modules\maps\randomZlevel.dm"
-#include "code\modules\maps\reader.dm"
-#include "code\modules\maps\SwapMaps.dm"
-#include "code\modules\maps\writer.dm"
+#include "code\modules\liquid\splash_simulation.dm"
#include "code\modules\mining\machine_input_output_plates.dm"
#include "code\modules\mining\machine_processing.dm"
#include "code\modules\mining\machine_stacking.dm"
@@ -966,7 +996,6 @@
#include "code\modules\mob\living\blob\blob.dm"
#include "code\modules\mob\living\carbon\carbon.dm"
#include "code\modules\mob\living\carbon\carbon_defines.dm"
-#include "code\modules\mob\living\carbon\give.dm"
#include "code\modules\mob\living\carbon\alien\alien.dm"
#include "code\modules\mob\living\carbon\alien\death.dm"
#include "code\modules\mob\living\carbon\alien\login.dm"
@@ -1109,11 +1138,9 @@
#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\organ\organ.dm"
#include "code\modules\mob\organ\organ_external.dm"
-#include "code\modules\mob\organ\pain.dm"
#include "code\modules\paperwork\clipboard.dm"
#include "code\modules\paperwork\filingcabinet.dm"
#include "code\modules\paperwork\folders.dm"
@@ -1139,7 +1166,6 @@
#include "code\modules\power\switch.dm"
#include "code\modules\power\terminal.dm"
#include "code\modules\power\tracker.dm"
-#include "code\modules\power\turbine.dm"
#include "code\modules\power\antimatter\containment_jar.dm"
#include "code\modules\power\antimatter\control.dm"
#include "code\modules\power\antimatter\shielding.dm"
@@ -1221,24 +1247,7 @@
#include "code\modules\research\rdconsole.dm"
#include "code\modules\research\rdmachines.dm"
#include "code\modules\research\research.dm"
-#include "code\modules\research\research_shuttle.dm"
#include "code\modules\research\server.dm"
-#include "code\modules\research\xenoarchaeology\archaeo_chem.dm"
-#include "code\modules\research\xenoarchaeology\archaeo_excavate.dm"
-#include "code\modules\research\xenoarchaeology\archaeo_machinery.dm"
-#include "code\modules\research\xenoarchaeology\archaeo_tools.dm"
-#include "code\modules\research\xenoarchaeology\artifact.dm"
-#include "code\modules\research\xenoarchaeology\artifact_analysis.dm"
-#include "code\modules\research\xenoarchaeology\artifact_db.dm"
-#include "code\modules\research\xenoarchaeology\artifact_effect.dm"
-#include "code\modules\research\xenoarchaeology\artifact_harvester.dm"
-#include "code\modules\research\xenoarchaeology\artifact_misc.dm"
-#include "code\modules\research\xenoarchaeology\artifact_synthetic.dm"
-#include "code\modules\research\xenoarchaeology\core_sampler.dm"
-#include "code\modules\research\xenoarchaeology\finds.dm"
-#include "code\modules\research\xenoarchaeology\geosample.dm"
-#include "code\modules\research\xenoarchaeology\readme.dm"
-#include "code\modules\research\xenoarchaeology\tools.dm"
#include "code\modules\scripting\Errors.dm"
#include "code\modules\scripting\IDE.dm"
#include "code\modules\scripting\Options.dm"
@@ -1263,36 +1272,6 @@
#include "code\modules\security levels\security levels.dm"
#include "code\WorkInProgress\buildmode.dm"
#include "code\WorkInProgress\explosion_particles.dm"
-#include "code\WorkInProgress\Cael_Aislinn\energy_field.dm"
-#include "code\WorkInProgress\Cael_Aislinn\external_shield_gen.dm"
-#include "code\WorkInProgress\Cael_Aislinn\shield_capacitor.dm"
-#include "code\WorkInProgress\Cael_Aislinn\shield_gen.dm"
-#include "code\WorkInProgress\Cael_Aislinn\Rust\core_field.dm"
-#include "code\WorkInProgress\Cael_Aislinn\Rust\core_gen.dm"
-#include "code\WorkInProgress\Cael_Aislinn\Rust\core_monitor.dm"
-#include "code\WorkInProgress\Cael_Aislinn\Rust\fuel_assembly.dm"
-#include "code\WorkInProgress\Cael_Aislinn\Rust\fuel_assembly_port.dm"
-#include "code\WorkInProgress\Cael_Aislinn\Rust\fuel_compressor.dm"
-#include "code\WorkInProgress\Cael_Aislinn\Rust\fuel_control.dm"
-#include "code\WorkInProgress\Cael_Aislinn\Rust\fuel_injector.dm"
-#include "code\WorkInProgress\Cael_Aislinn\Rust\gyrotron.dm"
-#include "code\WorkInProgress\Cael_Aislinn\Rust\gyrotron_controller.dm"
-#include "code\WorkInProgress\Cael_Aislinn\Rust\radiation.dm"
-#include "code\WorkInProgress\Cael_Aislinn\Rust\virtual_particle_catcher.dm"
-#include "code\WorkInProgress\Mini\atmos_control.dm"
-#include "code\WorkInProgress\SkyMarshal\Ultralight_procs.dm"
-#include "code\WorkInProgress\Tastyfish\livestock.dm"
-#include "code\WorkInProgress\Wrongnumber\weldbackpack.dm"
-#include "code\ZAS\Airflow.dm"
-#include "code\ZAS\Connection.dm"
-#include "code\ZAS\FEA_gas_mixture.dm"
-#include "code\ZAS\FEA_system.dm"
-#include "code\ZAS\Fire.dm"
-#include "code\ZAS\Functions.dm"
-#include "code\ZAS\Plasma.dm"
-#include "code\ZAS\Variable Settings.dm"
-#include "code\ZAS\ZAS_Turfs.dm"
-#include "code\ZAS\ZAS_Zones.dm"
#include "interface\interface.dm"
#include "interface\skin.dmf"
#include "maps\tgstation.2.0.9.dmm"
diff --git a/code/ATMOSPHERICS/components/valve.dm b/code/ATMOSPHERICS/components/valve.dm
index 835adeed27f..bcb962857cd 100644
--- a/code/ATMOSPHERICS/components/valve.dm
+++ b/code/ATMOSPHERICS/components/valve.dm
@@ -131,7 +131,7 @@ obj/machinery/atmospherics/valve
process()
..()
- machines.Remove(src)
+ . = PROCESS_KILL
/* if(open && (!node1 || !node2))
close()
diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm
index 054addadfc5..f124356bffd 100644
--- a/code/ATMOSPHERICS/pipes.dm
+++ b/code/ATMOSPHERICS/pipes.dm
@@ -106,7 +106,7 @@ obj/machinery/atmospherics/pipe
if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle
..()
else
- machines.Remove(src)
+ . = PROCESS_KILL
/*if(!node1)
parent.mingle_with_turf(loc, volume)
@@ -349,7 +349,7 @@ obj/machinery/atmospherics/pipe
if(!parent)
..()
else
- machines.Remove(src)
+ . = PROCESS_KILL
/* if(!node1)
parent.mingle_with_turf(loc, 200)
if(!nodealert)
@@ -615,7 +615,7 @@ obj/machinery/atmospherics/pipe
process()
if(!parent)
if(build_killswitch <= 0)
- machines.Remove(src)
+ . = PROCESS_KILL
else
build_killswitch--
..()
@@ -721,7 +721,7 @@ obj/machinery/atmospherics/pipe
if(!parent)
..()
else
- machines.Remove(src)
+ . = PROCESS_KILL
/*
if(!node1)
parent.mingle_with_turf(loc, 70)
diff --git a/code/game/objects/explosion2.dm b/code/WorkInProgress/carn/Explosion2.dm
similarity index 100%
rename from code/game/objects/explosion2.dm
rename to code/WorkInProgress/carn/Explosion2.dm
diff --git a/code/WorkInProgress/carn/master_controller_old.dm b/code/WorkInProgress/carn/master_controller_old.dm
new file mode 100644
index 00000000000..80a7659035d
--- /dev/null
+++ b/code/WorkInProgress/carn/master_controller_old.dm
@@ -0,0 +1,210 @@
+var/global/datum/controller/game_controller/master_controller //Set in world.New()
+var/global/datum/failsafe/Failsafe
+var/global/controller_iteration = 0
+
+
+var/global/last_tick_timeofday = world.timeofday
+var/global/last_tick_duration = 0
+
+datum/controller/game_controller
+ var/processing = 0
+
+ var/global/air_master_ready = 0
+ var/global/sun_ready = 0
+ var/global/mobs_ready = 0
+ var/global/diseases_ready = 0
+ var/global/machines_ready = 0
+ var/global/objects_ready = 0
+ var/global/networks_ready = 0
+ var/global/powernets_ready = 0
+ var/global/ticker_ready = 0
+
+ //Used for MC 'proc break' debugging
+ var/global/obj/last_obj_processed
+ var/global/datum/disease/last_disease_processed
+ var/global/obj/machinery/last_machine_processed
+ var/global/mob/last_mob_processed
+
+
+ proc/setup()
+ if(master_controller && (master_controller != src))
+ del(src)
+ return
+ //There can be only one master.
+
+ if(!air_master)
+ air_master = new /datum/controller/air_system()
+ air_master.setup()
+
+ if(!job_master)
+ job_master = new /datum/controller/occupations()
+ if(job_master.SetupOccupations())
+ world << "\red \b Job setup complete"
+ job_master.LoadJobs("config/jobs.txt")
+
+ world.tick_lag = config.Ticklag
+
+ createRandomZlevel()
+
+ setup_objects()
+
+ setupgenetics()
+
+
+ for(var/i = 0, i < max_secret_rooms, i++)
+ make_mining_asteroid_secret()
+
+ syndicate_code_phrase = generate_code_phrase()//Sets up code phrase for traitors, for the round.
+ syndicate_code_response = generate_code_phrase()
+
+ emergency_shuttle = new /datum/shuttle_controller/emergency_shuttle()
+
+ if(!ticker)
+ ticker = new /datum/controller/gameticker()
+
+ setupfactions()
+
+ spawn
+ ticker.pregame()
+
+ proc/setup_objects()
+ world << "\red \b Initializing objects"
+ sleep(-1)
+
+ for(var/obj/object in world)
+ object.initialize()
+
+ world << "\red \b Initializing pipe networks"
+ sleep(-1)
+
+ for(var/obj/machinery/atmospherics/machine in world)
+ machine.build_network()
+
+ world << "\red \b Initializing atmos machinery."
+ sleep(-1)
+ for(var/obj/machinery/atmospherics/unary/vent_pump/T in world)
+ T.broadcast_status()
+ for(var/obj/machinery/atmospherics/unary/vent_scrubber/T in world)
+ T.broadcast_status()
+
+ world << "\red \b Initializations complete."
+
+
+ proc/process()
+ processing = 1
+ spawn(0)
+ set background = 1
+ while(1)
+ var/currenttime = world.timeofday
+ var/diff = (currenttime - last_tick_timeofday) / 10
+ last_tick_timeofday = currenttime
+ last_tick_duration = diff
+
+ if(processing)
+
+ controller_iteration++
+
+ var/start_time = world.timeofday
+
+ air_master_ready = 0
+ sun_ready = 0
+ mobs_ready = 0
+ diseases_ready = 0
+ machines_ready = 0
+ objects_ready = 0
+ networks_ready = 0
+ powernets_ready = 0
+ ticker_ready = 0
+
+ spawn(0)
+ air_master.process()
+ air_master_ready = 1
+
+ sleep(1)
+
+ spawn(0)
+ sun.calc_position()
+ sun_ready = 1
+
+ sleep(-1)
+
+ spawn(0)
+ for(var/mob/M in world)
+ last_mob_processed = M
+ M.Life()
+ mobs_ready = 1
+
+ sleep(-1)
+
+ spawn(0)
+ for(var/datum/disease/D in active_diseases)
+ last_disease_processed = D
+ D.process()
+ diseases_ready = 1
+
+ spawn(0)
+ for(var/obj/machinery/machine in machines)
+ if(machine)
+ last_machine_processed = machine
+ machine.process()
+ if(machine && machine.use_power)
+ machine.auto_use_power()
+
+ machines_ready = 1
+
+ sleep(1)
+
+ spawn(-1)
+ for(var/obj/object in processing_objects)
+ last_obj_processed = object
+ object.process()
+ objects_ready = 1
+
+ sleep(-1)
+
+ spawn(-1)
+ for(var/datum/pipe_network/network in pipe_networks)
+ network.process()
+ networks_ready = 1
+
+ spawn(-1)
+ for(var/datum/powernet/P in powernets)
+ P.reset()
+ powernets_ready = 1
+
+ sleep(-1)
+
+ spawn(-1)
+ ticker.process()
+ ticker_ready = 1
+
+ var/IL_check = 0 //Infinite loop check (To report when the master controller breaks.)
+ while(!air_master_ready || !sun_ready || !mobs_ready || !diseases_ready || !machines_ready || !objects_ready || !networks_ready || !powernets_ready || !ticker_ready)
+ IL_check++
+ if(IL_check > 600)
+ var/MC_report = "air_master_ready = [air_master_ready]; sun_ready = [sun_ready]; mobs_ready = [mobs_ready]; diseases_ready = [diseases_ready]; machines_ready = [machines_ready]; objects_ready = [objects_ready]; networks_ready = [networks_ready]; powernets_ready = [powernets_ready]; ticker_ready = [ticker_ready];"
+ message_admins("PROC BREAKAGE WARNING: The game's master contorller appears to be stuck in one of it's cycles. It has looped through it's delaying loop [IL_check] times.")
+ message_admins("The master controller reports: [MC_report]")
+ if(!diseases_ready)
+ if(last_disease_processed)
+ message_admins("DISEASE PROCESSING stuck on [last_disease_processed]", 0, 1)
+ else
+ message_admins("DISEASE PROCESSING stuck on unknown")
+ if(!machines_ready)
+ if(last_machine_processed)
+ message_admins("MACHINE PROCESSING stuck on [last_machine_processed]", 0, 1)
+ else
+ message_admins("MACHINE PROCESSING stuck on unknown")
+ if(!objects_ready)
+ if(last_obj_processed)
+ message_admins("OBJ PROCESSING stuck on [last_obj_processed]", 0, 1)
+ else
+ message_admins("OBJ PROCESSING stuck on unknown")
+ log_admin("PROC BREAKAGE WARNING: infinite_loop_check = [IL_check]; [MC_report];")
+ message_admins("Master controller breaking out of delaying loop. Restarting the round is advised if problem persists. DO NOT manually restart the master controller.")
+ break;
+ sleep(1)
+
+ sleep(world.timeofday+12-start_time)
+ else
+ sleep(10)
\ No newline at end of file
diff --git a/code/WorkInProgress/carn/master_controller_sequential.dm b/code/WorkInProgress/carn/master_controller_sequential.dm
deleted file mode 100644
index 3c2978a6e8f..00000000000
--- a/code/WorkInProgress/carn/master_controller_sequential.dm
+++ /dev/null
@@ -1,209 +0,0 @@
-//simplified MC that is designed to fail when procs 'break'. When it fails it's just replaced with a new one.
-//It ensures master_controller.process() is never doubled up by killing the MC (hence terminating any of its sleeping procs)
-//WIP, needs lots of work still
-
-var/global/datum/controller/game_controller/master_controller //Set in world.New()
-var/global/datum/failsafe/Failsafe
-var/global/controller_iteration = 0
-
-
-var/global/last_tick_timeofday = world.timeofday
-var/global/last_tick_duration = 0
-
-var/global/obj/machinery/last_obj_processed //Used for MC 'proc break' debugging
-var/global/datum/disease/last_disease_processed //Used for MC 'proc break' debugging
-var/global/obj/machinery/last_machine_processed //Used for MC 'proc break' debugging
-
-datum/controller/game_controller
- var/processing = 0
- var/breather_ticks = 2 //a somewhat crude attempt to iron over the 'bumps' caused by high-cpu use by letting the MC have a breather for this many ticks after every loop
- var/minimum_ticks = 20 //The minimum length of time between MC ticks
-
- var/global/air_master_ready = 0
- var/global/tension_master_ready = 0
- var/global/sun_ready = 0
- var/global/mobs_ready = 0
- var/global/diseases_ready = 0
- var/global/machines_ready = 0
- var/global/objects_ready = 0
- var/global/networks_ready = 0
- var/global/powernets_ready = 0
- var/global/ticker_ready = 0
-
-datum/controller/game_controller/New()
- //There can be only one master_controller. Out with the old and in with the new.
- if(master_controller)
- if(master_controller != src)
- del(master_controller)
- master_controller = src
-
- if(!air_master)
- air_master = new /datum/controller/air_system()
- air_master.setup()
-
- if(!job_master)
- job_master = new /datum/controller/occupations()
- if(job_master.SetupOccupations())
- world << "\red \b Job setup complete"
- job_master.LoadJobs("config/jobs.txt")
-
- if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase()
- if(!syndicate_code_response) syndicate_code_response = generate_code_phrase()
- if(!ticker) ticker = new /datum/controller/gameticker()
- if(!emergency_shuttle) emergency_shuttle = new /datum/shuttle_controller/emergency_shuttle()
-
-
-datum/controller/game_controller/proc/setup()
- world.tick_lag = config.Ticklag
-
- createRandomZlevel()
- setup_objects()
- setupgenetics()
- setupfactions()
-
- for(var/i = 0, i < max_secret_rooms, i++)
- make_mining_asteroid_secret()
-
- spawn(0)
- if(ticker)
- ticker.pregame()
-
-datum/controller/game_controller/proc/setup_objects()
- world << "\red \b Initializing objects"
- sleep(-1)
- for(var/obj/object in world)
- object.initialize()
-
- world << "\red \b Initializing pipe networks"
- sleep(-1)
- for(var/obj/machinery/atmospherics/machine in world)
- machine.build_network()
-
- world << "\red \b Initializing atmos machinery."
- sleep(-1)
- for(var/obj/machinery/atmospherics/unary/vent_pump/T in world)
- T.broadcast_status()
- for(var/obj/machinery/atmospherics/unary/vent_scrubber/T in world)
- T.broadcast_status()
-
- world << "\red \b Initializations complete."
- sleep(-1)
-
-
-datum/controller/game_controller/proc/process()
- set background = 1
- processing = 1
- while(1) //far more efficient than recursively calling ourself
- if(!Failsafe) new /datum/failsafe()
-
- var/currenttime = world.timeofday
- last_tick_duration = (currenttime - last_tick_timeofday) / 10
- last_tick_timeofday = currenttime
-
- if(processing)
- var/start_time = world.timeofday
- controller_iteration++
-
- air_master.process()
- sleep(breather_ticks)
-
- sun.calc_position()
- sleep(breather_ticks)
-
- for(var/mob/living/M in world) //only living mobs have life processes
- M.Life()
- sleep(breather_ticks)
-
- for(var/datum/disease/D in active_diseases)
- last_disease_processed = D
- D.process()
- sleep(breather_ticks)
-
- for(var/obj/machinery/machine in machines)
- if(machine)
- last_machine_processed = machine
- machine.process()
- if(machine && machine.use_power)
- machine.auto_use_power()
- sleep(breather_ticks)
-
- for(var/obj/object in processing_objects)
- last_obj_processed = object
- object.process()
- sleep(breather_ticks)
-
- for(var/datum/pipe_network/network in pipe_networks)
- network.process()
- sleep(breather_ticks)
-
-
- for(var/datum/powernet/P in powernets)
- P.reset()
- sleep(breather_ticks)
-
- ticker.process()
-
- sleep( minimum_ticks - max(world.timeofday-start_time,0) ) //to prevent long delays happening at midnight
-
- else
- sleep(10)
-
-
-
-/datum/failsafe // This thing pretty much just keeps poking the master controller
- var/spinning = 1
- var/current_iteration = 0
- var/ticks_per_spin = 100 //poke the MC every 10 seconds
- var/defcon = 0 //alert level. For every poke that fails this is raised by 1. When it reaches 5 the MC is replaced with a new one. (effectively killing any master_controller.process() and starting a new one)
-
-/datum/failsafe/New()
- //There can be only one failsafe. Out with the old in with the new (that way we can restart the Failsafe by spawning a new one)
- if(Failsafe && (Failsafe != src))
- del(Failsafe)
- Failsafe = src
-
- current_iteration = controller_iteration
- spawn(0)
- Failsafe.spin()
-
-
-/datum/failsafe/proc/spin()
- set background = 1
- while(1) //more efficient than recursivly calling ourself over and over. background = 1 ensures we do not trigger an infinite loop
- if(master_controller)
- if(spinning && master_controller.processing) //only poke if these overrides aren't in effect
- if(current_iteration == controller_iteration) //master_controller hasn't finished processing in the defined interval
- switch(defcon)
- if(0 to 3)
- defcon++
- if(4)
- defcon = 5
- for(var/client/C)
- if(C.holder)
- C << "Warning. The Master Controller has not fired in the last [defcon*ticks_per_spin] ticks. Automatic restart in [ticks_per_spin] ticks."
- if(5)
- for(var/client/C)
- if(C.holder)
- C << "Warning. The Master Controller has still not fired within the last [defcon*ticks_per_spin] ticks. Killing and restarting..."
- spawn(0)
- new /datum/controller/game_controller() //replace the old master_controller (hence killing the old one's process)
- master_controller.process() //Start it rolling again
- defcon = 0
- else
- defcon = 0
- current_iteration = controller_iteration
- else
- defcon = 0
- else
- new /datum/controller/game_controller() //replace the missing master_controller! This should never happen.
- sleep(ticks_per_spin)
-
-//DEBUG VERBS
-/*
-/client/verb/spawn_MC()
- new /datum/controller/game_controller()
-
-
-/client/verb/spawn_FS()
- new /datum/failsafe()
-*/
\ No newline at end of file
diff --git a/code/controllers/_DynamicAreaLighting_TG.dm b/code/controllers/_DynamicAreaLighting_TG.dm
index 8a00ca9e1fa..519b5807086 100644
--- a/code/controllers/_DynamicAreaLighting_TG.dm
+++ b/code/controllers/_DynamicAreaLighting_TG.dm
@@ -37,9 +37,6 @@
#define LIGHTING_LAYER 10 //Drawing layer for lighting overlays
#define LIGHTING_ICON 'icons/effects/ss13_dark_alpha7.dmi' //Icon used for lighting shading effects
-datum/controller/lighting/New() //moved here so its in the define. eek :S
- lighting_states = max( 0, length(icon_states(LIGHTING_ICON))-1 )
-
datum/light_source
var/atom/owner
var/changed = 1
@@ -302,4 +299,4 @@ area
#undef LIGHTING_MAX_LUMINOSITY
#undef LIGHTING_MAX_LUMINOSITY_MOB
#undef LIGHTING_LAYER
-#undef LIGHTING_ICON
\ No newline at end of file
+//#undef LIGHTING_ICON
\ No newline at end of file
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index fae4575187b..b41cd570535 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -78,6 +78,20 @@
var/revival_cloning = 1
var/revival_brain_life = -1
+ //Used for modifying movement speed for mobs.
+ //Unversal modifiers
+ var/run_speed = 0
+ var/walk_speed = 0
+
+ //Mob specific modifiers. NOTE: These will affect different mob types in different ways
+ var/human_delay = 0
+ var/robot_delay = 0
+ var/monkey_delay = 0
+ var/alien_delay = 0
+ var/metroid_delay = 0
+ var/animal_delay = 0
+
+
/datum/configuration/New()
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
for (var/T in L)
@@ -341,6 +355,22 @@
config.revival_cloning = value
if("revival_brain_life")
config.revival_brain_life = value
+ if("run_speed")
+ config.run_speed = value
+ if("walk_speed")
+ config.walk_speed = value
+ if("human_delay")
+ config.human_delay = value
+ if("robot_delay")
+ config.robot_delay = value
+ if("monkey_delay")
+ config.monkey_delay = value
+ if("alien_delay")
+ config.alien_delay = value
+ if("metroid_delay")
+ config.metroid_delay = value
+ if("animal_delay")
+ config.animal_delay = value
else
diary << "Unknown setting in configuration: '[name]'"
diff --git a/code/controllers/lighting_controller.dm b/code/controllers/lighting_controller.dm
index b21b1cc6378..3d4f859efaf 100644
--- a/code/controllers/lighting_controller.dm
+++ b/code/controllers/lighting_controller.dm
@@ -16,6 +16,15 @@ datum/controller/lighting
var/list/changed_turfs = list()
var/changed_turfs_workload_max = 0
+datum/controller/lighting/New()
+ lighting_states = max( 0, length(icon_states(LIGHTING_ICON))-1 )
+ if(lighting_controller != src)
+ if(istype(lighting_controller,/datum/controller/lighting))
+ Recover() //if we are replacing an existing lighting_controller (due to a crash) we attempt to preserve as much as we can
+ del(lighting_controller)
+ lighting_controller = src
+
+
//Workhorse of lighting. It cycles through each light to see which ones need their effects updating. It updates their
//effects and then processes every turf in the queue, moving the turfs to the corresponing lighting sub-area.
//All queue lists prune themselves, which will cause lights with no luminosity to be garbage collected (cheaper and safer
@@ -33,9 +42,10 @@ datum/controller/lighting/proc/process()
lights_workload_max = max(lights_workload_max,lights.len)
for(var/i=1, i<=lights.len, i++)
var/datum/light_source/L = lights[i]
- if(L.check())
- lights.Cut(i,i+1)
- i--
+ if(L && !L.check())
+ continue
+ lights.Cut(i,i+1)
+ i--
sleep(-1)
@@ -78,4 +88,42 @@ datum/controller/lighting/proc/Initialize(var/z_level)
var/turf/T = locate(i,j,k)
if(T) T.shift_to_subarea()
- changed_turfs.Cut() // reset the changed list
\ No newline at end of file
+ changed_turfs.Cut() // reset the changed list
+
+
+//Used to strip valid information from an existing controller and transfer it to a replacement
+//It works by using spawn(-1) to transfer the data, if there is a runtime the data does not get transfered but the loop
+//does not crash
+datum/controller/lighting/proc/Recover()
+ if(!istype(lighting_controller.changed_turfs,/list))
+ lighting_controller.changed_turfs = list()
+ if(!istype(lighting_controller.lights,/list))
+ lighting_controller.lights = list()
+
+ for(var/i=1, i<=lighting_controller.lights.len, i++)
+ var/datum/light_source/L = lighting_controller.lights[i]
+ if(istype(L))
+ spawn(-1) //so we don't crash the loop (inefficient)
+ L.check()
+ lights += L //If we didn't runtime then this will get transferred over
+
+ for(var/i=1, i<=lighting_controller.changed_turfs.len, i++)
+ var/turf/T = lighting_controller.changed_turfs[i]
+ if(istype(T) && T.lighting_changed)
+ spawn(-1)
+ T.shift_to_subarea()
+
+ var/msg = "## DEBUG: [time2text(world.timeofday)] lighting_controller restarted. Reports:\n"
+ for(var/varname in lighting_controller.vars)
+ switch(varname)
+ if("tag","bestF","type","parent_type","vars") continue
+ else
+ var/varval1 = lighting_controller.vars[varname]
+ var/varval2 = vars[varname]
+ if(istype(varval1,/list))
+ varval1 = "/list([length(varval1)])"
+ varval2 = "/list([length(varval2)])"
+ msg += "\t [varname] = [varval1] -> [varval2]\n"
+ world.log << msg
+
+#undef LIGHTING_ICON
diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm
index 7256e78bb6e..248c760c4df 100644
--- a/code/controllers/master_controller.dm
+++ b/code/controllers/master_controller.dm
@@ -1,211 +1,310 @@
+//simplified MC that is designed to fail when procs 'break'. When it fails it's just replaced with a new one.
+//It ensures master_controller.process() is never doubled up by killing the MC (hence terminating any of its sleeping procs)
+//WIP, needs lots of work still
+
var/global/datum/controller/game_controller/master_controller //Set in world.New()
var/global/datum/failsafe/Failsafe
+
var/global/controller_iteration = 0
-
-
var/global/last_tick_timeofday = world.timeofday
var/global/last_tick_duration = 0
datum/controller/game_controller
var/processing = 0
+ var/breather_ticks = 2 //a somewhat crude attempt to iron over the 'bumps' caused by high-cpu use by letting the MC have a breather for this many ticks after every loop
+ var/minimum_ticks = 20 //The minimum length of time between MC ticks
- var/global/air_master_ready = 0
- var/global/sun_ready = 0
- var/global/mobs_ready = 0
- var/global/diseases_ready = 0
- var/global/machines_ready = 0
- var/global/objects_ready = 0
- var/global/networks_ready = 0
- var/global/powernets_ready = 0
- var/global/ticker_ready = 0
+ var/air_cost = 0
+ var/sun_cost = 0
+ var/mobs_cost = 0
+ var/diseases_cost = 0
+ var/machines_cost = 0
+ var/objects_cost = 0
+ var/networks_cost = 0
+ var/powernets_cost = 0
+ var/ticker_cost = 0
+ var/total_cost = 0
- //Used for MC 'proc break' debugging
- var/global/obj/last_obj_processed
- var/global/datum/disease/last_disease_processed
- var/global/obj/machinery/last_machine_processed
- var/global/mob/last_mob_processed
+ var/last_thing_processed
+
+datum/controller/game_controller/New()
+ //There can be only one master_controller. Out with the old and in with the new.
+ if(master_controller != src)
+ if(istype(master_controller,/datum/controller/game_controller))
+ Recover()
+ del(master_controller)
+ master_controller = src
+
+ if(!air_master)
+ air_master = new /datum/controller/air_system()
+ air_master.setup()
+
+ if(!job_master)
+ job_master = new /datum/controller/occupations()
+ if(job_master.SetupOccupations())
+ world << "\red \b Job setup complete"
+ job_master.LoadJobs("config/jobs.txt")
+
+ if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase()
+ if(!syndicate_code_response) syndicate_code_response = generate_code_phrase()
+ if(!ticker) ticker = new /datum/controller/gameticker()
+ if(!emergency_shuttle) emergency_shuttle = new /datum/shuttle_controller/emergency_shuttle()
- proc/setup()
- if(master_controller && (master_controller != src))
- del(src)
- return
- //There can be only one master.
+datum/controller/game_controller/proc/setup()
+ world.tick_lag = config.Ticklag
- if(!air_master)
- air_master = new /datum/controller/air_system()
- air_master.setup()
+ createRandomZlevel()
+ setup_objects()
+ setupgenetics()
+ setupfactions()
- if(!job_master)
- job_master = new /datum/controller/occupations()
- if(job_master.SetupOccupations())
- world << "\red \b Job setup complete"
- job_master.LoadJobs("config/jobs.txt")
+ for(var/i=0, i 600)
- var/MC_report = "air_master_ready = [air_master_ready]; sun_ready = [sun_ready]; mobs_ready = [mobs_ready]; diseases_ready = [diseases_ready]; machines_ready = [machines_ready]; objects_ready = [objects_ready]; networks_ready = [networks_ready]; powernets_ready = [powernets_ready]; ticker_ready = [ticker_ready];"
- message_admins("PROC BREAKAGE WARNING: The game's master contorller appears to be stuck in one of it's cycles. It has looped through it's delaying loop [IL_check] times.")
- message_admins("The master controller reports: [MC_report]")
- if(!diseases_ready)
- if(last_disease_processed)
- message_admins("DISEASE PROCESSING stuck on [last_disease_processed]", 0, 1)
- else
- message_admins("DISEASE PROCESSING stuck on unknown")
- if(!machines_ready)
- if(last_machine_processed)
- message_admins("MACHINE PROCESSING stuck on [last_machine_processed]", 0, 1)
- else
- message_admins("MACHINE PROCESSING stuck on unknown")
- if(!objects_ready)
- if(last_obj_processed)
- message_admins("OBJ PROCESSING stuck on [last_obj_processed]", 0, 1)
- else
- message_admins("OBJ PROCESSING stuck on unknown")
- log_admin("PROC BREAKAGE WARNING: infinite_loop_check = [IL_check]; [MC_report];")
- message_admins("Master controller breaking out of delaying loop. Restarting the round is advised if problem persists. DO NOT manually restart the master controller.")
- break;
- sleep(1)
+ var/end_time = world.timeofday
+ if(end_time < start_time)
+ start_time -= 864000 //deciseconds in a day
+ sleep( round(minimum_ticks - (end_time - start_time),1) )
+ else
+ sleep(10)
- sleep(world.timeofday+12-start_time)
+datum/controller/game_controller/proc/Recover() //Mostly a placeholder for now.
+ var/msg = "## DEBUG: [time2text(world.timeofday)] MC restarted. Reports:\n"
+ for(var/varname in master_controller.vars)
+ switch(varname)
+ if("tag","bestF","type","parent_type","vars") continue
+ else
+ var/varval = master_controller.vars[varname]
+ if(istype(varval,/datum))
+ var/datum/D = varval
+ msg += "\t [varname] = [D.type]\n"
else
- sleep(10)
\ No newline at end of file
+ msg += "\t [varname] = [varval]\n"
+ world.log << msg
+
+/datum/failsafe // This thing pretty much just keeps poking the master controller
+ var/spinning = 1
+ var/current_iteration = 0
+ var/ticks_per_spin = 100 //poke the MC every 10 seconds
+ var/defcon = 0 //alert level. For every poke that fails this is raised by 1. When it reaches 5 the MC is replaced with a new one. (effectively killing any master_controller.process() and starting a new one)
+
+/datum/failsafe/New()
+ //There can be only one failsafe. Out with the old in with the new (that way we can restart the Failsafe by spawning a new one)
+ if(Failsafe && (Failsafe != src))
+ del(Failsafe)
+ Failsafe = src
+
+ current_iteration = controller_iteration
+ Failsafe.spin()
+
+
+/datum/failsafe/proc/spin()
+ spawn(0)
+ set background = 1
+ while(1) //more efficient than recursivly calling ourself over and over. background = 1 ensures we do not trigger an infinite loop
+ if(master_controller)
+ if(spinning && master_controller.processing) //only poke if these overrides aren't in effect
+ if(current_iteration == controller_iteration) //master_controller hasn't finished processing in the defined interval
+ switch(defcon)
+ if(0 to 3)
+ defcon++
+ if(4)
+ defcon = 5
+ for(var/client/C in admin_list)
+ if(C.holder)
+ C << "Warning. The Master Controller has not fired in the last [defcon*ticks_per_spin] ticks. Automatic restart in [ticks_per_spin] ticks."
+ if(5)
+ for(var/client/C in admin_list)
+ if(C.holder)
+ C << "Warning. The Master Controller has still not fired within the last [defcon*ticks_per_spin] ticks. Killing and restarting..."
+ new /datum/controller/game_controller() //replace the old master_controller (hence killing the old one's process)
+ master_controller.process() //Start it rolling again
+ defcon = 0
+ else
+ defcon = 0
+ current_iteration = controller_iteration
+ else
+ defcon = 0
+ else
+ new /datum/controller/game_controller() //replace the missing master_controller! This should never happen.
+ sleep(ticks_per_spin)
+
+//DEBUG VERBS
+/*
+/client/verb/spawn_MC()
+ new /datum/controller/game_controller()
+
+
+/client/verb/spawn_FS()
+ new /datum/failsafe()
+
+/client/verb/machines_list()
+ for(var/i=1,i<=machines.len,i++)
+ var/machine = machines[i]
+ if(istype(machine,/datum)) world.log << machine:type
+ else world.log << machine
+*/
\ No newline at end of file
diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm
index 78e3bce9de4..04a1a47fed9 100644
--- a/code/controllers/verbs.dm
+++ b/code/controllers/verbs.dm
@@ -1,5 +1,5 @@
//TODO: rewrite and standardise all controller datums to the datum/controller type
-//TODO: allow all controllers to be deleted for clean restarts (see WIP master controller stuff)
+//TODO: allow all controllers to be deleted for clean restarts (see WIP master controller stuff) - MC done - lighting done
/client/proc/restart_controller(controller in list("Master","Lighting","Supply Shuttle"))
set category = "Debug"
@@ -11,9 +11,11 @@
src = null
switch(controller)
if("Master")
+ new /datum/controller/game_controller()
master_controller.process()
feedback_add_details("admin_verb","RMC")
if("Lighting")
+ new /datum/controller/lighting()
lighting_controller.process()
feedback_add_details("admin_verb","RLighting")
if("Supply Shuttle")
diff --git a/code/datums/spell.dm b/code/datums/spell.dm
index 0df7e595ca0..e3baeaf51dd 100644
--- a/code/datums/spell.dm
+++ b/code/datums/spell.dm
@@ -229,7 +229,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
switch(max_targets)
if(0) //unlimited
- for(var/mob/target in view_or_range(range, user, selection_type))
+ for(var/mob/living/target in view_or_range(range, user, selection_type))
targets += target
if(1) //single target can be picked
if(range < 0)
@@ -241,7 +241,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
targets += input("Choose the target for the spell.", "Targeting") as mob in possible_targets
else
var/list/possible_targets = list()
- for(var/mob/target in view_or_range(range, user, selection_type))
+ for(var/mob/living/target in view_or_range(range, user, selection_type))
possible_targets += target
for(var/i=1,i<=max_targets,i++)
if(!possible_targets.len)
diff --git a/code/defines/area/Space Station 13 areas.dm b/code/defines/area/Space Station 13 areas.dm
index f3929885fc3..e910c918f8c 100755
--- a/code/defines/area/Space Station 13 areas.dm
+++ b/code/defines/area/Space Station 13 areas.dm
@@ -1437,20 +1437,21 @@ proc/process_ghost_teleport_locs()
+// Away Missions
+/area/awaymission
+ name = "\improper Strange Location"
+ icon_state = "away"
+
+/area/awaymission/example
+ name = "\improper Strange Station"
+ icon_state = "away"
+
+/area/awaymission/desert
+ name = "Mars"
+ icon_state = "away"
-
-
-
-
-
-
-/area/turret_protected/AssistantRoom
- name = "\improper Assistant Room"
- icon_state = "storage"
- lighting_use_dynamic = 0
-
/////////////////////////////////////////////////////////////////////
/*
Lists of areas to be used with is_type_in_list.
diff --git a/code/defines/obj.dm b/code/defines/obj.dm
index 37bde534a43..0f09c88fc9a 100644
--- a/code/defines/obj.dm
+++ b/code/defines/obj.dm
@@ -1,83 +1,3 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
-
-/obj
- //var/datum/module/mod //not used
- var/m_amt = 0 // metal
- var/g_amt = 0 // glass
- var/w_amt = 0 // waster amounts
- var/origin_tech = null //Used by R&D to determine what research bonuses it grants.
- var/reliability = 100 //Used by SOME devices to determine how reliable they are.
- var/crit_fail = 0
- var/unacidable = 0 //universal "unacidabliness" var, here so you can use it in any obj.
- var/datum/marked_datum
- animate_movement = 2
- var/throwforce = 1
- var/list/attack_verb = list() //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
-
-/obj/proc/handle_internal_lifeform(mob/lifeform_inside_me, breath_request)
- //Return: (NONSTANDARD)
- // null if object handles breathing logic for lifeform
- // datum/air_group to tell lifeform to process using that breath return
- //DEFAULT: Take air from turf to give to have mob process
- if(breath_request>0)
- return remove_air(breath_request)
- else
- return null
-
-/obj/proc/initialize()
- return
-
-/obj/proc/updateUsrDialog()
- var/list/nearby = viewers(1, src)
- for(var/mob/M in nearby)
- if ((M.client && M.machine == src))
- src.attack_hand(M)
- if (istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot))
- if (!(usr in nearby))
- if (usr.client && usr.machine==src) // && M.machine == src is omitted because if we triggered this by using the dialog, it doesn't matter if our machine changed in between triggering it and this - the dialog is probably still supposed to refresh.
- src.attack_ai(usr)
-
- // check for TK users
- //AutoUpdateTK(src)
- if (istype(usr, /mob/living/carbon/human))
- if(istype(usr.l_hand, /obj/item/tk_grab) || istype(usr.r_hand, /obj/item/tk_grab/))
- if(!(usr in nearby))
- if(usr.client && usr.machine==src)
- src.attack_hand(usr)
-
-/obj/proc/updateDialog()
- var/list/nearby = viewers(1, src)
- for(var/mob/M in nearby)
- if ((M.client && M.machine == src))
- src.attack_hand(M)
- AutoUpdateAI(src)
- //AutoUpdateTK(src)
-
-/obj/proc/update_icon()
- return
-
-/obj/item/proc/updateSelfDialog()
- var/mob/M = src.loc
- if(istype(M) && M.client && M.machine == src)
- src.attack_self(M)
-
-
-/obj/proc/alter_health()
- return 1
-
-/obj/proc/hide(h)
- return
-
-
-/obj/proc/hear_talk(mob/M as mob, text)
-/*
- var/mob/mo = locate(/mob) in src
- if(mo)
- var/rendered = "[M.name]: [text]"
- mo.show_message(rendered, 2)
- */
- return
-
/obj/structure/signpost
icon = 'icons/obj/stationobjs.dmi'
icon_state = "signpost"
@@ -112,6 +32,14 @@
var/state = 1
//state = 1 for playing : default
//state = 2 for observing
+ var/admincaster_screen = 0 //See newscaster.dm under machinery for a full description
+ var/datum/feed_message/admincaster_feed_message = new /datum/feed_message //These two will act as holders.
+ var/datum/feed_channel/admincaster_feed_channel = new /datum/feed_channel
+ var/admincaster_signature //What you'll sign the newsfeeds as
+
+/obj/admins/New()
+ src.admincaster_signature = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]"
+ ..()
/obj/effect/beam
name = "beam"
@@ -119,13 +47,6 @@
var/def_zone
pass_flags = PASSTABLE
-/obj/structure/bedsheetbin
- name = "linen bin"
- desc = "A bin for containing bedsheets. It looks rather cosy."
- icon = 'icons/obj/items.dmi'
- icon_state = "bedbin"
- var/amount = 23.0
- anchored = 1.0
/obj/effect/begin
name = "begin"
@@ -142,142 +63,6 @@
//This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
var/locked[] = list()
- proc/get_manifest(monochrome)
- var/list/heads = new()
- var/list/sec = new()
- var/list/eng = new()
- var/list/med = new()
- var/list/sci = new()
- var/list/civ = new()
- var/list/bot = new()
- var/list/misc = new()
-
- var/dat = {"
-
-
- | Name | Rank |
- "}
- var/even = 0
-
- // sort mobs
- for(var/datum/data/record/t in data_core.general)
- var/name = t.fields["name"]
- var/rank = t.fields["rank"]
- var/real_rank = t.fields["real_rank"]
-
- //world << "[name]: [rank]"
-
- if(real_rank in command_positions)
- heads[name] = rank
- if(real_rank in security_positions)
- sec[name] = rank
- continue
- if(real_rank in engineering_positions)
- eng[name] = rank
- continue
- if(real_rank in medical_positions)
- med[name] = rank
- continue
- if(real_rank in science_positions)
- sci[name] = rank
- continue
- if(real_rank in civilian_positions)
- civ[name] = rank
- continue
- if(real_rank in nonhuman_positions)
- bot[name] = rank
- continue
-
- if(!(name in heads))
- misc[name] = rank
-
- if(heads.len > 0)
- dat += "| Heads |
"
- for(name in heads)
- dat += "| [name] | [heads[name]] |
"
- even = !even
-
- if(sec.len > 0)
- dat += "| Security |
"
- for(name in sec)
- dat += "| [name] | [sec[name]] |
"
- even = !even
-
- if(eng.len > 0)
- dat += "| Engineering |
"
- for(name in eng)
- dat += "| [name] | [eng[name]] |
"
- even = !even
-
- if(med.len > 0)
- dat += "| Medical |
"
- for(name in med)
- dat += "| [name] | [med[name]] |
"
- even = !even
-
- if(sci.len > 0)
- dat += "| Science |
"
- for(name in sci)
- dat += "| [name] | [sci[name]] |
"
- even = !even
-
- if(civ.len > 0)
- dat += "| Civilian |
"
- for(name in civ)
- dat += "| [name] | [civ[name]] |
"
- even = !even
-
- // in case somebody is insane and added them to the manifest, why not
- if(bot.len > 0)
- dat += "| Silicon |
"
- for(name in bot)
- dat += "| [name] | [bot[name]] |
"
- even = !even
-
- // misc guys
- if(misc.len > 0)
- dat += "| Miscellaneous |
"
- for(name in misc)
- dat += "| [name] | [misc[name]] |
"
- even = !even
-
- dat += "
"
- dat = dd_replacetext(dat, "\n", "") // so it can be placed on paper correctly
- dat = dd_replacetext(dat, "\t", "")
- return dat
-
-/obj/hud
- name = "hud"
- unacidable = 1
- var/mob/mymob = null
- var/list/adding = null
- var/list/other = null
- var/obj/screen/druggy = null
- var/vimpaired = null
- var/obj/screen/alien_view = null
- var/obj/screen/g_dither = null
- var/obj/screen/blurry = null
- var/list/darkMask = null
- var/obj/screen/r_hand_hud_object = null
- var/obj/screen/l_hand_hud_object = null
- var/show_intent_icons = 0
- var/list/obj/screen/hotkeybuttons = null
- var/hotkey_ui_hidden = 0 //This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons)
-
- var/list/obj/screen/item_action/item_action_list = null //Used for the item action ui buttons.
-
- var/h_type = /obj/screen //this is like...the most pointless thing ever. Use a god damn define!
-
-/obj/item/device
- icon = 'icons/obj/device.dmi'
-
/obj/item/device/infra_sensor
name = "Infrared Sensor"
desc = "Scans for infrared beams in the vicinity."
@@ -288,45 +73,6 @@
m_amt = 150
origin_tech = "magnets=2"
-/obj/item/device/multitool
- name = "multitool"
- desc = "Used for pulsing wires to test which to cut. Not recommended by doctors."
- icon_state = "multitool"
- flags = FPRINT | TABLEPASS| CONDUCT
- force = 5.0
- w_class = 2.0
- throwforce = 5.0
- throw_range = 15
- throw_speed = 3
- desc = "You can use this on airlocks or APCs to try to hack them without cutting wires."
- m_amt = 50
- g_amt = 20
- origin_tech = "magnets=1;engineering=1"
- var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage
-
-/obj/item/blueprints
- name = "station blueprints"
- desc = "Blueprints of the station. There's stamp \"Classified\" and several coffee stains on it."
- icon = 'icons/obj/items.dmi'
- icon_state = "blueprints"
- attack_verb = list("attacked", "bapped", "hit")
-
-/obj/item/apc_frame
- name = "APC frame"
- desc = "Used for repairing or building APCs"
- icon = 'icons/obj/apc_repair.dmi'
- icon_state = "apc_frame"
- flags = FPRINT | TABLEPASS| CONDUCT
-
-/obj/effect/landmark
- name = "landmark"
- icon = 'icons/mob/screen1.dmi'
- icon_state = "x2"
- anchored = 1.0
- unacidable = 1
-
-/obj/effect/landmark/alterations
- name = "alterations"
/obj/effect/laser
name = "laser"
@@ -335,80 +81,6 @@
var/damage = 0.0
var/range = 10.0
-/obj/structure/lattice
- desc = "A lightweight support lattice."
- name = "lattice"
- icon = 'icons/obj/structures.dmi'
- icon_state = "latticefull"
- density = 0
- anchored = 1.0
- layer = 2.3 //under pipes
- // flags = CONDUCT
-
-/obj/structure/lattice/New()
- ..()
- if(!(istype(src.loc, /turf/space)))
- del(src)
- for(var/obj/structure/lattice/LAT in src.loc)
- if(LAT != src)
- del(LAT)
- icon = 'icons/obj/smoothlattice.dmi'
- icon_state = "latticeblank"
- updateOverlays()
- for (var/dir in cardinal)
- var/obj/structure/lattice/L
- if(locate(/obj/structure/lattice, get_step(src, dir)))
- L = locate(/obj/structure/lattice, get_step(src, dir))
- L.updateOverlays()
-
-/obj/structure/lattice/Del()
- for (var/dir in cardinal)
- var/obj/structure/lattice/L
- if(locate(/obj/structure/lattice, get_step(src, dir)))
- L = locate(/obj/structure/lattice, get_step(src, dir))
- L.updateOverlays(src.loc)
- ..()
-
-/obj/structure/lattice/proc/updateOverlays()
- //if(!(istype(src.loc, /turf/space)))
- // del(src)
- spawn(1)
- overlays = list()
-
- var/dir_sum = 0
-
- for (var/direction in cardinal)
- if(locate(/obj/structure/lattice, get_step(src, direction)))
- dir_sum += direction
- else
- if(!(istype(get_step(src, direction), /turf/space)))
- dir_sum += direction
-
- icon_state = "lattice[dir_sum]"
- return
-
- /*
- overlays += icon(icon,"lattice-middlebar") //the nw-se bar in the cneter
- for (var/dir in cardinal)
- if(locate(/obj/structure/lattice, get_step(src, dir)))
- src.overlays += icon(icon,"lattice-[dir2text(dir)]")
- else
- src.overlays += icon(icon,"lattice-nc-[dir2text(dir)]") //t for turf
- if(!(istype(get_step(src, dir), /turf/space)))
- src.overlays += icon(icon,"lattice-t-[dir2text(dir)]") //t for turf
-
- //if ( !( (locate(/obj/structure/lattice, get_step(src, SOUTH))) || (locate(/obj/structure/lattice, get_step(src, EAST))) ))
- // src.overlays += icon(icon,"lattice-c-se")
- if ( !( (locate(/obj/structure/lattice, get_step(src, NORTH))) || (locate(/obj/structure/lattice, get_step(src, WEST))) ))
- src.overlays += icon(icon,"lattice-c-nw")
- if ( !( (locate(/obj/structure/lattice, get_step(src, NORTH))) || (locate(/obj/structure/lattice, get_step(src, EAST))) ))
- src.overlays += icon(icon,"lattice-c-ne")
- if ( !( (locate(/obj/structure/lattice, get_step(src, SOUTH))) || (locate(/obj/structure/lattice, get_step(src, WEST))) ))
- src.overlays += icon(icon,"lattice-c-sw")
-
- if(!(overlays))
- icon_state = "latticefull"
- */
/obj/effect/list_container
name = "list container"
@@ -419,29 +91,6 @@
var/list/container = list( )
-/obj/structure/m_tray
- name = "morgue tray"
- desc = "Apply corpse before closing."
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "morguet"
- density = 1
- layer = 2.0
- var/obj/structure/morgue/connected = null
- anchored = 1.0
-
-/obj/structure/c_tray
- name = "crematorium tray"
- desc = "Apply body before burning."
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "cremat"
- density = 1
- layer = 2.0
- var/obj/structure/crematorium/connected = null
- anchored = 1.0
-
-
-
-
/obj/structure/cable
level = 1
@@ -485,438 +134,18 @@
color="white"
icon = 'icons/obj/power_cond_white.dmi'
-/obj/effect/manifest
- name = "manifest"
- icon = 'icons/mob/screen1.dmi'
- icon_state = "x"
- unacidable = 1//Just to be sure.
-
-/obj/structure/morgue
- name = "morgue"
- desc = "Used to keep bodies in untill someone fetches them."
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "morgue1"
- density = 1
- var/obj/structure/m_tray/connected = null
- anchored = 1.0
-
-/obj/structure/crematorium
- name = "crematorium"
- desc = "A human incinerator. Works well on barbeque nights."
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "crema1"
- density = 1
- var/obj/structure/c_tray/connected = null
- anchored = 1.0
- var/cremating = 0
- var/id = 1
- var/locked = 0
-
-/obj/effect/mine
- name = "Mine"
- desc = "I Better stay away from that thing."
- density = 1
- anchored = 1
- layer = 3
- icon = 'icons/obj/weapons.dmi'
- icon_state = "uglymine"
- var/triggerproc = "explode" //name of the proc thats called when the mine is triggered
- var/triggered = 0
-
-/obj/effect/mine/dnascramble
- name = "Radiation Mine"
- icon_state = "uglymine"
- triggerproc = "triggerrad"
-
-/obj/effect/mine/plasma
- name = "Plasma Mine"
- icon_state = "uglymine"
- triggerproc = "triggerplasma"
-
-/obj/effect/mine/kick
- name = "Kick Mine"
- icon_state = "uglymine"
- triggerproc = "triggerkick"
-
-/obj/effect/mine/n2o
- name = "N2O Mine"
- icon_state = "uglymine"
- triggerproc = "triggern2o"
-
-/obj/effect/mine/stun
- name = "Stun Mine"
- icon_state = "uglymine"
- triggerproc = "triggerstun"
-
-/obj/effect/overlay
- name = "overlay"
- unacidable = 1
- var/i_attached//Added for possible image attachments to objects. For hallucinations and the like.
-
-/obj/effect/overlay/beam//Not actually a projectile, just an effect.
- name="beam"
- icon='icons/effects/beam.dmi'
- icon_state="b_beam"
- var/tmp/atom/BeamSource
- New()
- ..()
- spawn(10) del src
-
-/obj/effect/portal
- name = "portal"
- desc = "Looks unstable."
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "portal"
- density = 1
- unacidable = 1//Can't destroy energy portals.
- var/failchance = 5
- var/obj/item/target = null
- var/creator = null
- anchored = 1.0
/obj/effect/projection
name = "Projection"
desc = "This looks like a projection of something."
anchored = 1.0
-/obj/structure/rack
- name = "rack"
- desc = "Different from the Middle Ages version."
- icon = 'icons/obj/objects.dmi'
- icon_state = "rack"
- density = 1
- flags = FPRINT
- anchored = 1.0
- throwpass = 1 //You can throw objects over this, despite it's density.
/obj/effect/shut_controller
name = "shut controller"
var/moving = null
var/list/parts = list( )
-/obj/effect/landmark/start
- name = "start"
- icon = 'icons/mob/screen1.dmi'
- icon_state = "x"
- anchored = 1.0
-
-/obj/structure/stool
- name = "stool"
- desc = "Apply butt."
- icon = 'icons/obj/objects.dmi'
- icon_state = "stool"
- anchored = 1.0
- flags = FPRINT
- pressure_resistance = 3*ONE_ATMOSPHERE
-
-/obj/structure/stool/bed
- name = "bed"
- desc = "This is used to lie in, sleep in or strap on."
- icon_state = "bed"
- var/mob/living/buckled_mob
-
-/obj/structure/stool/bed/alien
- name = "resting contraption"
- desc = "This looks similar to contraptions from earth. Could aliens be stealing our technology?"
- icon_state = "abed"
-
-/obj/structure/stool/bed/nest
- name = "alien nest"
- desc = "It's a gruesome pile of thick, sticky resin shaped like a nest."
- icon = 'icons/mob/alien.dmi'
- icon_state = "nest"
- var/health = 100
-
-/obj/structure/stool/bed/chair //YES, chairs are a type of bed, which are a type of stool. This works, believe me. -Pete
- name = "chair"
- desc = "You sit in this. Either by will or force."
- icon_state = "chair"
-
-/obj/structure/stool/bed/chair/wood/normal
- icon_state = "wooden_chair"
- name = "wooden chair"
- desc = "Old is never too old to not be in fashion."
-
-/obj/structure/stool/bed/chair/wood/wings
- icon_state = "wooden_chair_wings"
- name = "wooden chair"
- desc = "Old is never too old to not be in fashion."
-
-/obj/structure/stool/bed/chair/comfy
- name = "comfy chair"
- desc = "It looks comfy."
-
-/obj/structure/stool/bed/chair/comfy/brown
- icon_state = "comfychair_brown"
-
-/obj/structure/stool/bed/chair/comfy/beige
- icon_state = "comfychair_beige"
-
-/obj/structure/stool/bed/chair/comfy/teal
- icon_state = "comfychair_teal"
-
-/obj/structure/stool/bed/chair/office
- anchored = 0
-
-/obj/structure/stool/bed/chair/comfy/black
- icon_state = "comfychair_black"
-
-/obj/structure/stool/bed/chair/comfy/lime
- icon_state = "comfychair_lime"
-
-/obj/structure/stool/bed/chair/office/Move()
- ..()
- handle_rotation()
-
-/obj/structure/stool/bed/chair/office/light
- icon_state = "officechair_white"
-
-/obj/structure/stool/bed/chair/office/dark
- icon_state = "officechair_dark"
-
-/obj/structure/table
- name = "table"
- desc = "A square piece of metal standing on four metal legs. It can not move."
- icon = 'icons/obj/structures.dmi'
- icon_state = "table"
- density = 1
- anchored = 1.0
- layer = 2.8
- throwpass = 1 //You can throw objects over this, despite it's density.")
-
-/obj/structure/table/New()
- ..()
- for(var/obj/structure/table/T in src.loc)
- if(T != src)
- del(T)
- update_icon()
- for(var/direction in list(1,2,4,8,5,6,9,10))
- if(locate(/obj/structure/table,get_step(src,direction)))
- var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,direction))
- T.update_icon()
-
-/obj/structure/table/Del()
- for(var/direction in list(1,2,4,8,5,6,9,10))
- if(locate(/obj/structure/table,get_step(src,direction)))
- var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,direction))
- T.update_icon()
- ..()
-
-/obj/structure/table/update_icon()
- spawn(2) //So it properly updates when deleting
- var/dir_sum = 0
- for(var/direction in list(1,2,4,8,5,6,9,10))
- var/skip_sum = 0
- for(var/obj/structure/window/W in src.loc)
- if(W.dir == direction) //So smooth tables don't go smooth through windows
- skip_sum = 1
- continue
- var/inv_direction //inverse direction
- switch(direction)
- if(1)
- inv_direction = 2
- if(2)
- inv_direction = 1
- if(4)
- inv_direction = 8
- if(8)
- inv_direction = 4
- if(5)
- inv_direction = 10
- if(6)
- inv_direction = 9
- if(9)
- inv_direction = 6
- if(10)
- inv_direction = 5
- for(var/obj/structure/window/W in get_step(src,direction))
- if(W.dir == inv_direction) //So smooth tables don't go smooth through windows when the window is on the other table's tile
- skip_sum = 1
- continue
- if(!skip_sum) //means there is a window between the two tiles in this direction
- if(locate(/obj/structure/table,get_step(src,direction)))
- if(direction <5)
- dir_sum += direction
- else
- if(direction == 5) //This permits the use of all table directions. (Set up so clockwise around the central table is a higher value, from north)
- dir_sum += 16
- if(direction == 6)
- dir_sum += 32
- if(direction == 8) //Aherp and Aderp. Jezes I am stupid. -- SkyMarshal
- dir_sum += 8
- if(direction == 10)
- dir_sum += 64
- if(direction == 9)
- dir_sum += 128
-
- var/table_type = 0 //stand_alone table
- if(dir_sum%16 in cardinal)
- table_type = 1 //endtable
- dir_sum %= 16
- if(dir_sum%16 in list(3,12))
- table_type = 2 //1 tile thick, streight table
- if(dir_sum%16 == 3) //3 doesn't exist as a dir
- dir_sum = 2
- if(dir_sum%16 == 12) //12 doesn't exist as a dir.
- dir_sum = 4
- if(dir_sum%16 in list(5,6,9,10))
- if(locate(/obj/structure/table,get_step(src.loc,dir_sum%16)))
- table_type = 3 //full table (not the 1 tile thick one, but one of the 'tabledir' tables)
- else
- table_type = 2 //1 tile thick, corner table (treated the same as streight tables in code later on)
- dir_sum %= 16
- if(dir_sum%16 in list(13,14,7,11)) //Three-way intersection
- table_type = 5 //full table as three-way intersections are not sprited, would require 64 sprites to handle all combinations. TOO BAD -- SkyMarshal
- switch(dir_sum%16) //Begin computation of the special type tables. --SkyMarshal
- if(7)
- if(dir_sum == 23)
- table_type = 6
- dir_sum = 8
- else if(dir_sum == 39)
- dir_sum = 4
- table_type = 6
- else if(dir_sum == 55 || dir_sum == 119 || dir_sum == 247 || dir_sum == 183)
- dir_sum = 4
- table_type = 3
- else
- dir_sum = 4
- if(11)
- if(dir_sum == 75)
- dir_sum = 5
- table_type = 6
- else if(dir_sum == 139)
- dir_sum = 9
- table_type = 6
- else if(dir_sum == 203 || dir_sum == 219 || dir_sum == 251 || dir_sum == 235)
- dir_sum = 8
- table_type = 3
- else
- dir_sum = 8
- if(13)
- if(dir_sum == 29)
- dir_sum = 10
- table_type = 6
- else if(dir_sum == 141)
- dir_sum = 6
- table_type = 6
- else if(dir_sum == 189 || dir_sum == 221 || dir_sum == 253 || dir_sum == 157)
- dir_sum = 1
- table_type = 3
- else
- dir_sum = 1
- if(14)
- if(dir_sum == 46)
- dir_sum = 1
- table_type = 6
- else if(dir_sum == 78)
- dir_sum = 2
- table_type = 6
- else if(dir_sum == 110 || dir_sum == 254 || dir_sum == 238 || dir_sum == 126)
- dir_sum = 2
- table_type = 3
- else
- dir_sum = 2 //These translate the dir_sum to the correct dirs from the 'tabledir' icon_state.
- if(dir_sum%16 == 15)
- table_type = 4 //4-way intersection, the 'middle' table sprites will be used.
-
- if(istype(src,/obj/structure/table/reinforced))
- switch(table_type)
- if(0)
- icon_state = "reinf_table"
- if(1)
- icon_state = "reinf_1tileendtable"
- if(2)
- icon_state = "reinf_1tilethick"
- if(3)
- icon_state = "reinf_tabledir"
- if(4)
- icon_state = "reinf_middle"
- if(5)
- icon_state = "reinf_tabledir2"
- if(6)
- icon_state = "reinf_tabledir3"
- else if(istype(src,/obj/structure/table/woodentable))
- switch(table_type)
- if(0)
- icon_state = "wood_table"
- if(1)
- icon_state = "wood_1tileendtable"
- if(2)
- icon_state = "wood_1tilethick"
- if(3)
- icon_state = "wood_tabledir"
- if(4)
- icon_state = "wood_middle"
- if(5)
- icon_state = "wood_tabledir2"
- if(6)
- icon_state = "wood_tabledir3"
- else
- switch(table_type)
- if(0)
- icon_state = "table"
- if(1)
- icon_state = "table_1tileendtable"
- if(2)
- icon_state = "table_1tilethick"
- if(3)
- icon_state = "tabledir"
- if(4)
- icon_state = "table_middle"
- if(5)
- icon_state = "tabledir2"
- if(6)
- icon_state = "tabledir3"
- if (dir_sum in list(1,2,4,8,5,6,9,10))
- dir = dir_sum
- else
- dir = 2
-
-/obj/structure/table/reinforced
- name = "reinforced table"
- desc = "A version of the four legged table. It is stronger."
- icon_state = "reinf_table"
- var/status = 2
-
-/obj/structure/table/woodentable
- name = "wooden table"
- desc = "Do not apply fire to this. Rumour says it burns easily."
- icon_state = "wood_table"
-
-/obj/structure/mopbucket
- desc = "Fill it with water, but don't forget a mop!"
- name = "mop bucket"
- icon = 'icons/obj/janitor.dmi'
- icon_state = "mopbucket"
- density = 1
- flags = FPRINT
- pressure_resistance = ONE_ATMOSPHERE
- flags = FPRINT | TABLEPASS | OPENCONTAINER
- var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite
-
-/obj/structure/kitchenspike
- name = "a meat spike"
- icon = 'icons/obj/kitchen.dmi'
- icon_state = "spike"
- desc = "A spike for collecting meat from animals"
- density = 1
- anchored = 1
- var/meat = 0
- var/occupied = 0
- var/meattype = 0 // 0 - Nothing, 1 - Monkey, 2 - Xeno
-
-/obj/structure/displaycase
- name = "Display Case"
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "glassbox1"
- desc = "A display case for prized possessions. It taunts you to kick it."
- density = 1
- anchored = 1
- unacidable = 1//Dissolving the case would also delete the gun.
- var/health = 30
- var/occupied = 1
- var/destroyed = 0
-
/obj/effect/showcase
name = "Showcase"
icon = 'icons/obj/stationobjs.dmi'
@@ -926,47 +155,6 @@
anchored = 1
unacidable = 1//temporary until I decide whether the borg can be removed. -veyveyr
-//BEGIN BRAINS=====================================================
-/obj/item/brain
- name = "brain"
- desc = "A piece of juicy meat found in a persons head."
- icon = 'icons/obj/surgery.dmi'
- icon_state = "brain2"
- flags = TABLEPASS
- force = 1.0
- w_class = 1.0
- throwforce = 1.0
- throw_speed = 3
- throw_range = 5
- origin_tech = "biotech=3"
- attack_verb = list("attacked", "slapped", "whacked")
-
- var/mob/living/carbon/brain/brainmob = null
-
- New()
- ..()
- //Shifting the brain "mob" over to the brain object so it's easier to keep track of. --NEO
- //WASSSSSUUUPPPP /N
- spawn(5)
- if(brainmob && brainmob.client)
- brainmob.client.screen.len = null //clear the hud
-
- proc
- transfer_identity(var/mob/living/carbon/human/H)
- name = "[H]'s brain"
- brainmob = new(src)
- brainmob.name = H.real_name
- brainmob.real_name = H.real_name
- brainmob.dna = H.dna
- brainmob.timeofhostdeath = H.timeofdeath
- if(H.mind)
- H.mind.transfer_to(brainmob)
- brainmob << "\blue You might feel slightly disoriented. That's normal when your brain gets cut out."
- return
-
-//END BRAINS=====================================================
-
-
// Basically this Metroid Core catalyzes reactions that normally wouldn't happen anywhere
/obj/item/metroid_core
@@ -1005,20 +193,6 @@
reagents.clear_reagents()
Flush = 30
-
-
-
-
-/obj/structure/noticeboard
- name = "Notice Board"
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "nboard00"
- flags = FPRINT
- desc = "A board for pinning important notices upon."
- density = 0
- anchored = 1
- var/notices = 0
-
/obj/effect/deskclutter
name = "desk clutter"
icon = 'icons/obj/items.dmi'
@@ -1045,328 +219,6 @@
src.pixel_y = rand(-5, 5)
-/*
-/obj/item/weapon/storage/glassbox
- name = "Glassware Box"
- icon_state = "beakerbox"
- item_state = "syringe_kit"
- New()
- ..()
- new /obj/item/weapon/glass( src )
- new /obj/item/weapon/glass( src )
- new /obj/item/weapon/glass( src )
- new /obj/item/weapon/glass( src )
- new /obj/item/weapon/glass( src )
- new /obj/item/weapon/glass( src )
- new /obj/item/weapon/glass( src )
-*/
-
-
-/obj/structure/falsewall
- name = "wall"
- desc = "A huge chunk of metal used to seperate rooms."
- icon = 'icons/turf/walls.dmi'
- icon_state = ""
- density = 1
- opacity = 1
- anchored = 1
-
-/obj/structure/falsewall/gold
- name = "gold wall"
- desc = "A wall with gold plating. Swag"
- icon_state = ""
-
-/obj/structure/falsewall/silver
- name = "silver wall"
- desc = "A wall with silver plating. Shiny"
- icon_state = ""
-
-/obj/structure/falsewall/diamond
- name = "diamond wall"
- desc = "A wall with diamond plating. You monster"
- icon_state = ""
-
-/obj/structure/falsewall/uranium
- name = "uranium wall"
- desc = "A wall with uranium plating. This is probably a bad idea"
- icon_state = ""
-
-/obj/structure/falsewall/plasma
- name = "plasma wall"
- desc = "A wall with plasma plating. This is definately a bad idea"
- icon_state = ""
-
-/obj/structure/falsewall/bananium
- name = "bananium wall"
- desc = "A wall with bananium plating. Honk"
- icon_state = ""
-
-/obj/structure/falsewall/sand
- name = "sandstone wall"
- desc = "A wall with sandstone plating."
- icon_state = ""
-
-/*/obj/structure/falsewall/wood
- name = "wooden wall"
- desc = "A wall with classy wooden paneling."
- icon_state = ""*/
-
-/obj/structure/falserwall
- name = "r wall"
- desc = "A huge chunk of reinforced metal used to seperate rooms."
- icon = 'icons/turf/walls.dmi'
- icon_state = "r_wall"
- density = 1
- opacity = 1
- anchored = 1
-
-/obj/item/stack
- var/singular_name
- var/amount = 1
- var/max_amount //also see stack recipes initialisation, param "max_res_amount" must be equal to this max_amount
-
-/obj/item/stack/rods
- name = "metal rods"
- desc = "Some rods. Can be used for building, or something."
- singular_name = "metal rod"
- icon_state = "rods"
- flags = FPRINT | TABLEPASS| CONDUCT
- w_class = 3.0
- force = 9.0
- throwforce = 15.0
- throw_speed = 5
- throw_range = 20
- m_amt = 1875
- max_amount = 60
- attack_verb = list("hit", "bludgeoned", "whacked")
-
-/obj/item/stack/sheet
- name = "sheet"
-// var/const/length = 2.5 //2.5*1.5*0.01*100000 == 3750 == m_amt
-// var/const/width = 1.5
-// var/const/height = 0.01
- flags = FPRINT | TABLEPASS
- w_class = 3.0
- force = 5
- throwforce = 5
- max_amount = 50
- throw_speed = 3
- throw_range = 3
- attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
- var/perunit = 3750
-
-/obj/item/stack/sheet/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if (istype(W, /obj/item/weapon/sheetsnatcher))
- var/obj/item/weapon/sheetsnatcher/S = W
- if(!S.mode)
- S.add(src,user)
- else
- for (var/obj/item/stack/sheet/stack in locate(src.x,src.y,src.z))
- S.add(stack,user)
- ..()
-
-/obj/item/stack/sheet/wood
- name = "wooden planks"
- desc = "One can only guess that this is a bunch of wood."
- singular_name = "wood plank"
- icon_state = "sheet-wood"
- origin_tech = "materials=1;biotech=1"
-
-/obj/item/stack/sheet/sandstone
- name = "sandstone bricks"
- desc = "This appears to be a combination of both sand and stone."
- singular_name = "sandstone brick"
- icon_state = "sheet-sandstone"
- throw_speed = 4
- throw_range = 5
- origin_tech = "materials=1"
-
-/obj/item/stack/sheet/glass
- name = "glass"
- desc = "HOLY HELL! That is a lot of glass."
- singular_name = "glass sheet"
- icon_state = "sheet-glass"
- g_amt = 3750
- origin_tech = "materials=1"
-
-
-/obj/item/stack/sheet/rglass
- name = "reinforced glass"
- desc = "Glass which seems to have rods or something stuck in them."
- singular_name = "reinforced glass sheet"
- icon_state = "sheet-rglass"
- g_amt = 3750
- m_amt = 1875
- origin_tech = "materials=2"
-
-/obj/item/stack/sheet/rglass/cyborg
- name = "reinforced glass"
- desc = "Glass which seems to have rods or something stuck in them."
- singular_name = "reinforced glass sheet"
- icon_state = "sheet-rglass"
- g_amt = 0
- m_amt = 0
-
-/obj/item/stack/sheet/cloth
- name = "cloth"
- desc = "This roll of cloth is made from only the finest chemicals and bunny rabbits."
- singular_name = "cloth roll"
- icon_state = "sheet-cloth"
- origin_tech = "materials=2"
-
-
-/obj/item/stack/sheet/metal
- name = "metal"
- desc = "Sheets made out off metal. It has been dubbed Metal Sheets."
- singular_name = "metal sheet"
- icon_state = "sheet-metal"
- m_amt = 3750
- throwforce = 14.0
- flags = FPRINT | TABLEPASS | CONDUCT
- origin_tech = "materials=1"
-
-/obj/item/stack/sheet/metal/cyborg
- name = "metal"
- desc = "Sheets made out off metal. It has been dubbed Metal Sheets."
- singular_name = "metal sheet"
- icon_state = "sheet-metal"
- m_amt = 0
- throwforce = 14.0
- flags = FPRINT | TABLEPASS | CONDUCT
-
-/obj/item/stack/sheet/plasteel
- name = "plasteel"
- singular_name = "plasteel sheet"
- desc = "This sheet is an alloy of iron and plasma."
- icon_state = "sheet-plasteel"
- item_state = "sheet-metal"
- m_amt = 7500
- throwforce = 15.0
- flags = FPRINT | TABLEPASS | CONDUCT
- origin_tech = "materials=2"
-
-/obj/item/stack/tile/plasteel
- name = "floor tiles"
- singular_name = "floor tile"
- desc = "Those could work as a pretty decent throwing weapon"
- icon_state = "tile"
- w_class = 3.0
- force = 6.0
- m_amt = 937.5
- throwforce = 15.0
- throw_speed = 5
- throw_range = 20
- flags = FPRINT | TABLEPASS | CONDUCT
- max_amount = 60
-
-/obj/item/stack/tile/grass
- name = "grass tiles"
- singular_name = "grass floor tile"
- desc = "A patch of grass like they often use on golf courses"
- icon_state = "tile_grass"
- w_class = 3.0
- force = 1.0
- throwforce = 1.0
- throw_speed = 5
- throw_range = 20
- flags = FPRINT | TABLEPASS | CONDUCT
- max_amount = 60
- origin_tech = "biotech=1"
-
-/obj/item/stack/tile/wood
- name = "wood floor tiles"
- singular_name = "wood floor tile"
- desc = "an easy to fit wood floor tile"
- icon_state = "tile-wood"
- w_class = 3.0
- force = 1.0
- throwforce = 1.0
- throw_speed = 5
- throw_range = 20
- flags = FPRINT | TABLEPASS | CONDUCT
- max_amount = 60
-
-/obj/item/stack/light_w
- name = "wired glass tiles"
- singular_name = "wired glass floor tile"
- desc = "A glass tile, which is wired, somehow."
- icon_state = "glass_wire"
- w_class = 3.0
- force = 3.0
- throwforce = 5.0
- throw_speed = 5
- throw_range = 20
- flags = FPRINT | TABLEPASS | CONDUCT
- max_amount = 60
-
- attackby(var/obj/item/O as obj, var/mob/user as mob)
- ..()
- if(istype(O,/obj/item/weapon/wirecutters))
- var/obj/item/weapon/cable_coil/CC = new/obj/item/weapon/cable_coil(user.loc)
- CC.amount = 5
- amount--
- new/obj/item/stack/sheet/glass(user.loc)
- if(amount <= 0)
- user.drop_from_inventory(src)
- del(src)
-
- if(istype(O,/obj/item/stack/sheet/metal))
- var/obj/item/stack/sheet/metal/M = O
- M.amount--
- if(M.amount <= 0)
- user.drop_from_inventory(M)
- del(M)
- amount--
- new/obj/item/stack/tile/light(user.loc)
- if(amount <= 0)
- user.drop_from_inventory(src)
- del(src)
-
-/obj/item/stack/tile/light
- name = "light tiles"
- singular_name = "light floor tile"
- desc = "A floor tile, made out off glass. It produces light."
- icon_state = "tile_e"
- w_class = 3.0
- force = 3.0
- throwforce = 5.0
- throw_speed = 5
- throw_range = 20
- flags = FPRINT | TABLEPASS | CONDUCT
- max_amount = 60
- attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
- var/on = 1
- var/state //0 = fine, 1 = flickering, 2 = breaking, 3 = broken
-
- New()
- ..()
- if(prob(5))
- state = 3 //broken
- else if(prob(5))
- state = 2 //breaking
- else if(prob(10))
- state = 1 //flickering occasionally
- else
- state = 0 //fine
-
- attackby(var/obj/item/O as obj, var/mob/user as mob)
- ..()
- if(istype(O,/obj/item/weapon/crowbar))
- new/obj/item/stack/sheet/metal(user.loc)
- amount--
- new/obj/item/stack/light_w(user.loc)
- if(amount <= 0)
- user.drop_from_inventory(src)
- del(src)
-
-/obj/item/stack/sheet/cardboard //BubbleWrap
- name = "cardboard"
- desc = "Large sheets of card, like boxes folded flat."
- singular_name = "cardboard sheet"
- icon_state = "sheet-card"
- flags = FPRINT | TABLEPASS
- origin_tech = "materials=1"
-
/obj/item/weapon/beach_ball
icon = 'icons/misc/beach.dmi'
icon_state = "ball"
diff --git a/code/defines/obj/machinery.dm b/code/defines/obj/machinery.dm
index bb914246f25..03059344c10 100644
--- a/code/defines/obj/machinery.dm
+++ b/code/defines/obj/machinery.dm
@@ -41,24 +41,6 @@
idle_power_usage = 10
active_power_usage = 100
-/obj/machinery/camera
- name = "security camera"
- desc = "It's used to monitor rooms."
- icon = 'icons/obj/monitors.dmi'
- icon_state = "camera"
- var/network = "SS13"
- layer = 5
- var/c_tag = null
- var/c_tag_order = 999
- var/status = 1.0
- anchored = 1.0
- var/invuln = null
- var/bugged = 0
- var/hardened = 0
- use_power = 2
- idle_power_usage = 5
- active_power_usage = 10
-
/obj/machinery/dispenser
name = "tank storage unit"
desc = "A simple yet bulky one-way storage device for gas tanks. Holds 10 plasma and 10 oxygen tanks."
diff --git a/code/defines/obj/supplypacks.dm b/code/defines/obj/supplypacks.dm
index 81cb7a4268d..8648dd52cc1 100755
--- a/code/defines/obj/supplypacks.dm
+++ b/code/defines/obj/supplypacks.dm
@@ -5,569 +5,591 @@
//BIG NOTE: Don't add living things to crates, that's bad, it will break the shuttle.
//NEW NOTE: Do NOT set the price of any crates below 7 points. Doing so allows infinite points.
+/datum/supply_packs
+ var/name = null
+ var/list/contains = list()
+ var/manifest
+ var/amount = null
+ var/cost = null
+ var/containertype = null
+ var/containername = null
+ var/access = null
+ var/hidden = 0
+ var/contraband = 0
+
+/datum/supply_packs/New()
+ manifest = ""
+ for(var/path in contains)
+ if(!path) continue
+ var/atom/movable/AM = new path()
+ manifest += "- [AM.name]
"
+ AM.loc = null //just to make sure they're deleted by the garbage collector
+ manifest += "
"
+
/datum/supply_packs/specialops
name = "Special Ops supplies"
- contains = list("/obj/item/weapon/storage/emp_kit",
- "/obj/item/weapon/smokebomb",
- "/obj/item/weapon/smokebomb",
- "/obj/item/weapon/smokebomb",
- "/obj/item/weapon/pen/paralysis",
- "/obj/item/weapon/grenade/chem_grenade/incendiary")
+ contains = list(/obj/item/weapon/storage/emp_kit,
+ /obj/item/weapon/grenade/smokebomb,
+ /obj/item/weapon/grenade/smokebomb,
+ /obj/item/weapon/grenade/smokebomb,
+ /obj/item/weapon/pen/paralysis,
+ /obj/item/weapon/grenade/chem_grenade/incendiary)
cost = 20
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Special Ops crate"
hidden = 1
/datum/supply_packs/food
name = "Food crate"
- contains = list("/obj/item/weapon/reagent_containers/food/snacks/flour",
- "/obj/item/weapon/reagent_containers/food/snacks/flour",
- "/obj/item/weapon/reagent_containers/food/snacks/flour",
- "/obj/item/weapon/reagent_containers/food/snacks/flour",
- "/obj/item/weapon/reagent_containers/food/snacks/flour",
- "/obj/item/weapon/reagent_containers/food/drinks/milk",
- "/obj/item/weapon/reagent_containers/food/drinks/milk",
- "/obj/item/weapon/storage/fancy/egg_box",
- "/obj/item/weapon/reagent_containers/food/condiment/enzyme",
- "/obj/item/weapon/reagent_containers/food/snacks/grown/banana",
- "/obj/item/weapon/reagent_containers/food/snacks/grown/banana",
- "/obj/item/weapon/reagent_containers/food/snacks/grown/banana")
+ contains = list(/obj/item/weapon/reagent_containers/food/snacks/flour,
+ /obj/item/weapon/reagent_containers/food/snacks/flour,
+ /obj/item/weapon/reagent_containers/food/snacks/flour,
+ /obj/item/weapon/reagent_containers/food/snacks/flour,
+ /obj/item/weapon/reagent_containers/food/snacks/flour,
+ /obj/item/weapon/reagent_containers/food/drinks/milk,
+ /obj/item/weapon/reagent_containers/food/drinks/milk,
+ /obj/item/weapon/storage/fancy/egg_box,
+ /obj/item/weapon/reagent_containers/food/condiment/enzyme,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/banana,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/banana,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/banana)
cost = 10
- containertype = "/obj/structure/closet/crate/freezer"
+ containertype = /obj/structure/closet/crate/freezer
containername = "Food crate"
/datum/supply_packs/monkey
name = "Monkey crate"
- contains = list ("/obj/item/weapon/storage/monkeycube_box")
+ contains = list (/obj/item/weapon/storage/monkeycube_box)
cost = 20
- containertype = "/obj/structure/closet/crate/freezer"
+ containertype = /obj/structure/closet/crate/freezer
containername = "Monkey crate"
/datum/supply_packs/beanbagammo
name = "Beanbag shells"
- contains = list("/obj/item/ammo_casing/shotgun/beanbag",
- "/obj/item/ammo_casing/shotgun/beanbag",
- "/obj/item/ammo_casing/shotgun/beanbag",
- "/obj/item/ammo_casing/shotgun/beanbag",
- "/obj/item/ammo_casing/shotgun/beanbag",
- "/obj/item/ammo_casing/shotgun/beanbag",
- "/obj/item/ammo_casing/shotgun/beanbag",
- "/obj/item/ammo_casing/shotgun/beanbag",
- "/obj/item/ammo_casing/shotgun/beanbag",
- "/obj/item/ammo_casing/shotgun/beanbag")
+ contains = list(/obj/item/ammo_casing/shotgun/beanbag,
+ /obj/item/ammo_casing/shotgun/beanbag,
+ /obj/item/ammo_casing/shotgun/beanbag,
+ /obj/item/ammo_casing/shotgun/beanbag,
+ /obj/item/ammo_casing/shotgun/beanbag,
+ /obj/item/ammo_casing/shotgun/beanbag,
+ /obj/item/ammo_casing/shotgun/beanbag,
+ /obj/item/ammo_casing/shotgun/beanbag,
+ /obj/item/ammo_casing/shotgun/beanbag,
+ /obj/item/ammo_casing/shotgun/beanbag)
cost = 10
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Beanbag shells"
/datum/supply_packs/toner
name = "Toner Cartridges"
- contains = list("/obj/item/device/toner",
- "/obj/item/device/toner",
- "/obj/item/device/toner",
- "/obj/item/device/toner",
- "/obj/item/device/toner",
- "/obj/item/device/toner")
+ contains = list(/obj/item/device/toner,
+ /obj/item/device/toner,
+ /obj/item/device/toner,
+ /obj/item/device/toner,
+ /obj/item/device/toner,
+ /obj/item/device/toner)
cost = 10
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Toner Cartridges"
/datum/supply_packs/party
name = "Party equipment"
- contains = list("/obj/item/weapon/storage/drinkingglasses",
- "/obj/item/weapon/reagent_containers/food/drinks/shaker",
- "/obj/item/weapon/reagent_containers/food/drinks/bottle/patron",
- "/obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager",
- "/obj/item/weapon/reagent_containers/food/drinks/ale",
- "/obj/item/weapon/reagent_containers/food/drinks/ale",
- "/obj/item/weapon/reagent_containers/food/drinks/beer",
- "/obj/item/weapon/reagent_containers/food/drinks/beer",
- "/obj/item/weapon/reagent_containers/food/drinks/beer",
- "/obj/item/weapon/reagent_containers/food/drinks/beer")
+ contains = list(/obj/item/weapon/storage/drinkingglasses,
+ /obj/item/weapon/reagent_containers/food/drinks/shaker,
+ /obj/item/weapon/reagent_containers/food/drinks/bottle/patron,
+ /obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager,
+ /obj/item/weapon/reagent_containers/food/drinks/ale,
+ /obj/item/weapon/reagent_containers/food/drinks/ale,
+ /obj/item/weapon/reagent_containers/food/drinks/beer,
+ /obj/item/weapon/reagent_containers/food/drinks/beer,
+ /obj/item/weapon/reagent_containers/food/drinks/beer,
+ /obj/item/weapon/reagent_containers/food/drinks/beer)
cost = 20
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Party equipment"
/datum/supply_packs/internals
name = "Internals crate"
- contains = list("/obj/item/clothing/mask/gas",
- "/obj/item/clothing/mask/gas",
- "/obj/item/clothing/mask/gas",
- "/obj/item/weapon/tank/air",
- "/obj/item/weapon/tank/air",
- "/obj/item/weapon/tank/air")
+ contains = list(/obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/weapon/tank/air,
+ /obj/item/weapon/tank/air,
+ /obj/item/weapon/tank/air)
cost = 10
- containertype = "/obj/structure/closet/crate/internals"
+ containertype = /obj/structure/closet/crate/internals
containername = "Internals crate"
/datum/supply_packs/evacuation
name = "Emergency equipment"
- contains = list("/obj/machinery/bot/floorbot",
- "/obj/machinery/bot/floorbot",
- "/obj/machinery/bot/medbot",
- "/obj/machinery/bot/medbot",
- "/obj/item/weapon/tank/air",
- "/obj/item/weapon/tank/air",
- "/obj/item/weapon/tank/air",
- "/obj/item/weapon/tank/air",
- "/obj/item/weapon/tank/air",
- "/obj/item/clothing/mask/gas",
- "/obj/item/clothing/mask/gas",
- "/obj/item/clothing/mask/gas",
- "/obj/item/clothing/mask/gas",
- "/obj/item/clothing/mask/gas")
+ contains = list(/obj/machinery/bot/floorbot,
+ /obj/machinery/bot/floorbot,
+ /obj/machinery/bot/medbot,
+ /obj/machinery/bot/medbot,
+ /obj/item/weapon/tank/air,
+ /obj/item/weapon/tank/air,
+ /obj/item/weapon/tank/air,
+ /obj/item/weapon/tank/air,
+ /obj/item/weapon/tank/air,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas)
cost = 35
- containertype = "/obj/structure/closet/crate/internals"
+ containertype = /obj/structure/closet/crate/internals
containername = "Emergency Crate"
/datum/supply_packs/janitor
name = "Janitorial supplies"
- contains = list("/obj/item/weapon/reagent_containers/glass/bucket",
- "/obj/item/weapon/reagent_containers/glass/bucket",
- "/obj/item/weapon/reagent_containers/glass/bucket",
- "/obj/item/weapon/mop",
- "/obj/item/weapon/caution",
- "/obj/item/weapon/caution",
- "/obj/item/weapon/caution",
- "/obj/item/weapon/cleaner",
- "/obj/item/weapon/grenade/chem_grenade/cleaner",
- "/obj/item/weapon/grenade/chem_grenade/cleaner",
- "/obj/item/weapon/grenade/chem_grenade/cleaner",
- "/obj/structure/mopbucket")
+ contains = list(/obj/item/weapon/reagent_containers/glass/bucket,
+ /obj/item/weapon/reagent_containers/glass/bucket,
+ /obj/item/weapon/reagent_containers/glass/bucket,
+ /obj/item/weapon/mop,
+ /obj/item/weapon/caution,
+ /obj/item/weapon/caution,
+ /obj/item/weapon/caution,
+ /obj/item/weapon/reagent_containers/spray/cleaner,
+ /obj/item/weapon/reagent_containers/glass/rag,
+ /obj/item/weapon/grenade/chem_grenade/cleaner,
+ /obj/item/weapon/grenade/chem_grenade/cleaner,
+ /obj/item/weapon/grenade/chem_grenade/cleaner,
+ /obj/structure/mopbucket)
cost = 10
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Janitorial supplies"
/datum/supply_packs/lightbulbs
name = "Replacement lights"
- contains = list("/obj/item/weapon/storage/lightbox/mixed",
- "/obj/item/weapon/storage/lightbox/mixed",
- "/obj/item/weapon/storage/lightbox/mixed")
+ contains = list(/obj/item/weapon/storage/lightbox/mixed,
+ /obj/item/weapon/storage/lightbox/mixed,
+ /obj/item/weapon/storage/lightbox/mixed)
cost = 10
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Replacement lights"
//BS12 EDIT
/*
/datum/supply_packs/costume
name = "Standard Costume crate"
- contains = list("/obj/item/weapon/storage/backpack/clown",
- "/obj/item/clothing/shoes/clown_shoes",
- "/obj/item/clothing/mask/gas/clown_hat",
- "/obj/item/clothing/under/rank/clown",
- "/obj/item/weapon/bikehorn",
- "/obj/item/clothing/under/mime",
- "/obj/item/clothing/shoes/black",
- "/obj/item/clothing/gloves/white",
- "/obj/item/clothing/mask/gas/mime",
- "/obj/item/clothing/head/beret",
- "/obj/item/clothing/suit/suspenders",
- "/obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing")
+ contains = list(/obj/item/weapon/storage/backpack/clown,
+ /obj/item/clothing/shoes/clown_shoes,
+ /obj/item/clothing/mask/gas/clown_hat,
+ /obj/item/clothing/under/rank/clown,
+ /obj/item/weapon/bikehorn,
+ /obj/item/clothing/under/mime,
+ /obj/item/clothing/shoes/black,
+ /obj/item/clothing/gloves/white,
+ /obj/item/clothing/mask/gas/mime,
+ /obj/item/clothing/head/beret,
+ /obj/item/clothing/suit/suspenders,
+ /obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing)
cost = 10
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Standard Costumes"
access = access_theatre
*/
/datum/supply_packs/wizard
name = "Wizard costume"
- contains = list("/obj/item/weapon/staff",
- "/obj/item/clothing/suit/wizrobe/fake",
- "/obj/item/clothing/shoes/sandal",
- "/obj/item/clothing/head/wizard/fake")
+ contains = list(/obj/item/weapon/staff,
+ /obj/item/clothing/suit/wizrobe/fake,
+ /obj/item/clothing/shoes/sandal,
+ /obj/item/clothing/head/wizard/fake)
cost = 20
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Wizard costume crate"
/datum/supply_packs/mule
name = "MULEbot Crate"
- contains = list("/obj/machinery/bot/mulebot")
+ contains = list(/obj/machinery/bot/mulebot)
cost = 20
- containertype = "/obj/structure/largecrate/mule"
+ containertype = /obj/structure/largecrate/mule
containername = "MULEbot Crate"
/datum/supply_packs/hydroponics // -- Skie
name = "Hydroponics Supply Crate"
- contains = list("/obj/item/weapon/plantbgone",
- "/obj/item/weapon/plantbgone",
- "/obj/item/weapon/plantbgone",
- "/obj/item/weapon/plantbgone",
- "/obj/item/weapon/hatchet",
- "/obj/item/weapon/minihoe",
- "/obj/item/device/analyzer/plant_analyzer",
- "/obj/item/clothing/gloves/botanic_leather",
- "/obj/item/clothing/suit/apron") // Updated with new things
- cost = 10
- containertype = "/obj/structure/closet/crate/hydroponics"
+ contains = list(/obj/item/weapon/reagent_containers/spray/plantbgone,
+ /obj/item/weapon/reagent_containers/spray/plantbgone,
+ /obj/item/weapon/reagent_containers/glass/bottle/ammonia,
+ /obj/item/weapon/reagent_containers/glass/bottle/ammonia,
+ /obj/item/weapon/hatchet,
+ /obj/item/weapon/minihoe,
+ /obj/item/device/analyzer/plant_analyzer,
+ /obj/item/clothing/gloves/botanic_leather,
+ /obj/item/clothing/suit/apron) // Updated with new things
+ cost = 15
+ containertype = /obj/structure/closet/crate/hydroponics
containername = "Hydroponics crate"
access = access_hydroponics
/datum/supply_packs/seeds
name = "Seeds Crate"
- contains = list("/obj/item/seeds/chiliseed",
- "/obj/item/seeds/berryseed",
- "/obj/item/seeds/cornseed",
- "/obj/item/seeds/eggplantseed",
- "/obj/item/seeds/tomatoseed",
- "/obj/item/seeds/soyaseed",
- "/obj/item/seeds/wheatseed",
- "/obj/item/seeds/carrotseed",
- "/obj/item/seeds/sunflowerseed",
- "/obj/item/seeds/chantermycelium",
- "/obj/item/seeds/potatoseed",
- "/obj/item/seeds/sugarcaneseed")
+ contains = list(/obj/item/seeds/chiliseed,
+ /obj/item/seeds/berryseed,
+ /obj/item/seeds/cornseed,
+ /obj/item/seeds/eggplantseed,
+ /obj/item/seeds/tomatoseed,
+ /obj/item/seeds/soyaseed,
+ /obj/item/seeds/wheatseed,
+ /obj/item/seeds/carrotseed,
+ /obj/item/seeds/sunflowerseed,
+ /obj/item/seeds/chantermycelium,
+ /obj/item/seeds/potatoseed,
+ /obj/item/seeds/sugarcaneseed)
cost = 10
- containertype = "/obj/structure/closet/crate/hydroponics"
+ containertype = /obj/structure/closet/crate/hydroponics
containername = "Seeds crate"
access = access_hydroponics
/datum/supply_packs/exoticseeds
name = "Exotic Seeds Crate"
- contains = list("/obj/item/seeds/nettleseed",
- "/obj/item/seeds/replicapod",
- "/obj/item/seeds/replicapod",
- "/obj/item/seeds/replicapod",
- "/obj/item/seeds/plumpmycelium",
- "/obj/item/seeds/libertymycelium",
- "/obj/item/seeds/amanitamycelium",
- "/obj/item/seeds/reishimycelium",
- "/obj/item/seeds/bananaseed",
- "/obj/item/seeds/eggyseed")
+ contains = list(/obj/item/seeds/nettleseed,
+ /obj/item/seeds/replicapod,
+ /obj/item/seeds/replicapod,
+ /obj/item/seeds/replicapod,
+ /obj/item/seeds/plumpmycelium,
+ /obj/item/seeds/libertymycelium,
+ /obj/item/seeds/amanitamycelium,
+ /obj/item/seeds/reishimycelium,
+ /obj/item/seeds/bananaseed,
+ /obj/item/seeds/eggyseed)
cost = 15
- containertype = "/obj/structure/closet/crate/hydroponics"
+ containertype = /obj/structure/closet/crate/hydroponics
containername = "Exotic Seeds crate"
access = access_hydroponics
/datum/supply_packs/medical
name = "Medical crate"
- contains = list("/obj/item/weapon/storage/firstaid/regular",
- "/obj/item/weapon/storage/firstaid/fire",
- "/obj/item/weapon/storage/firstaid/toxin",
- "/obj/item/weapon/storage/firstaid/o2",
- "/obj/item/weapon/reagent_containers/glass/bottle/antitoxin",
- "/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline",
- "/obj/item/weapon/reagent_containers/glass/bottle/stoxin",
- "/obj/item/weapon/storage/syringes")
+ contains = list(/obj/item/weapon/storage/firstaid/regular,
+ /obj/item/weapon/storage/firstaid/fire,
+ /obj/item/weapon/storage/firstaid/toxin,
+ /obj/item/weapon/storage/firstaid/o2,
+ /obj/item/weapon/reagent_containers/glass/bottle/antitoxin,
+ /obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,
+ /obj/item/weapon/reagent_containers/glass/bottle/stoxin,
+ /obj/item/weapon/storage/syringes)
cost = 10
- containertype = "/obj/structure/closet/crate/medical"
+ containertype = /obj/structure/closet/crate/medical
containername = "Medical crate"
/datum/supply_packs/virus
name = "Virus crate"
- contains = list("/obj/item/weapon/reagent_containers/glass/bottle/flu_virion",
- "/obj/item/weapon/reagent_containers/glass/bottle/cold",
- "/obj/item/weapon/reagent_containers/glass/bottle/fake_gbs",
- "/obj/item/weapon/reagent_containers/glass/bottle/magnitis",
-// "/obj/item/weapon/reagent_containers/glass/bottle/wizarditis", worse than GBS if anything
-// "/obj/item/weapon/reagent_containers/glass/bottle/gbs", No. Just no.
- "/obj/item/weapon/reagent_containers/glass/bottle/pierrot_throat",
- "/obj/item/weapon/reagent_containers/glass/bottle/brainrot",
- "/obj/item/weapon/storage/syringes",
- "/obj/item/weapon/storage/beakerbox")
+ contains = list(/obj/item/weapon/reagent_containers/glass/bottle/flu_virion,
+ /obj/item/weapon/reagent_containers/glass/bottle/cold,
+ /obj/item/weapon/reagent_containers/glass/bottle/fake_gbs,
+ /obj/item/weapon/reagent_containers/glass/bottle/magnitis,
+// /obj/item/weapon/reagent_containers/glass/bottle/wizarditis, worse than GBS if anything
+// /obj/item/weapon/reagent_containers/glass/bottle/gbs, No. Just no.
+ /obj/item/weapon/reagent_containers/glass/bottle/pierrot_throat,
+ /obj/item/weapon/reagent_containers/glass/bottle/brainrot,
+ /obj/item/weapon/storage/syringes,
+ /obj/item/weapon/storage/beakerbox)
cost = 20
- containertype = "/obj/structure/closet/crate/secure/weapon"
+ containertype = /obj/structure/closet/crate/secure/weapon
containername = "Virus crate"
access = access_cmo
/datum/supply_packs/metal50
name = "50 Metal Sheets"
- contains = list("/obj/item/stack/sheet/metal")
+ contains = list(/obj/item/stack/sheet/metal)
amount = 50
cost = 10
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Metal sheets crate"
/datum/supply_packs/glass50
name = "50 Glass Sheets"
- contains = list("/obj/item/stack/sheet/glass")
+ contains = list(/obj/item/stack/sheet/glass)
amount = 50
cost = 10
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Glass sheets crate"
/datum/supply_packs/electrical
name = "Electrical maintenance crate"
- contains = list("/obj/item/weapon/storage/toolbox/electrical",
- "/obj/item/weapon/storage/toolbox/electrical",
- "/obj/item/clothing/gloves/yellow",
- "/obj/item/clothing/gloves/yellow",
- "/obj/item/weapon/cell",
- "/obj/item/weapon/cell",
- "/obj/item/weapon/cell/high",
- "/obj/item/weapon/cell/high")
+ contains = list(/obj/item/weapon/storage/toolbox/electrical,
+ /obj/item/weapon/storage/toolbox/electrical,
+ /obj/item/clothing/gloves/yellow,
+ /obj/item/clothing/gloves/yellow,
+ /obj/item/weapon/cell,
+ /obj/item/weapon/cell,
+ /obj/item/weapon/cell/high,
+ /obj/item/weapon/cell/high)
cost = 15
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Electrical maintenance crate"
/datum/supply_packs/mechanical
name = "Mechanical maintenance crate"
- contains = list("/obj/item/weapon/storage/belt/utility/full",
- "/obj/item/weapon/storage/belt/utility/full",
- "/obj/item/weapon/storage/belt/utility/full",
- "/obj/item/clothing/suit/hazardvest",
- "/obj/item/clothing/suit/hazardvest",
- "/obj/item/clothing/suit/hazardvest",
- "/obj/item/clothing/head/welding",
- "/obj/item/clothing/head/welding",
- "/obj/item/clothing/head/hardhat")
+ contains = list(/obj/item/weapon/storage/belt/utility/full,
+ /obj/item/weapon/storage/belt/utility/full,
+ /obj/item/weapon/storage/belt/utility/full,
+ /obj/item/clothing/suit/hazardvest,
+ /obj/item/clothing/suit/hazardvest,
+ /obj/item/clothing/suit/hazardvest,
+ /obj/item/clothing/head/welding,
+ /obj/item/clothing/head/welding,
+ /obj/item/clothing/head/hardhat)
cost = 10
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Mechanical maintenance crate"
/datum/supply_packs/watertank
name = "Water tank crate"
- contains = list("/obj/structure/reagent_dispensers/watertank")
+ contains = list(/obj/structure/reagent_dispensers/watertank)
cost = 8
- containertype = "/obj/structure/largecrate"
+ containertype = /obj/structure/largecrate
containername = "water tank crate"
/datum/supply_packs/fueltank
name = "Fuel tank crate"
- contains = list("/obj/structure/reagent_dispensers/fueltank")
+ contains = list(/obj/structure/reagent_dispensers/fueltank)
cost = 8
- containertype = "/obj/structure/largecrate"
+ containertype = /obj/structure/largecrate
containername = "fuel tank crate"
/datum/supply_packs/engine
name = "Emitter crate"
- contains = list("/obj/machinery/emitter",
- "/obj/machinery/emitter",)
+ contains = list(/obj/machinery/emitter,
+ /obj/machinery/emitter)
cost = 10
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Emitter crate"
access = access_heads
/datum/supply_packs/engine/field_gen
name = "Field Generator crate"
- contains = list("/obj/machinery/field_generator",
- "/obj/machinery/field_generator",)
+ contains = list(/obj/machinery/field_generator,
+ /obj/machinery/field_generator)
containername = "Field Generator crate"
/datum/supply_packs/engine/sing_gen
name = "Singularity Generator crate"
- contains = list("/obj/machinery/the_singularitygen")
+ contains = list(/obj/machinery/the_singularitygen)
containername = "Singularity Generator crate"
/datum/supply_packs/engine/collector
name = "Collector crate"
- contains = list("/obj/machinery/power/rad_collector",
- "/obj/machinery/power/rad_collector",
- "/obj/machinery/power/rad_collector")
+ contains = list(/obj/machinery/power/rad_collector,
+ /obj/machinery/power/rad_collector,
+ /obj/machinery/power/rad_collector)
containername = "Collector crate"
/datum/supply_packs/engine/PA
name = "Particle Accelerator crate"
cost = 40
- contains = list("/obj/structure/particle_accelerator/fuel_chamber",
- "/obj/machinery/particle_accelerator/control_box",
- "/obj/structure/particle_accelerator/particle_emitter/center",
- "/obj/structure/particle_accelerator/particle_emitter/left",
- "/obj/structure/particle_accelerator/particle_emitter/right",
- "/obj/structure/particle_accelerator/power_box",
- "/obj/structure/particle_accelerator/end_cap")
+ contains = list(/obj/structure/particle_accelerator/fuel_chamber,
+ /obj/machinery/particle_accelerator/control_box,
+ /obj/structure/particle_accelerator/particle_emitter/center,
+ /obj/structure/particle_accelerator/particle_emitter/left,
+ /obj/structure/particle_accelerator/particle_emitter/right,
+ /obj/structure/particle_accelerator/power_box,
+ /obj/structure/particle_accelerator/end_cap)
containername = "Particle Accelerator crate"
/datum/supply_packs/mecha_ripley
name = "Circuit Crate (\"Ripley\" APLU)"
- contains = list("/obj/item/weapon/book/manual/ripley_build_and_repair",
- "/obj/item/weapon/circuitboard/mecha/ripley/main", //TEMPORARY due to lack of circuitboard printer
- "/obj/item/weapon/circuitboard/mecha/ripley/peripherals") //TEMPORARY due to lack of circuitboard printer
+ contains = list(/obj/item/weapon/book/manual/ripley_build_and_repair,
+ /obj/item/weapon/circuitboard/mecha/ripley/main, //TEMPORARY due to lack of circuitboard printer
+ /obj/item/weapon/circuitboard/mecha/ripley/peripherals) //TEMPORARY due to lack of circuitboard printer
cost = 30
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "APLU \"Ripley\" Circuit Crate"
access = access_robotics
/datum/supply_packs/mecha_odysseus
name = "Circuit Crate (\"Odysseus\")"
- contains = list("/obj/item/weapon/circuitboard/mecha/odysseus/peripherals", //TEMPORARY due to lack of circuitboard printer
- "/obj/item/weapon/circuitboard/mecha/odysseus/main") //TEMPORARY due to lack of circuitboard printer
+ contains = list(/obj/item/weapon/circuitboard/mecha/odysseus/peripherals, //TEMPORARY due to lack of circuitboard printer
+ /obj/item/weapon/circuitboard/mecha/odysseus/main) //TEMPORARY due to lack of circuitboard printer
cost = 25
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "\"Odysseus\" Circuit Crate"
access = access_robotics
/datum/supply_packs/robotics
name = "Robotics Assembly Crate"
- contains = list("/obj/item/device/assembly/prox_sensor",
- "/obj/item/device/assembly/prox_sensor",
- "/obj/item/device/assembly/prox_sensor",
- "/obj/item/weapon/storage/toolbox/electrical",
- "/obj/item/device/flash",
- "/obj/item/device/flash",
- "/obj/item/device/flash",
- "/obj/item/device/flash",
- "/obj/item/weapon/cell/high",
- "/obj/item/weapon/cell/high")
+ contains = list(/obj/item/device/assembly/prox_sensor,
+ /obj/item/device/assembly/prox_sensor,
+ /obj/item/device/assembly/prox_sensor,
+ /obj/item/weapon/storage/toolbox/electrical,
+ /obj/item/device/flash,
+ /obj/item/device/flash,
+ /obj/item/device/flash,
+ /obj/item/device/flash,
+ /obj/item/weapon/cell/high,
+ /obj/item/weapon/cell/high)
cost = 10
- containertype = "/obj/structure/closet/crate/secure/gear"
+ containertype = /obj/structure/closet/crate/secure/gear
containername = "Robotics Assembly"
access = access_robotics
/datum/supply_packs/plasma
name = "Plasma assembly crate"
- contains = list("/obj/item/weapon/tank/plasma",
- "/obj/item/weapon/tank/plasma",
- "/obj/item/weapon/tank/plasma",
- "/obj/item/device/assembly/igniter",
- "/obj/item/device/assembly/igniter",
- "/obj/item/device/assembly/igniter",
- "/obj/item/device/assembly/prox_sensor",
- "/obj/item/device/assembly/prox_sensor",
- "/obj/item/device/assembly/prox_sensor",
- "/obj/item/device/assembly/timer",
- "/obj/item/device/assembly/timer",
- "/obj/item/device/assembly/timer")
+ contains = list(/obj/item/weapon/tank/plasma,
+ /obj/item/weapon/tank/plasma,
+ /obj/item/weapon/tank/plasma,
+ /obj/item/device/assembly/igniter,
+ /obj/item/device/assembly/igniter,
+ /obj/item/device/assembly/igniter,
+ /obj/item/device/assembly/prox_sensor,
+ /obj/item/device/assembly/prox_sensor,
+ /obj/item/device/assembly/prox_sensor,
+ /obj/item/device/assembly/timer,
+ /obj/item/device/assembly/timer,
+ /obj/item/device/assembly/timer)
cost = 10
- containertype = "/obj/structure/closet/crate/secure/plasma"
+ containertype = /obj/structure/closet/crate/secure/plasma
containername = "Plasma assembly crate"
access = access_tox
/datum/supply_packs/weapons
name = "Weapons crate"
- contains = list("/obj/item/weapon/melee/baton",
- "/obj/item/weapon/melee/baton",
- "/obj/item/weapon/gun/energy/laser",
- "/obj/item/weapon/gun/energy/laser",
- "/obj/item/weapon/gun/energy/taser",
- "/obj/item/weapon/gun/energy/taser",
- "/obj/item/weapon/storage/flashbang_kit",
- "/obj/item/weapon/storage/flashbang_kit")
+ contains = list(/obj/item/weapon/melee/baton,
+ /obj/item/weapon/melee/baton,
+ /obj/item/weapon/gun/energy/laser,
+ /obj/item/weapon/gun/energy/laser,
+ /obj/item/weapon/gun/energy/taser,
+ /obj/item/weapon/gun/energy/taser,
+ /obj/item/weapon/storage/flashbang_kit,
+ /obj/item/weapon/storage/flashbang_kit)
cost = 30
- containertype = "/obj/structure/closet/crate/secure/weapon"
+ containertype = /obj/structure/closet/crate/secure/weapon
containername = "Weapons crate"
access = access_security
/datum/supply_packs/eweapons
name = "Experimental weapons crate"
- contains = list("/obj/item/weapon/flamethrower/full",
- "/obj/item/weapon/tank/plasma",
- "/obj/item/weapon/tank/plasma",
- "/obj/item/weapon/tank/plasma",
- "/obj/item/weapon/grenade/chem_grenade/incendiary",
- "/obj/item/weapon/grenade/chem_grenade/incendiary",
- "/obj/item/weapon/grenade/chem_grenade/incendiary")
+ contains = list(/obj/item/weapon/flamethrower/full,
+ /obj/item/weapon/tank/plasma,
+ /obj/item/weapon/tank/plasma,
+ /obj/item/weapon/tank/plasma,
+ /obj/item/weapon/grenade/chem_grenade/incendiary,
+ /obj/item/weapon/grenade/chem_grenade/incendiary,
+ /obj/item/weapon/grenade/chem_grenade/incendiary)
cost = 25
- containertype = "/obj/structure/closet/crate/secure/weapon"
+ containertype = /obj/structure/closet/crate/secure/weapon
containername = "Experimental weapons crate"
access = access_heads
/datum/supply_packs/armor
name = "Armor crate"
- contains = list("/obj/item/clothing/head/helmet",
- "/obj/item/clothing/head/helmet",
- "/obj/item/clothing/suit/armor/vest",
- "/obj/item/clothing/suit/armor/vest")
+ contains = list(/obj/item/clothing/head/helmet,
+ /obj/item/clothing/head/helmet,
+ /obj/item/clothing/suit/armor/vest,
+ /obj/item/clothing/suit/armor/vest)
cost = 15
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Armor crate"
access = access_security
/datum/supply_packs/riot
name = "Riot gear crate"
- contains = list("/obj/item/weapon/melee/baton",
- "/obj/item/weapon/melee/baton",
- "/obj/item/weapon/melee/baton",
- "/obj/item/weapon/shield/riot",
- "/obj/item/weapon/shield/riot",
- "/obj/item/weapon/shield/riot",
- "/obj/item/weapon/storage/flashbang_kit",
- "/obj/item/weapon/storage/flashbang_kit",
- "/obj/item/weapon/storage/flashbang_kit",
- "/obj/item/weapon/handcuffs",
- "/obj/item/weapon/handcuffs",
- "/obj/item/weapon/handcuffs",
- "/obj/item/clothing/head/helmet/riot",
- "/obj/item/clothing/suit/armor/riot",
- "/obj/item/clothing/head/helmet/riot",
- "/obj/item/clothing/suit/armor/riot",
- "/obj/item/clothing/head/helmet/riot",
- "/obj/item/clothing/suit/armor/riot")
+ contains = list(/obj/item/weapon/melee/baton,
+ /obj/item/weapon/melee/baton,
+ /obj/item/weapon/melee/baton,
+ /obj/item/weapon/shield/riot,
+ /obj/item/weapon/shield/riot,
+ /obj/item/weapon/shield/riot,
+ /obj/item/weapon/storage/flashbang_kit,
+ /obj/item/weapon/storage/flashbang_kit,
+ /obj/item/weapon/storage/flashbang_kit,
+ /obj/item/weapon/handcuffs,
+ /obj/item/weapon/handcuffs,
+ /obj/item/weapon/handcuffs,
+ /obj/item/clothing/head/helmet/riot,
+ /obj/item/clothing/suit/armor/riot,
+ /obj/item/clothing/head/helmet/riot,
+ /obj/item/clothing/suit/armor/riot,
+ /obj/item/clothing/head/helmet/riot,
+ /obj/item/clothing/suit/armor/riot)
cost = 60
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Riot gear crate"
access = access_armory
/datum/supply_packs/loyalty
name = "Loyalty implant crate"
- contains = list ("/obj/item/weapon/storage/lockbox/loyalty")
+ contains = list (/obj/item/weapon/storage/lockbox/loyalty)
cost = 60
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Loyalty implant crate"
access = access_armory
/datum/supply_packs/ballistic
name = "Ballistic gear crate"
- contains = list("/obj/item/clothing/suit/armor/bulletproof",
- "/obj/item/clothing/suit/armor/bulletproof",
- "/obj/item/weapon/gun/projectile/shotgun/pump/combat",
- "/obj/item/weapon/gun/projectile/shotgun/pump/combat")
+ contains = list(/obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/weapon/gun/projectile/shotgun/pump/combat,
+ /obj/item/weapon/gun/projectile/shotgun/pump/combat)
cost = 50
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Ballistic gear crate"
access = access_armory
/datum/supply_packs/expenergy
name = "Experimental energy gear crate"
- contains = list("/obj/item/clothing/suit/armor/laserproof",
- "/obj/item/clothing/suit/armor/laserproof",
- "/obj/item/weapon/gun/energy/gun",
- "/obj/item/weapon/gun/energy/gun")
+ contains = list(/obj/item/clothing/suit/armor/laserproof,
+ /obj/item/clothing/suit/armor/laserproof,
+ /obj/item/weapon/gun/energy/gun,
+ /obj/item/weapon/gun/energy/gun)
cost = 50
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Experimental energy gear crate"
access = access_armory
/datum/supply_packs/exparmor
name = "Experimental armor crate"
- contains = list("/obj/item/clothing/suit/armor/laserproof",
- "/obj/item/clothing/suit/armor/bulletproof",
- "/obj/item/clothing/head/helmet/riot",
- "/obj/item/clothing/suit/armor/riot")
+ contains = list(/obj/item/clothing/suit/armor/laserproof,
+ /obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/clothing/head/helmet/riot,
+ /obj/item/clothing/suit/armor/riot)
cost = 35
- containertype = "/obj/structure/closet/crate/secure"
+ containertype = /obj/structure/closet/crate/secure
containername = "Experimental armor crate"
access = access_armory
/datum/supply_packs/securitybarriers
name = "Security Barriers"
- contains = list("/obj/machinery/deployable/barrier",
- "/obj/machinery/deployable/barrier",
- "/obj/machinery/deployable/barrier",
- "/obj/machinery/deployable/barrier")
+ contains = list(/obj/machinery/deployable/barrier,
+ /obj/machinery/deployable/barrier,
+ /obj/machinery/deployable/barrier,
+ /obj/machinery/deployable/barrier)
cost = 20
- containertype = "/obj/structure/closet/crate/secure/gear"
+ containertype = /obj/structure/closet/crate/secure/gear
containername = "Security Barriers crate"
/datum/supply_packs/randomised
var/num_contained = 3 //number of items picked to be contained in a randomised crate
- contains = list("/obj/item/clothing/head/collectable/chef",
- "/obj/item/clothing/head/collectable/paper",
- "/obj/item/clothing/head/collectable/tophat",
- "/obj/item/clothing/head/collectable/captain",
- "/obj/item/clothing/head/collectable/beret",
- "/obj/item/clothing/head/collectable/welding",
- "/obj/item/clothing/head/collectable/flatcap",
- "/obj/item/clothing/head/collectable/pirate",
- "/obj/item/clothing/head/collectable/kitty",
- "/obj/item/clothing/head/collectable/rabbitears",
- "/obj/item/clothing/head/collectable/wizard",
- "/obj/item/clothing/head/collectable/hardhat",
- "/obj/item/clothing/head/collectable/HoS",
- "/obj/item/clothing/head/collectable/thunderdome",
- "/obj/item/clothing/head/collectable/swat",
- "/obj/item/clothing/head/collectable/metroid",
- "/obj/item/clothing/head/collectable/metroid",
- "/obj/item/clothing/head/collectable/police",
- "/obj/item/clothing/head/collectable/police",
- "/obj/item/clothing/head/collectable/slime",
- "/obj/item/clothing/head/collectable/slime",
- "/obj/item/clothing/head/collectable/xenom",
- "/obj/item/clothing/head/collectable/xenom",
- "/obj/item/clothing/head/collectable/petehat")
+ contains = list(/obj/item/clothing/head/collectable/chef,
+ /obj/item/clothing/head/collectable/paper,
+ /obj/item/clothing/head/collectable/tophat,
+ /obj/item/clothing/head/collectable/captain,
+ /obj/item/clothing/head/collectable/beret,
+ /obj/item/clothing/head/collectable/welding,
+ /obj/item/clothing/head/collectable/flatcap,
+ /obj/item/clothing/head/collectable/pirate,
+ /obj/item/clothing/head/collectable/kitty,
+ /obj/item/clothing/head/collectable/rabbitears,
+ /obj/item/clothing/head/collectable/wizard,
+ /obj/item/clothing/head/collectable/hardhat,
+ /obj/item/clothing/head/collectable/HoS,
+ /obj/item/clothing/head/collectable/thunderdome,
+ /obj/item/clothing/head/collectable/swat,
+ /obj/item/clothing/head/collectable/metroid,
+ /obj/item/clothing/head/collectable/metroid,
+ /obj/item/clothing/head/collectable/police,
+ /obj/item/clothing/head/collectable/police,
+ /obj/item/clothing/head/collectable/slime,
+ /obj/item/clothing/head/collectable/slime,
+ /obj/item/clothing/head/collectable/xenom,
+ /obj/item/clothing/head/collectable/xenom,
+ /obj/item/clothing/head/collectable/petehat)
name = "Collectable hat crate!"
cost = 200
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Collectable hats crate! Brought to you by Bass.inc!"
/datum/supply_packs/randomised/New()
@@ -580,10 +602,10 @@
/datum/supply_packs/randomised/contraband
num_contained = 5
- contains = list("/obj/item/weapon/contraband/poster",
- "/obj/item/weapon/cigpacket/dromedaryco")
+ contains = list(/obj/item/weapon/contraband/poster,
+ /obj/item/weapon/cigpacket/dromedaryco)
name = "Contraband crate"
cost = 30
- containertype = "/obj/structure/closet/crate"
+ containertype = /obj/structure/closet/crate
containername = "Contraband crate"
contraband = 1
diff --git a/code/defines/obj/vending.dm b/code/defines/obj/vending.dm
index 6b0043bc42b..75d51bba54f 100755
--- a/code/defines/obj/vending.dm
+++ b/code/defines/obj/vending.dm
@@ -116,7 +116,7 @@
icon_state = "Cola_Machine"
product_paths = "/obj/item/weapon/reagent_containers/food/drinks/cola;/obj/item/weapon/reagent_containers/food/drinks/space_mountain_wind;/obj/item/weapon/reagent_containers/food/drinks/dr_gibb;/obj/item/weapon/reagent_containers/food/drinks/starkist;/obj/item/weapon/reagent_containers/food/drinks/space_up"
product_amounts = "10;10;10;10;10"
- product_slogans = "Robust Softdrinks: More robust then a toolbox to the head!"
+ product_slogans = "Robust Softdrinks: More robust than a toolbox to the head!"
product_hidden = "/obj/item/weapon/reagent_containers/food/drinks/thirteenloko"
product_hideamt = "5"
product_ads = "Refreshing!;Hope you're thirsty!;Over 1 million drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks in space."
@@ -136,7 +136,7 @@
product_coin_amt = ""
/obj/machinery/vending/cigarette
- name = "cigarette machine"
+ name = "Cigarette machine" //OCD had to be uppercase to look nice with the new formating
desc = "If you want to get cancer, might as well do it in style"
icon_state = "cigs"
product_paths = "/obj/item/weapon/cigpacket;/obj/item/weapon/storage/matchbox;/obj/item/weapon/lighter/random"
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index 629f224f4ab..57420905754 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -7,6 +7,19 @@
/obj/item/weapon/shield
name = "shield"
+/obj/item/weapon/phone
+ name = "red phone"
+ desc = "Should anything ever go wrong..."
+ icon = 'icons/obj/items.dmi'
+ icon_state = "red_phone"
+ flags = FPRINT | TABLEPASS | CONDUCT
+ force = 3.0
+ throwforce = 2.0
+ throw_speed = 1
+ throw_range = 4
+ w_class = 2
+ attack_verb = list("called", "rang")
+
/obj/item/weapon/shield/riot
name = "riot shield"
desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
@@ -75,6 +88,10 @@
w_class = 3
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+/obj/item/weapon/sord/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
+ return ..()
+
/obj/item/weapon/claymore
name = "claymore"
desc = "What are you standing around staring at this for? Get to killing!"
@@ -90,6 +107,10 @@
IsShield()
return 1
+/obj/item/weapon/claymore/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
+ return ..()
+
/obj/item/weapon/katana
name = "katana"
desc = "Woefully underpowered in D20"
@@ -102,9 +123,12 @@
w_class = 3
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
- IsShield()
+/obj/item/weapon/katana/IsShield()
return 1
+/obj/item/weapon/katana/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
+ return ..()
/obj/item/weapon/bodybag
name = "body bag"
@@ -741,28 +765,6 @@
icon_state = "fcardholder0"
item_state = "clipboard"
-/obj/item/weapon/flasks
- name = "flask"
- icon = 'icons/obj/Cryogenic2.dmi'
- var/oxygen = 0.0
- var/plasma = 0.0
- var/coolant = 0.0
-
-/obj/item/weapon/flasks/coolant
- name = "light blue flask"
- icon_state = "coolant-c"
- coolant = 1000.0
-
-/obj/item/weapon/flasks/oxygen
- name = "blue flask"
- icon_state = "oxygen-c"
- oxygen = 500.0
-
-/obj/item/weapon/flasks/plasma
- name = "orange flask"
- icon_state = "plasma-c"
- plasma = 500.0
-
/*
/obj/item/weapon/game_kit
name = "Gaming Kit"
@@ -1052,6 +1054,10 @@
g_amt = 3750
attack_verb = list("stabbed", "slashed", "sliced", "cut")
+/obj/item/weapon/shard/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
+ return ..()
+
/*/obj/item/weapon/syndicate_uplink
name = "station bounced radio"
desc = "Remain silent about this..."
@@ -1409,6 +1415,10 @@
origin_tech = "materials=1"
attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+/obj/item/weapon/butch/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
+ return ..()
+
/obj/item/weapon/tray
name = "tray"
icon = 'icons/obj/food.dmi'
@@ -1577,6 +1587,9 @@
origin_tech = "materials=2;combat=1"
attack_verb = list("chopped", "torn", "cut")
+/obj/item/weapon/hatchet/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
+ return ..()
/*
/obj/item/weapon/cigarpacket
diff --git a/code/game/area/ai_monitored.dm b/code/game/area/ai_monitored.dm
index d56f8f37c86..59f1c693bc0 100644
--- a/code/game/area/ai_monitored.dm
+++ b/code/game/area/ai_monitored.dm
@@ -1,6 +1,6 @@
/area/ai_monitored
name = "AI Monitored Area"
- var/obj/machinery/camera/motion/motioncamera = null
+ var/obj/machinery/camera/motioncamera = null
/area/ai_monitored/New()
@@ -21,66 +21,4 @@
if (istype(O, /mob) && motioncamera)
motioncamera.lostTarget(O)
-/obj/machinery/camera/motion
- name = "Motion Security Camera"
- var/list/motionTargets = list()
- var/detectTime = 0
- var/locked = 1
-/obj/machinery/camera/motion/process()
- // motion camera event loop
- if (detectTime > 0)
- var/elapsed = world.time - detectTime
- if (elapsed > 300)
- triggerAlarm()
- else if (detectTime == -1)
- for (var/mob/target in motionTargets)
- if (target.stat == 2) lostTarget(target)
-
-/obj/machinery/camera/motion/proc/newTarget(var/mob/target)
- if (istype(target, /mob/living/silicon/ai)) return 0
- if (detectTime == 0)
- detectTime = world.time // start the clock
- if (!(target in motionTargets))
- motionTargets += target
- return 1
-
-/obj/machinery/camera/motion/proc/lostTarget(var/mob/target)
- if (target in motionTargets)
- motionTargets -= target
- if (motionTargets.len == 0)
- cancelAlarm()
-
-/obj/machinery/camera/motion/proc/cancelAlarm()
- if (detectTime == -1)
- for (var/mob/living/silicon/aiPlayer in player_list)
- if (status) aiPlayer.cancelAlarm("Motion", src.loc.loc)
- detectTime = 0
- return 1
-
-/obj/machinery/camera/motion/proc/triggerAlarm()
- if (!detectTime) return 0
- for (var/mob/living/silicon/aiPlayer in player_list)
- if (status) aiPlayer.triggerAlarm("Motion", src.loc.loc, src)
- detectTime = -1
- return 1
-
-/obj/machinery/camera/motion/attackby(W as obj, mob/user as mob)
- if (istype(W, /obj/item/weapon/wirecutters) && locked == 1) return
- if (istype(W, /obj/item/weapon/screwdriver))
- var/turf/T = user.loc
- user << text("\blue []ing the access hatch... (this is a long process)", (locked) ? "Open" : "Clos")
- sleep(100)
- if ((user.loc == T && user.get_active_hand() == W && !( user.stat )))
- src.locked ^= 1
- user << text("\blue The access hatch is now [].", (locked) ? "closed" : "open")
-
- ..() // call the parent to (de|re)activate
-
- if (istype(W, /obj/item/weapon/wirecutters)) // now handle alarm on/off...
- if (status) // ok we've just been reconnected... send an alarm!
- detectTime = world.time - 301
- triggerAlarm()
- else
- for (var/mob/living/silicon/aiPlayer in player_list) // manually cancel, to not disturb internal state
- aiPlayer.cancelAlarm("Motion", src.loc.loc)
diff --git a/code/game/atom_procs.dm b/code/game/atom_procs.dm
index c8dcb74c313..47d8f1cf7f0 100644
--- a/code/game/atom_procs.dm
+++ b/code/game/atom_procs.dm
@@ -67,6 +67,9 @@
src.attack_paw(user)
return
+/atom/proc/attack_larva(mob/user as mob)
+ return
+
// for metroids
/atom/proc/attack_metroid(mob/user as mob)
return
@@ -342,48 +345,44 @@
/atom/proc/clean_blood()
clean_prints()
-
if(istype(blood_DNA, /list))
del(blood_DNA)
- .=1
+ return 1
- //Cleaning blood off of mobs
- if(istype(src, /mob/living/carbon))
- var/mob/living/carbon/M = src
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(H.gloves)
- if(H.gloves.clean_blood())
- H.update_inv_gloves(0)
- else
- if(H.bloody_hands)
- H.bloody_hands = 0
- H.update_inv_gloves(0)
- M.update_icons() //apply the now updated overlays to the mob
-
- //Cleaning blood off of items
- else if(istype(src, /obj/item))
- var/obj/item/O = src
- if(O.blood_overlay)
- O.overlays.Remove(O.blood_overlay)
-
- if(istype(src, /obj/item/clothing/gloves))
- var/obj/item/clothing/gloves/G = src
- G.transfer_blood = 0
-
- //Cleaning blood off of turfs
- else if(istype(src, /turf/simulated))
- var/turf/simulated/T = src
- if(T.icon_old)
- var/icon/I = new /icon(T.icon_old, T.icon_state)
- T.icon = I
+/mob/living/carbon/clean_blood()
+ . = ..()
+ if(ishuman(src))
+ var/mob/living/carbon/human/H = src
+ if(H.gloves)
+ if(H.gloves.clean_blood())
+ H.update_inv_gloves(0)
else
- T.icon = initial(icon)
- return
+ if(H.bloody_hands)
+ H.bloody_hands = 0
+ H.update_inv_gloves(0)
+ update_icons() //apply the now updated overlays to the mob
+
+/obj/item/clean_blood()
+ . = ..()
+ if(blood_overlay)
+ overlays.Remove(blood_overlay)
+ if(istype(src, /obj/item/clothing/gloves))
+ var/obj/item/clothing/gloves/G = src
+ G.transfer_blood = 0
+
+/*
+/turf/simulated/clean_blood()
+ . = ..()
+ if(icon_old)
+ var/icon/I = new /icon(icon_old, icon_state)
+ icon = I
+ else
+ icon = initial(icon)
+*/
+
/atom/MouseDrop(atom/over_object as mob|obj|turf|area)
- spawn( 0 )
-
+ spawn(0)
if (istype(over_object, /atom))
over_object.MouseDrop_T(src, usr)
return
@@ -654,6 +653,16 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
if ( (W) && !alien.restrained() )
W.afterattack(src, alien)
+ else if(islarva(usr))
+ var/mob/living/carbon/alien/larva/alien = usr
+ if(alien.stat)
+ return
+
+ var/in_range = in_range(src, alien) || src.loc == alien
+
+ if (in_range)
+ if ( !alien.restrained() )
+ attack_larva(alien)
else if(ismetroid(usr))
var/mob/living/carbon/metroid/metroid = usr
@@ -938,6 +947,8 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
usr.hud_used.move_intent.icon_state = "running"
usr.update_icons()
src.attack_alien(usr, usr.hand)
+ else if (istype(usr, /mob/living/carbon/alien/larva))
+ src.attack_larva(usr)
else if (istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot))
src.attack_ai(usr, usr.hand)
else if(istype(usr, /mob/living/carbon/metroid))
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index 85a2b924366..26bf308cdc7 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -12,6 +12,7 @@
/obj/item/weapon/melee/cultblade/attack(mob/living/target as mob, mob/living/carbon/human/user as mob)
if(iscultist(user))
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
return ..()
else
user.Paralyse(5)
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 3264e863158..7ca0ce75a83 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -122,7 +122,7 @@ rcd light flash thingy on matter drain
mod_pick_name = "recam"
uses = 10
-/client/proc/reactivate_camera(obj/machinery/camera/C as obj in world)
+/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras)
set name = "Reactivate Camera"
set category = "Malfunction"
if (istype (C, /obj/machinery/camera))
@@ -138,6 +138,36 @@ rcd light flash thingy on matter drain
else usr << "Out of uses."
else usr << "That's not a camera."
+/datum/AI_Module/small/upgrade_camera
+ module_name = "Upgrade Camera"
+ mod_pick_name = "upgradecam"
+ uses = 10
+
+/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras)
+ set name = "Upgrade Camera"
+ set category = "Malfunction"
+ if(istype(C))
+ var/datum/AI_Module/small/upgrade_camera/UC = locate(/datum/AI_Module/small/upgrade_camera) in usr:current_modules
+ if(UC)
+ if(UC.uses > 0)
+ if(C.assembly)
+ var/upgraded = 0
+ if(!C.isXRay())
+ C.upgradeXRay()
+ cameranet.updateVisibility(C)
+ upgraded = 1
+ if(!C.isEmpProof())
+ C.upgradeEmpProof()
+ upgraded = 1
+ if(upgraded)
+ UC.uses --
+ C.visible_message("\icon[src] *beep*")
+ usr << "Camera successully upgraded!"
+ else
+ usr << "This camera is already upgraded!"
+ else
+ usr << "Out of uses."
+
/datum/AI_Module/module_picker
var/temp = null
@@ -152,6 +182,7 @@ rcd light flash thingy on matter drain
src.possible_modules += new /datum/AI_Module/small/interhack
src.possible_modules += new /datum/AI_Module/small/blackout
src.possible_modules += new /datum/AI_Module/small/reactivate_camera
+ src.possible_modules += new /datum/AI_Module/small/upgrade_camera
/datum/AI_Module/module_picker/proc/use(user as mob)
var/dat
@@ -264,6 +295,19 @@ rcd light flash thingy on matter drain
else src.temp = "Ten additional uses added to ReCam module."
src.processing_time -= 15
+ else if(href_list["upgradecam"])
+ var/already
+ for (var/datum/AI_Module/mod in usr:current_modules)
+ if(istype(mod, /datum/AI_Module/small/upgrade_camera))
+ mod:uses += 10
+ already = 1
+ if (!already)
+ usr.verbs += /client/proc/upgrade_camera
+ src.temp = "Upgrades a camera to have X-Ray vision and be EMP-Proof. 10 uses."
+ usr:current_modules += new /datum/AI_Module/small/upgrade_camera
+ else src.temp = "Ten additional uses added to ReCam module."
+ src.processing_time -= 15
+
else
if (href_list["temp"])
src.temp = null
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index e7f9cdbedb0..4e5fdfb5e92 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -5,7 +5,7 @@
/datum/game_mode/nuclear
name = "nuclear emergency"
config_tag = "nuclear"
- required_players = 15
+ required_players = 20 // 20 players - 5 players to be the nuke ops = 15 players remaining
required_enemies = 5
recommended_enemies = 5
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 1fe84641bcc..d007cc1adec 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -5,7 +5,7 @@
/datum/game_mode/wizard
name = "wizard"
config_tag = "wizard"
- required_players = 0
+ required_players = 20
required_enemies = 1
recommended_enemies = 1
diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm
index 4d302c6749c..f62c78ccbcb 100644
--- a/code/game/machinery/airlock_control.dm
+++ b/code/game/machinery/airlock_control.dm
@@ -6,6 +6,7 @@ obj/machinery/door/airlock
var/frequency
var/shockedby = list()
var/datum/radio_frequency/radio_connection
+ explosion_resistance = 15
receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index bce0465d46a..7becd90b483 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -41,6 +41,7 @@ var/global/list/autolathe_recipes = list( \
new /obj/item/device/assembly/timer(), \
new /obj/item/weapon/light/tube(), \
new /obj/item/weapon/light/bulb(), \
+ new /obj/item/weapon/camera_assembly(), \
)
var/global/list/autolathe_recipes_hidden = list( \
diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm
index 67c8cbeb939..ae5ee8545f7 100644
--- a/code/game/machinery/bots/bots.dm
+++ b/code/game/machinery/bots/bots.dm
@@ -3,7 +3,7 @@
/obj/machinery/bot
icon = 'icons/obj/aibots.dmi'
layer = MOB_LAYER
- luminosity = 2
+ luminosity = 3
var/obj/item/weapon/card/id/botcard // the ID card that the bot "holds"
var/on = 1
var/health = 0 //do not forget to set health for your bot!
@@ -16,13 +16,14 @@
/obj/machinery/bot/proc/turn_on()
- if (stat)
- return 0
- src.on = 1
+ if(stat) return 0
+ on = 1
+ SetLuminosity(initial(luminosity))
return 1
/obj/machinery/bot/proc/turn_off()
- src.on = 0
+ on = 0
+ SetLuminosity(0)
/obj/machinery/bot/proc/explode()
del(src)
diff --git a/code/game/machinery/camera.dm b/code/game/machinery/camera.dm
deleted file mode 100644
index 93f46b97d17..00000000000
--- a/code/game/machinery/camera.dm
+++ /dev/null
@@ -1,367 +0,0 @@
-/mob/living/silicon/ai/proc/ai_camera_list()
- set category = "AI Commands"
- set name = "Show Camera List"
-
- if(usr.stat == 2)
- usr << "You can't track with camera because you are dead!"
- return
-
- attack_ai(src)
-
-/mob/living/silicon/ai/proc/ai_camera_track()
- set category = "AI Commands"
- set name = "Track With Camera"
- if(usr.stat == 2)
- usr << "You can't track with camera because you are dead!"
- return
-
- var/list/names = list()
- var/list/namecounts = list()
- var/list/humans = list()
- var/list/others = list()
-
- for(var/mob/living/M in mob_list)
- // Easy checks first.
- // Don't detect mobs on Centcom. Since the wizard den is on Centcomm, we only need this.
- if(M.loc.z == 2)
- continue
- if(M == usr)
- continue
- if(M.invisibility)//cloaked
- continue
- if(M.digitalcamo)
- continue
-
- // Human check
- var/human = 0
- if(istype(M, /mob/living/carbon/human))
- human = 1
- var/mob/living/carbon/human/H = M
- //Cameras can't track people wearing an agent card or a ninja hood.
- if(istype(H.wear_id, /obj/item/weapon/card/id/syndicate))
- continue
- if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja))
- var/obj/item/clothing/head/helmet/space/space_ninja/hood = H.head
- if(!hood.canremove)
- continue
-
- if(!isturf(M.loc))
- continue
- // Now, are they viewable by a camera? (This is last because it's the most intensive check)
- if(!cameranet.checkCameraVis(M))
- continue
-
- var/name = M.name
- if (name in names)
- namecounts[name]++
- name = text("[] ([])", name, namecounts[name])
- else
- names.Add(name)
- namecounts[name] = 1
- if(human)
- humans[name] = M
- else
- others[name] = M
-
- var/list/targets = sortList(humans) + sortList(others)
- var/target_name = input(usr, "Which creature should you track?") as null|anything in targets
-
- if (!target_name)
- usr:cameraFollow = null
- return
-
- var/mob/target = (isnull(humans[target_name]) ? others[target_name] : humans[target_name])
- ai_actual_track(target)
-
-/mob/living/silicon/ai/proc/ai_actual_track(mob/living/target as mob)
- if(!istype(target)) return
- var/mob/living/silicon/ai/U = usr
-
- U.cameraFollow = target
- //U << text("Now tracking [] on camera.", target.name)
- //if (U.machine == null)
- // U.machine = U
- U << "Now tracking [target.name] on camera."
-
- spawn (0)
- while (U.cameraFollow == target)
- if (U.cameraFollow == null)
- return
- if (istype(target, /mob/living/carbon/human))
- if(istype(target:wear_id, /obj/item/weapon/card/id/syndicate))
- U << "Follow camera mode terminated."
- U.cameraFollow = null
- return
- if(istype(target:head, /obj/item/clothing/head/helmet/space/space_ninja) && !target:head:canremove)
- U << "Follow camera mode terminated."
- U.cameraFollow = null
- return
- if(target.digitalcamo)
- U << "Follow camera mode terminated."
- U.cameraFollow = null
- return
-
- if(istype(target.loc,/obj/effect/dummy))
- U << "Follow camera mode ended."
- U.cameraFollow = null
- return
- if (!isturf(target.loc)) //in a closet
- U << "Target is not on or near any active cameras on the station. We'll check again in 5 seconds (unless you use the cancel-camera verb)."
- sleep(50) //because we're sleeping another second after this (a few lines down)
- continue
- if(!cameranet.checkCameraVis(target))
- U << "Target is not on or near any active cameras on the station. We'll check again in 5 seconds (unless you use the cancel-camera verb)."
- sleep(50) //because we're sleeping another second after this (a few lines down)
- continue
-
- U.eyeobj.setLoc(get_turf(target))
- sleep(10)
-
-/proc/camera_sort(list/L)
- var/obj/machinery/camera/a
- var/obj/machinery/camera/b
-
- for (var/i = L.len, i > 0, i--)
- for (var/j = 1 to i - 1)
- a = L[j]
- b = L[j + 1]
- if (a.c_tag_order != b.c_tag_order)
- if (a.c_tag_order > b.c_tag_order)
- L.Swap(j, j + 1)
- else
- if (sorttext(a.c_tag, b.c_tag) < 0)
- L.Swap(j, j + 1)
- return L
-
-/mob/living/silicon/ai/attack_ai(var/mob/user as mob)
- if (user != src)
- return
-
- if (stat == 2)
- return
-
- var/list/L = list()
- for (var/obj/machinery/camera/C in cameranet.cameras)
- L.Add(C)
-
- camera_sort(L)
-
- var/list/D = list()
- D["Cancel"] = "Cancel"
- for (var/obj/machinery/camera/C in L)
- if (C.network == src.network)
- D[text("[][]", C.c_tag, (C.can_use() ? null : " (Deactivated)"))] = C
-
- var/t = input(user, "Which camera should you change to?") as null|anything in D
-
- if (!t || t == "Cancel")
- return 0
-
- var/obj/machinery/camera/C = D[t]
- src.eyeobj.setLoc(C)
-
- return
-
-/obj/machinery/camera/emp_act(severity)
- if(prob(100/(hardened + severity)))
- icon_state = "cameraemp"
- network = null //Not the best way but it will do. I think.
- cameranet.removeCamera(src)
- stat |= EMPED
- SetLuminosity(0)
- spawn(900)
- network = initial(network)
- icon_state = initial(icon_state)
- stat &= ~EMPED
- if(can_use())
- cameranet.addCamera(src)
- for(var/mob/O in mob_list)
- if (istype(O.machine, /obj/machinery/computer/security))
- var/obj/machinery/computer/security/S = O.machine
- if (S.current == src)
- O.machine = null
- O.reset_view(null)
- O << "The screen bursts into static."
- ..()
-
-/obj/machinery/camera/emp_proof/emp_act(severity)
- return
-
-/obj/machinery/camera/ex_act(severity)
- if(src.invuln)
- return
- else
- ..(severity)
- return
-
-/obj/machinery/camera/blob_act()
- return
-
-/obj/machinery/camera/attack_ai(var/mob/living/silicon/ai/user as mob)
- if (!istype(user))
- return
- if (!src.can_use())
- return
- user.eyeobj.setLoc(get_turf(src))
-
-/obj/machinery/camera/attack_paw(mob/living/carbon/alien/humanoid/user as mob)
- if(!istype(user))
- return
- status = 0
- for(var/mob/O in viewers(user, null))
- O.show_message("\The [user] slashes at [src]!", 1)
- playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
- icon_state = "camera1"
- add_hiddenprint(user)
- deactivate(user,0)
-
-/obj/machinery/camera/attackby(W as obj, user as mob)
- if (istype(W, /obj/item/weapon/wirecutters))
- deactivate(user)
- else if ((istype(W, /obj/item/weapon/paper) || istype(W, /obj/item/device/pda)) && isliving(user))
- var/mob/living/U = user
- var/obj/item/weapon/paper/X = null
- var/obj/item/device/pda/P = null
-
- var/itemname = ""
- var/info = ""
- if(istype(W, /obj/item/weapon/paper))
- X = W
- itemname = X.name
- info = X.info
- else
- P = W
- itemname = P.name
- info = P.notehtml
- U << "You hold \a [itemname] up to the camera ..."
- for(var/mob/living/silicon/ai/O in player_list)
- //if (O.current == src)
- if(U.name == "Unknown") O << "[U] holds \a [itemname] up to one of your cameras ..."
- else O << "[U] holds \a [itemname] up to one of your cameras ..."
- O << browse(text("[][]", itemname, info), text("window=[]", itemname))
- for(var/mob/O in player_list)
- if (istype(O.machine, /obj/machinery/computer/security))
- var/obj/machinery/computer/security/S = O.machine
- if (S.current == src)
- O << "[U] holds \a [itemname] up to one of the cameras ..."
- O << browse(text("[][]", itemname, info), text("window=[]", itemname))
- else if (istype(W, /obj/item/weapon/wrench)) //Adding dismantlable cameras to go with the constructable ones. --NEO
- if(src.status)
- user << "\red You can't dismantle a camera while it is active."
- else
- user << "\blue Dismantling camera..."
- if(do_after(user, 20))
- var/obj/item/weapon/grenade/chem_grenade/case = new /obj/item/weapon/grenade/chem_grenade(src.loc)
- case.name = "Camera Assembly"
- case.icon = 'icons/obj/monitors.dmi'
-//JESUS WHAT THE FUCK EVERYTHING TO DO WITH CAMERAS IS TERRIBLE FUCK
- case.icon_state = "cameracase"
- case.path = 2
- case.state = 5
- case.circuit = new /obj/item/device/multitool
- if (istype(src, /obj/machinery/camera/motion))
- case.motion = 1
- del(src)
- else if (istype(W, /obj/item/weapon/camera_bug))
- if (!src.can_use())
- user << "\blue Camera non-functional"
- return
- if (src.bugged)
- user << "\blue Camera bug removed."
- src.bugged = 0
- else
- user << "\blue Camera bugged."
- src.bugged = 1
- else if(istype(W, /obj/item/weapon/melee/energy/blade))//Putting it here last since it's a special case. I wonder if there is a better way to do these than type casting.
- deactivate(user,2)//Here so that you can disconnect anyone viewing the camera, regardless if it's on or off.
- var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
- spark_system.set_up(5, 0, loc)
- spark_system.start()
- playsound(loc, 'sound/weapons/blade1.ogg', 50, 1)
- playsound(loc, "sparks", 50, 1)
-
- var/obj/item/weapon/grenade/chem_grenade/case = new /obj/item/weapon/grenade/chem_grenade(loc)
- case.name = "Camera Assembly"
- case.icon = 'icons/obj/monitors.dmi'
- case.icon_state = "cameracase"
- case.path = 2
- case.state = 5
- case.circuit = new /obj/item/device/multitool
- if (istype(src, /obj/machinery/camera/motion))
- case.motion = 1
-
- for(var/mob/O in viewers(user, 3))
- O.show_message(text("\blue The camera has been sliced apart by [] with an energy blade!", user), 1, text("\red You hear metal being sliced and sparks flying."), 2)
- del(src)
- else
- ..()
- return
-
-/obj/machinery/camera/proc/deactivate(user as mob, var/choice = 1)
- if(choice==1)
- status = !( src.status )
- if (!(src.status))
- for(var/mob/O in viewers(user, null))
- O.show_message(text("\red [] has deactivated []!", user, src), 1)
- playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
- icon_state = "camera1"
- add_hiddenprint(user)
- else
- for(var/mob/O in viewers(user, null))
- O.show_message(text("\red [] has reactivated []!", user, src), 1)
- playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
- icon_state = "camera"
- add_hiddenprint(user)
- // now disconnect anyone using the camera
- //Apparently, this will disconnect anyone even if the camera was re-activated.
- //I guess that doesn't matter since they can't use it anyway?
- for(var/mob/O in player_list)
- if (istype(O.machine, /obj/machinery/computer/security))
- var/obj/machinery/computer/security/S = O.machine
- if (S.current == src)
- O.machine = null
- O.reset_view(null)
- O << "The screen bursts into static."
-
-/obj/machinery/camera/proc/can_use()
- if(!status)
- return 0
- if(stat & EMPED)
- return 0
- return 1
-
-/atom/proc/auto_turn()
- //Automatically turns based on nearby walls.
- var/turf/simulated/wall/T = null
- for(var/i = 1, i <= 8; i += i)
- T = get_ranged_target_turf(src, i, 1)
- if(!isnull(T) && istype(T))
- //If someone knows a better way to do this, let me know. -Giacom
- switch(i)
- if(NORTH)
- src.dir = SOUTH
- if(SOUTH)
- src.dir = NORTH
- if(WEST)
- src.dir = EAST
- if(EAST)
- src.dir = WEST
- break
-
-//Return a working camera that can see a given mob
-//or null if none
-/proc/seen_by_camera(var/mob/M)
- for(var/obj/machinery/camera/C in oview(4, M))
- if(C.can_use()) // check if camera disabled
- return C
- break
- return null
-
-/proc/near_range_camera(var/mob/M)
-
- for(var/obj/machinery/camera/C in range(4, M))
- if(C.can_use()) // check if camera disabled
- return C
- break
-
- return null
\ No newline at end of file
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
new file mode 100644
index 00000000000..3a253d09c46
--- /dev/null
+++ b/code/game/machinery/camera/camera.dm
@@ -0,0 +1,293 @@
+/obj/machinery/camera
+ name = "security camera"
+ desc = "It's used to monitor rooms."
+ icon = 'icons/obj/monitors.dmi'
+ icon_state = "camera"
+ use_power = 2
+ idle_power_usage = 5
+ active_power_usage = 10
+ layer = 5
+
+ var/network = "SS13"
+ var/c_tag = null
+ var/c_tag_order = 999
+ var/status = 1.0
+ anchored = 1.0
+ var/panel_open = 0 // 0 = Closed / 1 = Open
+ var/invuln = null
+ var/bugged = 0
+ var/obj/item/weapon/camera_assembly/assembly = null
+
+ // WIRES
+ var/wires = 63 // 0b111111
+ var/list/IndexToFlag = list()
+ var/list/IndexToWireColor = list()
+ var/list/WireColorToIndex = list()
+ var/list/WireColorToFlag = list()
+
+ //OTHER
+
+ var/view_range = 7
+ var/short_range = 2
+
+ var/light_disabled = 0
+ var/alarm_on = 0
+ var/busy = 0
+
+/obj/machinery/camera/New()
+ WireColorToFlag = randomCameraWires()
+ assembly = new(src)
+ assembly.state = 4
+ ..()
+
+
+/obj/machinery/camera/emp_act(severity)
+ if(!isEmpProof())
+ if(prob(100/severity))
+ icon_state = "cameraemp"
+ network = null //Not the best way but it will do. I think.
+ cameranet.removeCamera(src)
+ stat |= EMPED
+ SetLuminosity(0)
+ triggerCameraAlarm()
+ spawn(900)
+ network = initial(network)
+ icon_state = initial(icon_state)
+ stat &= ~EMPED
+ cancelCameraAlarm()
+ if(can_use())
+ cameranet.addCamera(src)
+ for(var/mob/O in mob_list)
+ if (istype(O.machine, /obj/machinery/computer/security))
+ var/obj/machinery/computer/security/S = O.machine
+ if (S.current == src)
+ O.machine = null
+ O.reset_view(null)
+ O << "The screen bursts into static."
+ ..()
+
+
+/obj/machinery/camera/ex_act(severity)
+ if(src.invuln)
+ return
+ else
+ ..(severity)
+ return
+
+/obj/machinery/camera/blob_act()
+ return
+
+/obj/machinery/camera/proc/setViewRange(var/num = 7)
+ src.view_range = num
+ cameranet.updateVisibility(src, 0)
+
+/obj/machinery/camera/proc/shock(var/mob/living/user)
+ if(!istype(user))
+ return
+ user.electrocute_act(10, src)
+
+/obj/machinery/camera/attack_paw(mob/living/carbon/alien/humanoid/user as mob)
+ if(!istype(user))
+ return
+ status = 0
+ for(var/mob/O in viewers(user, null))
+ O.show_message("\The [user] slashes at [src]!", 1)
+ playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
+ icon_state = "camera1"
+ add_hiddenprint(user)
+ deactivate(user,0)
+
+/obj/machinery/camera/attackby(W as obj, mob/living/user as mob)
+
+ // DECONSTRUCTION
+ if(isscrewdriver(W))
+ //user << "You start to [panel_open ? "close" : "open"] the camera's panel."
+ //if(toggle_panel(user)) // No delay because no one likes screwdrivers trying to be hip and have a duration cooldown
+ panel_open = !panel_open
+ user.visible_message("[user] screws the camera's panel [panel_open ? "open" : "closed"]!",
+ "You screw the camera's panel [panel_open ? "open" : "closed"].")
+
+ else if((iswirecutter(W) || ismultitool(W)) && panel_open)
+ interact(user)
+
+ else if(iswelder(W) && canDeconstruct())
+ if(weld(W, user))
+ if(assembly)
+ assembly.loc = src.loc
+ assembly.state = 1
+ del(src)
+
+
+ // OTHER
+ else if ((istype(W, /obj/item/weapon/paper) || istype(W, /obj/item/device/pda)) && isliving(user))
+ var/mob/living/U = user
+ var/obj/item/weapon/paper/X = null
+ var/obj/item/device/pda/P = null
+
+ var/itemname = ""
+ var/info = ""
+ if(istype(W, /obj/item/weapon/paper))
+ X = W
+ itemname = X.name
+ info = X.info
+ else
+ P = W
+ itemname = P.name
+ info = P.notehtml
+ U << "You hold \a [itemname] up to the camera ..."
+ for(var/mob/living/silicon/ai/O in player_list)
+ //if (O.current == src)
+ if(U.name == "Unknown") O << "[U] holds \a [itemname] up to one of your cameras ..."
+ else O << "[U] holds \a [itemname] up to one of your cameras ..."
+ O << browse(text("[][]", itemname, info), text("window=[]", itemname))
+ for(var/mob/O in player_list)
+ if (istype(O.machine, /obj/machinery/computer/security))
+ var/obj/machinery/computer/security/S = O.machine
+ if (S.current == src)
+ O << "[U] holds \a [itemname] up to one of the cameras ..."
+ O << browse(text("[][]", itemname, info), text("window=[]", itemname))
+ else if (istype(W, /obj/item/weapon/camera_bug))
+ if (!src.can_use())
+ user << "\blue Camera non-functional"
+ return
+ if (src.bugged)
+ user << "\blue Camera bug removed."
+ src.bugged = 0
+ else
+ user << "\blue Camera bugged."
+ src.bugged = 1
+ else if(istype(W, /obj/item/weapon/melee/energy/blade))//Putting it here last since it's a special case. I wonder if there is a better way to do these than type casting.
+ deactivate(user,2)//Here so that you can disconnect anyone viewing the camera, regardless if it's on or off.
+ var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
+ spark_system.set_up(5, 0, loc)
+ spark_system.start()
+ playsound(loc, 'sound/weapons/blade1.ogg', 50, 1)
+ playsound(loc, "sparks", 50, 1)
+
+ for(var/mob/O in viewers(user, 3))
+ O.show_message(text("\blue The camera has been sliced apart by [] with an energy blade!", user), 1, text("\red You hear metal being sliced and sparks flying."), 2)
+ del(src)
+ else
+ ..()
+ return
+
+/obj/machinery/camera/proc/deactivate(user as mob, var/choice = 1)
+ if(choice==1)
+ status = !( src.status )
+ if (!(src.status))
+ for(var/mob/O in viewers(user, null))
+ O.show_message(text("\red [] has deactivated []!", user, src), 1)
+ playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
+ icon_state = "camera1"
+ add_hiddenprint(user)
+ else
+ for(var/mob/O in viewers(user, null))
+ O.show_message(text("\red [] has reactivated []!", user, src), 1)
+ playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
+ icon_state = "camera"
+ add_hiddenprint(user)
+ // now disconnect anyone using the camera
+ //Apparently, this will disconnect anyone even if the camera was re-activated.
+ //I guess that doesn't matter since they can't use it anyway?
+ for(var/mob/O in player_list)
+ if (istype(O.machine, /obj/machinery/computer/security))
+ var/obj/machinery/computer/security/S = O.machine
+ if (S.current == src)
+ O.machine = null
+ O.reset_view(null)
+ O << "The screen bursts into static."
+
+/obj/machinery/camera/proc/triggerCameraAlarm()
+ alarm_on = 1
+ for(var/mob/living/silicon/S in mob_list)
+ S.triggerAlarm("Camera", get_area(src), list(src), src)
+
+
+/obj/machinery/camera/proc/cancelCameraAlarm()
+ alarm_on = 0
+ for(var/mob/living/silicon/S in mob_list)
+ S.cancelAlarm("Camera", get_area(src), list(src), src)
+
+/obj/machinery/camera/proc/toggle_panel(var/mob/user)
+ if(busy)
+ return 0
+ playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ busy = 1
+ if(do_after(user, 30))
+ panel_open = !panel_open
+ busy = 0
+ return 1
+ busy = 0
+ return 0
+
+/obj/machinery/camera/proc/can_use()
+ if(!status)
+ return 0
+ if(stat & EMPED)
+ return 0
+ return 1
+
+/obj/machinery/camera/proc/can_see()
+ var/list/see = null
+ var/turf/pos = get_turf(src)
+ if(isXRay())
+ see = range(view_range, pos)
+ else
+ see = hear(view_range, pos)
+ return see
+
+/atom/proc/auto_turn()
+ //Automatically turns based on nearby walls.
+ var/turf/simulated/wall/T = null
+ for(var/i = 1, i <= 8; i += i)
+ T = get_ranged_target_turf(src, i, 1)
+ if(!isnull(T) && istype(T))
+ //If someone knows a better way to do this, let me know. -Giacom
+ switch(i)
+ if(NORTH)
+ src.dir = SOUTH
+ if(SOUTH)
+ src.dir = NORTH
+ if(WEST)
+ src.dir = EAST
+ if(EAST)
+ src.dir = WEST
+ break
+
+//Return a working camera that can see a given mob
+//or null if none
+/proc/seen_by_camera(var/mob/M)
+ for(var/obj/machinery/camera/C in oview(4, M))
+ if(C.can_use()) // check if camera disabled
+ return C
+ break
+ return null
+
+/proc/near_range_camera(var/mob/M)
+
+ for(var/obj/machinery/camera/C in range(4, M))
+ if(C.can_use()) // check if camera disabled
+ return C
+ break
+
+ return null
+
+/obj/machinery/camera/proc/weld(var/obj/item/weapon/weldingtool/WT, var/mob/user)
+
+ if(busy)
+ return 0
+ if(!WT.isOn())
+ return 0
+
+ // Do after stuff here
+ user << "You start to weld the [src].."
+ playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
+ WT.eyecheck(user)
+ busy = 1
+ if(do_after(user, 100))
+ busy = 0
+ if(!WT.isOn())
+ return 0
+ return 1
+ busy = 0
+ return 0
\ No newline at end of file
diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm
new file mode 100644
index 00000000000..375b54529ab
--- /dev/null
+++ b/code/game/machinery/camera/camera_assembly.dm
@@ -0,0 +1,152 @@
+/obj/item/weapon/camera_assembly
+ name = "camera assembly"
+ desc = "The basic construction for Nanotrasen-Always-Watching-You cameras."
+ icon = 'icons/obj/monitors.dmi'
+ icon_state = "cameracase"
+ w_class = 2
+ anchored = 0
+
+ m_amt = 700
+ g_amt = 300
+
+ // Motion, EMP-Proof, X-Ray
+ var/list/obj/item/possible_upgrades = list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/plasma, /obj/item/weapon/reagent_containers/food/snacks/grown/carrot)
+ var/list/upgrades = list()
+ var/state = 0
+ var/busy = 0
+ /*
+ 0 = Nothing done to it
+ 1 = Wrenched in place
+ 2 = Welded in place
+ 3 = Wires attached to it (you can now attach/dettach upgrades)
+ 4 = Screwdriver panel closed and is fully built (you cannot attach upgrades)
+ */
+
+/obj/item/weapon/camera_assembly/attackby(obj/item/W as obj, mob/living/user as mob)
+
+ switch(state)
+
+ if(0)
+ // State 0
+ if(iswrench(W) && isturf(src.loc))
+ playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ user << "You wrench the assembly into place."
+ anchored = 1
+ state = 1
+ update_icon()
+ auto_turn()
+ return
+
+ if(1)
+ // State 1
+ if(iswelder(W))
+ if(weld(W, user))
+ user << "You weld the assembly securely into place."
+ state = 2
+ return
+
+ else if(iswrench(W))
+ playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
+ user << "You unattach the assembly from it's place."
+ anchored = 0
+ update_icon()
+ state = 0
+ return
+
+ if(2)
+ // State 2
+ if(iscoil(W))
+ var/obj/item/weapon/cable_coil/C = W
+ if(C.use(2))
+ user << "You add wires to the assembly."
+ state = 3
+ return
+
+ else if(iswelder(W))
+
+ if(weld(W, user))
+ user << "You unweld the assembly from it's place."
+ state = 1
+ return
+
+
+ if(3)
+ // State 3
+ if(isscrewdriver(W))
+ playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
+ state = 4
+ var/obj/machinery/camera/C = new(src.loc)
+ src.loc = C
+ C.assembly = src
+
+ C.auto_turn()
+
+ C.network = "SS13"
+ C.network = input(usr, "Which network would you like to connect this camera to?", "Set Network", "SS13")
+
+ for(var/i = 5; i >= 0; i -= 1)
+ var/direct = input(user, "Direction?", "Assembling Camera", null) in list("LEAVE IT", "NORTH", "EAST", "SOUTH", "WEST" )
+ if(direct != "LEAVE IT")
+ C.dir = text2dir(direct)
+ if(i != 0)
+ var/confirm = alert(user, "Is this what you want? Chances Remaining: [i]", "Confirmation", "Yes", "No")
+ if(confirm == "Yes")
+ break
+ return
+
+ else if(iswirecutter(W))
+
+ new/obj/item/weapon/cable_coil(src.loc, 2)
+ playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1)
+ user << "You cut the wires from the circuits."
+ state = 2
+ return
+
+ // Upgrades!
+ if(is_type_in_list(W, possible_upgrades))
+ user << "You attach the [W] into the assembly inner circuits."
+ upgrades += W
+ user.drop_item(W)
+ W.loc = src
+ return
+
+ // Taking out upgrades
+ else if(iscrowbar(W) && upgrades.len)
+ var/obj/U = locate(/obj) in upgrades
+ if(U)
+ user << "You unattach an upgrade from the assembly."
+ playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
+ U.loc = src.loc
+ upgrades -= U
+ return
+
+ ..()
+
+/obj/item/weapon/camera_assembly/update_icon()
+ if(anchored)
+ icon_state = "camera1"
+ else
+ icon_state = "cameracase"
+
+/obj/item/weapon/camera_assembly/attack_hand(mob/user as mob)
+ if(!anchored)
+ ..()
+
+/obj/item/weapon/camera_assembly/proc/weld(var/obj/item/weapon/weldingtool/WT, var/mob/user)
+
+ if(busy)
+ return 0
+ if(!WT.isOn())
+ return 0
+
+ user << "You start to weld the [src].."
+ playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
+ WT.eyecheck(user)
+ busy = 1
+ if(do_after(user, 20))
+ busy = 0
+ if(!WT.isOn())
+ return 0
+ return 1
+ busy = 0
+ return 0
\ No newline at end of file
diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm
new file mode 100644
index 00000000000..d17a0e8f0d2
--- /dev/null
+++ b/code/game/machinery/camera/motion.dm
@@ -0,0 +1,48 @@
+/obj/machinery/camera
+
+ var/list/motionTargets = list()
+ var/detectTime = 0
+ var/locked = 1
+
+
+/obj/machinery/camera/process()
+ // motion camera event loop
+ if(!isMotion())
+ . = PROCESS_KILL
+ return
+ if (detectTime > 0)
+ var/elapsed = world.time - detectTime
+ if (elapsed > 300)
+ triggerAlarm()
+ else if (detectTime == -1)
+ for (var/mob/target in motionTargets)
+ if (target.stat == 2) lostTarget(target)
+
+/obj/machinery/camera/proc/newTarget(var/mob/target)
+ if (istype(target, /mob/living/silicon/ai)) return 0
+ if (detectTime == 0)
+ detectTime = world.time // start the clock
+ if (!(target in motionTargets))
+ motionTargets += target
+ return 1
+
+/obj/machinery/camera/proc/lostTarget(var/mob/target)
+ if (target in motionTargets)
+ motionTargets -= target
+ if (motionTargets.len == 0)
+ cancelAlarm()
+
+/obj/machinery/camera/proc/cancelAlarm()
+ if (detectTime == -1)
+ for (var/mob/living/silicon/aiPlayer in player_list)
+ if (status) aiPlayer.cancelAlarm("Motion", src.loc.loc)
+ detectTime = 0
+ return 1
+
+/obj/machinery/camera/proc/triggerAlarm()
+ if (!detectTime) return 0
+ for (var/mob/living/silicon/aiPlayer in player_list)
+ if (status) aiPlayer.triggerAlarm("Motion", src.loc.loc, src)
+ detectTime = -1
+ return 1
+
diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm
new file mode 100644
index 00000000000..99d13c01d24
--- /dev/null
+++ b/code/game/machinery/camera/presets.dm
@@ -0,0 +1,45 @@
+// PRESETS
+
+/obj/machinery/camera/emp_proof/New()
+ ..()
+ upgradeEmpProof()
+
+/obj/machinery/camera/xray/New()
+ ..()
+ upgradeXRay()
+
+/obj/machinery/camera/motion/New()
+ ..()
+ upgradeMotion()
+
+/obj/machinery/camera/all/New()
+ ..()
+ upgradeEmpProof()
+ upgradeXRay()
+ upgradeMotion()
+
+// CHECKS
+
+/obj/machinery/camera/proc/isEmpProof()
+ var/O = locate(/obj/item/stack/sheet/plasma) in assembly.upgrades
+ return O
+
+/obj/machinery/camera/proc/isXRay()
+ var/O = locate(/obj/item/weapon/reagent_containers/food/snacks/grown/carrot) in assembly.upgrades
+ return O
+
+/obj/machinery/camera/proc/isMotion()
+ var/O = locate(/obj/item/device/assembly/prox_sensor) in assembly.upgrades
+ return O
+
+// UPGRADE PROCS
+
+/obj/machinery/camera/proc/upgradeEmpProof()
+ assembly.upgrades.Add(new /obj/item/stack/sheet/plasma(assembly))
+
+/obj/machinery/camera/proc/upgradeXRay()
+ assembly.upgrades.Add(new /obj/item/weapon/reagent_containers/food/snacks/grown/carrot(assembly))
+
+// If you are upgrading Motion, and it isn't in the camera's New(), add it to the machines list.
+/obj/machinery/camera/proc/upgradeMotion()
+ assembly.upgrades.Add(new /obj/item/device/assembly/prox_sensor(assembly))
\ No newline at end of file
diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm
new file mode 100644
index 00000000000..ac3ad6b68d3
--- /dev/null
+++ b/code/game/machinery/camera/tracking.dm
@@ -0,0 +1,181 @@
+/mob/living/silicon/ai/proc/ai_camera_list()
+ set category = "AI Commands"
+ set name = "Show Camera List"
+
+ if(usr.stat == 2)
+ usr << "You can't track with camera because you are dead!"
+ return
+
+ attack_ai(src)
+
+/mob/living/silicon/ai/proc/ai_camera_track()
+ set category = "AI Commands"
+ set name = "Track With Camera"
+ if(usr.stat == 2)
+ usr << "You can't track with camera because you are dead!"
+ return
+
+ var/list/names = list()
+ var/list/namecounts = list()
+ var/list/humans = list()
+ var/list/others = list()
+
+ for(var/mob/living/M in mob_list)
+ // Easy checks first.
+ // Don't detect mobs on Centcom. Since the wizard den is on Centcomm, we only need this.
+ if(M.loc.z == 2)
+ continue
+ if(M == usr)
+ continue
+ if(M.invisibility)//cloaked
+ continue
+ if(M.digitalcamo)
+ continue
+
+ // Human check
+ var/human = 0
+ if(istype(M, /mob/living/carbon/human))
+ human = 1
+ var/mob/living/carbon/human/H = M
+ //Cameras can't track people wearing an agent card or a ninja hood.
+ if(istype(H.wear_id, /obj/item/weapon/card/id/syndicate))
+ continue
+ if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja))
+ var/obj/item/clothing/head/helmet/space/space_ninja/hood = H.head
+ if(!hood.canremove)
+ continue
+
+ // Now, are they viewable by a camera? (This is last because it's the most intensive check)
+ if(!near_camera(M))
+ continue
+
+ var/name = M.name
+ if (name in names)
+ namecounts[name]++
+ name = text("[] ([])", name, namecounts[name])
+ else
+ names.Add(name)
+ namecounts[name] = 1
+ if(human)
+ humans[name] = M
+ else
+ others[name] = M
+
+ var/list/targets = sortList(humans) + sortList(others)
+ var/target_name = input(usr, "Which creature should you track?") as null|anything in targets
+
+ if (!target_name)
+ usr:cameraFollow = null
+ return
+
+ var/mob/target = (isnull(humans[target_name]) ? others[target_name] : humans[target_name])
+ ai_actual_track(target)
+
+/mob/living/silicon/ai/proc/ai_actual_track(mob/living/target as mob)
+ if(!istype(target)) return
+ var/mob/living/silicon/ai/U = usr
+
+ U.cameraFollow = target
+ //U << text("Now tracking [] on camera.", target.name)
+ //if (U.machine == null)
+ // U.machine = U
+ U << "Now tracking [target.name] on camera."
+
+ spawn (0)
+ while (U.cameraFollow == target)
+ if (U.cameraFollow == null)
+ return
+ if (istype(target, /mob/living/carbon/human))
+ if(istype(target:wear_id, /obj/item/weapon/card/id/syndicate))
+ U << "Follow camera mode terminated."
+ U.cameraFollow = null
+ return
+ if(istype(target:head, /obj/item/clothing/head/helmet/space/space_ninja) && !target:head:canremove)
+ U << "Follow camera mode terminated."
+ U.cameraFollow = null
+ return
+ if(target.digitalcamo)
+ U << "Follow camera mode terminated."
+ U.cameraFollow = null
+ return
+
+ if(istype(target.loc,/obj/effect/dummy))
+ U << "Follow camera mode ended."
+ U.cameraFollow = null
+ return
+
+ if (!near_camera(target))
+ U << "Target is not on or near any active cameras on the station. We'll check again in 5 seconds (unless you use the cancel-camera verb)."
+ sleep(50) //because we're sleeping another second after this (a few lines down)
+ continue
+
+ if(U.eyeobj)
+ U.eyeobj.setLoc(get_turf(target))
+ else
+ core()
+ return
+ sleep(10)
+
+/proc/near_camera(var/mob/M)
+ if (!isturf(M.loc))
+ return 0
+ if(isrobot(M))
+ var/mob/living/silicon/robot/R = M
+ if(!(R.camera && R.camera.can_use()) && !cameranet.checkCameraVis(M))
+ return 0
+ else if(!cameranet.checkCameraVis(M))
+ return 0
+ return 1
+
+/obj/machinery/camera/attack_ai(var/mob/living/silicon/ai/user as mob)
+ if (!istype(user))
+ return
+ if (!src.can_use())
+ return
+ user.eyeobj.setLoc(get_turf(src))
+
+
+/mob/living/silicon/ai/attack_ai(var/mob/user as mob)
+ if (user != src)
+ return
+
+ if (stat == 2)
+ return
+
+ var/list/L = list()
+ for (var/obj/machinery/camera/C in cameranet.cameras)
+ L.Add(C)
+
+ camera_sort(L)
+
+ var/list/D = list()
+ D["Cancel"] = "Cancel"
+ for (var/obj/machinery/camera/C in L)
+ if (C.network == src.network)
+ D[text("[][]", C.c_tag, (C.can_use() ? null : " (Deactivated)"))] = C
+
+ var/t = input(user, "Which camera should you change to?") as null|anything in D
+
+ if (!t || t == "Cancel")
+ return 0
+
+ var/obj/machinery/camera/C = D[t]
+ src.eyeobj.setLoc(C)
+
+ return
+
+/proc/camera_sort(list/L)
+ var/obj/machinery/camera/a
+ var/obj/machinery/camera/b
+
+ for (var/i = L.len, i > 0, i--)
+ for (var/j = 1 to i - 1)
+ a = L[j]
+ b = L[j + 1]
+ if (a.c_tag_order != b.c_tag_order)
+ if (a.c_tag_order > b.c_tag_order)
+ L.Swap(j, j + 1)
+ else
+ if (sorttext(a.c_tag, b.c_tag) < 0)
+ L.Swap(j, j + 1)
+ return L
\ No newline at end of file
diff --git a/code/game/machinery/camera/wires.dm b/code/game/machinery/camera/wires.dm
new file mode 100644
index 00000000000..e27069c17b2
--- /dev/null
+++ b/code/game/machinery/camera/wires.dm
@@ -0,0 +1,170 @@
+#define CAMERA_WIRE_FOCUS 1
+#define CAMERA_WIRE_POWER 2
+#define CAMERA_WIRE_LIGHT 3
+#define CAMERA_WIRE_ALARM 4
+#define CAMERA_WIRE_NOTHING1 5
+#define CAMERA_WIRE_NOTHING2 6
+
+/obj/machinery/camera/proc/randomCameraWires()
+ //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else).
+ var/list/wires = list(0, 0, 0, 0, 0, 0)
+ IndexToFlag = list(0, 0, 0, 0, 0, 0)
+ IndexToWireColor = list(0, 0, 0, 0, 0, 0)
+ WireColorToIndex = list(0, 0, 0, 0, 0, 0)
+ var/flagIndex = 1
+ //I think it's easier to read this way, also doesn't rely on the random number generator to land on a new wire.
+ var/list/colorIndexList = list(CAMERA_WIRE_FOCUS, CAMERA_WIRE_POWER, CAMERA_WIRE_LIGHT, CAMERA_WIRE_ALARM, CAMERA_WIRE_NOTHING1, CAMERA_WIRE_NOTHING2)
+ for (var/flag=1, flag<=32, flag+=flag)
+ var/colorIndex = pick(colorIndexList)
+ if (wires[colorIndex]==0)
+ wires[colorIndex] = flag
+ IndexToFlag[flagIndex] = flag
+ IndexToWireColor[flagIndex] = colorIndex
+ WireColorToIndex[colorIndex] = flagIndex
+ colorIndexList -= colorIndex // Shortens the list.
+ //world.log << "Flag: [flag], CIndex: [colorIndex], FIndex: [flagIndex]"
+ flagIndex+=1
+ return wires
+
+/obj/machinery/camera/proc/isWireColorCut(var/wireColor)
+ var/wireFlag = WireColorToFlag[wireColor]
+ return ((src.wires & wireFlag) == 0)
+
+/obj/machinery/camera/proc/isWireCut(var/wireIndex)
+ var/wireFlag = IndexToFlag[wireIndex]
+ return ((src.wires & wireFlag) == 0)
+
+/obj/machinery/camera/proc/canDeconstruct()
+ if(isWireCut(CAMERA_WIRE_POWER) && isWireCut(CAMERA_WIRE_FOCUS) && isWireCut(CAMERA_WIRE_LIGHT) && isWireCut(CAMERA_WIRE_NOTHING1) && isWireCut(CAMERA_WIRE_NOTHING2))
+ return 1
+ else
+ return 0
+
+/obj/machinery/camera/proc/cut(var/wireColor)
+ var/wireFlag = WireColorToFlag[wireColor]
+ var/wireIndex = WireColorToIndex[wireColor]
+ wires &= ~wireFlag
+ switch(wireIndex)
+ if(CAMERA_WIRE_FOCUS)
+ setViewRange(short_range)
+
+ if(CAMERA_WIRE_POWER)
+ deactivate(usr, 1)
+ shock(usr)
+
+ if(CAMERA_WIRE_LIGHT)
+ light_disabled = 1
+
+ if(CAMERA_WIRE_ALARM)
+ triggerCameraAlarm()
+
+ src.interact(usr)
+
+/obj/machinery/camera/proc/mend(var/wireColor)
+ var/wireFlag = WireColorToFlag[wireColor]
+ var/wireIndex = WireColorToIndex[wireColor]
+ wires |= wireFlag
+ switch(wireIndex)
+ if(CAMERA_WIRE_FOCUS)
+ setViewRange(initial(view_range))
+
+ if(CAMERA_WIRE_POWER)
+ deactivate(usr, 1)
+
+ if(CAMERA_WIRE_LIGHT)
+ light_disabled = 0
+
+ if(CAMERA_WIRE_ALARM)
+ cancelCameraAlarm()
+
+ src.interact(usr)
+
+
+/obj/machinery/camera/proc/pulse(var/wireColor)
+ var/wireIndex = WireColorToIndex[wireColor]
+ switch(wireIndex)
+ if(CAMERA_WIRE_FOCUS)
+ var/new_range = (view_range == initial(view_range) ? short_range : initial(view_range))
+ setViewRange(new_range)
+
+ if(CAMERA_WIRE_POWER)
+ deactivate(usr, 0) // Kicks anyone watching the camera
+
+ if(CAMERA_WIRE_LIGHT)
+ light_disabled = !light_disabled
+
+ if(CAMERA_WIRE_ALARM)
+ src.visible_message("\icon[src] *beep*", "\icon[src] *beep*")
+
+ src.interact(usr)
+
+/obj/machinery/camera/proc/interact(mob/living/user as mob)
+ if(!panel_open || isAI(user))
+ return
+
+ user.machine = src
+ var/t1 = text("Access Panel
\n")
+ var/list/wires = list(
+ "Orange" = 1,
+ "Dark red" = 2,
+ "White" = 3,
+ "Yellow" = 4,
+ "Blue" = 5,
+ "Pink" = 6
+ )
+ for(var/wiredesc in wires)
+ var/is_uncut = src.wires & WireColorToFlag[wires[wiredesc]]
+ t1 += "[wiredesc] wire: "
+ if(!is_uncut)
+ t1 += "Mend"
+ else
+ t1 += "Cut "
+ t1 += "Pulse "
+ t1 += "
"
+
+ t1 += "
\n[(src.view_range == initial(view_range) ? "The focus light is on." : "The focus light is off.")]"
+ t1 += "
\n[(src.can_use() ? "The power link light is on." : "The power link light is off.")]"
+ t1 += "
\n[(light_disabled ? "The camera light is off." : "The camera light is on.")]"
+ t1 += "
\n[(alarm_on ? "The alarm light is on." : "The alarm light is off.")]"
+
+ t1 += "Close
\n"
+ user << browse(t1, "window=wires")
+ onclose(user, "wires")
+
+
+
+/obj/machinery/camera/Topic(href, href_list)
+ ..()
+ if (((in_range(src, usr) && istype(src.loc, /turf))) && !istype(usr, /mob/living/silicon))
+ usr.machine = src
+ if (href_list["wires"])
+ var/t1 = text2num(href_list["wires"])
+ if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) ))
+ usr << "You need wirecutters!"
+ return
+ if (src.isWireColorCut(t1))
+ src.mend(t1)
+ else
+ src.cut(t1)
+ else if (href_list["pulse"])
+ var/t1 = text2num(href_list["pulse"])
+ if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
+ usr << "You need a multitool!"
+ return
+ if (src.isWireColorCut(t1))
+ usr << "You can't pulse a cut wire."
+ return
+ else
+ src.pulse(t1)
+ else if (href_list["close2"])
+ usr << browse(null, "window=wires")
+ usr.machine = null
+ return
+
+
+#undef CAMERA_WIRE_FOCUS
+#undef CAMERA_WIRE_POWER
+#undef CAMERA_WIRE_LIGHT
+#undef CAMERA_WIRE_ALARM
+#undef CAMERA_WIRE_NOTHING1
+#undef CAMERA_WIRE_NOTHING2
\ No newline at end of file
diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm
index 746d00fbd8c..e3f51ce211b 100644
--- a/code/game/machinery/computer/robot.dm
+++ b/code/game/machinery/computer/robot.dm
@@ -97,14 +97,6 @@
onclose(user, "computer")
return
-//Why is this in robot/computer and why does it exist when /obj/machinery/computer/engine does not? -Nodrak
-/*/obj/machinery/computer/engine/process()
- if(stat & (NOPOWER|BROKEN))
- return
- use_power(500)
- src.updateDialog()
- return*/
-
/obj/machinery/computer/robotics/Topic(href, href_list)
if(..())
return
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 3863a8d6d48..f698d027cb7 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -29,8 +29,10 @@
..()
if(density)
layer = 3.1 //Above most items if closed
+ explosion_resistance = initial(explosion_resistance)
else
layer = 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
+ explosion_resistance = 0
update_nearby_tiles(need_rebuild=1)
return
@@ -208,6 +210,7 @@
sleep(10)
src.layer = 2.7
src.density = 0
+ explosion_resistance = 0
update_icon()
// src.SetOpacity(0)
update_nearby_tiles()
@@ -231,6 +234,7 @@
animate("closing")
src.density = 1
+ explosion_resistance = initial(explosion_resistance)
src.layer = 3.1
sleep(10)
update_icon()
@@ -294,4 +298,4 @@
else
close()
return
-*/
+*/
diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm
index 60253441a26..f02f4644031 100644
--- a/code/game/machinery/doors/poddoor.dm
+++ b/code/game/machinery/doors/poddoor.dm
@@ -4,6 +4,7 @@
icon = 'icons/obj/doors/rapid_pdoor.dmi'
icon_state = "pdoor1"
var/id = 1.0
+ explosion_resistance = 25
/obj/machinery/door/poddoor/Bumped(atom/AM)
if(!density)
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index 84777c5193a..503077c5261 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -9,6 +9,7 @@
flags = ON_BORDER
opacity = 0
var/obj/item/weapon/airlock_electronics/electronics = null
+ explosion_resistance = 5
/obj/machinery/door/window/update_nearby_tiles(need_rebuild)
@@ -93,6 +94,7 @@
src.icon_state = text("[]open", src.base_state)
sleep(10)
+ explosion_resistance = 0
src.density = 0
// src.sd_SetOpacity(0) //TODO: why is this here? Opaque windoors? ~Carn
update_nearby_tiles()
@@ -107,9 +109,10 @@
src.operating = 1
flick(text("[]closing", src.base_state), src)
playsound(src.loc, 'sound/machines/windowdoor.ogg', 100, 1)
- src.icon_state = text("[]", src.base_state)
+ src.icon_state = src.base_state
src.density = 1
+ explosion_resistance = initial(explosion_resistance)
// if(src.visible)
// SetOpacity(1) //TODO: why is this here? Opaque windoors? ~Carn
update_nearby_tiles()
diff --git a/code/game/machinery/hydroponics.dm b/code/game/machinery/hydroponics.dm
index 830ffd47ab6..788dce4a553 100644
--- a/code/game/machinery/hydroponics.dm
+++ b/code/game/machinery/hydroponics.dm
@@ -50,8 +50,8 @@
obj/machinery/hydroponics/process()
- if(myseed && !(myseed in contents))
- contents += myseed
+ if(myseed && (myseed.loc != src))
+ myseed.loc = src
if(world.time > (src.lastcycle + src.cycledelay))
src.lastcycle = world.time
diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm
index 7459a175edd..0cacca07ed7 100755
--- a/code/game/machinery/igniter.dm
+++ b/code/game/machinery/igniter.dm
@@ -16,7 +16,7 @@
src.icon_state = text("igniter[]", src.on)
return
-/obj/machinery/igniter/process()
+/obj/machinery/igniter/process() //ugh why is this even in process()?
if (src.on && !(stat & NOPOWER) )
var/turf/location = src.loc
if (isturf(location))
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 0978c5f9067..b622c169fb1 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -93,24 +93,13 @@ Class Procs:
/obj/machinery/New()
..()
- machines.Add(src)
+ machines += src
/obj/machinery/Del()
- machines.Remove(src)
..()
/obj/machinery/process()//If you dont use process or power why are you here
-
- /*
- Big note: if do not call ..() in any machinery subtype process() call or it will
- be removed from the list of machines to iterate. It is, however, okay to call ..()
- if the machine has a parent process() call. For instance, machinery/atmosphereics has a
- root process() call, so things like cryocells can call ..() and not worry about
- it getting removed from machines.
- */
-
- machines.Remove(src) // uncommented by Doohl
- return
+ return PROCESS_KILL
/obj/machinery/emp_act(severity)
if(use_power && stat == 0)
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index d3b244be295..e0274f2bb54 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -3,11 +3,12 @@
//###-Agouri###################################
/datum/feed_message
- var/author=""
- var/body=""
+ var/author =""
+ var/body =""
//var/parent_channel
- var/backup_body=""
- var/backup_author=""
+ var/backup_body =""
+ var/backup_author =""
+ var/is_admin_message = 0
/datum/feed_channel
var/channel_name=""
@@ -17,9 +18,31 @@
var/author=""
var/backup_author=""
var/censored=0
+ var/is_admin_channel=0
//var/page = null //For newspapers
-var/list/obj/machinery/newscaster/allCasters = list() //list that will contain reference to all newscasters in existence.
+/datum/feed_message/proc/clear()
+ src.author = ""
+ src.body = ""
+ src.backup_body = ""
+ src.backup_author = ""
+
+/datum/feed_channel/proc/clear()
+ src.channel_name = ""
+ src.messages = list()
+ src.locked = 0
+ src.author = ""
+ src.backup_author = ""
+ src.censored = 0
+ src.is_admin_channel = 0
+
+/datum/feed_network
+ var/list/datum/feed_channel/network_channels = list()
+ var/datum/feed_message/wanted_issue
+
+var/datum/feed_network/news_network = new /datum/feed_network //The global news-network, which is coincidentally a global list.
+
+var/list/obj/machinery/newscaster/allCasters = list() //Global list that will contain reference to all newscasters in existence.
/obj/machinery/newscaster
@@ -29,7 +52,8 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
icon_state = "newscaster_normal"
var/isbroken = 0 //1 if someone banged it with something heavy
var/ispowered = 1 //starts powered, changes with power_change()
- var/list/datum/feed_channel/channel_list = list() //This list will contain the names of the feed channels. Each name will refer to a data region where the messages of the feed channels are stored.
+ //var/list/datum/feed_channel/channel_list = list() //This list will contain the names of the feed channels. Each name will refer to a data region where the messages of the feed channels are stored.
+ //OBSOLETE: We're now using a global news network
var/screen = 0 //Or maybe I'll make it into a list within a list afterwards... whichever I prefer, go fuck yourselves :3
// 0 = welcome screen - main menu
// 1 = view feed channels
@@ -46,37 +70,38 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
//Holy shit this is outdated, made this when I was still starting newscasters :3
var/paper_remaining = 0
var/securityCaster = 0
- var/unit_no = 0 //Each newscaster has a unit_no
// 0 = Caster cannot be used to issue wanted posters
// 1 = the opposite
- var/datum/feed_message/wanted //We're gonna use a feed_message to store data of the wanted person because fields are similar
- var/wanted_issue = 0
+ var/unit_no = 0 //Each newscaster has a unit number
+ //var/datum/feed_message/wanted //We're gonna use a feed_message to store data of the wanted person because fields are similar
+ //var/wanted_issue = 0 //OBSOLETE
// 0 = there's no WANTED issued, we don't need a special icon_state
// 1 = Guess what.
+ var/alert_delay = 500
var/alert = 0
- // 0 = there hasn't been a news/wanted update in the last minutes
+ // 0 = there hasn't been a news/wanted update in the last alert_delay
// 1 = there has
var/scanned_user = "Unknown" //Will contain the name of the person who currently uses the newscaster
- var/msg = ""; //Feed message
+ var/msg = ""; //Feed message
var/channel_name = ""; //the feed channel which will be receiving the feed, or being created
- var/c_locked=0;
- var/hitstaken = 0 //Death at 3 hits from an item with force>=15
+ var/c_locked=0; //Will our new channel be locked to public submissions?
+ var/hitstaken = 0 //Death at 3 hits from an item with force>=15
var/datum/feed_channel/viewing_channel = null
luminosity = 0
anchored = 1
-/obj/machinery/newscaster/security_unit
+/obj/machinery/newscaster/security_unit //Security unit
name = "Security Newscaster"
securityCaster = 1
-
-/obj/machinery/newscaster/New() //Right, apparently it's good to have a New() for machinery for some sort of global machine list...
+/obj/machinery/newscaster/New() //Constructor, ho~
allCasters += src
src.paper_remaining = 15 // Will probably change this to something better
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) // Let's give it an appropriate unit number
src.unit_no++
src.update_icon() //for any custom ones on the map...
+ ..() //I just realised the newscasters weren't in the global machines list. The superconstructor call will tend to that
/obj/machinery/newscaster/Del()
allCasters -= src
@@ -91,15 +116,17 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
return
src.overlays = null //reset overlays
- if(alert) //new message alert overlay
- src.overlays += "newscaster_alert"
- if(hitstaken > 0) //Cosmetic damage overlay
- src.overlays += image(src.icon, "crack[hitstaken]")
- if(wanted_issue) //wanted icon state
+ if(news_network.wanted_issue) //wanted icon state, there can be no overlays on it as it's a priority message
icon_state = "newscaster_wanted"
return
+ if(alert) //new message alert overlay
+ src.overlays += "newscaster_alert"
+
+ if(hitstaken > 0) //Cosmetic damage overlay
+ src.overlays += image(src.icon, "crack[hitstaken]")
+
icon_state = "newscaster_normal"
return
@@ -139,7 +166,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
/obj/machinery/newscaster/attack_ai(mob/user as mob)
return src.attack_hand(user)
-/obj/machinery/newscaster/attack_hand(mob/user as mob)
+/obj/machinery/newscaster/attack_hand(mob/user as mob) //########### THE MAIN BEEF IS HERE! And in the proc below this...############
if(!src.ispowered || src.isbroken)
return
if(istype(user, /mob/living/carbon/human) || istype(user,/mob/living/silicon) )
@@ -153,7 +180,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
if(0)
dat += "Welcome to Newscasting Unit #[src.unit_no].
Interface & News networks Operational."
dat += "
Property of Nanotransen Inc"
- if(src.wanted_issue)
+ if(news_network.wanted_issue)
dat+= "
Read Wanted Issue"
dat+= "
Create Feed Channel"
dat+= "
View Feed Channels"
@@ -163,10 +190,9 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
dat+= "
Exit"
if(src.securityCaster)
var/wanted_already = 0
- for(var/obj/machinery/newscaster/N in allCasters)
- if(N.wanted_issue)
- wanted_already = 1
- break
+ if(news_network.wanted_issue)
+ wanted_already = 1
+
dat+="
Feed Security functions:
"
dat+="
[(wanted_already) ? ("Manage") : ("Publish")] \"Wanted\" Issue"
dat+="
Censor Feed Stories"
@@ -174,11 +200,14 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
dat+="
The newscaster recognises you as: [src.scanned_user]"
if(1)
dat+= "Station Feed Channels
"
- if( isemptylist(src.channel_list) )
+ if( isemptylist(news_network.network_channels) )
dat+="No active channels found..."
else
- for(var/datum/feed_channel/CHANNEL in src.channel_list)
- dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
+ for(var/datum/feed_channel/CHANNEL in news_network.network_channels)
+ if(CHANNEL.is_admin_channel)
+ dat+="[CHANNEL.channel_name]
"
+ else
+ dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
/*for(var/datum/feed_channel/CHANNEL in src.channel_list)
dat+="[CHANNEL.channel_name]:
\[created by: [CHANNEL.author]\]
"
if( isemptylist(CHANNEL.messages) )
@@ -219,30 +248,35 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
dat+="
Return
"
if(7)
dat+="ERROR: Could not submit Feed Channel to Network.
"
- var/list/existing_channels = list() //Let's get dem existing channels
+ //var/list/existing_channels = list() //Let's get dem existing channels - OBSOLETE
var/list/existing_authors = list()
- for(var/datum/feed_channel/FC in src.channel_list)
- existing_channels += FC.channel_name
+ for(var/datum/feed_channel/FC in news_network.network_channels)
+ //existing_channels += FC.channel_name //OBSOLETE
if(FC.author == "\[REDACTED\]")
existing_authors += FC.backup_author
else
- existing_authors +=FC.author
+ existing_authors += FC.author
if(src.scanned_user in existing_authors)
dat+="•There already exists a Feed channel under your name.
"
if(src.channel_name=="" || src.channel_name == "\[REDACTED\]")
dat+="•Invalid channel name.
"
- if(src.channel_name in existing_channels)
+ var/check = 0
+ for(var/datum/feed_channel/FC in news_network.network_channels)
+ if(FC.channel_name == src.channel_name)
+ check = 1
+ break
+ if(check)
dat+="•Channel name already in use.
"
if(src.scanned_user=="Unknown")
dat+="•Channel author unverified.
"
dat+="
Return
"
if(8)
- var/total_num=length(src.channel_list)
+ var/total_num=length(news_network.network_channels)
var/active_num=total_num
var/message_num=0
- for(var/datum/feed_channel/FC in src.channel_list)
+ for(var/datum/feed_channel/FC in news_network.network_channels)
if(!FC.censored)
- message_num += length(FC.messages)
+ message_num += length(FC.messages) //Dont forget, datum/feed_channel's var messages is a list of datum/feed_message
else
active_num--
dat+="Network currently serves a total of [total_num] Feed channels, [active_num] of which are active, and a total of [message_num] Feed Stories." //TODO: CONTINUE
@@ -267,10 +301,10 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
dat+="NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible.
"
dat+="Keep in mind that users attempting to view a censored feed will instead see the \[REDACTED\] tag above it."
dat+="
Select Feed channel to get Stories from:
"
- if(isemptylist(src.channel_list))
+ if(isemptylist(news_network.network_channels))
dat+="No feed channels found active...
"
else
- for(var/datum/feed_channel/CHANNEL in src.channel_list)
+ for(var/datum/feed_channel/CHANNEL in news_network.network_channels)
dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
dat+="
Cancel"
if(11)
@@ -278,10 +312,10 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
dat+="A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the station's"
dat+="morale, integrity or disciplinary behaviour. A D-Notice will render a channel unable to be updated by anyone, without deleting any feed"
dat+="stories it might contain at the time. You can lift a D-Notice if you have the required access at any time.
"
- if(isemptylist(src.channel_list))
+ if(isemptylist(news_network.network_channels))
dat+="No feed channels found active...
"
else
- for(var/datum/feed_channel/CHANNEL in src.channel_list)
+ for(var/datum/feed_channel/CHANNEL in news_network.network_channels)
dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ()]
"
dat+="
Back"
@@ -315,17 +349,19 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
dat+="Wanted Issue Handler:"
var/wanted_already = 0
var/end_param = 1
- for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
- if(NEWSCASTER.wanted_issue)
- wanted_already = 1
- end_param = 2
- break
+ if(news_network.wanted_issue)
+ wanted_already = 1
+ end_param = 2
+
if(wanted_already)
dat+="
A wanted issue is already in Feed Circulation. You can edit or cancel it below."
dat+="
"
dat+="Criminal Name: [src.channel_name]
"
dat+="Description: [src.msg]
"
- dat+="Wanted Issue created by: [src.scanned_user]
"
+ if(wanted_already)
+ dat+="Wanted Issue created by: [news_network.wanted_issue.backup_author]
"
+ else
+ dat+="Wanted Issue will be created under prosecutor: [src.scanned_user]
"
dat+="
[(wanted_already) ? ("Edit Issue") : ("Submit")]"
if(wanted_already)
dat+="
Take down Issue"
@@ -346,9 +382,9 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
dat+="Wanted Issue successfully deleted from Circulation
"
dat+="
Return
"
if(18)
- dat+="-- STATIONWIDE WANTED ISSUE --
\[Submitted by: [src.wanted.backup_author]\]
"
- dat+="Criminal: [src.wanted.author]
"
- dat+="Description: [src.wanted.body]
"
+ dat+="-- STATIONWIDE WANTED ISSUE --
\[Submitted by: [news_network.wanted_issue.backup_author]\]
"
+ dat+="Criminal: [news_network.wanted_issue.author]
"
+ dat+="Description: [news_network.wanted_issue.body]
"
dat+="
Back
"
if(19)
dat+="Wanted issue for [src.channel_name] successfully edited.
"
@@ -380,7 +416,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.machine = src
if(href_list["set_channel_name"])
- src.channel_name = strip_html(input(usr, "Provide a Feed Channel Name", "Network Channel Handler", ""))
+ src.channel_name = strip_html_simple(input(usr, "Provide a Feed Channel Name", "Network Channel Handler", ""))
while (findtext(src.channel_name," ") == 1)
src.channel_name = copytext(src.channel_name,2,lentext(src.channel_name)+1)
src.updateUsrDialog()
@@ -392,15 +428,20 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
//src.update_icon()
else if(href_list["submit_new_channel"])
- var/list/existing_channels = list()
+ //var/list/existing_channels = list() //OBSOLETE
var/list/existing_authors = list()
- for(var/datum/feed_channel/FC in src.channel_list)
- existing_channels += FC.channel_name
+ for(var/datum/feed_channel/FC in news_network.network_channels)
+ //existing_channels += FC.channel_name
if(FC.author == "\[REDACTED\]")
existing_authors += FC.backup_author
else
existing_authors +=FC.author
- if(src.channel_name == "" || src.channel_name == "\[REDACTED\]" || src.scanned_user == "Unknown" || (src.channel_name in existing_channels) || (src.scanned_user in existing_authors) )
+ var/check = 0
+ for(var/datum/feed_channel/FC in news_network.network_channels)
+ if(FC.channel_name == src.channel_name)
+ check = 1
+ break
+ if(src.channel_name == "" || src.channel_name == "\[REDACTED\]" || src.scanned_user == "Unknown" || check || (src.scanned_user in existing_authors) )
src.screen=7
else
var/choice = alert("Please confirm Feed channel creation","Network Channel Handler","Confirm","Cancel")
@@ -410,8 +451,9 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
newChannel.author = src.scanned_user
newChannel.locked = c_locked
feedback_inc("newscaster_channels",1)
- for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) //Let's add the new channel in all casters.
- NEWSCASTER.channel_list += newChannel //Now that it is sane, get it into the list.
+ /*for(var/obj/machinery/newscaster/NEWSCASTER in allCasters) //Let's add the new channel in all casters.
+ NEWSCASTER.channel_list += newChannel*/ //Now that it is sane, get it into the list. -OBSOLETE
+ news_network.network_channels += newChannel //Adding channel to the global network
src.screen=5
src.updateUsrDialog()
//src.update_icon()
@@ -419,7 +461,7 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
else if(href_list["set_channel_receiving"])
//var/list/datum/feed_channel/available_channels = list()
var/list/available_channels = list()
- for(var/datum/feed_channel/F in src.channel_list)
+ for(var/datum/feed_channel/F in news_network.network_channels)
if( (!F.locked || F.author == scanned_user) && !F.censored)
available_channels += F.channel_name
src.channel_name = strip_html(input(usr, "Choose receiving Feed Channel", "Network Channel Handler") in available_channels )
@@ -439,12 +481,11 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
newMsg.author = src.scanned_user
newMsg.body = src.msg
feedback_inc("newscaster_stories",1)
- for(var/datum/feed_channel/FC in src.channel_list)
+ for(var/datum/feed_channel/FC in news_network.network_channels)
if(FC.channel_name == src.channel_name)
- FC.messages += newMsg // To avoid further confusion, this one for adds the message to all existing newscasters' channel_list's channels.
- break // Another for to go through newscasters is not needed. Due to the nature of submit_new_CHANNEL, every reference
- src.screen=4 // to a channel in ANY newscaster is the same. Editing one will edit them all.
-
+ FC.messages += newMsg //Adding message to the network's appropriate feed_channel
+ break
+ src.screen=4
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
NEWSCASTER.newsAlert(src.channel_name)
@@ -479,13 +520,12 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
else if(href_list["menu_wanted"])
var/already_wanted = 0
- for(var/obj/machinery/newscaster/N in allCasters)
- if(N.wanted_issue)
- already_wanted = 1
- break
+ if(news_network.wanted_issue)
+ already_wanted = 1
+
if(already_wanted)
- src.channel_name = src.wanted.author
- src.msg = src.wanted.body
+ src.channel_name = news_network.wanted_issue.author
+ src.msg = news_network.wanted_issue.body
src.screen = 14
src.updateUsrDialog()
@@ -508,31 +548,35 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
else
var/choice = alert("Please confirm Wanted Issue [(input_param==1) ? ("creation.") : ("edit.")]","Network Security Handler","Confirm","Cancel")
if(choice=="Confirm")
- if(input_param==1)
+ if(input_param==1) //If input_param == 1 we're submitting a new wanted issue. At 2 we're just editing an existing one. See the else below
var/datum/feed_message/WANTED = new /datum/feed_message
WANTED.author = src.channel_name
WANTED.body = src.msg
WANTED.backup_author = src.scanned_user //I know, a bit wacky
+ news_network.wanted_issue = WANTED
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
- NEWSCASTER.wanted = WANTED
- NEWSCASTER.wanted_issue = 1
NEWSCASTER.newsAlert()
NEWSCASTER.update_icon()
src.screen = 15
else
- src.wanted.author = src.channel_name
- src.wanted.body = src.msg
- src.wanted.backup_author = src.scanned_user
+ if(news_network.wanted_issue.is_admin_message)
+ alert("The wanted issue has been distributed by a Nanotrasen higherup. You cannot edit it.","Ok")
+ return
+ news_network.wanted_issue.author = src.channel_name
+ news_network.wanted_issue.body = src.msg
+ news_network.wanted_issue.backup_author = src.scanned_user
src.screen = 19
src.updateUsrDialog()
else if(href_list["cancel_wanted"])
+ if(news_network.wanted_issue.is_admin_message)
+ alert("The wanted issue has been distributed by a Nanotrasen higherup. You cannot take it down.","Ok")
+ return
var/choice = alert("Please confirm Wanted Issue removal","Network Security Handler","Confirm","Cancel")
if(choice=="Confirm")
+ news_network.wanted_issue = null
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
- NEWSCASTER.wanted_issue = 0
- NEWSCASTER.wanted = null
NEWSCASTER.update_icon()
src.screen=17
src.updateUsrDialog()
@@ -542,6 +586,9 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
src.updateUsrDialog()
else if(href_list["censor_channel_author"])
var/datum/feed_channel/FC = locate(href_list["censor_channel_author"])
+ if(FC.is_admin_channel)
+ alert("This channel was created by a Nanotrasen Officer. You cannot censor it.","Ok")
+ return
if(FC.author != "\[REDACTED\]")
FC.backup_author = FC.author
FC.author = "\[REDACTED\]"
@@ -551,6 +598,9 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
else if(href_list["censor_channel_story_author"])
var/datum/feed_message/MSG = locate(href_list["censor_channel_story_author"])
+ if(MSG.is_admin_message)
+ alert("This message was created by a Nanotrasen Officer. You cannot censor its author.","Ok")
+ return
if(MSG.author != "\[REDACTED\]")
MSG.backup_author = MSG.author
MSG.author = "\[REDACTED\]"
@@ -560,6 +610,9 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
else if(href_list["censor_channel_story_body"])
var/datum/feed_message/MSG = locate(href_list["censor_channel_story_body"])
+ if(MSG.is_admin_message)
+ alert("This channel was created by a Nanotrasen Officer. You cannot censor it.","Ok")
+ return
if(MSG.body != "\[REDACTED\]")
MSG.backup_body = MSG.body
MSG.body = "\[REDACTED\]"
@@ -575,6 +628,9 @@ var/list/obj/machinery/newscaster/allCasters = list() //list that will contain r
else if(href_list["toggle_d_notice"])
var/datum/feed_channel/FC = locate(href_list["toggle_d_notice"])
+ if(FC.is_admin_channel)
+ alert("This channel was created by a Nanotrasen Officer. You cannot place a D-Notice upon it.","Ok")
+ return
FC.censored = !FC.censored
src.updateUsrDialog()
@@ -827,26 +883,31 @@ obj/item/weapon/newspaper/attackby(obj/item/weapon/W as obj, mob/user as mob)
/obj/machinery/newscaster/proc/print_paper()
feedback_inc("newscaster_newspapers_printed",1)
var/obj/item/weapon/newspaper/NEWSPAPER = new /obj/item/weapon/newspaper
- for(var/datum/feed_channel/FC in src.channel_list)
+ for(var/datum/feed_channel/FC in news_network.network_channels)
NEWSPAPER.news_content += FC
- if(src.wanted_issue)
- NEWSPAPER.important_message = src.wanted
+ if(news_network.wanted_issue)
+ NEWSPAPER.important_message = news_network.wanted_issue
NEWSPAPER.loc = get_turf(src)
src.paper_remaining--
return
+//Removed for now so these aren't even checked every tick. Left this here in-case Agouri needs it later.
+///obj/machinery/newscaster/process() //Was thinking of doing the icon update through process, but multiple iterations per second does not
+// return //bode well with a newscaster network of 10+ machines. Let's just return it, as it's added in the machines list.
-/obj/machinery/newscaster/proc/newsAlert(channel)
- var/turf/T = get_turf(src)
+/obj/machinery/newscaster/proc/newsAlert(channel) //This isn't Agouri's work, for it is ugly and vile.
+ var/turf/T = get_turf(src) //Who the fuck uses spawn(600) anyway, jesus christ
if(channel)
for(var/mob/O in hearers(world.view-1, T))
O.show_message("[src.name] beeps, \"Breaking news from [channel]!\"",2)
src.alert = 1
src.update_icon()
- spawn(600)
+ spawn(300)
src.alert = 0
src.update_icon()
+ playsound(src.loc, 'sound/machines/twobeep.ogg', 75, 1)
else
for(var/mob/O in hearers(world.view-1, T))
- O.show_message("[src.name] beeps, \"Wanted notice posted!\"",2)
- playsound(src.loc, 'sound/machines/twobeep.ogg', 75, 1)
+ O.show_message("[src.name] beeps, \"Attention! Wanted issue distributed!\"",2)
+ playsound(src.loc, 'sound/machines/warning-buzzer.ogg', 75, 1)
+ return
diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm
index 8063c39cedf..8b2a5e19cce 100644
--- a/code/game/machinery/telecomms/telecomunications.dm
+++ b/code/game/machinery/telecomms/telecomunications.dm
@@ -38,7 +38,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
var/listening_level = 0 // 0 = auto set in New() - this is the z level that the machine is listening to.
-/obj/machinery/telecomms/proc/relay_information(datum/signal/signal, filter, copysig, amount)
+/obj/machinery/telecomms/proc/relay_information(datum/signal/signal, filter, copysig, amount = 20)
// relay signal to all linked machinery that are of type [filter]. If signal has been sent [amount] times, stop sending
if(!on)
@@ -321,12 +321,12 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
if(istype(machine_from, /obj/machinery/telecomms/relay))
//If the signal is compressed, send it to the bus.
- relay_information(signal, "/obj/machinery/telecomms/bus", 1) // ideally relay the copied information to bus units
+ relay_information(signal, "/obj/machinery/telecomms/bus") // ideally relay the copied information to bus units
else
//The signal is ready to be sent!
- var/can_send = relay_information(signal, "/obj/machinery/telecomms/relay", 1)
+ var/can_send = relay_information(signal, "/obj/machinery/telecomms/relay")
if(!can_send)
- relay_information(signal, "/obj/machinery/telecomms/broadcaster", 1) // Send it to a broadcaster instead, if it's linked to one
+ relay_information(signal, "/obj/machinery/telecomms/broadcaster") // Send it to a broadcaster instead, if it's linked to one
/*
The relay idles until it receives information. It then passes on that information
depending on where it came from.
@@ -356,12 +356,12 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
if(istype(machine_from, /obj/machinery/telecomms/receiver))
//If the signal is compressed, send it to the bus.
- var/can_send = relay_information(signal, "/obj/machinery/telecomms/hub", 1) // ideally relay the copied information to bus units
+ var/can_send = relay_information(signal, "/obj/machinery/telecomms/hub") // ideally relay the copied information to bus units
if(!can_send)
- relay_information(signal, "/obj/machinery/telecomms/bus", 1) // Send it to a bus instead, if it's linked to one
+ relay_information(signal, "/obj/machinery/telecomms/bus") // Send it to a bus instead, if it's linked to one
else
//The signal is ready to be sent!
- relay_information(signal, "/obj/machinery/telecomms/broadcaster", 1)
+ relay_information(signal, "/obj/machinery/telecomms/broadcaster")
/*
The bus mainframe idles and waits for hubs to relay them signals. They act
@@ -392,7 +392,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
if(is_freq_listening(signal))
if(!istype(machine_from, /obj/machinery/telecomms/processor)) // Signal must be ready (stupid assuming machine), let's send it
// send to one linked processor unit
- var/send_to_processor = relay_information(signal, "/obj/machinery/telecomms/processor", 1)
+ var/send_to_processor = relay_information(signal, "/obj/machinery/telecomms/processor")
if(!send_to_processor) // failed to send to a processor, relay information anyway
signal.data["slow"] += rand(1, 5) // slow the signal down only slightly
@@ -401,7 +401,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
else // the signal has been decompressed by a processor unit
// send to all linked server units
- var/sendserver = relay_information(signal, "/obj/machinery/telecomms/server", 1)
+ var/sendserver = relay_information(signal, "/obj/machinery/telecomms/server")
// Can't send to a single server, send to a hub instead!
if(!sendserver)
@@ -446,7 +446,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
relay_direct_information(signal, machine_from) // send the signal back to the machine
else // no bus detected - send the signal to servers instead
signal.data["slow"] += rand(5, 10) // slow the signal down
- relay_information(signal, "/obj/machinery/telecomms/server", 1)
+ relay_information(signal, "/obj/machinery/telecomms/server")
/*
@@ -542,8 +542,9 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
if(Compiler && autoruncode)
Compiler.Run(signal) // execute the code
- relay_information(signal, "/obj/machinery/telecomms/broadcaster", 1)
- relay_information(signal, "/obj/machinery/telecomms/hub", 1)
+ var/can_send = relay_information(signal, "/obj/machinery/telecomms/hub")
+ if(!can_send)
+ relay_information(signal, "/obj/machinery/telecomms/broadcaster")
/obj/machinery/telecomms/server/proc/setcode(var/t)
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index be78e482d98..5d35b349b8e 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -73,7 +73,7 @@
R.product_name = capitalize(temp.name)
R.product_path = path_list[p]
R.display_color = pick("red","blue","green")
-// R.amount = text2num(amt_list[p])
+// R. = text2num(amt_list[p])
// src.product_records += R
if(hidden)
@@ -134,7 +134,9 @@
if(src.shock(user, 100))
return
- var/dat = "Select an item:
"
+ var/vendorname = (src.name) //import the machine's name
+ var/dat = "[vendorname]
" //display the name, and added a horizontal rule
+ dat += "Select an item:
" //the rest is just general spacing and bolding
if (product_coin != "")
dat += "Coin slot: [coin ? coin : "No coin inserted"] (Remove)
"
@@ -152,11 +154,11 @@
for (var/datum/data/vending_product/R in display_records)
dat += "[R.product_name]:"
- dat += " [R.amount] "
+ dat += " [R.amount] "
if (R.amount > 0)
- dat += "Vend"
+ dat += "(Vend)"
else
- dat += "SOLD OUT"
+ dat += " SOLD OUT"
dat += "
"
dat += ""
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 43d3e764b32..bbd096d7616 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -399,6 +399,9 @@
/obj/machinery/mecha_part_fabricator/proc/process_queue()
var/obj/item/part = listgetindex(src.queue, 1)
+ if(!part)
+ remove_from_queue(1)
+ return process_queue()
if(!(part.vars.Find("construction_time")) || !(part.vars.Find("construction_cost")))//If it shouldn't be printed
remove_from_queue(1)//Take it out of the quene
return process_queue()//Then reprocess it
diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm
index fc6eaac744b..4190664b92f 100644
--- a/code/game/objects/effects/aliens.dm
+++ b/code/game/objects/effects/aliens.dm
@@ -296,6 +296,8 @@ Alien plants should do something if theres a lot of poison
var/ticks = 0
/obj/effect/alien/acid/proc/tick()
+ if(!target)
+ del(src)
ticks += 1
for(var/mob/O in hearers(src, null))
O.show_message("\green [src.target] sizzles and begins to melt under the bubbling mess of acid!", 1)
@@ -307,7 +309,7 @@ Alien plants should do something if theres a lot of poison
del(target)
del(src)
return
- spawn(rand(200, 600)) tick()
+ spawn(rand(200, 400)) tick()
/*
* Egg
diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm
new file mode 100644
index 00000000000..5f0ccad98a3
--- /dev/null
+++ b/code/game/objects/effects/landmarks.dm
@@ -0,0 +1,12 @@
+/obj/effect/landmark
+ name = "landmark"
+ icon = 'icons/mob/screen1.dmi'
+ icon_state = "x2"
+ anchored = 1.0
+ unacidable = 1
+
+/obj/effect/landmark/start
+ name = "start"
+ icon = 'icons/mob/screen1.dmi'
+ icon_state = "x"
+ anchored = 1.0
\ No newline at end of file
diff --git a/code/game/objects/effects/manifest.dm b/code/game/objects/effects/manifest.dm
index 605be9852e5..bee6174f123 100644
--- a/code/game/objects/effects/manifest.dm
+++ b/code/game/objects/effects/manifest.dm
@@ -1,4 +1,8 @@
-
+/obj/effect/manifest
+ name = "manifest"
+ icon = 'icons/mob/screen1.dmi'
+ icon_state = "x"
+ unacidable = 1//Just to be sure.
/obj/effect/manifest/New()
diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm
index 5800fab2886..83cbb7b39ff 100644
--- a/code/game/objects/effects/mines.dm
+++ b/code/game/objects/effects/mines.dm
@@ -1,3 +1,14 @@
+/obj/effect/mine
+ name = "Mine"
+ desc = "I Better stay away from that thing."
+ density = 1
+ anchored = 1
+ layer = 3
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "uglymine"
+ var/triggerproc = "explode" //name of the proc thats called when the mine is triggered
+ var/triggered = 0
+
/obj/effect/mine/New()
icon_state = "uglyminearmed"
@@ -84,4 +95,32 @@
/obj/effect/mine/proc/explode(obj)
explosion(loc, 0, 1, 2, 3)
spawn(0)
- del(src)
\ No newline at end of file
+ del(src)
+
+
+
+
+/obj/effect/mine/dnascramble
+ name = "Radiation Mine"
+ icon_state = "uglymine"
+ triggerproc = "triggerrad"
+
+/obj/effect/mine/plasma
+ name = "Plasma Mine"
+ icon_state = "uglymine"
+ triggerproc = "triggerplasma"
+
+/obj/effect/mine/kick
+ name = "Kick Mine"
+ icon_state = "uglymine"
+ triggerproc = "triggerkick"
+
+/obj/effect/mine/n2o
+ name = "N2O Mine"
+ icon_state = "uglymine"
+ triggerproc = "triggern2o"
+
+/obj/effect/mine/stun
+ name = "Stun Mine"
+ icon_state = "uglymine"
+ triggerproc = "triggerstun"
diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm
new file mode 100644
index 00000000000..140e5314eb3
--- /dev/null
+++ b/code/game/objects/effects/overlays.dm
@@ -0,0 +1,30 @@
+/obj/effect/overlay
+ name = "overlay"
+ unacidable = 1
+ var/i_attached//Added for possible image attachments to objects. For hallucinations and the like.
+
+/obj/effect/overlay/beam//Not actually a projectile, just an effect.
+ name="beam"
+ icon='icons/effects/beam.dmi'
+ icon_state="b_beam"
+ var/tmp/atom/BeamSource
+ New()
+ ..()
+ spawn(10) del src
+
+/obj/effect/overlay/palmtree_r
+ name = "Palm tree"
+ icon = 'icons/misc/beach2.dmi'
+ icon_state = "palm1"
+ density = 1
+
+/obj/effect/overlay/palmtree_l
+ name = "Palm tree"
+ icon = 'icons/misc/beach2.dmi'
+ icon_state = "palm2"
+ density = 1
+
+/obj/effect/overlay/coconut
+ name = "Coconuts"
+ icon = 'icons/misc/beach.dmi'
+ icon_state = "coconuts"
\ No newline at end of file
diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm
index f0e698555b6..ae174260e38 100644
--- a/code/game/objects/effects/portals.dm
+++ b/code/game/objects/effects/portals.dm
@@ -1,4 +1,14 @@
-
+/obj/effect/portal
+ name = "portal"
+ desc = "Looks unstable. Best to test it with the clown."
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "portal"
+ density = 1
+ unacidable = 1//Can't destroy energy portals.
+ var/failchance = 5
+ var/obj/item/target = null
+ var/creator = null
+ anchored = 1.0
/obj/effect/portal/Bumped(mob/M as mob|obj)
spawn(0)
diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm
index 626953c33d9..ce3c7c4940b 100644
--- a/code/game/objects/explosion.dm
+++ b/code/game/objects/explosion.dm
@@ -8,7 +8,7 @@
proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1)
- src = null
+ src = null //so we don't abort once src is deleted
spawn(0)
var/start = world.timeofday
epicenter = get_turf(epicenter)
@@ -47,12 +47,12 @@ proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impa
T.ex_act(dist)
if(T)
- for(var/atom_movable in T.contents)
+ for(var/atom_movable in T.contents) //bypass type checking since only atom/movable can be contained by turfs anyway
var/atom/movable/AM = atom_movable
AM.ex_act(dist)
- //here util we get explosions to be less laggy, might help us identify issues after changes to splosions (because let's face it we've had a few)
- world.log << "## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [(world.timeofday-start)/10] seconds."
+ //You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
+ if(Debug2) world.log << "## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [(world.timeofday-start)/10] seconds."
sleep(8)
diff --git a/code/game/objects/explosion_recursive.dm b/code/game/objects/explosion_recursive.dm
index 3171db1fb38..d5aea573bc4 100644
--- a/code/game/objects/explosion_recursive.dm
+++ b/code/game/objects/explosion_recursive.dm
@@ -1,9 +1,10 @@
-/* - uncomment this to test it out!
-/mob/verb/kaboom()
+/client/proc/kaboom()
var/power = input(src, "power?", "power?") as num
- var/turf/T = get_turf(src)
+ var/turf/T = get_turf(src.mob)
explosion_rec(T, power)
-*/
+
+/obj
+ var/explosion_resistance
/datum/explosion_turf
var/turf/turf //The turf which will get ex_act called on it
@@ -58,7 +59,7 @@ proc/explosion_rec(turf/epicenter, power)
//This steap handles the gathering of turfs which will be ex_act() -ed in the next step. It also ensures each turf gets the maximum possible amount of power dealt to it.
for(var/direction in cardinal)
var/turf/T = get_step(epicenter, direction)
- T.explosion_spread(power - epicenter.explosion_resistance)
+ T.explosion_spread(power - epicenter.explosion_resistance, direction)
//This step applies the ex_act effects for the explosion, as planned in the previous step.
for( var/datum/explosion_turf/ET in explosion_turfs )
@@ -111,18 +112,40 @@ proc/explosion_rec(turf/epicenter, power)
explosion_resistance = 25
//Code-wise, a safe value for power is something up to ~25 or ~30.. This does quite a bit of damage to the station.
-/turf/proc/explosion_spread(power)
+//direction is the direction that the spread took to come to this tile. So it is pointing in the main blast direction - meaning where this tile should spread most of it's force.
+/turf/proc/explosion_spread(power, direction)
if(power <= 0)
return
+ /*
+ sleep(2)
+ new/obj/effect/debugging/marker(src)
+ */
+
var/datum/explosion_turf/ET = get_explosion_turf(src)
if(ET.max_power >= power)
return //The turf already sustained and spread a power greated than what we are dealing with. No point spreading again.
ET.max_power = power
+ var/spread_power = power - src.explosion_resistance //This is the amount of power that will be spread to the tile in the direction of the blast
+ var/side_spread_power = power - 2 * src.explosion_resistance //This is the amount of power that will be spread to the side tiles
+ for(var/obj/O in src)
+ if(O.explosion_resistance)
+ spread_power -= O.explosion_resistance
+ side_spread_power -= O.explosion_resistance
+
+ var/turf/T = get_step(src, direction)
+ T.explosion_spread(spread_power, direction)
+ T = get_step(src, turn(direction,90))
+ T.explosion_spread(side_spread_power, turn(direction,90))
+ T = get_step(src, turn(direction,-90))
+ T.explosion_spread(side_spread_power, turn(direction,90))
+
+ /*
for(var/direction in cardinal)
var/turf/T = get_step(src, direction)
- T.explosion_spread(power - src.explosion_resistance)
+ T.explosion_spread(spread_power)
+ */
/turf/unsimulated/explosion_spread(power)
return //So it doesn't get to the parent proc, which simulates explosions
\ No newline at end of file
diff --git a/code/game/objects/hud.dm b/code/game/objects/hud.dm
new file mode 100644
index 00000000000..7559f9044b5
--- /dev/null
+++ b/code/game/objects/hud.dm
@@ -0,0 +1,21 @@
+/obj/hud
+ name = "hud"
+ unacidable = 1
+ var/mob/mymob = null
+ var/list/adding = null
+ var/list/other = null
+ var/obj/screen/druggy = null
+ var/vimpaired = null
+ var/obj/screen/alien_view = null
+ var/obj/screen/g_dither = null
+ var/obj/screen/blurry = null
+ var/list/darkMask = null
+ var/obj/screen/r_hand_hud_object = null
+ var/obj/screen/l_hand_hud_object = null
+ var/show_intent_icons = 0
+ var/list/obj/screen/hotkeybuttons = null
+ var/hotkey_ui_hidden = 0 //This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons)
+
+ var/list/obj/screen/item_action/item_action_list = null //Used for the item action ui buttons.
+
+ var/h_type = /obj/screen //this is like...the most pointless thing ever. Use a god damn define!
\ No newline at end of file
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 35f871f3344..9bd96fb50ca 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -41,6 +41,8 @@
var/list/allowed = null //suit storage stuff.
var/obj/item/device/uplink/hidden/hidden_uplink = null // All items can have an uplink hidden inside, just remember to add the triggers.
+/obj/item/device
+ icon = 'icons/obj/device.dmi'
/obj/item/ex_act(severity)
switch(severity)
diff --git a/code/game/objects/items/apc_frame.dm b/code/game/objects/items/apc_frame.dm
index ba1a2597c18..03c43d2b098 100644
--- a/code/game/objects/items/apc_frame.dm
+++ b/code/game/objects/items/apc_frame.dm
@@ -1,5 +1,12 @@
// APC HULL
+/obj/item/apc_frame
+ name = "APC frame"
+ desc = "Used for repairing or building APCs"
+ icon = 'icons/obj/apc_repair.dmi'
+ icon_state = "apc_frame"
+ flags = FPRINT | TABLEPASS| CONDUCT
+
/obj/item/apc_frame/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
if (istype(W, /obj/item/weapon/wrench))
diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm
index ca33aa23d52..5ce14b361ec 100644
--- a/code/game/objects/items/blueprints.dm
+++ b/code/game/objects/items/blueprints.dm
@@ -1,4 +1,9 @@
/obj/item/blueprints
+ name = "station blueprints"
+ desc = "Blueprints of the station. There's stamp \"Classified\" and several coffee stains on it."
+ icon = 'icons/obj/items.dmi'
+ icon_state = "blueprints"
+ attack_verb = list("attacked", "bapped", "hit")
var/const/AREA_ERRNONE = 0
var/const/AREA_STATION = 1
var/const/AREA_SPACE = 2
diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index e4024c838d7..497b5c4ef39 100644
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -3,8 +3,10 @@
* TO-DO -- Using it as a power measurement tool for cables etc. Nannek.
*
*/
+
/obj/item/device/multitool
name = "multitool"
+ desc = "Used for pulsing wires to test which to cut. Not recommended by doctors."
icon_state = "multitool"
flags = FPRINT | TABLEPASS| CONDUCT
force = 5.0
@@ -15,4 +17,5 @@
desc = "You can use this on airlocks or APCs to try to hack them without cutting wires."
m_amt = 50
g_amt = 20
- origin_tech = "magnets=1"
\ No newline at end of file
+ origin_tech = "magnets=1;engineering=1"
+ var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage
\ No newline at end of file
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index ed9b7a05f0a..c0816c356d0 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -199,6 +199,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
if(!on) return // the device has to be on
// Fix for permacell radios, but kinda eh about actually fixing them.
+ if(!M || !message) return
// Uncommenting this. To the above comment:
// The permacell radios aren't suppose to be able to transmit, this isn't a bug and this "fix" is just making radio wires useless. -Giacom
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 6922fd3a462..31882fca830 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -1,4 +1,6 @@
+//What is this even used for?
+
/obj/item/stack/medical/attack(mob/living/carbon/M as mob, mob/user as mob)
if (M.stat == 2)
var/t_him = "it"
diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm
new file mode 100644
index 00000000000..b7119eba021
--- /dev/null
+++ b/code/game/objects/items/stacks/rods.dm
@@ -0,0 +1,66 @@
+/obj/item/stack/rods
+ name = "metal rods"
+ desc = "Some rods. Can be used for building, or something."
+ singular_name = "metal rod"
+ icon_state = "rods"
+ flags = FPRINT | TABLEPASS| CONDUCT
+ w_class = 3.0
+ force = 9.0
+ throwforce = 15.0
+ throw_speed = 5
+ throw_range = 20
+ m_amt = 1875
+ max_amount = 60
+ attack_verb = list("hit", "bludgeoned", "whacked")
+
+/obj/item/stack/rods/attackby(obj/item/W as obj, mob/user as mob)
+ ..()
+ if (istype(W, /obj/item/weapon/weldingtool))
+ var/obj/item/weapon/weldingtool/WT = W
+
+ if(amount < 2)
+ user << "\red You need at least two rods to do this."
+ return
+
+ if(WT.remove_fuel(0,user))
+ var/obj/item/stack/sheet/metal/new_item = new(usr.loc)
+ new_item.add_to_stacks(usr)
+ for (var/mob/M in viewers(src))
+ M.show_message("\red [src] is shaped into metal by [user.name] with the weldingtool.", 3, "\red You hear welding.", 2)
+ var/obj/item/stack/rods/R = src
+ src = null
+ var/replace = (user.get_inactive_hand()==R)
+ R.use(2)
+ if (!R && replace)
+ user.put_in_hands(new_item)
+ return
+ ..()
+
+
+/obj/item/stack/rods/attack_self(mob/user as mob)
+ src.add_fingerprint(user)
+
+ if(!istype(user.loc,/turf)) return 0
+
+ if (locate(/obj/structure/grille, usr.loc))
+ for(var/obj/structure/grille/G in usr.loc)
+ if (G.destroyed)
+ G.health = 10
+ G.density = 1
+ G.destroyed = 0
+ G.icon_state = "grille"
+ use(1)
+ else
+ return 1
+ else
+ if(amount < 2)
+ user << "\blue You need at least two rods to do this."
+ return
+ usr << "\blue Assembling grille..."
+ if (!do_after(usr, 10))
+ return
+ var/obj/structure/grille/F = new /obj/structure/grille/ ( usr.loc )
+ usr << "\blue You assemble a grille"
+ F.add_fingerprint(usr)
+ use(2)
+ return
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm
similarity index 85%
rename from code/game/objects/items/stacks/glass.dm
rename to code/game/objects/items/stacks/sheets/glass.dm
index 37fa99b51a2..2f1242cb5d9 100644
--- a/code/game/objects/items/stacks/glass.dm
+++ b/code/game/objects/items/stacks/sheets/glass.dm
@@ -1,12 +1,21 @@
+/* Glass stack types
+ * Contains:
+ * Glass sheets
+ * Reinforced glass sheets
+ * Glass shards - TODO: Move this into code/game/object/item/weapons
+ */
+
/*
-CONTAINS:
-GLASS SHEET
-REINFORCED GLASS SHEET
-SHARDS
+ * Glass sheets
+ */
+/obj/item/stack/sheet/glass
+ name = "glass"
+ desc = "HOLY HELL! That is a lot of glass."
+ singular_name = "glass sheet"
+ icon_state = "sheet-glass"
+ g_amt = 3750
+ origin_tech = "materials=1"
-*/
-
-// GLASS
/obj/item/stack/sheet/glass/attack_self(mob/user as mob)
construct_window(user)
@@ -97,7 +106,25 @@ SHARDS
return 0
-// REINFORCED GLASS
+/*
+ * Reinforced glass sheets
+ */
+/obj/item/stack/sheet/rglass
+ name = "reinforced glass"
+ desc = "Glass which seems to have rods or something stuck in them."
+ singular_name = "reinforced glass sheet"
+ icon_state = "sheet-rglass"
+ g_amt = 3750
+ m_amt = 1875
+ origin_tech = "materials=2"
+
+/obj/item/stack/sheet/rglass/cyborg
+ name = "reinforced glass"
+ desc = "Glass which seems to have rods or something stuck in them."
+ singular_name = "reinforced glass sheet"
+ icon_state = "sheet-rglass"
+ g_amt = 0
+ m_amt = 0
/obj/item/stack/sheet/rglass/attack_self(mob/user as mob)
construct_window(user)
@@ -201,8 +228,9 @@ SHARDS
return 0
-// SHARDS
-
+/*
+ * Glass shards - TODO: Move this into code/game/object/item/weapons
+ */
/obj/item/weapon/shard/Bump()
spawn( 0 )
@@ -216,9 +244,6 @@ SHARDS
/obj/item/weapon/shard/New()
- //****RM
- //world<<"New shard at [x],[y],[z]"
-
src.icon_state = pick("large", "medium", "small")
switch(src.icon_state)
if("small")
diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm
new file mode 100644
index 00000000000..5437fdeccd5
--- /dev/null
+++ b/code/game/objects/items/stacks/sheets/light.dm
@@ -0,0 +1,35 @@
+/obj/item/stack/light_w
+ name = "wired glass tiles"
+ singular_name = "wired glass floor tile"
+ desc = "A glass tile, which is wired, somehow."
+ icon_state = "glass_wire"
+ w_class = 3.0
+ force = 3.0
+ throwforce = 5.0
+ throw_speed = 5
+ throw_range = 20
+ flags = FPRINT | TABLEPASS | CONDUCT
+ max_amount = 60
+
+/obj/item/stack/light_w/attackby(var/obj/item/O as obj, var/mob/user as mob)
+ ..()
+ if(istype(O,/obj/item/weapon/wirecutters))
+ var/obj/item/weapon/cable_coil/CC = new/obj/item/weapon/cable_coil(user.loc)
+ CC.amount = 5
+ amount--
+ new/obj/item/stack/sheet/glass(user.loc)
+ if(amount <= 0)
+ user.drop_from_inventory(src)
+ del(src)
+
+ if(istype(O,/obj/item/stack/sheet/metal))
+ var/obj/item/stack/sheet/metal/M = O
+ M.amount--
+ if(M.amount <= 0)
+ user.drop_from_inventory(M)
+ del(M)
+ amount--
+ new/obj/item/stack/tile/light(user.loc)
+ if(amount <= 0)
+ user.drop_from_inventory(src)
+ del(src)
diff --git a/code/game/objects/items/stacks/minerals.dm b/code/game/objects/items/stacks/sheets/mineral.dm
similarity index 77%
rename from code/game/objects/items/stacks/minerals.dm
rename to code/game/objects/items/stacks/sheets/mineral.dm
index cbd0d465a6d..74ba8d930de 100644
--- a/code/game/objects/items/stacks/minerals.dm
+++ b/code/game/objects/items/stacks/sheets/mineral.dm
@@ -1,14 +1,16 @@
-/*
-CONTAINS:
-SANDSTONE
-DIAMOND
-URANIUM
-PLASMA
-GOLD
-SILVER
-*/
+/* Mineral Sheets
+ * Contains:
+ * Sandstone
+ * Diamond
+ * Uranium
+ * Plasma
+ * Gold
+ * Silver
+ */
-//Sandstone
+/*
+ * Sandstone
+ */
var/global/list/datum/stack_recipe/sandstone_recipes = list ( \
new/datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \
@@ -16,12 +18,23 @@ var/global/list/datum/stack_recipe/sandstone_recipes = list ( \
new/datum/stack_recipe("sandstone floor", ???),\*/
)
+/obj/item/stack/sheet/sandstone
+ name = "sandstone bricks"
+ desc = "This appears to be a combination of both sand and stone."
+ singular_name = "sandstone brick"
+ icon_state = "sheet-sandstone"
+ throw_speed = 4
+ throw_range = 5
+ origin_tech = "materials=1"
+
/obj/item/stack/sheet/sandstone
New(var/loc, var/amount=null)
recipes = sandstone_recipes
return ..()
-//Diamond
+/*
+ * Diamond
+ */
var/global/list/datum/stack_recipe/diamond_recipes = list ( \
new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \
)
@@ -31,7 +44,9 @@ var/global/list/datum/stack_recipe/diamond_recipes = list ( \
recipes = diamond_recipes
return ..()
-//Uranium
+/*
+ * Uranium
+ */
var/global/list/datum/stack_recipe/uranium_recipes = list ( \
new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \
)
@@ -41,7 +56,9 @@ var/global/list/datum/stack_recipe/uranium_recipes = list ( \
recipes = uranium_recipes
return ..()
-//Plasma
+/*
+ * Plasma
+ */
var/global/list/datum/stack_recipe/plasma_recipes = list ( \
new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \
)
@@ -51,7 +68,9 @@ var/global/list/datum/stack_recipe/plasma_recipes = list ( \
recipes = plasma_recipes
return ..()
-//Gold
+/*
+ * Gold
+ */
var/global/list/datum/stack_recipe/gold_recipes = list ( \
new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \
)
@@ -61,7 +80,9 @@ var/global/list/datum/stack_recipe/gold_recipes = list ( \
recipes = gold_recipes
return ..()
-//Silver
+/*
+ * Silver
+ */
var/global/list/datum/stack_recipe/silver_recipes = list ( \
new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \
)
diff --git a/code/game/objects/items/stacks/metal.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
similarity index 50%
rename from code/game/objects/items/stacks/metal.dm
rename to code/game/objects/items/stacks/sheets/sheet_types.dm
index 3a90b87e8a9..65fee3b6dc1 100644
--- a/code/game/objects/items/stacks/metal.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -1,72 +1,15 @@
+/* Diffrent misc types of sheets
+ * Contains:
+ * Metal
+ * Plasteel
+ * Wood
+ * Cloth
+ * Cardboard
+ */
+
/*
-CONTAINS:
-RODS
-METAL
-REINFORCED METAL
-FLOOR TILES
-*/
-
-
-
-// RODS
-
-/obj/item/stack/rods/attackby(obj/item/W as obj, mob/user as mob)
- ..()
- if (istype(W, /obj/item/weapon/weldingtool))
- var/obj/item/weapon/weldingtool/WT = W
-
- if(amount < 2)
- user << "\red You need at least two rods to do this."
- return
-
- if(WT.remove_fuel(0,user))
- var/obj/item/stack/sheet/metal/new_item = new(usr.loc)
- new_item.add_to_stacks(usr)
- for (var/mob/M in viewers(src))
- M.show_message("\red [src] is shaped into metal by [user.name] with the weldingtool.", 3, "\red You hear welding.", 2)
- var/obj/item/stack/rods/R = src
- src = null
- var/replace = (user.get_inactive_hand()==R)
- R.use(2)
- if (!R && replace)
- user.put_in_hands(new_item)
- return
- ..()
-
-
-/obj/item/stack/rods/attack_self(mob/user as mob)
- src.add_fingerprint(user)
-
- if(!istype(user.loc,/turf)) return 0
-
- if (locate(/obj/structure/grille, usr.loc))
- for(var/obj/structure/grille/G in usr.loc)
- if (G.destroyed)
- G.health = 10
- G.density = 1
- G.destroyed = 0
- G.icon_state = "grille"
- use(1)
- else
- return 1
- else
- if(amount < 2)
- user << "\blue You need at least two rods to do this."
- return
- usr << "\blue Assembling grille..."
- if (!do_after(usr, 10))
- return
- var/obj/structure/grille/F = new /obj/structure/grille/ ( usr.loc )
- usr << "\blue You assemble a grille"
- F.add_fingerprint(usr)
- use(2)
- return
-
-
-
-// METAL SHEET
-
-// /datum/stack_recipe/New(title, result_type, req_amount, res_amount, max_res_amount, time, one_per_turf, on_floor = 0)
+ * Metal
+ */
var/global/list/datum/stack_recipe/metal_recipes = list ( \
new/datum/stack_recipe("stool", /obj/structure/stool, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("chair", /obj/structure/stool/bed/chair, one_per_turf = 1, on_floor = 1), \
@@ -95,58 +38,87 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \
)
/obj/item/stack/sheet/metal
- New(var/loc, var/amount=null)
- recipes = metal_recipes
- return ..()
+ name = "metal"
+ desc = "Sheets made out off metal. It has been dubbed Metal Sheets."
+ singular_name = "metal sheet"
+ icon_state = "sheet-metal"
+ m_amt = 3750
+ throwforce = 14.0
+ flags = FPRINT | TABLEPASS | CONDUCT
+ origin_tech = "materials=1"
-// REINFORCED METAL SHEET
+/obj/item/stack/sheet/metal/cyborg
+ name = "metal"
+ desc = "Sheets made out off metal. It has been dubbed Metal Sheets."
+ singular_name = "metal sheet"
+ icon_state = "sheet-metal"
+ m_amt = 0
+ throwforce = 14.0
+ flags = FPRINT | TABLEPASS | CONDUCT
-// /datum/stack_recipe/New(title, result_type, req_amount, res_amount, max_res_amount, time, one_per_turf, on_floor = 0)
+/obj/item/stack/sheet/metal/New(var/loc, var/amount=null)
+ recipes = metal_recipes
+ return ..()
+
+
+/*
+ * Plasteel
+ */
var/global/list/datum/stack_recipe/plasteel_recipes = list ( \
new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = 1), \
)
/obj/item/stack/sheet/plasteel
- New(var/loc, var/amount=null)
+ name = "plasteel"
+ singular_name = "plasteel sheet"
+ desc = "This sheet is an alloy of iron and plasma."
+ icon_state = "sheet-plasteel"
+ item_state = "sheet-metal"
+ m_amt = 7500
+ throwforce = 15.0
+ flags = FPRINT | TABLEPASS | CONDUCT
+ origin_tech = "materials=2"
+
+/obj/item/stack/sheet/plasteel/New(var/loc, var/amount=null)
recipes = plasteel_recipes
return ..()
+/*
+ * Wood
+ */
+var/global/list/datum/stack_recipe/wood_recipes = list ( \
+ new/datum/stack_recipe("wooden sandals", /obj/item/clothing/shoes/sandal, 1), \
+ new/datum/stack_recipe("table parts", /obj/item/weapon/table_parts/wood, 2), \
+ new/datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20), \
+ new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \
+ )
+/obj/item/stack/sheet/wood
+ name = "wooden planks"
+ desc = "One can only guess that this is a bunch of wood."
+ singular_name = "wood plank"
+ icon_state = "sheet-wood"
+ origin_tech = "materials=1;biotech=1"
-// TILES
-
-/obj/item/stack/tile/plasteel/New(var/loc, var/amount=null)
- ..()
- src.pixel_x = rand(1, 14)
- src.pixel_y = rand(1, 14)
- return
+/obj/item/stack/sheet/wood/New(var/loc, var/amount=null)
+ recipes = wood_recipes
+ return ..()
/*
-/obj/item/stack/tile/plasteel/attack_self(mob/user as mob)
- if (usr.stat)
- return
- var/T = user.loc
- if (!( istype(T, /turf) ))
- user << "\red You must be on the ground!"
- return
- if (!( istype(T, /turf/space) ))
- user << "\red You cannot build on or repair this turf!"
- return
- src.build(T)
- src.add_fingerprint(user)
- use(1)
- return
-*/
+ * Cloth
+ */
+/obj/item/stack/sheet/cloth
+ name = "cloth"
+ desc = "This roll of cloth is made from only the finest chemicals and bunny rabbits."
+ singular_name = "cloth roll"
+ icon_state = "sheet-cloth"
+ origin_tech = "materials=2"
-/obj/item/stack/tile/plasteel/proc/build(turf/S as turf)
- S.ReplaceWithPlating()
-// var/turf/simulated/floor/W = S.ReplaceWithFloor()
-// W.make_plating()
- return
-
-// CARDBOARD SHEET - BubbleWrap
-
-// /datum/stack_recipe/New(title, result_type, req_amount, res_amount, max_res_amount, time, one_per_turf, on_floor = 0)
+/*
+ * Cardboard
+ */
var/global/list/datum/stack_recipe/cardboard_recipes = list ( \
new/datum/stack_recipe("box", /obj/item/weapon/storage/box), \
new/datum/stack_recipe("light tubes", /obj/item/weapon/storage/lightbox/tubes), \
@@ -157,7 +129,14 @@ var/global/list/datum/stack_recipe/cardboard_recipes = list ( \
new/datum/stack_recipe("pizza box", /obj/item/pizzabox), \
)
-/obj/item/stack/sheet/cardboard
- New(var/loc, var/amount=null)
+/obj/item/stack/sheet/cardboard //BubbleWrap
+ name = "cardboard"
+ desc = "Large sheets of card, like boxes folded flat."
+ singular_name = "cardboard sheet"
+ icon_state = "sheet-card"
+ flags = FPRINT | TABLEPASS
+ origin_tech = "materials=1"
+
+/obj/item/stack/sheet/cardboard/New(var/loc, var/amount=null)
recipes = cardboard_recipes
- return ..()
+ return ..()
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/sheets/sheets.dm b/code/game/objects/items/stacks/sheets/sheets.dm
new file mode 100644
index 00000000000..138f904ae9f
--- /dev/null
+++ b/code/game/objects/items/stacks/sheets/sheets.dm
@@ -0,0 +1,21 @@
+/obj/item/stack/sheet
+ name = "sheet"
+ flags = FPRINT | TABLEPASS
+ w_class = 3.0
+ force = 5
+ throwforce = 5
+ max_amount = 50
+ throw_speed = 3
+ throw_range = 3
+ attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
+ var/perunit = 3750
+
+/obj/item/stack/sheet/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if (istype(W, /obj/item/weapon/sheetsnatcher))
+ var/obj/item/weapon/sheetsnatcher/S = W
+ if(!S.mode)
+ S.add(src,user)
+ else
+ for (var/obj/item/stack/sheet/stack in locate(src.x,src.y,src.z))
+ S.add(stack,user)
+ ..()
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index c040d5034af..5eb7d9b26ff 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -1,116 +1,36 @@
+/* Stack type objects!
+ * Contains:
+ * Stacks
+ * Recipe datum
+ */
+
/*
- Base object for stackable items.
- Stackable items are:
- metal
- rmetal
- glass
- rglass
- wood planks
- floor tiles
- metal rods
-*/
+ * Stacks
+ */
+/obj/item/stack
+ origin_tech = "materials=1"
+ var/list/datum/stack_recipe/recipes
+ var/singular_name
+ var/amount = 1
+ var/max_amount //also see stack recipes initialisation, param "max_res_amount" must be equal to this max_amount
/obj/item/stack/New(var/loc, var/amount=null)
..()
if (amount)
src.amount=amount
-
return
+/obj/item/stack/Del()
+ if (src && usr && usr.machine==src)
+ usr << browse(null, "window=stack")
+ ..()
+
/obj/item/stack/examine()
set src in view(1)
..()
usr << "There are [src.amount] [src.singular_name]\s in the stack."
return
-/obj/item/stack/proc/use(var/amount)
- src.amount-=amount
- if (src.amount<=0)
- var/oldsrc = src
- src = null //dont kill proc after del()
- if(usr)
- usr.before_take_item(oldsrc)
- del(oldsrc)
- return
-
-/obj/item/stack/proc/add_to_stacks(mob/usr as mob)
- var/obj/item/stack/oldsrc = src
- src = null
- for (var/obj/item/stack/item in usr.loc)
- if (item==oldsrc)
- continue
- if (!istype(item, oldsrc.type))
- continue
- if (item.amount>=item.max_amount)
- continue
- oldsrc.attackby(item, usr)
- usr << "You add new [item.singular_name] to the stack. It now contains [item.amount] [item.singular_name]\s."
- if(!oldsrc)
- break
-
-/obj/item/stack/attack_hand(mob/user as mob)
- if (user.get_inactive_hand() == src)
- var/obj/item/stack/F = new src.type( user, amount=1)
- F.copy_evidences(src)
- user.put_in_hands(F)
- src.add_fingerprint(user)
- F.add_fingerprint(user)
- use(1)
- if (src && usr.machine==src)
- spawn(0) src.interact(usr)
- else
- ..()
- return
-
-/obj/item/stack/attackby(obj/item/W as obj, mob/user as mob)
- ..()
- if (istype(W, src.type))
- var/obj/item/stack/S = W
- if (S.amount >= max_amount)
- return 1
- var/to_transfer as num
- if (user.get_inactive_hand()==src)
- to_transfer = 1
- else
- to_transfer = min(src.amount, S.max_amount-S.amount)
- S.amount+=to_transfer
- if (S && usr.machine==S)
- spawn(0) S.interact(usr)
- src.use(to_transfer)
- if (src && usr.machine==src)
- spawn(0) src.interact(usr)
- else return ..()
-
-/obj/item/stack/proc/copy_evidences(obj/item/stack/from as obj)
- src.blood_DNA = from.blood_DNA
- src.fingerprints = from.fingerprints
- src.fingerprintshidden = from.fingerprintshidden
- src.fingerprintslast = from.fingerprintslast
- //TODO bloody overlay
-
-/datum/stack_recipe
- var/title = "ERROR"
- var/result_type
- var/req_amount = 1
- var/res_amount = 1
- var/max_res_amount = 1
- var/time = 0
- var/one_per_turf = 0
- var/on_floor = 0
- New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0)
- src.title = title
- src.result_type = result_type
- src.req_amount = req_amount
- src.res_amount = res_amount
- src.max_res_amount = max_res_amount
- src.time = time
- src.one_per_turf = one_per_turf
- src.on_floor = on_floor
-
-/obj/item/stack
- var/list/datum/stack_recipe/recipes
- origin_tech = "materials=1"
-
/obj/item/stack/attack_self(mob/user as mob)
interact(user)
@@ -217,7 +137,89 @@
return
return
-/obj/item/stack/Del()
- if (src && usr && usr.machine==src)
- usr << browse(null, "window=stack")
+/obj/item/stack/proc/use(var/amount)
+ src.amount-=amount
+ if (src.amount<=0)
+ var/oldsrc = src
+ src = null //dont kill proc after del()
+ if(usr)
+ usr.before_take_item(oldsrc)
+ del(oldsrc)
+ return
+
+/obj/item/stack/proc/add_to_stacks(mob/usr as mob)
+ var/obj/item/stack/oldsrc = src
+ src = null
+ for (var/obj/item/stack/item in usr.loc)
+ if (item==oldsrc)
+ continue
+ if (!istype(item, oldsrc.type))
+ continue
+ if (item.amount>=item.max_amount)
+ continue
+ oldsrc.attackby(item, usr)
+ usr << "You add new [item.singular_name] to the stack. It now contains [item.amount] [item.singular_name]\s."
+ if(!oldsrc)
+ break
+
+/obj/item/stack/attack_hand(mob/user as mob)
+ if (user.get_inactive_hand() == src)
+ var/obj/item/stack/F = new src.type( user, amount=1)
+ F.copy_evidences(src)
+ user.put_in_hands(F)
+ src.add_fingerprint(user)
+ F.add_fingerprint(user)
+ use(1)
+ if (src && usr.machine==src)
+ spawn(0) src.interact(usr)
+ else
+ ..()
+ return
+
+/obj/item/stack/attackby(obj/item/W as obj, mob/user as mob)
..()
+ if (istype(W, src.type))
+ var/obj/item/stack/S = W
+ if (S.amount >= max_amount)
+ return 1
+ var/to_transfer as num
+ if (user.get_inactive_hand()==src)
+ to_transfer = 1
+ else
+ to_transfer = min(src.amount, S.max_amount-S.amount)
+ S.amount+=to_transfer
+ if (S && usr.machine==S)
+ spawn(0) S.interact(usr)
+ src.use(to_transfer)
+ if (src && usr.machine==src)
+ spawn(0) src.interact(usr)
+ else return ..()
+
+/obj/item/stack/proc/copy_evidences(obj/item/stack/from as obj)
+ src.blood_DNA = from.blood_DNA
+ src.fingerprints = from.fingerprints
+ src.fingerprintshidden = from.fingerprintshidden
+ src.fingerprintslast = from.fingerprintslast
+ //TODO bloody overlay
+
+/*
+ * Recipe datum
+ */
+/datum/stack_recipe
+ var/title = "ERROR"
+ var/result_type
+ var/req_amount = 1
+ var/res_amount = 1
+ var/max_res_amount = 1
+ var/time = 0
+ var/one_per_turf = 0
+ var/on_floor = 0
+ New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0)
+ src.title = title
+ src.result_type = result_type
+ src.req_amount = req_amount
+ src.res_amount = res_amount
+ src.max_res_amount = max_res_amount
+ src.time = time
+ src.one_per_turf = one_per_turf
+ src.on_floor = on_floor
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/tiles/light.dm b/code/game/objects/items/stacks/tiles/light.dm
new file mode 100644
index 00000000000..460db9b7662
--- /dev/null
+++ b/code/game/objects/items/stacks/tiles/light.dm
@@ -0,0 +1,36 @@
+/obj/item/stack/tile/light
+ name = "light tiles"
+ singular_name = "light floor tile"
+ desc = "A floor tile, made out off glass. It produces light."
+ icon_state = "tile_e"
+ w_class = 3.0
+ force = 3.0
+ throwforce = 5.0
+ throw_speed = 5
+ throw_range = 20
+ flags = FPRINT | TABLEPASS | CONDUCT
+ max_amount = 60
+ attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
+ var/on = 1
+ var/state //0 = fine, 1 = flickering, 2 = breaking, 3 = broken
+
+/obj/item/stack/tile/light/New()
+ ..()
+ if(prob(5))
+ state = 3 //broken
+ else if(prob(5))
+ state = 2 //breaking
+ else if(prob(10))
+ state = 1 //flickering occasionally
+ else
+ state = 0 //fine
+
+/obj/item/stack/tile/light/attackby(var/obj/item/O as obj, var/mob/user as mob)
+ ..()
+ if(istype(O,/obj/item/weapon/crowbar))
+ new/obj/item/stack/sheet/metal(user.loc)
+ amount--
+ new/obj/item/stack/light_w(user.loc)
+ if(amount <= 0)
+ user.drop_from_inventory(src)
+ del(src)
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/tiles/plasteel.dm b/code/game/objects/items/stacks/tiles/plasteel.dm
new file mode 100644
index 00000000000..05823faf341
--- /dev/null
+++ b/code/game/objects/items/stacks/tiles/plasteel.dm
@@ -0,0 +1,42 @@
+/obj/item/stack/tile/plasteel
+ name = "floor tiles"
+ singular_name = "floor tile"
+ desc = "Those could work as a pretty decent throwing weapon"
+ icon_state = "tile"
+ w_class = 3.0
+ force = 6.0
+ m_amt = 937.5
+ throwforce = 15.0
+ throw_speed = 5
+ throw_range = 20
+ flags = FPRINT | TABLEPASS | CONDUCT
+ max_amount = 60
+
+/obj/item/stack/tile/plasteel/New(var/loc, var/amount=null)
+ ..()
+ src.pixel_x = rand(1, 14)
+ src.pixel_y = rand(1, 14)
+ return
+
+/*
+/obj/item/stack/tile/plasteel/attack_self(mob/user as mob)
+ if (usr.stat)
+ return
+ var/T = user.loc
+ if (!( istype(T, /turf) ))
+ user << "\red You must be on the ground!"
+ return
+ if (!( istype(T, /turf/space) ))
+ user << "\red You cannot build on or repair this turf!"
+ return
+ src.build(T)
+ src.add_fingerprint(user)
+ use(1)
+ return
+*/
+
+/obj/item/stack/tile/plasteel/proc/build(turf/S as turf)
+ S.ReplaceWithPlating()
+// var/turf/simulated/floor/W = S.ReplaceWithFloor()
+// W.make_plating()
+ return
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm
new file mode 100644
index 00000000000..16fe749e862
--- /dev/null
+++ b/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -0,0 +1,38 @@
+/* Diffrent misc types of tiles
+ * Contains:
+ * Grass
+ * Wood
+ */
+
+/*
+ * Grass
+ */
+/obj/item/stack/tile/grass
+ name = "grass tiles"
+ singular_name = "grass floor tile"
+ desc = "A patch of grass like they often use on golf courses"
+ icon_state = "tile_grass"
+ w_class = 3.0
+ force = 1.0
+ throwforce = 1.0
+ throw_speed = 5
+ throw_range = 20
+ flags = FPRINT | TABLEPASS | CONDUCT
+ max_amount = 60
+ origin_tech = "biotech=1"
+
+/*
+ * Wood
+ */
+/obj/item/stack/tile/wood
+ name = "wood floor tiles"
+ singular_name = "wood floor tile"
+ desc = "an easy to fit wood floor tile"
+ icon_state = "tile-wood"
+ w_class = 3.0
+ force = 1.0
+ throwforce = 1.0
+ throw_speed = 5
+ throw_range = 20
+ flags = FPRINT | TABLEPASS | CONDUCT
+ max_amount = 60
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/wood.dm b/code/game/objects/items/stacks/wood.dm
deleted file mode 100644
index 772c1b42d54..00000000000
--- a/code/game/objects/items/stacks/wood.dm
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
-CONTAINS:
-WOOD PLANKS
-*/
-
-var/global/list/datum/stack_recipe/wood_recipes = list ( \
- new/datum/stack_recipe("wooden sandals", /obj/item/clothing/shoes/sandal, 1), \
- new/datum/stack_recipe("table parts", /obj/item/weapon/table_parts/wood, 2), \
- new/datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20), \
- new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1), \
- new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \
- )
-
-/obj/item/stack/sheet/wood/New(var/loc, var/amount=null)
- recipes = wood_recipes
- return ..()
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm
index 7a5ec5522bf..43f34e7ec57 100644
--- a/code/game/objects/items/weapons/cigs_lighters.dm
+++ b/code/game/objects/items/weapons/cigs_lighters.dm
@@ -1,5 +1,3 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
-
/*
CONTAINS:
MATCHES
@@ -7,6 +5,7 @@ CIGARETTES
CIGARS
SMOKING PIPES
CIG PACKET
+CHEAP LIGHTERS
ZIPPO
*/
@@ -14,8 +13,8 @@ ZIPPO
//MATCHES//
///////////
/obj/item/weapon/match
- name = "Match"
- desc = "A simple match stick, used for lighting tobacco"
+ name = "match"
+ desc = "A simple match stick, used for lighting fine smokables."
icon = 'icons/obj/cigarettes.dmi'
icon_state = "match_unlit"
var/lit = 0
@@ -27,10 +26,10 @@ ZIPPO
process()
var/turf/location = get_turf(src)
- src.smoketime--
- if(src.smoketime < 1)
- src.icon_state = "match_burnt"
- src.lit = -1
+ smoketime--
+ if(smoketime < 1)
+ icon_state = "match_burnt"
+ lit = -1
processing_objects.Remove(src)
return
if(location)
@@ -39,20 +38,18 @@ ZIPPO
dropped(mob/user as mob)
- if(src.lit == 1)
- src.lit = -1
- src.damtype = "brute"
- src.icon_state = "match_burnt"
- src.item_state = "cigoff"
- src.name = "Burnt match"
- src.desc = "A match that has been burnt"
+ if(lit == 1)
+ lit = -1
+ damtype = "brute"
+ icon_state = "match_burnt"
+ item_state = "cigoff"
+ name = "burnt match"
+ desc = "A match. This one has seen better days."
return ..()
-
-///////////////////////
-//CIGARETTES + CIGARS//
-///////////////////////
-
+//////////////////
+//FINE SMOKABLES//
+//////////////////
/obj/item/clothing/mask/cigarette
name = "cigarette"
desc = "A roll of tobacco and nicotine."
@@ -115,37 +112,37 @@ ZIPPO
/obj/item/clothing/mask/cigarette/afterattack(obj/item/weapon/reagent_containers/glass/glass, mob/user as mob)
..()
- if(istype(glass)) // you can dip cigarettes into beakers
+ if(istype(glass)) //you can dip cigarettes into beakers
var/transfered = glass.reagents.trans_to(src, chem_volume)
- if(transfered) // if reagents were transfered, show the message
- user << "\blue You dip \the [src] into \the [glass]."
- else // if not, either the beaker was empty, or the cigarette was full
+ if(transfered) //if reagents were transfered, show the message
+ user << "You dip \the [src] into \the [glass]."
+ else //if not, either the beaker was empty, or the cigarette was full
if(!glass.reagents.total_volume)
- user << "\red [glass] is empty."
+ user << "[glass] is empty."
else
- user << "\red [src] is full."
+ user << "[src] is full."
/obj/item/clothing/mask/cigarette/proc/light(var/flavor_text = "[usr] lights the [name].")
- if(!src.lit)
- src.lit = 1
- src.damtype = "fire"
+ if(!lit)
+ lit = 1
+ damtype = "fire"
if(reagents.get_reagent_amount("plasma")) // the plasma explodes when exposed to fire
var/datum/effect/effect/system/reagents_explosion/e = new()
- e.set_up(round (src.reagents.get_reagent_amount("plasma")/2.5, 1), get_turf(src), 0, 0)
+ e.set_up(round (reagents.get_reagent_amount("plasma")/2.5, 1), get_turf(src), 0, 0)
e.start()
del(src)
return
if(reagents.get_reagent_amount("fuel")) // the fuel explodes, too, but much less violently
var/datum/effect/effect/system/reagents_explosion/e = new()
- e.set_up(round (src.reagents.get_reagent_amount("fuel")/5, 1), get_turf(src), 0, 0)
+ e.set_up(round (reagents.get_reagent_amount("fuel")/5, 1), get_turf(src), 0, 0)
e.start()
del(src)
return
- src.flags &= ~NOREACT // allowing reagents to react after being lit
- src.reagents.handle_reactions()
- src.icon_state = icon_on
- src.item_state = icon_on
+ flags &= ~NOREACT // allowing reagents to react after being lit
+ reagents.handle_reactions()
+ icon_state = icon_on
+ item_state = icon_on
for(var/mob/O in viewers(usr, null))
O.show_message(flavor_text, 1)
processing_objects.Add(src)
@@ -153,13 +150,13 @@ ZIPPO
/obj/item/clothing/mask/cigarette/process()
var/turf/location = get_turf(src)
- src.smoketime--
- if(src.smoketime < 1)
+ smoketime--
+ if(smoketime < 1)
new type_butt(location)
processing_objects.Remove(src)
- if(ismob(src.loc))
- var/mob/living/M = src.loc
- M << "\red Your [src.name] goes out."
+ if(ismob(loc))
+ var/mob/living/M = loc
+ M << "\red Your [name] goes out."
M.u_equip(src) //un-equip it so the overlays can update
M.update_icons()
del(src)
@@ -167,7 +164,7 @@ ZIPPO
if(location)
location.hotspot_expose(700, 5)
if(reagents && reagents.total_volume) // check if it has any reagents at all
- if( iscarbon(src.loc) && (src == loc:wear_mask) ) // if it's in the human/monkey mouth, transfer reagents to the mob
+ if( iscarbon(loc) && (src == loc:wear_mask) ) // if it's in the human/monkey mouth, transfer reagents to the mob
var/mob/living/carbon/C = loc
if(prob(15)) // so it's not an instarape in case of acid
reagents.reaction(C, INGEST)
@@ -178,9 +175,9 @@ ZIPPO
/obj/item/clothing/mask/cigarette/dropped(mob/user as mob)
- if(src.lit == 1)
+ if(lit == 1)
for(var/mob/O in viewers(user, null))
- O.show_message(text("\red [] calmly drops and treads on the lit [], putting it out instantly.", user,src.name), 1)
+ O.show_message(text("\red [] calmly drops and treads on the lit [], putting it out instantly.", user,name), 1)
new type_butt(loc)
processing_objects.Remove(src)
del(src)
@@ -291,26 +288,26 @@ ZIPPO
light("\red [user] lights their [name] with their [W].")
light(var/flavor_text = "[usr] lights the [name].")
- if(!src.lit)
- src.lit = 1
- src.damtype = "fire"
- src.icon_state = icon_on
- src.item_state = icon_on
+ if(!lit)
+ lit = 1
+ damtype = "fire"
+ icon_state = icon_on
+ item_state = icon_on
for(var/mob/O in viewers(usr, null))
O.show_message(flavor_text, 1)
processing_objects.Add(src)
process()
var/turf/location = get_turf(src)
- src.smoketime--
- if(src.smoketime < 1)
+ smoketime--
+ if(smoketime < 1)
new /obj/effect/decal/cleanable/ash(location)
- if(ismob(src.loc))
- var/mob/living/M = src.loc
- M << "\red Your [src.name] goes out, and you empty the ash."
- src.lit = 0
- src.icon_state = icon_off
- src.item_state = icon_off
+ if(ismob(loc))
+ var/mob/living/M = loc
+ M << "\red Your [name] goes out, and you empty the ash."
+ lit = 0
+ icon_state = icon_off
+ item_state = icon_off
processing_objects.Remove(src)
return
if(location)
@@ -318,17 +315,16 @@ ZIPPO
return
dropped(mob/user as mob)
- if(src.lit == 1)
- for(var/mob/O in viewers(user, null))
- O.show_message(text("\red [] puts out the [].", user,src.name), 1)
- src.lit = 0
- src.icon_state = icon_off
- src.item_state = icon_off
+ if(lit == 1)
+ user.visible_message("[user] puts out [src].")
+ lit = 0
+ icon_state = icon_off
+ item_state = icon_off
processing_objects.Remove(src)
return ..()
/obj/item/clothing/mask/pipe/attack_self(mob/user as mob) //Refills the pipe. Can be changed to an attackby later, if loose tobacco is added to vendors or something.
- if(src.smoketime <= 0)
+ if(smoketime <= 0)
user << "\blue You refill the pipe with tobacco."
smoketime = maxsmoketime
return
@@ -379,13 +375,13 @@ ZIPPO
attack_hand(mob/user as mob)
if(user.r_hand == src || user.l_hand == src)
if(cigcount == 0)
- user << "\red You're out of cigs, shit! How you gonna get through the rest of the day..."
+ user << "You're out of cigs, shit! How you gonna get through the rest of the day..."
return
else
var/obj/item/clothing/mask/cigarette/W = new /obj/item/clothing/mask/cigarette(user)
reagents.trans_to(W, (reagents.total_volume/cigcount))
user.put_in_active_hand(W)
- src.reagents.maximum_volume = 15*cigcount
+ reagents.maximum_volume = 15*cigcount
cigcount--
else
return ..()
@@ -436,10 +432,10 @@ ZIPPO
attack_self(mob/living/user)
if(user.r_hand == src || user.l_hand == src)
- if(!src.lit)
- src.lit = 1
- src.icon_state = icon_on
- src.item_state = icon_on
+ if(!lit)
+ lit = 1
+ icon_state = icon_on
+ item_state = icon_on
if( istype(src,/obj/item/weapon/lighter/zippo) )
for(var/mob/O in viewers(user, null))
O.show_message(text("\red Without even breaking stride, [] flips open and lights the [] in one smooth movement.", user, src), 1)
@@ -456,9 +452,9 @@ ZIPPO
user.SetLuminosity(user.luminosity + 2)
processing_objects.Add(src)
else
- src.lit = 0
- src.icon_state = icon_off
- src.item_state = icon_off
+ lit = 0
+ icon_state = icon_off
+ item_state = icon_off
if( istype(src,/obj/item/weapon/lighter/zippo) )
for(var/mob/O in viewers(user, null))
O.show_message(text("\red You hear a quiet click, as [] shuts off the [] without even looking at what they're doing. Wow.", user, src), 1)
@@ -477,11 +473,11 @@ ZIPPO
if(!istype(M, /mob))
return
- if(istype(M.wear_mask,/obj/item/clothing/mask/cigarette) && user.zone_sel.selecting == "mouth" && src.lit)
+ if(istype(M.wear_mask,/obj/item/clothing/mask/cigarette) && user.zone_sel.selecting == "mouth" && lit)
if(M == user)
- M.wear_mask:light("\red With a single flick of their wrist, [user] smoothly lights their [M.wear_mask.name] with their [src.name]. Damn they're cool.")
+ M.wear_mask:light("\red With a single flick of their wrist, [user] smoothly lights their [M.wear_mask.name] with their [name]. Damn they're cool.")
else
- M.wear_mask:light("\red [user] whips the [src.name] out and holds it for [M]. Their arm is as steady as the unflickering flame they light the [M.wear_mask.name] with.")
+ M.wear_mask:light("\red [user] whips the [name] out and holds it for [M]. Their arm is as steady as the unflickering flame they light the [M.wear_mask.name] with.")
else
..()
@@ -495,7 +491,7 @@ ZIPPO
pickup(mob/user)
if(lit)
- src.SetLuminosity(0)
+ SetLuminosity(0)
user.SetLuminosity(user.luminosity+2)
return
@@ -503,5 +499,5 @@ ZIPPO
dropped(mob/user)
if(lit)
user.SetLuminosity(user.luminosity-2)
- src.SetLuminosity(2)
+ SetLuminosity(2)
return
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index 45b6003e575..e3f943701e1 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -7,8 +7,6 @@
var/stage = 0
var/state = 0
var/path = 0
- var/motion = 0
- var/direct = "SOUTH"
var/obj/item/weapon/circuitboard/circuit = null
var/list/beakers = new/list()
var/list/allowed_containers = list("/obj/item/weapon/reagent_containers/glass/beaker", "/obj/item/weapon/reagent_containers/glass/dispenser", "/obj/item/weapon/reagent_containers/glass/bottle")
@@ -57,131 +55,6 @@
else
user << "\red \the [W] is empty."
- else if(path != 1)
- if(!istype(src.loc,/turf))
- user << "\red You need to put the canister on the ground to do that!"
- else
- switch(state)
- if(0)
- if(istype(W, /obj/item/weapon/wrench))
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
- if(do_after(user, 20))
- user << "\blue You wrench the canister in place."
- src.name = "Camera Assembly"
- src.anchored = 1
- src.state = 1
- path = 2
- if(1)
- if(istype(W, /obj/item/weapon/wrench))
- playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
- if(do_after(user, 20))
- user << "\blue You unfasten the canister."
- src.name = "Grenade Casing"
- src.anchored = 0
- src.state = 0
- path = 0
- if(istype(W, /obj/item/device/multitool))
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
- user << "\blue You place the electronics inside the canister."
- src.circuit = W
- user.drop_item()
- W.loc = src
- if(istype(W, /obj/item/weapon/screwdriver) && circuit)
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
- user << "\blue You screw the circuitry into place."
- src.state = 2
- if(istype(W, /obj/item/weapon/crowbar) && circuit)
- playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
- user << "\blue You remove the circuitry."
- src.state = 1
- circuit.loc = src.loc
- src.circuit = null
- if(2)
- if(istype(W, /obj/item/weapon/screwdriver) && circuit)
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
- user << "\blue You unfasten the circuitry."
- src.state = 1
- if(istype(W, /obj/item/weapon/cable_coil))
- if(W:amount >= 1)
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
- if(do_after(user, 20))
- W:amount -= 1
- if(!W:amount) del(W)
- user << "\blue You add cabling to the canister."
- src.state = 3
- if(3)
- if(istype(W, /obj/item/weapon/wirecutters))
- playsound(src.loc, 'sound/items/Wirecutter.ogg', 50, 1)
- user << "\blue You remove the cabling."
- src.state = 2
- var/obj/item/weapon/cable_coil/A = new /obj/item/weapon/cable_coil( src.loc )
- A.amount = 1
- if(issignaler(W))
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
- user << "\blue You attach the wireless signaller unit to the circutry."
- user.drop_item()
- W.loc = src
- src.state = 4
- if(4)
- if(istype(W, /obj/item/weapon/crowbar) && !motion)
- playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
- user << "\blue You remove the remote signalling device."
- src.state = 3
- new /obj/item/device/assembly/signaler( src.loc, 1 )
- if(isprox(W) && motion == 0)
-// if(W:amount >= 1)
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
-// W:use(1)
- user << "\blue You attach the proximity sensor."
- user.drop_item()
- W.loc = src
- motion = 1
- if(istype(W, /obj/item/weapon/crowbar) && motion)
- playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
- user << "\blue You remove the proximity sensor."
- new /obj/item/device/assembly/prox_sensor( src.loc, 1 )
- motion = 0
- if(istype(W, /obj/item/stack/sheet/glass))
- if(W:amount >= 1)
- playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
- if(do_after(user, 20))
- W:use(1)
- user << "\blue You put in the glass lens."
- src.state = 5
- if(5)
- if(istype(W, /obj/item/weapon/crowbar))
- playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
- user << "\blue You remove the glass lens."
- src.state = 4
- new /obj/item/stack/sheet/glass( src.loc, 2 )
- if(istype(W, /obj/item/weapon/screwdriver))
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
- user << "\blue You connect the lense."
- var/obj/machinery/camera/B = null
- if(motion == 1)
- B = new /obj/machinery/camera/motion( src.loc )
- else
- B = new /obj/machinery/camera( src.loc )
- // To prevent people exploiting the fact that it doesn't delete the assembly until the user is done
- // entering the camera options.
- src.loc = B
-
- //Auto detect walls and turn camera based on wall locations.
- B.auto_turn()
-
- B.network = "SS13"
- B.network = input(usr, "Which network would you like to connect this camera to?", "Set Network", "SS13")
-
- for(var/i = 5; i >= 0; i -= 1)
- direct = input(user, "Direction?", "Assembling Camera", null) in list("LEAVE IT", "NORTH", "EAST", "SOUTH", "WEST" )
- if(direct != "LEAVE IT")
- B.dir = text2dir(direct)
- if(i != 0)
- var/confirm = alert(user, "Is this what you want? Chances Remaining: [i]", "Confirmation", "Yes", "No")
- if(confirm == "Yes")
- break
- del(src)
-
prime()
if(prob(reliability))
var/has_reagents = 0
diff --git a/code/game/objects/items/weapons/grenades/emgrenade.dm b/code/game/objects/items/weapons/grenades/emgrenade.dm
index 3454f9b9fa9..95ad0b77b1e 100644
--- a/code/game/objects/items/weapons/grenades/emgrenade.dm
+++ b/code/game/objects/items/weapons/grenades/emgrenade.dm
@@ -1,11 +1,12 @@
/obj/item/weapon/grenade/empgrenade
- name = "emp grenade"
+ name = "classic emp grenade"
icon_state = "emp"
item_state = "emp"
origin_tech = "materials=2;magnets=3"
prime()
..()
- if(empulse(src, 5, 7))
+ if(empulse(src, 10, 20))
del(src)
return
+
diff --git a/code/game/objects/items/weapons/grenades/smokebomb.dm b/code/game/objects/items/weapons/grenades/smokebomb.dm
index aa8920bb4fc..ea6ab037bc4 100644
--- a/code/game/objects/items/weapons/grenades/smokebomb.dm
+++ b/code/game/objects/items/weapons/grenades/smokebomb.dm
@@ -13,10 +13,10 @@
..()
src.smoke = new /datum/effect/effect/system/bad_smoke_spread
src.smoke.attach(src)
- src.smoke.set_up(10, 0, usr.loc)
prime()
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
+ src.smoke.set_up(10, 0, usr.loc)
spawn(0)
src.smoke.start()
sleep(10)
diff --git a/code/game/objects/items/weapons/hydroponics.dm b/code/game/objects/items/weapons/hydroponics.dm
index 87d592a1e9e..a6699b41966 100644
--- a/code/game/objects/items/weapons/hydroponics.dm
+++ b/code/game/objects/items/weapons/hydroponics.dm
@@ -65,6 +65,7 @@
/obj/item/weapon/grown/nettle/afterattack(atom/A as mob|obj, mob/user as mob)
if(force > 0)
force -= rand(1,(force/3)+1) // When you whack someone with it, leaves fall off
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
else
usr << "All the leaves have fallen off the nettle from violent whacking."
del(src)
@@ -99,6 +100,8 @@
log_attack(" [user.name] ([user.ckey]) used the [src.name] on [M.name] ([M.ckey])")
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
+
M.eye_blurry += force/7
if(prob(20))
M.Paralyse(force/6)
diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm
index 0b2c869cc3a..3a6a4d434f7 100644
--- a/code/game/objects/items/weapons/kitchen.dm
+++ b/code/game/objects/items/weapons/kitchen.dm
@@ -50,6 +50,7 @@
user << "\red You accidentally cut yourself with the [src]."
user.take_organ_damage(20)
return
+ playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
return ..()
/*
diff --git a/code/game/objects/items/weapons/storage/kit.dm b/code/game/objects/items/weapons/storage/kit.dm
index 7f81d26c3ac..6ae63352f47 100644
--- a/code/game/objects/items/weapons/storage/kit.dm
+++ b/code/game/objects/items/weapons/storage/kit.dm
@@ -41,6 +41,8 @@
new /obj/item/weapon/grenade/empgrenade(src)
new /obj/item/weapon/grenade/empgrenade(src)
new /obj/item/weapon/grenade/empgrenade(src)
+ new /obj/item/weapon/grenade/empgrenade(src)
+ new /obj/item/weapon/grenade/empgrenade(src)
..()
return
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index e69de29bb2d..11deb181af5 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -0,0 +1,77 @@
+/obj
+ //var/datum/module/mod //not used
+ var/m_amt = 0 // metal
+ var/g_amt = 0 // glass
+ var/w_amt = 0 // waster amounts
+ var/origin_tech = null //Used by R&D to determine what research bonuses it grants.
+ var/reliability = 100 //Used by SOME devices to determine how reliable they are.
+ var/crit_fail = 0
+ var/unacidable = 0 //universal "unacidabliness" var, here so you can use it in any obj.
+ var/datum/marked_datum
+ animate_movement = 2
+ var/throwforce = 1
+ var/list/attack_verb = list() //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
+
+/obj/proc/handle_internal_lifeform(mob/lifeform_inside_me, breath_request)
+ //Return: (NONSTANDARD)
+ // null if object handles breathing logic for lifeform
+ // datum/air_group to tell lifeform to process using that breath return
+ //DEFAULT: Take air from turf to give to have mob process
+ if(breath_request>0)
+ return remove_air(breath_request)
+ else
+ return null
+
+/obj/proc/initialize()
+ return
+
+/obj/proc/updateUsrDialog()
+ var/list/nearby = viewers(1, src)
+ for(var/mob/M in nearby)
+ if ((M.client && M.machine == src))
+ src.attack_hand(M)
+ if (istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot))
+ if (!(usr in nearby))
+ if (usr.client && usr.machine==src) // && M.machine == src is omitted because if we triggered this by using the dialog, it doesn't matter if our machine changed in between triggering it and this - the dialog is probably still supposed to refresh.
+ src.attack_ai(usr)
+
+ // check for TK users
+ //AutoUpdateTK(src)
+ if (istype(usr, /mob/living/carbon/human))
+ if(istype(usr.l_hand, /obj/item/tk_grab) || istype(usr.r_hand, /obj/item/tk_grab/))
+ if(!(usr in nearby))
+ if(usr.client && usr.machine==src)
+ src.attack_hand(usr)
+
+/obj/proc/updateDialog()
+ var/list/nearby = viewers(1, src)
+ for(var/mob/M in nearby)
+ if ((M.client && M.machine == src))
+ src.attack_hand(M)
+ AutoUpdateAI(src)
+ //AutoUpdateTK(src)
+
+/obj/proc/update_icon()
+ return
+
+/obj/item/proc/updateSelfDialog()
+ var/mob/M = src.loc
+ if(istype(M) && M.client && M.machine == src)
+ src.attack_self(M)
+
+
+/obj/proc/alter_health()
+ return 1
+
+/obj/proc/hide(h)
+ return
+
+
+/obj/proc/hear_talk(mob/M as mob, text)
+/*
+ var/mob/mo = locate(/mob) in src
+ if(mo)
+ var/rendered = "[M.name]: [text]"
+ mo.show_message(rendered, 2)
+ */
+ return
\ No newline at end of file
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index ba1fe00fe62..d286eba22da 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -1,5 +1,13 @@
// BEDSHEET BIN
+/obj/structure/bedsheetbin
+ name = "linen bin"
+ desc = "A bin for containing bedsheets. It looks rather cosy."
+ icon = 'icons/obj/items.dmi'
+ icon_state = "bedbin"
+ var/amount = 23.0
+ anchored = 1.0
+
/obj/structure/bedsheetbin/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/bedsheet))
del(W)
diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm
index 9fd89980da4..a9a767b84bc 100644
--- a/code/game/objects/structures/displaycase.dm
+++ b/code/game/objects/structures/displaycase.dm
@@ -1,3 +1,15 @@
+/obj/structure/displaycase
+ name = "Display Case"
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "glassbox1"
+ desc = "A display case for prized possessions. It taunts you to kick it."
+ density = 1
+ anchored = 1
+ unacidable = 1//Dissolving the case would also delete the gun.
+ var/health = 30
+ var/occupied = 1
+ var/destroyed = 0
+
/obj/structure/displaycase/ex_act(severity)
switch(severity)
if (1)
diff --git a/code/game/objects/structures/crates_lockers/closets/extinguisher.dm b/code/game/objects/structures/extinguisher.dm
similarity index 100%
rename from code/game/objects/structures/crates_lockers/closets/extinguisher.dm
rename to code/game/objects/structures/extinguisher.dm
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index 62a509c00bf..76e0240e1f0 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -1,34 +1,65 @@
/obj/structure/falsewall
var/mineral = "metal"
-/obj/structure/falserwall
- var/mineral = "metal"
-
/obj/structure/falsewall/gold
+ name = "gold wall"
+ desc = "A wall with gold plating. Swag"
+ icon_state = ""
mineral = "gold"
/obj/structure/falsewall/silver
+ name = "silver wall"
+ desc = "A wall with silver plating. Shiny"
+ icon_state = ""
mineral = "silver"
/obj/structure/falsewall/diamond
+ name = "diamond wall"
+ desc = "A wall with diamond plating. You monster"
+ icon_state = ""
mineral = "diamond"
/obj/structure/falsewall/uranium
+ name = "uranium wall"
+ desc = "A wall with uranium plating. This is probably a bad idea"
+ icon_state = ""
mineral = "uranium"
var/active = null
var/last_event = 0
/obj/structure/falsewall/plasma
+ name = "plasma wall"
+ desc = "A wall with plasma plating. This is definately a bad idea"
+ icon_state = ""
mineral = "plasma"
+//-----------wtf?-----------start
+/obj/structure/falsewall/bananium
+ name = "bananium wall"
+ desc = "A wall with bananium plating. Honk"
+ icon_state = ""
+
/obj/structure/falsewall/clown
mineral = "clown"
+/obj/structure/falsewall/sand
+ name = "sandstone wall"
+ desc = "A wall with sandstone plating."
+ icon_state = ""
+
/obj/structure/falsewall/sandstone
mineral = "sandstone"
+//------------wtf?------------end
-/*/obj/structure/falsewall/wood
- mineral = "wood"*/
+/obj/structure/falserwall
+ name = "r wall"
+ desc = "A huge chunk of reinforced metal used to seperate rooms."
+ icon = 'icons/turf/walls.dmi'
+ icon_state = "r_wall"
+ density = 1
+ opacity = 1
+ anchored = 1
+ var/mineral = "metal"
/obj/structure/falsewall/attack_hand(mob/user as mob)
if(density)
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 6498103be3b..7b4687bf478 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -12,9 +12,7 @@
layer = 2.9
var/health = 10
var/destroyed = 0
- proc
- healthcheck()
- shock(mob/user, prb)
+ explosion_resistance = 5
ex_act(severity)
switch(severity)
@@ -178,7 +176,7 @@
return
- healthcheck()
+ proc/healthcheck()
if (src.health <= 0)
if (!( src.destroyed ))
src.icon_state = "brokengrille"
@@ -197,7 +195,7 @@
// shock user with probability prb (if all connections & power are working)
// returns 1 if shocked, 0 otherwise
- shock(mob/user, prb)
+ proc/shock(mob/user, prb)
if(!anchored || destroyed) // anchored/destroyed grilles are never connected
return 0
if(!prob(prb))
diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm
index 7900e3f41f9..308103ab7c0 100644
--- a/code/game/objects/structures/kitchen_spike.dm
+++ b/code/game/objects/structures/kitchen_spike.dm
@@ -1,5 +1,16 @@
//////Kitchen Spike
+/obj/structure/kitchenspike
+ name = "a meat spike"
+ icon = 'icons/obj/kitchen.dmi'
+ icon_state = "spike"
+ desc = "A spike for collecting meat from animals"
+ density = 1
+ anchored = 1
+ var/meat = 0
+ var/occupied = 0
+ var/meattype = 0 // 0 - Nothing, 1 - Monkey, 2 - Xeno
+
/obj/structure/kitchenspike
attack_paw(mob/user as mob)
return src.attack_hand(usr)
diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm
index 56ce8cb1e43..12ce9e0b5ff 100644
--- a/code/game/objects/structures/lattice.dm
+++ b/code/game/objects/structures/lattice.dm
@@ -1,3 +1,37 @@
+/obj/structure/lattice
+ desc = "A lightweight support lattice."
+ name = "lattice"
+ icon = 'icons/obj/structures.dmi'
+ icon_state = "latticefull"
+ density = 0
+ anchored = 1.0
+ layer = 2.3 //under pipes
+ // flags = CONDUCT
+
+/obj/structure/lattice/New()
+ ..()
+ if(!(istype(src.loc, /turf/space)))
+ del(src)
+ for(var/obj/structure/lattice/LAT in src.loc)
+ if(LAT != src)
+ del(LAT)
+ icon = 'icons/obj/smoothlattice.dmi'
+ icon_state = "latticeblank"
+ updateOverlays()
+ for (var/dir in cardinal)
+ var/obj/structure/lattice/L
+ if(locate(/obj/structure/lattice, get_step(src, dir)))
+ L = locate(/obj/structure/lattice, get_step(src, dir))
+ L.updateOverlays()
+
+/obj/structure/lattice/Del()
+ for (var/dir in cardinal)
+ var/obj/structure/lattice/L
+ if(locate(/obj/structure/lattice, get_step(src, dir)))
+ L = locate(/obj/structure/lattice, get_step(src, dir))
+ L.updateOverlays(src.loc)
+ ..()
+
/obj/structure/lattice/blob_act()
del(src)
return
@@ -28,4 +62,22 @@
new /obj/item/stack/rods(src.loc)
del(src)
- return
\ No newline at end of file
+ return
+
+/obj/structure/lattice/proc/updateOverlays()
+ //if(!(istype(src.loc, /turf/space)))
+ // del(src)
+ spawn(1)
+ overlays = list()
+
+ var/dir_sum = 0
+
+ for (var/direction in cardinal)
+ if(locate(/obj/structure/lattice, get_step(src, direction)))
+ dir_sum += direction
+ else
+ if(!(istype(get_step(src, direction), /turf/space)))
+ dir_sum += direction
+
+ icon_state = "lattice[dir_sum]"
+ return
\ No newline at end of file
diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm
index 530aeddf96a..b59e3a28768 100644
--- a/code/game/objects/structures/mop_bucket.dm
+++ b/code/game/objects/structures/mop_bucket.dm
@@ -1,3 +1,14 @@
+/obj/structure/mopbucket
+ desc = "Fill it with water, but don't forget a mop!"
+ name = "mop bucket"
+ icon = 'icons/obj/janitor.dmi'
+ icon_state = "mopbucket"
+ density = 1
+ flags = FPRINT
+ pressure_resistance = ONE_ATMOSPHERE
+ flags = FPRINT | TABLEPASS | OPENCONTAINER
+ var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite
+
/obj/structure/mopbucket/New()
var/datum/reagents/R = new/datum/reagents(100)
reagents = R
diff --git a/code/game/machinery/morgue.dm b/code/game/objects/structures/morgue.dm
similarity index 85%
rename from code/game/machinery/morgue.dm
rename to code/game/objects/structures/morgue.dm
index c864eaadac4..6bb2cf69ab9 100644
--- a/code/game/machinery/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -1,3 +1,24 @@
+/* Morgue stuff
+ * Contains:
+ * Morgue
+ * Morgue trays
+ * Creamatorium
+ * Creamatorium trays
+ */
+
+/*
+ * Morgue
+ */
+
+/obj/structure/morgue
+ name = "morgue"
+ desc = "Used to keep bodies in untill someone fetches them."
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "morgue1"
+ density = 1
+ var/obj/structure/m_tray/connected = null
+ anchored = 1.0
+
/obj/structure/morgue/proc/update()
if (src.connected)
src.icon_state = "morgue0"
@@ -99,6 +120,20 @@
del(src.connected)
return
+
+/*
+ * Morgue tray
+ */
+/obj/structure/m_tray
+ name = "morgue tray"
+ desc = "Apply corpse before closing."
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "morguet"
+ density = 1
+ layer = 2.0
+ var/obj/structure/morgue/connected = null
+ anchored = 1.0
+
/obj/structure/m_tray/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if (istype(mover, /obj/item/weapon/dummy))
return 1
@@ -134,6 +169,23 @@
B << text("\red [] stuffs [] into []!", user, O, src)
return
+
+/*
+ * Crematorium
+ */
+
+/obj/structure/crematorium
+ name = "crematorium"
+ desc = "A human incinerator. Works well on barbeque nights."
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "crema1"
+ density = 1
+ var/obj/structure/c_tray/connected = null
+ anchored = 1.0
+ var/cremating = 0
+ var/id = 1
+ var/locked = 0
+
/obj/structure/crematorium/proc/update()
if (src.connected)
src.icon_state = "crema0"
@@ -287,6 +339,20 @@
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
return
+
+/*
+ * Crematorium tray
+ */
+/obj/structure/c_tray
+ name = "crematorium tray"
+ desc = "Apply body before burning."
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "cremat"
+ density = 1
+ layer = 2.0
+ var/obj/structure/crematorium/connected = null
+ anchored = 1.0
+
/obj/structure/c_tray/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if (istype(mover, /obj/item/weapon/dummy))
return 1
diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm
index 5bcece15ea2..edc28e5041b 100644
--- a/code/game/objects/structures/musician.dm
+++ b/code/game/objects/structures/musician.dm
@@ -17,470 +17,313 @@
var/edit = 1
var/repeat = 0
- proc
- playnote(var/note as text)
- //world << "Note: [note]"
- var/soundfile
- /*BYOND loads resource files at compile time if they are ''. This means you can't really manipulate them dynamically.
- Tried doing it dynamically at first but its more trouble than its worth. Would have saved many lines tho.*/
- switch(note)
- if("Cn1")
- soundfile = 'sound/piano/Cn1.ogg'
- if("C#1")
- soundfile = 'sound/piano/C#1.ogg'
- if("Db1")
- soundfile = 'sound/piano/Db1.ogg'
- if("Dn1")
- soundfile = 'sound/piano/Dn1.ogg'
- if("D#1")
- soundfile = 'sound/piano/D#1.ogg'
- if("Eb1")
- soundfile = 'sound/piano/Eb1.ogg'
- if("En1")
- soundfile = 'sound/piano/En1.ogg'
- if("E#1")
- soundfile = 'sound/piano/E#1.ogg'
- if("Fb1")
- soundfile = 'sound/piano/Fb1.ogg'
- if("Fn1")
- soundfile = 'sound/piano/Fn1.ogg'
- if("F#1")
- soundfile = 'sound/piano/F#1.ogg'
- if("Gb1")
- soundfile = 'sound/piano/Gb1.ogg'
- if("Gn1")
- soundfile = 'sound/piano/Gn1.ogg'
- if("G#1")
- soundfile = 'sound/piano/G#1.ogg'
- if("Ab1")
- soundfile = 'sound/piano/Ab1.ogg'
- if("An1")
- soundfile = 'sound/piano/An1.ogg'
- if("A#1")
- soundfile = 'sound/piano/A#1.ogg'
- if("Bb1")
- soundfile = 'sound/piano/Bb1.ogg'
- if("Bn1")
- soundfile = 'sound/piano/Bn1.ogg'
- if("B#1")
- soundfile = 'sound/piano/B#1.ogg'
- if("Cb2")
- soundfile = 'sound/piano/Cb2.ogg'
- if("Cn2")
- soundfile = 'sound/piano/Cn2.ogg'
- if("C#2")
- soundfile = 'sound/piano/C#2.ogg'
- if("Db2")
- soundfile = 'sound/piano/Db2.ogg'
- if("Dn2")
- soundfile = 'sound/piano/Dn2.ogg'
- if("D#2")
- soundfile = 'sound/piano/D#2.ogg'
- if("Eb2")
- soundfile = 'sound/piano/Eb2.ogg'
- if("En2")
- soundfile = 'sound/piano/En2.ogg'
- if("E#2")
- soundfile = 'sound/piano/E#2.ogg'
- if("Fb2")
- soundfile = 'sound/piano/Fb2.ogg'
- if("Fn2")
- soundfile = 'sound/piano/Fn2.ogg'
- if("F#2")
- soundfile = 'sound/piano/F#2.ogg'
- if("Gb2")
- soundfile = 'sound/piano/Gb2.ogg'
- if("Gn2")
- soundfile = 'sound/piano/Gn2.ogg'
- if("G#2")
- soundfile = 'sound/piano/G#2.ogg'
- if("Ab2")
- soundfile = 'sound/piano/Ab2.ogg'
- if("An2")
- soundfile = 'sound/piano/An2.ogg'
- if("A#2")
- soundfile = 'sound/piano/A#2.ogg'
- if("Bb2")
- soundfile = 'sound/piano/Bb2.ogg'
- if("Bn2")
- soundfile = 'sound/piano/Bn2.ogg'
- if("B#2")
- soundfile = 'sound/piano/B#2.ogg'
- if("Cb3")
- soundfile = 'sound/piano/Cb3.ogg'
- if("Cn3")
- soundfile = 'sound/piano/Cn3.ogg'
- if("C#3")
- soundfile = 'sound/piano/C#3.ogg'
- if("Db3")
- soundfile = 'sound/piano/Db3.ogg'
- if("Dn3")
- soundfile = 'sound/piano/Dn3.ogg'
- if("D#3")
- soundfile = 'sound/piano/D#3.ogg'
- if("Eb3")
- soundfile = 'sound/piano/Eb3.ogg'
- if("En3")
- soundfile = 'sound/piano/En3.ogg'
- if("E#3")
- soundfile = 'sound/piano/E#3.ogg'
- if("Fb3")
- soundfile = 'sound/piano/Fb3.ogg'
- if("Fn3")
- soundfile = 'sound/piano/Fn3.ogg'
- if("F#3")
- soundfile = 'sound/piano/F#3.ogg'
- if("Gb3")
- soundfile = 'sound/piano/Gb3.ogg'
- if("Gn3")
- soundfile = 'sound/piano/Gn3.ogg'
- if("G#3")
- soundfile = 'sound/piano/G#3.ogg'
- if("Ab3")
- soundfile = 'sound/piano/Ab3.ogg'
- if("An3")
- soundfile = 'sound/piano/An3.ogg'
- if("A#3")
- soundfile = 'sound/piano/A#3.ogg'
- if("Bb3")
- soundfile = 'sound/piano/Bb3.ogg'
- if("Bn3")
- soundfile = 'sound/piano/Bn3.ogg'
- if("B#3")
- soundfile = 'sound/piano/B#3.ogg'
- if("Cb4")
- soundfile = 'sound/piano/Cb4.ogg'
- if("Cn4")
- soundfile = 'sound/piano/Cn4.ogg'
- if("C#4")
- soundfile = 'sound/piano/C#4.ogg'
- if("Db4")
- soundfile = 'sound/piano/Db4.ogg'
- if("Dn4")
- soundfile = 'sound/piano/Dn4.ogg'
- if("D#4")
- soundfile = 'sound/piano/D#4.ogg'
- if("Eb4")
- soundfile = 'sound/piano/Eb4.ogg'
- if("En4")
- soundfile = 'sound/piano/En4.ogg'
- if("E#4")
- soundfile = 'sound/piano/E#4.ogg'
- if("Fb4")
- soundfile = 'sound/piano/Fb4.ogg'
- if("Fn4")
- soundfile = 'sound/piano/Fn4.ogg'
- if("F#4")
- soundfile = 'sound/piano/F#4.ogg'
- if("Gb4")
- soundfile = 'sound/piano/Gb4.ogg'
- if("Gn4")
- soundfile = 'sound/piano/Gn4.ogg'
- if("G#4")
- soundfile = 'sound/piano/G#4.ogg'
- if("Ab4")
- soundfile = 'sound/piano/Ab4.ogg'
- if("An4")
- soundfile = 'sound/piano/An4.ogg'
- if("A#4")
- soundfile = 'sound/piano/A#4.ogg'
- if("Bb4")
- soundfile = 'sound/piano/Bb4.ogg'
- if("Bn4")
- soundfile = 'sound/piano/Bn4.ogg'
- if("B#4")
- soundfile = 'sound/piano/B#4.ogg'
- if("Cb5")
- soundfile = 'sound/piano/Cb5.ogg'
- if("Cn5")
- soundfile = 'sound/piano/Cn5.ogg'
- if("C#5")
- soundfile = 'sound/piano/C#5.ogg'
- if("Db5")
- soundfile = 'sound/piano/Db5.ogg'
- if("Dn5")
- soundfile = 'sound/piano/Dn5.ogg'
- if("D#5")
- soundfile = 'sound/piano/D#5.ogg'
- if("Eb5")
- soundfile = 'sound/piano/Eb5.ogg'
- if("En5")
- soundfile = 'sound/piano/En5.ogg'
- if("E#5")
- soundfile = 'sound/piano/E#5.ogg'
- if("Fb5")
- soundfile = 'sound/piano/Fb5.ogg'
- if("Fn5")
- soundfile = 'sound/piano/Fn5.ogg'
- if("F#5")
- soundfile = 'sound/piano/F#5.ogg'
- if("Gb5")
- soundfile = 'sound/piano/Gb5.ogg'
- if("Gn5")
- soundfile = 'sound/piano/Gn5.ogg'
- if("G#5")
- soundfile = 'sound/piano/G#5.ogg'
- if("Ab5")
- soundfile = 'sound/piano/Ab5.ogg'
- if("An5")
- soundfile = 'sound/piano/An5.ogg'
- if("A#5")
- soundfile = 'sound/piano/A#5.ogg'
- if("Bb5")
- soundfile = 'sound/piano/Bb5.ogg'
- if("Bn5")
- soundfile = 'sound/piano/Bn5.ogg'
- if("B#5")
- soundfile = 'sound/piano/B#5.ogg'
- if("Cb6")
- soundfile = 'sound/piano/Cb6.ogg'
- if("Cn6")
- soundfile = 'sound/piano/Cn6.ogg'
- if("C#6")
- soundfile = 'sound/piano/C#6.ogg'
- if("Db6")
- soundfile = 'sound/piano/Db6.ogg'
- if("Dn6")
- soundfile = 'sound/piano/Dn6.ogg'
- if("D#6")
- soundfile = 'sound/piano/D#6.ogg'
- if("Eb6")
- soundfile = 'sound/piano/Eb6.ogg'
- if("En6")
- soundfile = 'sound/piano/En6.ogg'
- if("E#6")
- soundfile = 'sound/piano/E#6.ogg'
- if("Fb6")
- soundfile = 'sound/piano/Fb6.ogg'
- if("Fn6")
- soundfile = 'sound/piano/Fn6.ogg'
- if("F#6")
- soundfile = 'sound/piano/F#6.ogg'
- if("Gb6")
- soundfile = 'sound/piano/Gb6.ogg'
- if("Gn6")
- soundfile = 'sound/piano/Gn6.ogg'
- if("G#6")
- soundfile = 'sound/piano/G#6.ogg'
- if("Ab6")
- soundfile = 'sound/piano/Ab6.ogg'
- if("An6")
- soundfile = 'sound/piano/An6.ogg'
- if("A#6")
- soundfile = 'sound/piano/A#6.ogg'
- if("Bb6")
- soundfile = 'sound/piano/Bb6.ogg'
- if("Bn6")
- soundfile = 'sound/piano/Bn6.ogg'
- if("B#6")
- soundfile = 'sound/piano/B#6.ogg'
- if("Cb7")
- soundfile = 'sound/piano/Cb7.ogg'
- if("Cn7")
- soundfile = 'sound/piano/Cn7.ogg'
- if("C#7")
- soundfile = 'sound/piano/C#7.ogg'
- if("Db7")
- soundfile = 'sound/piano/Db7.ogg'
- if("Dn7")
- soundfile = 'sound/piano/Dn7.ogg'
- if("D#7")
- soundfile = 'sound/piano/D#7.ogg'
- if("Eb7")
- soundfile = 'sound/piano/Eb7.ogg'
- if("En7")
- soundfile = 'sound/piano/En7.ogg'
- if("E#7")
- soundfile = 'sound/piano/E#7.ogg'
- if("Fb7")
- soundfile = 'sound/piano/Fb7.ogg'
- if("Fn7")
- soundfile = 'sound/piano/Fn7.ogg'
- if("F#7")
- soundfile = 'sound/piano/F#7.ogg'
- if("Gb7")
- soundfile = 'sound/piano/Gb7.ogg'
- if("Gn7")
- soundfile = 'sound/piano/Gn7.ogg'
- if("G#7")
- soundfile = 'sound/piano/G#7.ogg'
- if("Ab7")
- soundfile = 'sound/piano/Ab7.ogg'
- if("An7")
- soundfile = 'sound/piano/An7.ogg'
- if("A#7")
- soundfile = 'sound/piano/A#7.ogg'
- if("Bb7")
- soundfile = 'sound/piano/Bb7.ogg'
- if("Bn7")
- soundfile = 'sound/piano/Bn7.ogg'
- if("B#7")
- soundfile = 'sound/piano/B#7.ogg'
- if("Cb8")
- soundfile = 'sound/piano/Cb8.ogg'
- if("Cn8")
- soundfile = 'sound/piano/Cn8.ogg'
- if("C#8")
- soundfile = 'sound/piano/C#8.ogg'
- if("Db8")
- soundfile = 'sound/piano/Db8.ogg'
- if("Dn8")
- soundfile = 'sound/piano/Dn8.ogg'
- if("D#8")
- soundfile = 'sound/piano/D#8.ogg'
- if("Eb8")
- soundfile = 'sound/piano/Eb8.ogg'
- if("En8")
- soundfile = 'sound/piano/En8.ogg'
- if("E#8")
- soundfile = 'sound/piano/E#8.ogg'
- if("Fb8")
- soundfile = 'sound/piano/Fb8.ogg'
- if("Fn8")
- soundfile = 'sound/piano/Fn8.ogg'
- if("F#8")
- soundfile = 'sound/piano/F#8.ogg'
- if("Gb8")
- soundfile = 'sound/piano/Gb8.ogg'
- if("Gn8")
- soundfile = 'sound/piano/Gn8.ogg'
- if("G#8")
- soundfile = 'sound/piano/G#8.ogg'
- if("Ab8")
- soundfile = 'sound/piano/Ab8.ogg'
- if("An8")
- soundfile = 'sound/piano/An8.ogg'
- if("A#8")
- soundfile = 'sound/piano/A#8.ogg'
- if("Bb8")
- soundfile = 'sound/piano/Bb8.ogg'
- if("Bn8")
- soundfile = 'sound/piano/Bn8.ogg'
- if("B#8")
- soundfile = 'sound/piano/B#8.ogg'
- if("Cb9")
- soundfile = 'sound/piano/Cb9.ogg'
- if("Cn9")
- soundfile = 'sound/piano/Cn9.ogg'
- else
- return
+/obj/structure/device/piano/New()
+ if(prob(50))
+ name = "space minimoog"
+ desc = "This is a minimoog, like a space piano, but more spacey!"
+ icon_state = "minimoog"
+ else
+ name = "space piano"
+ desc = "This is a space piano, like a regular piano, but always in tune! Even if the musician isn't."
+ icon_state = "piano"
- for(var/mob/M in hearers(15, src))
- M << sound(soundfile)
+/obj/structure/device/piano/proc/playnote(var/note as text)
+ //world << "Note: [note]"
+ var/soundfile
+ /*BYOND loads resource files at compile time if they are ''. This means you can't really manipulate them dynamically.
+ Tried doing it dynamically at first but its more trouble than its worth. Would have saved many lines tho.*/
+ switch(note)
+ if("Cn1") soundfile = 'sound/piano/Cn1.ogg'
+ if("C#1") soundfile = 'sound/piano/C#1.ogg'
+ if("Db1") soundfile = 'sound/piano/Db1.ogg'
+ if("Dn1") soundfile = 'sound/piano/Dn1.ogg'
+ if("D#1") soundfile = 'sound/piano/D#1.ogg'
+ if("Eb1") soundfile = 'sound/piano/Eb1.ogg'
+ if("En1") soundfile = 'sound/piano/En1.ogg'
+ if("E#1") soundfile = 'sound/piano/E#1.ogg'
+ if("Fb1") soundfile = 'sound/piano/Fb1.ogg'
+ if("Fn1") soundfile = 'sound/piano/Fn1.ogg'
+ if("F#1") soundfile = 'sound/piano/F#1.ogg'
+ if("Gb1") soundfile = 'sound/piano/Gb1.ogg'
+ if("Gn1") soundfile = 'sound/piano/Gn1.ogg'
+ if("G#1") soundfile = 'sound/piano/G#1.ogg'
+ if("Ab1") soundfile = 'sound/piano/Ab1.ogg'
+ if("An1") soundfile = 'sound/piano/An1.ogg'
+ if("A#1") soundfile = 'sound/piano/A#1.ogg'
+ if("Bb1") soundfile = 'sound/piano/Bb1.ogg'
+ if("Bn1") soundfile = 'sound/piano/Bn1.ogg'
+ if("B#1") soundfile = 'sound/piano/B#1.ogg'
+ if("Cb2") soundfile = 'sound/piano/Cb2.ogg'
+ if("Cn2") soundfile = 'sound/piano/Cn2.ogg'
+ if("C#2") soundfile = 'sound/piano/C#2.ogg'
+ if("Db2") soundfile = 'sound/piano/Db2.ogg'
+ if("Dn2") soundfile = 'sound/piano/Dn2.ogg'
+ if("D#2") soundfile = 'sound/piano/D#2.ogg'
+ if("Eb2") soundfile = 'sound/piano/Eb2.ogg'
+ if("En2") soundfile = 'sound/piano/En2.ogg'
+ if("E#2") soundfile = 'sound/piano/E#2.ogg'
+ if("Fb2") soundfile = 'sound/piano/Fb2.ogg'
+ if("Fn2") soundfile = 'sound/piano/Fn2.ogg'
+ if("F#2") soundfile = 'sound/piano/F#2.ogg'
+ if("Gb2") soundfile = 'sound/piano/Gb2.ogg'
+ if("Gn2") soundfile = 'sound/piano/Gn2.ogg'
+ if("G#2") soundfile = 'sound/piano/G#2.ogg'
+ if("Ab2") soundfile = 'sound/piano/Ab2.ogg'
+ if("An2") soundfile = 'sound/piano/An2.ogg'
+ if("A#2") soundfile = 'sound/piano/A#2.ogg'
+ if("Bb2") soundfile = 'sound/piano/Bb2.ogg'
+ if("Bn2") soundfile = 'sound/piano/Bn2.ogg'
+ if("B#2") soundfile = 'sound/piano/B#2.ogg'
+ if("Cb3") soundfile = 'sound/piano/Cb3.ogg'
+ if("Cn3") soundfile = 'sound/piano/Cn3.ogg'
+ if("C#3") soundfile = 'sound/piano/C#3.ogg'
+ if("Db3") soundfile = 'sound/piano/Db3.ogg'
+ if("Dn3") soundfile = 'sound/piano/Dn3.ogg'
+ if("D#3") soundfile = 'sound/piano/D#3.ogg'
+ if("Eb3") soundfile = 'sound/piano/Eb3.ogg'
+ if("En3") soundfile = 'sound/piano/En3.ogg'
+ if("E#3") soundfile = 'sound/piano/E#3.ogg'
+ if("Fb3") soundfile = 'sound/piano/Fb3.ogg'
+ if("Fn3") soundfile = 'sound/piano/Fn3.ogg'
+ if("F#3") soundfile = 'sound/piano/F#3.ogg'
+ if("Gb3") soundfile = 'sound/piano/Gb3.ogg'
+ if("Gn3") soundfile = 'sound/piano/Gn3.ogg'
+ if("G#3") soundfile = 'sound/piano/G#3.ogg'
+ if("Ab3") soundfile = 'sound/piano/Ab3.ogg'
+ if("An3") soundfile = 'sound/piano/An3.ogg'
+ if("A#3") soundfile = 'sound/piano/A#3.ogg'
+ if("Bb3") soundfile = 'sound/piano/Bb3.ogg'
+ if("Bn3") soundfile = 'sound/piano/Bn3.ogg'
+ if("B#3") soundfile = 'sound/piano/B#3.ogg'
+ if("Cb4") soundfile = 'sound/piano/Cb4.ogg'
+ if("Cn4") soundfile = 'sound/piano/Cn4.ogg'
+ if("C#4") soundfile = 'sound/piano/C#4.ogg'
+ if("Db4") soundfile = 'sound/piano/Db4.ogg'
+ if("Dn4") soundfile = 'sound/piano/Dn4.ogg'
+ if("D#4") soundfile = 'sound/piano/D#4.ogg'
+ if("Eb4") soundfile = 'sound/piano/Eb4.ogg'
+ if("En4") soundfile = 'sound/piano/En4.ogg'
+ if("E#4") soundfile = 'sound/piano/E#4.ogg'
+ if("Fb4") soundfile = 'sound/piano/Fb4.ogg'
+ if("Fn4") soundfile = 'sound/piano/Fn4.ogg'
+ if("F#4") soundfile = 'sound/piano/F#4.ogg'
+ if("Gb4") soundfile = 'sound/piano/Gb4.ogg'
+ if("Gn4") soundfile = 'sound/piano/Gn4.ogg'
+ if("G#4") soundfile = 'sound/piano/G#4.ogg'
+ if("Ab4") soundfile = 'sound/piano/Ab4.ogg'
+ if("An4") soundfile = 'sound/piano/An4.ogg'
+ if("A#4") soundfile = 'sound/piano/A#4.ogg'
+ if("Bb4") soundfile = 'sound/piano/Bb4.ogg'
+ if("Bn4") soundfile = 'sound/piano/Bn4.ogg'
+ if("B#4") soundfile = 'sound/piano/B#4.ogg'
+ if("Cb5") soundfile = 'sound/piano/Cb5.ogg'
+ if("Cn5") soundfile = 'sound/piano/Cn5.ogg'
+ if("C#5") soundfile = 'sound/piano/C#5.ogg'
+ if("Db5") soundfile = 'sound/piano/Db5.ogg'
+ if("Dn5") soundfile = 'sound/piano/Dn5.ogg'
+ if("D#5") soundfile = 'sound/piano/D#5.ogg'
+ if("Eb5") soundfile = 'sound/piano/Eb5.ogg'
+ if("En5") soundfile = 'sound/piano/En5.ogg'
+ if("E#5") soundfile = 'sound/piano/E#5.ogg'
+ if("Fb5") soundfile = 'sound/piano/Fb5.ogg'
+ if("Fn5") soundfile = 'sound/piano/Fn5.ogg'
+ if("F#5") soundfile = 'sound/piano/F#5.ogg'
+ if("Gb5") soundfile = 'sound/piano/Gb5.ogg'
+ if("Gn5") soundfile = 'sound/piano/Gn5.ogg'
+ if("G#5") soundfile = 'sound/piano/G#5.ogg'
+ if("Ab5") soundfile = 'sound/piano/Ab5.ogg'
+ if("An5") soundfile = 'sound/piano/An5.ogg'
+ if("A#5") soundfile = 'sound/piano/A#5.ogg'
+ if("Bb5") soundfile = 'sound/piano/Bb5.ogg'
+ if("Bn5") soundfile = 'sound/piano/Bn5.ogg'
+ if("B#5") soundfile = 'sound/piano/B#5.ogg'
+ if("Cb6") soundfile = 'sound/piano/Cb6.ogg'
+ if("Cn6") soundfile = 'sound/piano/Cn6.ogg'
+ if("C#6") soundfile = 'sound/piano/C#6.ogg'
+ if("Db6") soundfile = 'sound/piano/Db6.ogg'
+ if("Dn6") soundfile = 'sound/piano/Dn6.ogg'
+ if("D#6") soundfile = 'sound/piano/D#6.ogg'
+ if("Eb6") soundfile = 'sound/piano/Eb6.ogg'
+ if("En6") soundfile = 'sound/piano/En6.ogg'
+ if("E#6") soundfile = 'sound/piano/E#6.ogg'
+ if("Fb6") soundfile = 'sound/piano/Fb6.ogg'
+ if("Fn6") soundfile = 'sound/piano/Fn6.ogg'
+ if("F#6") soundfile = 'sound/piano/F#6.ogg'
+ if("Gb6") soundfile = 'sound/piano/Gb6.ogg'
+ if("Gn6") soundfile = 'sound/piano/Gn6.ogg'
+ if("G#6") soundfile = 'sound/piano/G#6.ogg'
+ if("Ab6") soundfile = 'sound/piano/Ab6.ogg'
+ if("An6") soundfile = 'sound/piano/An6.ogg'
+ if("A#6") soundfile = 'sound/piano/A#6.ogg'
+ if("Bb6") soundfile = 'sound/piano/Bb6.ogg'
+ if("Bn6") soundfile = 'sound/piano/Bn6.ogg'
+ if("B#6") soundfile = 'sound/piano/B#6.ogg'
+ if("Cb7") soundfile = 'sound/piano/Cb7.ogg'
+ if("Cn7") soundfile = 'sound/piano/Cn7.ogg'
+ if("C#7") soundfile = 'sound/piano/C#7.ogg'
+ if("Db7") soundfile = 'sound/piano/Db7.ogg'
+ if("Dn7") soundfile = 'sound/piano/Dn7.ogg'
+ if("D#7") soundfile = 'sound/piano/D#7.ogg'
+ if("Eb7") soundfile = 'sound/piano/Eb7.ogg'
+ if("En7") soundfile = 'sound/piano/En7.ogg'
+ if("E#7") soundfile = 'sound/piano/E#7.ogg'
+ if("Fb7") soundfile = 'sound/piano/Fb7.ogg'
+ if("Fn7") soundfile = 'sound/piano/Fn7.ogg'
+ if("F#7") soundfile = 'sound/piano/F#7.ogg'
+ if("Gb7") soundfile = 'sound/piano/Gb7.ogg'
+ if("Gn7") soundfile = 'sound/piano/Gn7.ogg'
+ if("G#7") soundfile = 'sound/piano/G#7.ogg'
+ if("Ab7") soundfile = 'sound/piano/Ab7.ogg'
+ if("An7") soundfile = 'sound/piano/An7.ogg'
+ if("A#7") soundfile = 'sound/piano/A#7.ogg'
+ if("Bb7") soundfile = 'sound/piano/Bb7.ogg'
+ if("Bn7") soundfile = 'sound/piano/Bn7.ogg'
+ if("B#7") soundfile = 'sound/piano/B#7.ogg'
+ if("Cb8") soundfile = 'sound/piano/Cb8.ogg'
+ if("Cn8") soundfile = 'sound/piano/Cn8.ogg'
+ if("C#8") soundfile = 'sound/piano/C#8.ogg'
+ if("Db8") soundfile = 'sound/piano/Db8.ogg'
+ if("Dn8") soundfile = 'sound/piano/Dn8.ogg'
+ if("D#8") soundfile = 'sound/piano/D#8.ogg'
+ if("Eb8") soundfile = 'sound/piano/Eb8.ogg'
+ if("En8") soundfile = 'sound/piano/En8.ogg'
+ if("E#8") soundfile = 'sound/piano/E#8.ogg'
+ if("Fb8") soundfile = 'sound/piano/Fb8.ogg'
+ if("Fn8") soundfile = 'sound/piano/Fn8.ogg'
+ if("F#8") soundfile = 'sound/piano/F#8.ogg'
+ if("Gb8") soundfile = 'sound/piano/Gb8.ogg'
+ if("Gn8") soundfile = 'sound/piano/Gn8.ogg'
+ if("G#8") soundfile = 'sound/piano/G#8.ogg'
+ if("Ab8") soundfile = 'sound/piano/Ab8.ogg'
+ if("An8") soundfile = 'sound/piano/An8.ogg'
+ if("A#8") soundfile = 'sound/piano/A#8.ogg'
+ if("Bb8") soundfile = 'sound/piano/Bb8.ogg'
+ if("Bn8") soundfile = 'sound/piano/Bn8.ogg'
+ if("B#8") soundfile = 'sound/piano/B#8.ogg'
+ if("Cb9") soundfile = 'sound/piano/Cb9.ogg'
+ if("Cn9") soundfile = 'sound/piano/Cn9.ogg'
+ else return
- playsong()
- do
- var/cur_oct[7]
- var/cur_acc[7]
- for(var/i = 1 to 7)
- cur_oct[i] = "3"
- cur_acc[i] = "n"
+ hearers(15, src) << sound(soundfile)
- for(var/line in song.lines)
- //world << line
- for(var/beat in dd_text2list(lowertext(line), ","))
- //world << "beat: [beat]"
- var/list/notes = dd_text2list(beat, "/")
- for(var/note in dd_text2list(notes[1], "-"))
- //world << "note: [note]"
- if(!playing || !anchored)//If the piano is playing, or is loose
- playing = 0
- return
- if(lentext(note) == 0)
- continue
- //world << "Parse: [copytext(note,1,2)]"
- var/cur_note = text2ascii(note) - 96
- if(cur_note < 1 || cur_note > 7)
- continue
- for(var/i=2 to lentext(note))
- var/ni = copytext(note,i,i+1)
- if(!text2num(ni))
- if(ni == "#" || ni == "b" || ni == "n")
- cur_acc[cur_note] = ni
- else if(ni == "s")
- cur_acc[cur_note] = "#" // so shift is never required
- else
- cur_oct[cur_note] = ni
- playnote(uppertext(copytext(note,1,2)) + cur_acc[cur_note] + cur_oct[cur_note])
- if(notes.len >= 2 && text2num(notes[2]))
- sleep(song.tempo / text2num(notes[2]))
+/obj/structure/device/piano/proc/playsong()
+ do
+ var/cur_oct[7]
+ var/cur_acc[7]
+ for(var/i = 1 to 7)
+ cur_oct[i] = "3"
+ cur_acc[i] = "n"
+
+ for(var/line in song.lines)
+ //world << line
+ for(var/beat in dd_text2list(lowertext(line), ","))
+ //world << "beat: [beat]"
+ var/list/notes = dd_text2list(beat, "/")
+ for(var/note in dd_text2list(notes[1], "-"))
+ //world << "note: [note]"
+ if(!playing || !anchored)//If the piano is playing, or is loose
+ playing = 0
+ return
+ if(lentext(note) == 0)
+ continue
+ //world << "Parse: [copytext(note,1,2)]"
+ var/cur_note = text2ascii(note) - 96
+ if(cur_note < 1 || cur_note > 7)
+ continue
+ for(var/i=2 to lentext(note))
+ var/ni = copytext(note,i,i+1)
+ if(!text2num(ni))
+ if(ni == "#" || ni == "b" || ni == "n")
+ cur_acc[cur_note] = ni
+ else if(ni == "s")
+ cur_acc[cur_note] = "#" // so shift is never required
else
- sleep(song.tempo)
- if(repeat > 0)
- repeat-- //Infinite loops are baaaad.
- while(repeat > 0)
- playing = 0
- updateUsrDialog()
+ cur_oct[cur_note] = ni
+ playnote(uppertext(copytext(note,1,2)) + cur_acc[cur_note] + cur_oct[cur_note])
+ if(notes.len >= 2 && text2num(notes[2]))
+ sleep(song.tempo / text2num(notes[2]))
+ else
+ sleep(song.tempo)
+ if(repeat > 0)
+ repeat-- //Infinite loops are baaaad.
+ while(repeat > 0)
+ playing = 0
+ updateUsrDialog()
- attack_hand(var/mob/user as mob)
- if(!anchored)
- return
+/obj/structure/device/piano/attack_hand(var/mob/user as mob)
+ if(!anchored)
+ return
- usr.machine = src
- var/dat = "Piano"
+ usr.machine = src
+ var/dat = "Piano"
+ if(song)
+ if(song.lines.len > 0 && !(playing))
+ dat += "Play Song
"
+ dat += "Repeat Song: [repeat] times.
"
+ if(playing)
+ dat += "Stop Playing
"
+ dat += "Repeats left: [repeat].
"
+ if(!edit)
+ dat += "Show Editor
"
+ else
+ dat += "Hide Editor
"
+ dat += "Start a New Song
"
+ dat += "Import a Song
"
if(song)
- if(song.lines.len > 0 && !(playing))
- dat += "Play Song
"
- dat += "Repeat Song: [repeat] times.
"
- if(playing)
- dat += "Stop Playing
"
- dat += "Repeats left: [repeat].
"
- if(!edit)
- dat += "Show Editor
"
+ var/calctempo = (10/song.tempo)*60
+ dat += "Tempo : -- [calctempo] BPM ++
"
+ var/linecount = 0
+ for(var/line in song.lines)
+ linecount += 1
+ dat += "Line [linecount]: [line] Delete Line Modify Line
"
+ dat += "Add Line
"
+ if(help)
+ dat += "Hide Help
"
+ dat += {"
+ Lines are a series of chords, separated by commas (,), each with notes seperated by hyphens (-).
+ Every note in a chord will play together, with chord timed by the tempo.
+
+ Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.
+ By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.
+ Example: C,D,E,F,G,A,B will play a C major scale.
+ After a note has an accidental placed, it will be remembered: C,C4,C,C3 is C3,C4,C4,C3
+ Chords can be played simply by seperating each note with a hyphon: A-C#,Cn-E,E-G#,Gn-B
+ A pause may be denoted by an empty chord: C,E,,C,G
+ To make a chord be a different time, end it with /x, where the chord length will be length
+ defined by tempo / x: C,G/2,E/4
+ Combined, an example is: E-E4/4,/2,G#/8,B/8,E3-E4/4
+
+ Lines may be up to 50 characters.
+ A song may only contain up to 50 lines.
+ "}
else
- dat += "Hide Editor
"
- dat += "Start a New Song
"
- dat += "Import a Song
"
- if(song)
- var/calctempo = (10/song.tempo)*60
- dat += "Tempo : -- [calctempo] BPM ++
"
- var/linecount = 0
- for(var/line in song.lines)
- linecount += 1
- dat += "Line [linecount]: [line] Delete Line Modify Line
"
- dat += "Add Line
"
- if(help)
- dat += "Hide Help
"
- dat += {"
- Lines are a series of chords, separated by commas (,), each with notes seperated by hyphens (-).
- Every note in a chord will play together, with chord timed by the tempo.
-
- Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.
- By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.
- Example: C,D,E,F,G,A,B will play a C major scale.
- After a note has an accidental placed, it will be remembered: C,C4,C,C3 is C3,C4,C4,C3
- Chords can be played simply by seperating each note with a hyphon: A-C#,Cn-E,E-G#,Gn-B
- A pause may be denoted by an empty chord: C,E,,C,G
- To make a chord be a different time, end it with /x, where the chord length will be length
- defined by tempo / x: C,G/2,E/4
- Combined, an example is: E-E4/4,/2,G#/8,B/8,E3-E4/4
-
- Lines may be up to 50 characters.
- A song may only contain up to 50 lines.
- "}
- else
- dat += "Show Help
"
- dat += ""
- user << browse(dat, "window=piano;size=700x300")
- onclose(user, "piano")
+ dat += "Show Help
"
+ dat += "